TuttleOFX
1
|
00001 #include "ColorGradationDefinitions.hpp" 00002 #include "ColorGradationProcess.hpp" 00003 #include "ColorGradationPlugin.hpp" 00004 00005 #include <tuttle/plugin/exceptions.hpp> 00006 #include <terry/typedefs.hpp> 00007 #include <terry/algorithm/transform_pixels_progress.hpp> 00008 00009 #include <terry/globals.hpp> 00010 #include <terry/copy.hpp> 00011 #include <terry/colorspace/gradation.hpp> 00012 00013 #include <boost/mpl/if.hpp> 00014 #include <boost/static_assert.hpp> 00015 00016 namespace tuttle { 00017 namespace plugin { 00018 namespace colorGradation { 00019 00020 using namespace boost::gil; 00021 00022 template<class View> 00023 ColorGradationProcess<View>::ColorGradationProcess( ColorGradationPlugin& effect ) 00024 : ImageGilFilterProcessor<View>( effect, eImageOrientationIndependant ) 00025 , _plugin( effect ) 00026 {} 00027 00028 template<class View> 00029 void ColorGradationProcess<View>::setup( const OFX::RenderArguments& args ) 00030 { 00031 ImageGilFilterProcessor<View>::setup( args ); 00032 00033 _params = _plugin.getProcessParams( args.renderScale ); 00034 00035 } 00036 00037 template<class View> 00038 template<class TIN, class TOUT> 00039 GIL_FORCEINLINE 00040 void ColorGradationProcess<View>::processSwitchAlpha( const bool processAlpha, const View& src, const View& dst, TIN gradationIn, TOUT gradationOut ) 00041 { 00042 using namespace boost::gil; 00043 if( processAlpha ) 00044 { 00045 terry::algorithm::transform_pixels_progress( src, dst, terry::color::transform_pixel_color_gradation_t<TIN, TOUT>( gradationIn, gradationOut ), *this ); 00046 } 00047 else 00048 { 00049 /// @todo do not apply process on alpha directly inside transform, with a "channel_for_each_if_channel" 00050 terry::algorithm::transform_pixels_progress( src, dst, terry::color::transform_pixel_color_gradation_t<TIN, TOUT>( gradationIn, gradationOut ), *this ); 00051 00052 // temporary solution copy alpha channel 00053 terry::copy_channel_if_exist<alpha_t>( src, dst ); 00054 } 00055 } 00056 00057 template<class View> 00058 template<class TIN> 00059 GIL_FORCEINLINE 00060 void ColorGradationProcess<View>::processSwitchOut( const EParamGradation out, const bool processAlpha, const View& src, const View& dst, TIN gradationIn ) 00061 { 00062 using namespace boost::gil; 00063 terry::color::gradation::Gamma gamma ( _params._GammaValueOut ); 00064 terry::color::gradation::Cineon cineon( _params._BlackPointOut, _params._WhitePointOut, _params._GammaSensitoOut ); 00065 switch( out ) 00066 { 00067 case eParamGradation_linear: 00068 processSwitchAlpha<TIN, terry::color::gradation::Linear> ( processAlpha, src, dst, gradationIn ); 00069 break; 00070 case eParamGradation_sRGB: 00071 processSwitchAlpha<TIN, terry::color::gradation::sRGB> ( processAlpha, src, dst, gradationIn ); 00072 break; 00073 case eParamGradation_Rec709: 00074 processSwitchAlpha<TIN, terry::color::gradation::Rec709>( processAlpha, src, dst, gradationIn ); 00075 break; 00076 case eParamGradation_cineon: 00077 processSwitchAlpha<TIN, terry::color::gradation::Cineon> ( processAlpha, src, dst, gradationIn, cineon ); 00078 break; 00079 case eParamGradation_gamma: 00080 processSwitchAlpha<TIN, terry::color::gradation::Gamma> ( processAlpha, src, dst, gradationIn, gamma ); 00081 break; 00082 case eParamGradation_panalog: 00083 processSwitchAlpha<TIN, terry::color::gradation::Panalog> ( processAlpha, src, dst, gradationIn ); 00084 break; 00085 case eParamGradation_REDLog: 00086 processSwitchAlpha<TIN, terry::color::gradation::REDLog> ( processAlpha, src, dst, gradationIn ); 00087 break; 00088 case eParamGradation_ViperLog: 00089 processSwitchAlpha<TIN, terry::color::gradation::ViperLog> ( processAlpha, src, dst, gradationIn ); 00090 break; 00091 case eParamGradation_REDSpace: 00092 processSwitchAlpha<TIN, terry::color::gradation::REDSpace> ( processAlpha, src, dst, gradationIn ); 00093 break; 00094 case eParamGradation_AlexaV3LogC: 00095 processSwitchAlpha<TIN, terry::color::gradation::AlexaV3LogC>( processAlpha, src, dst, gradationIn ); 00096 break; 00097 } 00098 } 00099 00100 template<class View> 00101 void ColorGradationProcess<View>::processSwitchInOut( const EParamGradation in, const EParamGradation out, const bool processAlpha, const View& src, const View& dst ) 00102 { 00103 using namespace boost::gil; 00104 terry::color::gradation::Gamma gamma ( _params._GammaValueIn ); 00105 terry::color::gradation::Cineon cineon( _params._BlackPointIn, _params._WhitePointIn, _params._GammaSensitoIn ); 00106 switch( in ) 00107 { 00108 case eParamGradation_linear: 00109 processSwitchOut<terry::color::gradation::Linear> ( out, processAlpha, src, dst ); 00110 break; 00111 case eParamGradation_sRGB: 00112 processSwitchOut<terry::color::gradation::sRGB> ( out, processAlpha, src, dst ); 00113 break; 00114 case eParamGradation_Rec709: 00115 processSwitchOut<terry::color::gradation::Rec709> ( out, processAlpha, src, dst ); 00116 break; 00117 case eParamGradation_cineon: 00118 processSwitchOut<terry::color::gradation::Cineon> ( out, processAlpha, src, dst, cineon ); 00119 break; 00120 case eParamGradation_gamma: 00121 processSwitchOut<terry::color::gradation::Gamma> ( out, processAlpha, src, dst, gamma ); 00122 break; 00123 case eParamGradation_panalog: 00124 processSwitchOut<terry::color::gradation::Panalog> ( out, processAlpha, src, dst ); 00125 break; 00126 case eParamGradation_REDLog: 00127 processSwitchOut<terry::color::gradation::REDLog> ( out, processAlpha, src, dst ); 00128 break; 00129 case eParamGradation_ViperLog: 00130 processSwitchOut<terry::color::gradation::ViperLog> ( out, processAlpha, src, dst ); 00131 break; 00132 case eParamGradation_REDSpace: 00133 processSwitchOut<terry::color::gradation::REDSpace> ( out, processAlpha, src, dst ); 00134 break; 00135 case eParamGradation_AlexaV3LogC: 00136 processSwitchOut<terry::color::gradation::AlexaV3LogC>( out, processAlpha, src, dst ); 00137 break; 00138 } 00139 } 00140 00141 /** 00142 * @brief Function called by rendering thread each time a process must be done. 00143 * @param[in] procWindowRoW Processing window 00144 */ 00145 template<class View> 00146 void ColorGradationProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00147 { 00148 using namespace boost::gil; 00149 OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW ); 00150 OfxPointI procWindowSize = { 00151 procWindowRoW.x2 - procWindowRoW.x1, 00152 procWindowRoW.y2 - procWindowRoW.y1 00153 }; 00154 00155 View src = subimage_view( this->_srcView, procWindowOutput.x1, procWindowOutput.y1, 00156 procWindowSize.x, 00157 procWindowSize.y ); 00158 View dst = subimage_view( this->_dstView, procWindowOutput.x1, procWindowOutput.y1, 00159 procWindowSize.x, 00160 procWindowSize.y ); 00161 00162 processSwitchInOut( _params._in, _params._out, _params._processAlpha, src, dst ); 00163 } 00164 00165 } 00166 } 00167 } 00168 00169