TuttleOFX  1
OCIOColorSpaceProcess.tcc
Go to the documentation of this file.
00001 #include "OCIOColorSpaceDefinitions.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 colorspace {
00019 
00020 
00021 
00022 template<class View>
00023 OCIOColorSpaceProcess<View>::OCIOColorSpaceProcess(OCIOColorSpacePlugin& instance) :
00024         ImageGilFilterProcessor<View> (instance, eImageOrientationIndependant),
00025         _plugin(instance)
00026 {
00027 }
00028 
00029 template<class View>
00030 void OCIOColorSpaceProcess<View>::setup(const OFX::RenderArguments& args)
00031 {
00032         ImageGilFilterProcessor<View>::setup(args);
00033         _params = _plugin.getProcessParams(args.renderScale);
00034         
00035         try
00036         {
00037                 // Load the current config.
00038                 _config = _params._config;
00039 
00040                 // Try to load the processor
00041                 _config->getProcessor(  _params._inputSpace.c_str(),  _params._outputSpace.c_str() );
00042         }
00043         catch(OCIO::Exception & exception)
00044         {
00045                 BOOST_THROW_EXCEPTION( exception::File() << exception::user(exception.what()) );
00046         }
00047         
00048 }
00049 
00050 /**
00051  * @brief Function called by rendering thread each time a process must be done.
00052  * @param[in] procWindowRoW  Processing window in RoW
00053  */
00054 template<class View>
00055 void OCIOColorSpaceProcess<View>::multiThreadProcessImages(
00056                 const OfxRectI& procWindowRoW)
00057 {
00058         
00059         OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates(
00060                         procWindowRoW);
00061         OfxPointI procWindowSize = { procWindowRoW.x2 - procWindowRoW.x1,
00062                         procWindowRoW.y2 - procWindowRoW.y1 };
00063 
00064         View src = subimage_view(this->_srcView, procWindowOutput.x1,
00065                         procWindowOutput.y1, procWindowSize.x, procWindowSize.y);
00066         View dst = subimage_view(this->_dstView, procWindowOutput.x1,
00067                         procWindowOutput.y1, procWindowSize.x, procWindowSize.y);
00068 
00069         applyLut(dst, src);
00070 }
00071 
00072 template<class View>
00073 void OCIOColorSpaceProcess<View>::applyLut(View& dst, View& src) {
00074         using namespace boost::gil;
00075         typedef typename View::x_iterator vIterator;
00076         typedef typename channel_type<View>::type Pixel;
00077 
00078         copy_pixels(src, dst);
00079 
00080         try
00081         {
00082                 OCIO::ConstProcessorRcPtr processor = _config->getProcessor( _params._inputSpace.c_str(), _params._outputSpace.c_str() );
00083                 
00084                 if (is_planar<View>::value)
00085                 {
00086                         BOOST_THROW_EXCEPTION( exception::NotImplemented() );
00087                 }
00088                 else
00089                 {
00090                         for (std::size_t y = 0; y < (unsigned int) dst.height(); ++y)
00091                         {
00092                                 // Wrap the image in a light-weight ImageDescription
00093                                 OCIO::PackedImageDesc imageDesc((float*) &(dst(0, y)[0]),
00094                                                 dst.width(), 1, num_channels<View>::type::value,
00095                                                 OCIO::AutoStride, dst.pixels().pixel_size(),
00096                                                 dst.pixels().row_size());
00097                                 // Apply the color transformation (in place)
00098                                 // Need normalized values
00099                                 processor->apply(imageDesc);
00100                                 if (this->progressForward(dst.width()))
00101                                         return;
00102                         }
00103                 }
00104                 
00105         }
00106         catch( OCIO::Exception & exception )
00107         {
00108                 BOOST_THROW_EXCEPTION( exception::Failed()
00109                         << exception::user() + "OCIO: " + exception.what() ) ;
00110         }
00111 }
00112 
00113 }
00114 }
00115 }
00116 }