TuttleOFX  1
ColorGradationProcess.tcc
Go to the documentation of this file.
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