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