TuttleOFX
1
|
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 }