TuttleOFX
1
|
00001 #include "NormalizePlugin.hpp" 00002 #include "NormalizeProcess.hpp" 00003 #include "NormalizeDefinitions.hpp" 00004 #include "NormalizeAlgorithm.hpp" 00005 00006 #include <tuttle/plugin/NoProgress.hpp> 00007 #include <tuttle/plugin/param/gilColor.hpp> 00008 00009 #include <terry/numeric/operations.hpp> 00010 #include <terry/numeric/assign.hpp> 00011 00012 #include <boost/gil/extension/color/convert.hpp> 00013 #include <boost/gil/gil_all.hpp> 00014 00015 namespace tuttle { 00016 namespace plugin { 00017 namespace normalize { 00018 00019 NormalizePlugin::NormalizePlugin( OfxImageEffectHandle handle ) 00020 : ImageEffectGilPlugin( handle ) 00021 { 00022 _mode = fetchChoiceParam( kParamMode ); 00023 _analyseMode = fetchChoiceParam( kParamAnalyseMode ); 00024 _analyseNow = fetchPushButtonParam( kParamAnalyseNow ); 00025 _srcGroup = fetchGroupParam( kParamSrcGroup ); 00026 _srcMinColor = fetchRGBAParam( kParamSrcCustomColorMin ); 00027 _srcMaxColor = fetchRGBAParam( kParamSrcCustomColorMax ); 00028 _dstGroup = fetchGroupParam( kParamDstGroup ); 00029 _dstMinColor = fetchRGBAParam( kParamDstCustomColorMin ); 00030 _dstMaxColor = fetchRGBAParam( kParamDstCustomColorMax ); 00031 _processGroup = fetchGroupParam( kParamProcessGroup ); 00032 _processR = fetchBooleanParam( kParamProcessR ); 00033 _processG = fetchBooleanParam( kParamProcessG ); 00034 _processB = fetchBooleanParam( kParamProcessB ); 00035 _processA = fetchBooleanParam( kParamProcessA ); 00036 00037 // init param props 00038 static const OFX::InstanceChangedArgs args; 00039 changedParam( args, kParamMode ); 00040 } 00041 00042 NormalizeProcessParams<NormalizePlugin::Scalar> NormalizePlugin::getProcessParams( const OfxPointD& renderScale ) const 00043 { 00044 using namespace boost::gil; 00045 NormalizeProcessParams<Scalar> params; 00046 00047 params._mode = static_cast<EParamMode>( _mode->getValue() ); 00048 params._analyseMode = static_cast<EParamAnalyseMode>( _analyseMode->getValue() ); 00049 00050 color_convert( ofxToGil( _srcMinColor->getValue() ), params._srcMinColor ); 00051 color_convert( ofxToGil( _srcMaxColor->getValue() ), params._srcMaxColor ); 00052 color_convert( ofxToGil( _dstMinColor->getValue() ), params._dstMinColor ); 00053 color_convert( ofxToGil( _dstMaxColor->getValue() ), params._dstMaxColor ); 00054 00055 params._processR = _processR->getValue(); 00056 params._processG = _processG->getValue(); 00057 params._processB = _processB->getValue(); 00058 params._processA = _processA->getValue(); 00059 00060 return params; 00061 } 00062 00063 void NormalizePlugin::changedParam( const OFX::InstanceChangedArgs &args, const std::string ¶mName ) 00064 { 00065 if( paramName == kParamMode ) 00066 { 00067 switch( static_cast<EParamMode>( _mode->getValue() ) ) 00068 { 00069 case eParamModeAnalyse: 00070 { 00071 _srcGroup->setIsSecretAndDisabled( true ); 00072 _srcMinColor->setIsSecretAndDisabled( true ); 00073 _srcMaxColor->setIsSecretAndDisabled( true ); 00074 _analyseNow->setIsSecretAndDisabled( true ); 00075 break; 00076 } 00077 case eParamModeCustom: 00078 { 00079 _srcGroup->setIsSecretAndDisabled( false ); 00080 _srcMinColor->setIsSecretAndDisabled( false ); 00081 _srcMaxColor->setIsSecretAndDisabled( false ); 00082 _analyseNow->setIsSecretAndDisabled( false ); 00083 break; 00084 } 00085 } 00086 } 00087 else if( paramName == kParamAnalyseNow ) 00088 { 00089 using namespace boost::gil; 00090 if( ! _clipSrc->isConnected() ) 00091 return; 00092 00093 boost::scoped_ptr<OFX::Image> src( _clipSrc->fetchImage( args.time ) ); 00094 if( ! src.get() ) 00095 BOOST_THROW_EXCEPTION( exception::ImageNotReady() ); 00096 if( src->getRowDistanceBytes() == 0 ) 00097 BOOST_THROW_EXCEPTION( exception::WrongRowBytes() ); 00098 OfxRectI srcPixelRod = _clipSrc->getPixelRod( args.time, args.renderScale ); 00099 00100 EParamAnalyseMode mode = static_cast<EParamAnalyseMode>( _analyseMode->getValue() ); 00101 NoProgress progress; 00102 00103 switch( _clipSrc->getPixelComponents() ) 00104 { 00105 case OFX::ePixelComponentRGBA: 00106 { 00107 TUTTLE_TLOG( TUTTLE_TRACE, "RGBA" ); 00108 rgba32f_pixel_t min, max; 00109 switch( _clipSrc->getPixelDepth() ) 00110 { 00111 case OFX::eBitDepthFloat: 00112 { 00113 typedef rgba32f_view_t View; 00114 typedef View::value_type Pixel; 00115 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00116 analyseInputMinMax<View>( srcView, mode, min, max, progress ); 00117 break; 00118 } 00119 case OFX::eBitDepthUShort: 00120 { 00121 typedef rgba16_view_t View; 00122 typedef View::value_type Pixel; 00123 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00124 Pixel smin, smax; 00125 analyseInputMinMax<View>( srcView, mode, smin, smax, progress ); 00126 color_convert(smin, min); 00127 color_convert(smax, max); 00128 break; 00129 } 00130 case OFX::eBitDepthUByte: 00131 { 00132 typedef rgba8_view_t View; 00133 typedef View::value_type Pixel; 00134 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00135 Pixel smin, smax; 00136 analyseInputMinMax<View>( srcView, mode, smin, smax, progress ); 00137 color_convert(smin, min); 00138 color_convert(smax, max); 00139 break; 00140 } 00141 case OFX::eBitDepthNone: 00142 case OFX::eBitDepthCustom: 00143 { 00144 BOOST_THROW_EXCEPTION( exception::Unsupported() ); 00145 } 00146 } 00147 setRGBAParamValues( _srcMinColor, min ); 00148 setRGBAParamValues( _srcMaxColor, max ); 00149 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, red_t() ) ); 00150 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, green_t() ) ); 00151 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, blue_t() ) ); 00152 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, alpha_t() ) ); 00153 00154 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, red_t() ) ); 00155 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, green_t() ) ); 00156 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, blue_t() ) ); 00157 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, alpha_t() ) ); 00158 break; 00159 } 00160 case OFX::ePixelComponentRGB: 00161 { 00162 TUTTLE_TLOG( TUTTLE_TRACE, "RGB" ); 00163 rgb32f_pixel_t min, max; 00164 switch( _clipSrc->getPixelDepth() ) 00165 { 00166 case OFX::eBitDepthFloat: 00167 { 00168 typedef rgb32f_view_t View; 00169 typedef View::value_type Pixel; 00170 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00171 analyseInputMinMax<View>( srcView, mode, min, max, progress ); 00172 break; 00173 } 00174 case OFX::eBitDepthUShort: 00175 { 00176 typedef rgb16_view_t View; 00177 typedef View::value_type Pixel; 00178 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00179 Pixel smin, smax; 00180 analyseInputMinMax<View>( srcView, mode, smin, smax, progress ); 00181 color_convert(smin, min); 00182 color_convert(smax, max); 00183 break; 00184 } 00185 case OFX::eBitDepthUByte: 00186 { 00187 typedef rgb8_view_t View; 00188 typedef View::value_type Pixel; 00189 View srcView = getGilView<View>( src.get(), srcPixelRod, eImageOrientationIndependant ); 00190 Pixel smin, smax; 00191 analyseInputMinMax<View>( srcView, mode, smin, smax, progress ); 00192 color_convert(smin, min); 00193 color_convert(smax, max); 00194 break; 00195 } 00196 case OFX::eBitDepthNone: 00197 case OFX::eBitDepthCustom: 00198 { 00199 BOOST_THROW_EXCEPTION( exception::Unsupported() ); 00200 } 00201 } 00202 setRGBParamValues( _srcMinColor, min ); 00203 setRGBParamValues( _srcMaxColor, max ); 00204 00205 TUTTLE_TLOG( TUTTLE_INFO, "results" ); 00206 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, red_t() ) ); 00207 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, green_t() ) ); 00208 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( min, blue_t() ) ); 00209 00210 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, red_t() ) ); 00211 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, green_t() ) ); 00212 TUTTLE_TLOG_VAR( TUTTLE_INFO, get_color( max, blue_t() ) ); 00213 break; 00214 } 00215 case OFX::ePixelComponentAlpha: 00216 { 00217 TUTTLE_TLOG( TUTTLE_TRACE, "alpha" ); 00218 break; 00219 } 00220 case OFX::ePixelComponentCustom: 00221 case OFX::ePixelComponentNone: 00222 { 00223 BOOST_THROW_EXCEPTION( exception::Unsupported() ); 00224 } 00225 } 00226 } 00227 } 00228 00229 void NormalizePlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois ) 00230 { 00231 NormalizeProcessParams<Scalar> params = getProcessParams(); 00232 OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time ); 00233 switch( params._mode ) 00234 { 00235 case eParamModeAnalyse: 00236 { 00237 // in this case, we need the full input image to do the analyse. 00238 rois.setRegionOfInterest( *_clipSrc, srcRod ); 00239 break; 00240 } 00241 case eParamModeCustom: 00242 { 00243 rois.setRegionOfInterest( *_clipSrc, args.regionOfInterest ); 00244 break; 00245 } 00246 } 00247 00248 } 00249 00250 bool NormalizePlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, double& identityTime ) 00251 { 00252 NormalizeProcessParams<Scalar> params = getProcessParams(); 00253 if( params._mode == eParamModeCustom && 00254 params._srcMinColor == params._dstMinColor && 00255 params._srcMaxColor == params._dstMaxColor ) 00256 { 00257 identityClip = _clipSrc; 00258 identityTime = args.time; 00259 return true; 00260 } 00261 return false; 00262 } 00263 00264 /** 00265 * @brief The overridden render function 00266 * @param[in] args Rendering parameters 00267 */ 00268 void NormalizePlugin::render( const OFX::RenderArguments &args ) 00269 { 00270 using namespace boost::gil; 00271 // instantiate the render code based on the pixel depth of the dst clip 00272 OFX::EBitDepth bitDepth = _clipDst->getPixelDepth( ); 00273 OFX::EPixelComponent components = _clipDst->getPixelComponents( ); 00274 00275 // do the rendering 00276 switch( components ) 00277 { 00278 case OFX::ePixelComponentRGBA: 00279 { 00280 switch( bitDepth ) 00281 { 00282 case OFX::eBitDepthFloat: 00283 { 00284 doGilRender<NormalizeProcess, false, rgba_layout_t, bits32f>( *this, args ); 00285 return; 00286 } 00287 case OFX::eBitDepthUShort: 00288 { 00289 doGilRender<NormalizeProcess, false, rgba_layout_t, bits16>( *this, args ); 00290 return; 00291 } 00292 case OFX::eBitDepthUByte: 00293 { 00294 doGilRender<NormalizeProcess, false, rgba_layout_t, bits8>( *this, args ); 00295 return; 00296 } 00297 case OFX::eBitDepthCustom: 00298 case OFX::eBitDepthNone: 00299 { 00300 BOOST_THROW_EXCEPTION( exception::Unsupported() 00301 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00302 } 00303 } 00304 break; 00305 } 00306 case OFX::ePixelComponentRGB: 00307 { 00308 switch( bitDepth ) 00309 { 00310 case OFX::eBitDepthFloat: 00311 { 00312 doGilRender<NormalizeProcess, false, rgb_layout_t, bits32f>( *this, args ); 00313 return; 00314 } 00315 case OFX::eBitDepthUShort: 00316 { 00317 doGilRender<NormalizeProcess, false, rgb_layout_t, bits16>( *this, args ); 00318 return; 00319 } 00320 case OFX::eBitDepthUByte: 00321 { 00322 doGilRender<NormalizeProcess, false, rgb_layout_t, bits8>( *this, args ); 00323 return; 00324 } 00325 case OFX::eBitDepthCustom: 00326 case OFX::eBitDepthNone: 00327 { 00328 BOOST_THROW_EXCEPTION( exception::Unsupported() 00329 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00330 } 00331 } 00332 break; 00333 } 00334 case OFX::ePixelComponentAlpha: 00335 { 00336 switch( bitDepth ) 00337 { 00338 case OFX::eBitDepthFloat: 00339 { 00340 doGilRender<NormalizeProcess, false, gray_layout_t, bits32f>( *this, args ); 00341 return; 00342 } 00343 case OFX::eBitDepthUShort: 00344 { 00345 doGilRender<NormalizeProcess, false, gray_layout_t, bits16>( *this, args ); 00346 return; 00347 } 00348 case OFX::eBitDepthUByte: 00349 { 00350 doGilRender<NormalizeProcess, false, gray_layout_t, bits8>( *this, args ); 00351 return; 00352 } 00353 case OFX::eBitDepthCustom: 00354 case OFX::eBitDepthNone: 00355 { 00356 BOOST_THROW_EXCEPTION( exception::Unsupported() 00357 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00358 } 00359 } 00360 break; 00361 } 00362 case OFX::ePixelComponentCustom: 00363 case OFX::ePixelComponentNone: 00364 { 00365 BOOST_THROW_EXCEPTION( exception::Unsupported() 00366 << exception::user() + "Pixel components (" + mapPixelComponentEnumToString(components) + ") not supported by the plugin." ); 00367 } 00368 } 00369 BOOST_THROW_EXCEPTION( exception::Unknown() ); 00370 } 00371 00372 00373 } 00374 } 00375 }