TuttleOFX
1
|
00001 #include "ColorSuppressProcess.hpp" 00002 #include "ColorSuppressPlugin.hpp" 00003 00004 namespace tuttle { 00005 namespace plugin { 00006 namespace colorSuppress { 00007 00008 template<typename T> 00009 T luminance( const T r, const T g, const T b ) 00010 { 00011 static const T redCoef = 0.2989; 00012 static const T greenCoef = 0.5866; 00013 static const T blueCoef = 0.1145; 00014 00015 return r * redCoef + g * greenCoef + b * blueCoef; 00016 } 00017 00018 double luminance( const OfxRGBAColourD& color ) 00019 { 00020 return luminance( color.r, color.g, color.b ); 00021 } 00022 00023 template<class View> 00024 ColorSuppressProcess<View>::ColorSuppressProcess( ColorSuppressPlugin &instance ) 00025 : ImageGilFilterProcessor<View>( instance, eImageOrientationIndependant ) 00026 , _plugin( instance ) 00027 {} 00028 00029 template<class View> 00030 void ColorSuppressProcess<View>::setup( const OFX::RenderArguments& args ) 00031 { 00032 ImageGilFilterProcessor<View>::setup( args ); 00033 00034 _params = _plugin.getProcessParams( ); 00035 } 00036 00037 /** 00038 * @brief Function called by rendering thread each time a process must be done. 00039 * @param[in] procWindowRoW Processing window in RoW 00040 */ 00041 template<class View> 00042 void ColorSuppressProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00043 { 00044 using namespace boost::gil; 00045 const OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW ); 00046 const OfxPointI procWindowSize = { 00047 procWindowRoW.x2 - procWindowRoW.x1, 00048 procWindowRoW.y2 - procWindowRoW.y1 00049 }; 00050 00051 /// @todo use a gil functor 00052 // transform_pixels_progress( 00053 // src, 00054 // dst, 00055 // pixel_suppres_color_t(), 00056 // *this 00057 // ); 00058 00059 OfxRGBAColourD input, output, save; 00060 00061 //For suppressing warning 00062 save.r = save.g = save.b = save.a = .0; 00063 00064 for( int y = procWindowOutput.y1; 00065 y < procWindowOutput.y2; 00066 ++y ) 00067 { 00068 typename View::x_iterator src_it = this->_srcView.x_at( procWindowOutput.x1, y ); 00069 typename View::x_iterator dst_it = this->_dstView.x_at( procWindowOutput.x1, y ); 00070 for( int x = procWindowOutput.x1; 00071 x < procWindowOutput.x2; 00072 ++x, ++src_it, ++dst_it ) 00073 { 00074 double suppressed = 0; 00075 input.r = ( *src_it )[ 0 ]; 00076 input.g = ( *src_it )[ 1 ]; 00077 input.b = ( *src_it )[ 2 ]; 00078 input.a = ( *src_it )[ 3 ]; 00079 output = input; 00080 00081 double luma1 = .0; 00082 if( _params.preserveLuma == true ) 00083 { 00084 luma1 = luminance( input ); 00085 } 00086 if( _params.output == eOutputTypeAlpha || _params.obeyAlpha == true ) 00087 { 00088 save = input; 00089 } 00090 if( _params.yellow > 0.0 ) 00091 { 00092 if( output.b < output.g && output.b < output.r ) 00093 { 00094 double diff1 = output.g - output.b; 00095 double diff2 = output.r - output.b; 00096 diff1 *= _params.yellow; 00097 diff2 *= _params.yellow; 00098 if( diff1 > diff2 ) 00099 { 00100 output.g -= diff2; 00101 output.r -= diff2; 00102 suppressed += diff2; 00103 } 00104 else 00105 { 00106 output.g -= diff1; 00107 output.r -= diff1; 00108 suppressed += diff1; 00109 } 00110 } 00111 } 00112 if( _params.magenta > 0.0 ) 00113 { 00114 if( output.g < output.b && output.g < output.r ) 00115 { 00116 double diff1 = output.b - output.g; 00117 double diff2 = output.r - output.g; 00118 diff1 *= _params.magenta; 00119 diff2 *= _params.magenta; 00120 if( diff1 > diff2 ) 00121 { 00122 output.b -= diff2; 00123 output.r -= diff2; 00124 suppressed += diff2; 00125 } 00126 else 00127 { 00128 output.b -= diff1; 00129 output.r -= diff1; 00130 suppressed += diff1; 00131 } 00132 } 00133 } 00134 if( _params.cyan > 0.0 ) 00135 { 00136 if( output.r < output.g && output.r < output.b ) 00137 { 00138 double diff1 = output.g - output.r; 00139 double diff2 = output.b - output.r; 00140 diff1 *= _params.cyan; 00141 diff2 *= _params.cyan; 00142 if( diff1 > diff2 ) 00143 { 00144 output.g -= diff2; 00145 output.b -= diff2; 00146 suppressed += diff2; 00147 } 00148 else 00149 { 00150 output.g -= diff1; 00151 output.b -= diff1; 00152 suppressed += diff1; 00153 } 00154 } 00155 } 00156 if( _params.red > 0.0 ) 00157 { 00158 if( output.r > output.g && output.r > output.b ) 00159 { 00160 double diff1; 00161 if( output.g < output.b ) 00162 { 00163 diff1 = output.r - output.b; 00164 } 00165 else 00166 { 00167 diff1 = output.r - output.g; 00168 } 00169 diff1 *= _params.red; 00170 output.r -= diff1; 00171 suppressed += diff1; 00172 } 00173 } 00174 if( _params.green > 0.0 ) 00175 { 00176 if( output.g > output.b && output.g > output.r ) 00177 { 00178 double diff1; 00179 if( output.b < output.r ) 00180 { 00181 diff1 = output.g - output.r; 00182 } 00183 else 00184 { 00185 diff1 = output.g - output.b; 00186 } 00187 diff1 *= _params.green; 00188 output.g -= diff1; 00189 suppressed += diff1; 00190 } 00191 } 00192 if( _params.blue > 0.0 ) 00193 { 00194 if( output.b > output.g && output.b > output.r ) 00195 { 00196 double diff1; 00197 if( output.g < output.r ) 00198 { 00199 diff1 = output.b - output.r; 00200 } 00201 else 00202 { 00203 diff1 = output.b - output.g; 00204 } 00205 diff1 *= _params.blue; 00206 output.b -= diff1; 00207 suppressed += diff1; 00208 } 00209 } 00210 if( _params.output == eOutputTypeAlpha || _params.output == eOutputTypeAlphaImage ) 00211 { 00212 output.a = suppressed; 00213 } 00214 if( _params.preserveLuma == true && _params.output != eOutputTypeAlpha ) 00215 { 00216 double luma2 = luminance( output ); 00217 luma2 = luma1 - luma2; 00218 output.r += luma2; 00219 output.g += luma2; 00220 output.b += luma2; 00221 } 00222 if( _params.obeyAlpha == true ) 00223 { 00224 output.r = save.a * output.r + ( 1.0 - save.a ) * save.r; 00225 output.g = save.a * output.g + ( 1.0 - save.a ) * save.g; 00226 output.b = save.a * output.b + ( 1.0 - save.a ) * save.b; 00227 if( _params.output != eOutputTypeImage ) 00228 { 00229 output.a = save.a + ( 1.0 - save.a ) * output.a; 00230 } 00231 } 00232 if( _params.output == eOutputTypeAlpha ) 00233 { 00234 output.r = save.r; 00235 output.g = save.g; 00236 output.b = save.b; 00237 } 00238 ( *dst_it )[ 0 ] = output.r; 00239 ( *dst_it )[ 1 ] = output.g; 00240 ( *dst_it )[ 2 ] = output.b; 00241 ( *dst_it )[ 3 ] = output.a; 00242 } 00243 if( this->progressForward( procWindowSize.x ) ) 00244 return; 00245 } 00246 } 00247 00248 } 00249 } 00250 } 00251