TuttleOFX  1
NLMDenoiserPlugin.cpp
Go to the documentation of this file.
00001 #include "NLMDenoiserPlugin.hpp"
00002 #include "NLMDenoiserProcess.hpp"
00003 #include "NLMDenoiserDefinitions.hpp"
00004 
00005 #include <ofxsImageEffect.h>
00006 #include <ofxsMultiThread.h>
00007 
00008 #include <boost/gil/gil_all.hpp>
00009 
00010 namespace tuttle {
00011 namespace plugin {
00012 namespace nlmDenoiser {
00013 
00014 
00015 template<class T>
00016 inline T clamp( const T& v, const T& min, const T& max )
00017 {
00018         if( v < min )
00019                 return min;
00020         if( v > max )
00021                 return max;
00022         return v;
00023 }
00024 
00025 NLMDenoiserPlugin::NLMDenoiserPlugin( OfxImageEffectHandle handle )
00026 : OFX::ImageEffect( handle )
00027 , _clipDst( 0 )
00028 , _clipSrc( 0 )
00029 {
00030         _clipSrc = fetchClip( kOfxImageEffectSimpleSourceClipName );
00031         _clipDst = fetchClip( kOfxImageEffectOutputClipName );
00032         _paramDepth = fetchIntParam( kParamDepth );
00033         _paramRegionRadius = fetchIntParam( kParamRegionRadius );
00034         _paramPatchRadius = fetchIntParam( kParamPatchRadius );
00035 }
00036 
00037 /**
00038  * Obtain a window of frames before and after the current frame.
00039  * This is needed because our denoiser has a video option.
00040  */
00041 void NLMDenoiserPlugin::getFramesNeeded( const OFX::FramesNeededArguments &args, OFX::FramesNeededSetter &frames )
00042 {
00043     const int depth = _paramDepth->getValue();
00044         
00045     const OfxRangeD clipFullRange = _clipSrc->getFrameRange( );
00046 //      TUTTLE_TLOG_VAR2( TUTTLE_INFO, clipFullRange.min, clipFullRange.max );
00047         OfxRangeD requestedRange;
00048         requestedRange.min = args.time - depth;
00049         requestedRange.max = args.time + depth;
00050 //      TUTTLE_TLOG_VAR2( TUTTLE_INFO, requestedRange.min, requestedRange.max );
00051         OfxRangeD realRange;
00052         realRange.min = clamp( requestedRange.min, clipFullRange.min, clipFullRange.max );
00053         realRange.max = clamp( requestedRange.max, clipFullRange.min, clipFullRange.max );
00054 //      TUTTLE_TLOG_VAR2( TUTTLE_INFO, realRange.min, realRange.max );
00055         
00056     frames.setFramesNeeded( *_clipSrc, realRange );
00057 //      TUTTLE_TLOG( TUTTLE_INFO, "NLMDenoiserPlugin::getFramesNeeded timerange min:" << realRange.min << ", max:" << realRange.max << " for time:" << args.time );
00058 }
00059 
00060 
00061 void NLMDenoiserPlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois )
00062 {
00063         const double margin = ( _paramRegionRadius->getValue() + _paramPatchRadius->getValue() ) * _clipSrc->getPixelAspectRatio();
00064 
00065         const OfxRectD roi = {
00066                         double(args.regionOfInterest.x1 - margin),
00067                         double(args.regionOfInterest.y1 - margin),
00068                         double(args.regionOfInterest.x2 + margin + 1),
00069                         double(args.regionOfInterest.y2 + margin + 1)
00070                 };
00071 
00072         rois.setRegionOfInterest( *_clipSrc, roi );
00073 }
00074 
00075 
00076 /**
00077  * @brief The overridden render function
00078  * @param[in]   args     Rendering parameters
00079  */
00080 void NLMDenoiserPlugin::render( const OFX::RenderArguments &args )
00081 {
00082     // instantiate the render code based on the pixel depth of the dst clip
00083     OFX::EBitDepth dstBitDepth = _clipDst->getPixelDepth( );
00084     OFX::EPixelComponent dstComponents = _clipDst->getPixelComponents( );
00085         
00086     // do the rendering
00087     switch( dstComponents )
00088         {
00089                 case OFX::ePixelComponentRGBA:
00090                 {
00091                         switch( dstBitDepth )
00092                         {
00093                                 case OFX::eBitDepthUByte :
00094                                 {
00095                                         NLMDenoiserProcess<boost::gil::rgba8_view_t> fred( *this );
00096                                         fred.setupAndProcess( args );
00097                                         break;
00098                                 }
00099                                 case OFX::eBitDepthUShort :
00100                                 {
00101                                         NLMDenoiserProcess<boost::gil::rgba16_view_t> fred( *this );
00102                                         fred.setupAndProcess( args );
00103                                         break;
00104                                 }
00105                                 case OFX::eBitDepthFloat :
00106                                 {
00107                                         NLMDenoiserProcess<boost::gil::rgba32f_view_t> fred( *this );
00108                                         fred.setupAndProcess( args );
00109                                         break;
00110                                 }
00111                                 case OFX::eBitDepthCustom:
00112                                 case OFX::eBitDepthNone:
00113                                 {
00114                                         TUTTLE_LOG_ERROR( "Bit depth (" << mapBitDepthEnumToString(dstBitDepth) << ") not recognized by the plugin." );
00115                                         break;
00116                                 }
00117                         }
00118                         break;
00119                 }
00120                 case OFX::ePixelComponentRGB:
00121                 {
00122                         switch( dstBitDepth )
00123                         {
00124                                 case OFX::eBitDepthUByte:
00125                                 {
00126                                         NLMDenoiserProcess<boost::gil::rgb8_view_t> fred( *this );
00127                                         fred.setupAndProcess( args );
00128                                         break;
00129                                 }
00130                                 case OFX::eBitDepthUShort:
00131                                 {
00132                                         NLMDenoiserProcess<boost::gil::rgb16_view_t> fred( *this );
00133                                         fred.setupAndProcess( args );
00134                                         break;
00135                                 }
00136                                 case OFX::eBitDepthFloat:
00137                                 {
00138                                         NLMDenoiserProcess<boost::gil::rgb32f_view_t> fred( *this );
00139                                         fred.setupAndProcess( args );
00140                                         break;
00141                                 }
00142                                 case OFX::eBitDepthCustom:
00143                                 case OFX::eBitDepthNone:
00144                                 {
00145                                         TUTTLE_LOG_ERROR( "Bit depth (" << mapBitDepthEnumToString(dstBitDepth) << ") not recognized by the plugin." );
00146                                         break;
00147                                 }
00148                         }
00149                         break;
00150                 }
00151                 case OFX::ePixelComponentAlpha:
00152                 {
00153                         switch( dstBitDepth )
00154                         {
00155                                 case OFX::eBitDepthUByte:
00156                                 {
00157                                         NLMDenoiserProcess<boost::gil::gray8_view_t> fred( *this );
00158                                         fred.setupAndProcess( args );
00159                                         break;
00160                                 }
00161                                 case OFX::eBitDepthUShort:
00162                                 {
00163                                         NLMDenoiserProcess<boost::gil::gray16_view_t> fred( *this );
00164                                         fred.setupAndProcess( args );
00165                                         break;
00166                                 }
00167                                 case OFX::eBitDepthFloat:
00168                                 {
00169                                         NLMDenoiserProcess<boost::gil::gray32f_view_t> fred( *this );
00170                                         fred.setupAndProcess( args );
00171                                         break;
00172                                 }
00173                                 case OFX::eBitDepthCustom:
00174                                 case OFX::eBitDepthNone:
00175                                 {
00176                                         TUTTLE_LOG_ERROR( "Bit depth (" << mapBitDepthEnumToString(dstBitDepth) << ") not recognized by the plugin." );
00177                                         break;
00178                                 }
00179                         }
00180                         break;
00181                 }
00182                 case OFX::ePixelComponentCustom:
00183                 case OFX::ePixelComponentNone:
00184                 {
00185                         TUTTLE_LOG_ERROR( "Pixel components (" << mapPixelComponentEnumToString(dstComponents) << ") not supported by the plugin." );
00186                         break;
00187                 }
00188         }
00189 }
00190 
00191 }
00192 }
00193 }