TuttleOFX  1
OCIOLutProcess.tcc
Go to the documentation of this file.
00001 #include "OCIOLutDefinitions.hpp"
00002 
00003 #include <tuttle/plugin/global.hpp>
00004 #include <tuttle/plugin/ImageGilProcessor.hpp>
00005 #include <tuttle/plugin/exceptions.hpp>
00006 #include <terry/globals.hpp>
00007 
00008 #include <ofxsImageEffect.h>
00009 #include <ofxsMultiThread.h>
00010 
00011 #include <OpenColorIO/OpenColorIO.h>
00012 
00013 #include <boost/gil/gil_all.hpp>
00014 
00015 namespace tuttle {
00016 namespace plugin {
00017 namespace ocio {
00018 namespace lut {
00019 
00020 
00021 
00022 template<class View>
00023 OCIOLutProcess<View>::OCIOLutProcess(OCIOLutPlugin& instance) :
00024         ImageGilFilterProcessor<View> (instance, eImageOrientationIndependant),
00025         _plugin(instance)
00026 {
00027 }
00028 
00029 template<class View>
00030 void OCIOLutProcess<View>::setup(const OFX::RenderArguments& args)
00031 {
00032         ImageGilFilterProcessor<View>::setup(args);
00033         _params = _plugin.getProcessParams(args.renderScale);
00034         
00035         try {
00036                 fileTransform = OCIO::FileTransform::Create();
00037                 fileTransform->setSrc( _params._filename.c_str() );
00038                 fileTransform->setInterpolation( _params._interpolationType );
00039         
00040                 //Add the file transform to the group, required by the transform process
00041                 groupTransform = OCIO::GroupTransform::Create();
00042                 groupTransform->push_back( fileTransform );
00043         
00044                 // Create the OCIO processor for the specified transform.
00045                 config = OCIO::Config::Create();
00046         
00047                 OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create();
00048                 inputColorSpace->setName( kOCIOInputspace.c_str() );
00049                 
00050                 config->addColorSpace( inputColorSpace );
00051                 
00052                 OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create();
00053                 outputColorSpace->setName( kOCIOOutputspace.c_str()) ;
00054         
00055                 outputColorSpace->setTransform( groupTransform, OCIO::COLORSPACE_DIR_FROM_REFERENCE );
00056         
00057                 TUTTLE_TLOG( TUTTLE_WARNING, "Specified Transform:" << *(groupTransform) );
00058         
00059                 config->addColorSpace( outputColorSpace );
00060                 
00061                 // Try to load the processor
00062                 config->getProcessor( kOCIOInputspace.c_str(), kOCIOOutputspace.c_str() );
00063         }
00064         catch(OCIO::Exception & exception)
00065         {
00066                 BOOST_THROW_EXCEPTION( exception::File() << exception::user() + "OCIO Error: " + exception.what() );
00067         }
00068         
00069 }
00070 
00071 /**
00072  * @brief Function called by rendering thread each time a process must be done.
00073  * @param[in] procWindowRoW  Processing window in RoW
00074  */
00075 template<class View>
00076 void OCIOLutProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00077 {
00078         
00079         OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates(
00080                         procWindowRoW);
00081         OfxPointI procWindowSize = { procWindowRoW.x2 - procWindowRoW.x1,
00082                         procWindowRoW.y2 - procWindowRoW.y1 };
00083 
00084         View src = subimage_view(this->_srcView, procWindowOutput.x1,
00085                         procWindowOutput.y1, procWindowSize.x, procWindowSize.y);
00086         View dst = subimage_view(this->_dstView, procWindowOutput.x1,
00087                         procWindowOutput.y1, procWindowSize.x, procWindowSize.y);
00088 
00089         applyLut(dst, src);
00090 }
00091 
00092 template<class View>
00093 void OCIOLutProcess<View>::applyLut(View& dst, View& src) {
00094         using namespace boost::gil;
00095         typedef typename View::x_iterator vIterator;
00096         typedef typename channel_type<View>::type Pixel;
00097 
00098         copy_pixels(src, dst);
00099 
00100         try
00101         {
00102                 OCIO::ConstProcessorRcPtr processor = config->getProcessor( kOCIOInputspace.c_str(), kOCIOOutputspace.c_str() );
00103                 
00104                 if (is_planar<View>::value)
00105                 {
00106                         BOOST_THROW_EXCEPTION( exception::NotImplemented() );
00107                 }
00108                 else
00109                 {
00110                         for (std::size_t y = 0; y < (unsigned int) dst.height(); ++y)
00111                         {
00112                                 // Wrap the image in a light-weight ImageDescription
00113                                 OCIO::PackedImageDesc imageDesc((float*) &(dst(0, y)[0]),
00114                                                 dst.width(), 1, num_channels<View>::type::value,
00115                                                 OCIO::AutoStride, dst.pixels().pixel_size(),
00116                                                 dst.pixels().row_size());
00117                                 // Apply the color transformation (in place)
00118                                 // Need normalized values
00119                                 processor->apply(imageDesc);
00120                                 if (this->progressForward(dst.width()))
00121                                         return;
00122                         }
00123                 }
00124         }
00125         catch (OCIO::Exception & exception)
00126         {
00127                 BOOST_THROW_EXCEPTION( exception::Failed() << exception::user() + "OCIO Error: " + exception.what() );
00128         }
00129 }
00130 
00131 }
00132 }
00133 }
00134 }