TuttleOFX  1
ResizePlugin.cpp
Go to the documentation of this file.
00001 #include "ResizePlugin.hpp"
00002 #include "ResizeProcess.hpp"
00003 #include "ResizeDefinitions.hpp"
00004 
00005 #include <tuttle/plugin/ofxToGil/point.hpp>
00006 
00007 #include <terry/sampler/sampler.hpp>
00008 #include <terry/point/operations.hpp>
00009 
00010 #include <boost/gil/gil_all.hpp>
00011 
00012 #include <boost/numeric/conversion/cast.hpp>
00013 
00014 namespace tuttle {
00015 namespace plugin {
00016 namespace resize {
00017 
00018 using namespace ::terry::sampler;
00019 using boost::numeric_cast;
00020 
00021 ResizePlugin::ResizePlugin( OfxImageEffectHandle handle )
00022         : SamplerPlugin( handle )
00023 {
00024         _paramMode            = fetchChoiceParam   ( kParamMode );
00025 
00026         _paramFormat          = fetchChoiceParam   ( kParamFormat );
00027 
00028         _paramScale           = fetchDouble2DParam ( kParamModeScale );
00029         
00030         _paramSize            = fetchInt2DParam    ( kParamSize );
00031         _paramSizeWidth       = fetchIntParam      ( kParamSizeWidth );
00032         _paramSizeHeight      = fetchIntParam      ( kParamSizeHeight );
00033         _paramSizeOrientation = fetchChoiceParam   ( kParamSizeOrientation );
00034         _paramSizeKeepRatio   = fetchBooleanParam  ( kParamSizeKeepRatio );
00035 
00036 #ifndef TUTTLE_PRODUCTION
00037         _paramCenter          = fetchBooleanParam  ( kParamCenter );
00038         _paramCenterPoint     = fetchDouble2DParam ( kParamCenterPoint );
00039 #endif
00040 
00041         updateVisibleTools();
00042 }
00043 
00044 void ResizePlugin::updateVisibleTools()
00045 {
00046         OFX::InstanceChangedArgs args( this->timeLineGetTime() );
00047         changedParam( args, kParamMode );
00048 #ifndef TUTTLE_PRODUCTION
00049         changedParam( args, kParamCenter );
00050 #endif
00051         changedParam( args, kParamFilter );
00052         changedParam( args, kParamSizeKeepRatio );
00053         changedParam( args, kParamSizeOrientation );
00054 }
00055 
00056 ResizeProcessParams<ResizePlugin::Scalar> ResizePlugin::getProcessParams( const OfxPointD& renderScale ) const
00057 {
00058         ResizeProcessParams<Scalar> params;
00059 #ifndef TUTTLE_PRODUCTION
00060         OfxPointD centerPoint                           = _paramCenterPoint->getValue();
00061 
00062         params._centerPoint.x                           = centerPoint.x;
00063         params._centerPoint.y                           = centerPoint.y;
00064 
00065         params._changeCenter                            = _paramCenter->getValue();
00066 #endif
00067         SamplerPlugin::fillProcessParams( params._samplerProcessParams );
00068 
00069         return params;
00070 }
00071 
00072 void ResizePlugin::changedParam( const OFX::InstanceChangedArgs &args, const std::string &paramName )
00073 {
00074         SamplerPlugin::changedParam( args, paramName );
00075 
00076         if( paramName == kParamMode )
00077         {
00078                 switch( _paramMode->getValue() )
00079                 {
00080                         case eParamModeFormat:
00081                         {
00082                                 _paramScale           -> setIsSecretAndDisabled( true );
00083                                 _paramSize            -> setIsSecretAndDisabled( true );
00084                                 _paramSizeWidth       -> setIsSecretAndDisabled( true );
00085                                 _paramSizeHeight      -> setIsSecretAndDisabled( true );
00086                                 _paramSizeOrientation -> setIsSecretAndDisabled( true );
00087                                 _paramSizeKeepRatio   -> setIsSecretAndDisabled( true );
00088                                 
00089                                 _paramFormat          -> setIsSecretAndDisabled( false );
00090                                 break;
00091                         }
00092                         case eParamModeSize:
00093                         {
00094                                 const bool                  keepRatio   = _paramSizeKeepRatio->getValue();
00095                                 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue());
00096 
00097                                 _paramFormat          -> setIsSecretAndDisabled( true );
00098                                 _paramScale           -> setIsSecretAndDisabled( true );
00099 
00100                                 _paramSizeKeepRatio   -> setIsSecretAndDisabled( false );
00101 
00102                                 _paramSizeWidth       -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX );
00103                                 _paramSizeHeight      -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY );
00104                                 _paramSizeOrientation -> setIsSecretAndDisabled( ! keepRatio );
00105                                 _paramSize            -> setIsSecretAndDisabled( keepRatio );
00106                                 break;
00107                         }
00108                         case eParamModeScale:
00109                         {
00110                                 _paramFormat          -> setIsSecretAndDisabled( true );
00111                                 _paramSize            -> setIsSecretAndDisabled( true );
00112                                 _paramSizeWidth       -> setIsSecretAndDisabled( true );
00113                                 _paramSizeHeight      -> setIsSecretAndDisabled( true );
00114                                 _paramSizeOrientation -> setIsSecretAndDisabled( true );
00115                                 _paramSizeKeepRatio   -> setIsSecretAndDisabled( true );
00116                                 
00117                                 _paramScale           -> setIsSecretAndDisabled( false );
00118                                 break;
00119                         }
00120                 }
00121         }
00122         else if( paramName == kParamFormat && args.reason == OFX::eChangeUserEdit )
00123         {
00124                 std::size_t width  = 0;
00125                 std::size_t height = 0;
00126                 getFormatResolution( static_cast<EParamFormat>(_paramFormat->getValue()), width, height );
00127 
00128                 _paramMode            -> setValue( eParamModeFormat );
00129                 _paramSize            -> setValue( numeric_cast<int>(width), numeric_cast<int>(height) );
00130                 _paramSizeWidth       -> setValue( numeric_cast<int>(width) );
00131                 _paramSizeHeight      -> setValue( numeric_cast<int>(height) );
00132         }
00133         else if( paramName == kParamSize && args.reason == OFX::eChangeUserEdit )
00134         {
00135                 const OfxPointI s = _paramSize->getValue();
00136 
00137                 _paramMode->setValue( eParamModeSize );
00138                 _paramSizeWidth       -> setValue( s.x );
00139                 _paramSizeHeight      -> setValue( s.y );
00140         }
00141         else if( paramName == kParamSizeKeepRatio && args.reason == OFX::eChangeUserEdit )
00142         {
00143                 const bool                  keepRatio   = _paramSizeKeepRatio->getValue();
00144                 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue());
00145 
00146                 _paramSizeWidth       -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX );
00147                 _paramSizeHeight      -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY );
00148                 _paramSizeOrientation -> setIsSecretAndDisabled( ! keepRatio );
00149                 _paramSize            -> setIsSecretAndDisabled( keepRatio );
00150         }
00151         else if( paramName == kParamSizeOrientation && args.reason == OFX::eChangeUserEdit )
00152         {
00153                 const bool                  keepRatio   = _paramSizeKeepRatio->getValue();
00154                 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue());
00155 
00156                 _paramSizeWidth       -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX );
00157                 _paramSizeHeight      -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY );
00158         }
00159         else if( paramName == kParamSizeWidth && args.reason == OFX::eChangeUserEdit )
00160         {
00161                 _paramMode            -> setValue( eParamModeSize );
00162                 _paramSizeKeepRatio   -> setValue( true );
00163                 _paramSizeOrientation -> setValue( eParamSizeOrientationX );
00164                 
00165                 _paramSize            -> setValue( _paramSizeWidth->getValue(), _paramSize->getValue().y );
00166         }
00167         else if( paramName == kParamSizeHeight && args.reason == OFX::eChangeUserEdit )
00168         {
00169                 _paramMode            -> setValue( eParamModeSize );
00170                 _paramSizeKeepRatio   -> setValue( true );
00171                 _paramSizeOrientation -> setValue( eParamSizeOrientationY );
00172                 
00173                 _paramSize            -> setValue( _paramSize->getValue().x, _paramSizeHeight->getValue() );
00174         }
00175         else if( paramName == kParamScale && args.reason == OFX::eChangeUserEdit )
00176         {
00177                 _paramMode->setValue( eParamModeScale );
00178         }
00179 #ifndef TUTTLE_PRODUCTION
00180         else if( paramName == kParamCenter )
00181         {
00182                 if( _paramCenter->getValue() )
00183                 {
00184                         _paramCenterPoint->setIsSecretAndDisabled( false );
00185                 }
00186                 else
00187                 {
00188                         _paramCenterPoint->setIsSecretAndDisabled( true );
00189                 }
00190         }
00191 #endif
00192 }
00193 
00194 bool ResizePlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod )
00195 {
00196         using namespace boost::gil;
00197 
00198         const OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time );
00199         const Point2   srcRodSize( srcRod.x2 - srcRod.x1, srcRod.y2 - srcRod.y1 );
00200 //      const OfxRectD srcRodInDstFrame = { 0, 0, srcRodSize.x, srcRodSize.y };
00201 
00202         //OfxPointD centerPoint = _paramCenterPoint->getValue();
00203 
00204         //TUTTLE_LOG_INFO( centerPoint.x << " x " << centerPoint.y );
00205 
00206         ResizeProcessParams<Scalar> params = getProcessParams();
00207         
00208 //      TUTTLE_LOG_INFO( rod.x1 << ", " << rod.y1 << " || " << rod.x2 << ", " << rod.y2 );
00209 
00210         switch(_paramMode->getValue())
00211         {
00212                 case eParamModeFormat :
00213                 {
00214                         std::size_t width = 0;
00215                         std::size_t height = 0;
00216                         getFormatResolution( static_cast<EParamFormat>(_paramFormat->getValue()), width, height );
00217                         rod.x1 = 0;
00218                         rod.y1 = 0;
00219                         rod.x2 = width;
00220                         rod.y2 = height;
00221 
00222                         return true;
00223                 }
00224                 case eParamModeSize :
00225                 {
00226                         std::size_t sizex = 0;
00227                         std::size_t sizey = 0;
00228                         if( _paramSizeKeepRatio->getValue() )
00229                         {
00230                                 if( _paramSizeOrientation->getValue() == eParamSizeOrientationX )
00231                                 {
00232                                         sizex   = _paramSizeWidth->getValue();
00233                                         sizey   = srcRodSize.y / numeric_cast<double>(srcRodSize.x) * sizex;
00234                                 }
00235                                 else // direction == eParamSizeY
00236                                 {
00237                                         sizey   = _paramSizeHeight->getValue();
00238                                         sizex   = srcRodSize.x / numeric_cast<double>(srcRodSize.y) * sizey;
00239                                 }
00240                         }
00241                         else
00242                         {
00243                                 const OfxPointI s = _paramSize->getValue();
00244                                 sizex = s.x;
00245                                 sizey = s.y;
00246                         }
00247 
00248                         rod.x1 = 0;
00249                         rod.y1 = 0;
00250                         rod.x2 = sizex;
00251                         rod.y2 = sizey;
00252 
00253                         return true;
00254                 }
00255                 case eParamModeScale :
00256                 {
00257                         /*
00258                         const Point2 inA( srcRodInDstFrame.x1, srcRodInDstFrame.y1 ); // top left corner
00259                         const Point2 inB( srcRodInDstFrame.x2, srcRodInDstFrame.y2 ); // down right corner
00260                         const Point2 center( srcRodSize * 0.5 );
00261                         */
00262 
00263                         const Point2 scale = ofxToGil( _paramScale->getValue() );
00264                         if( scale.x == 0.0 || scale.y == 0.0 )
00265                                 return false;
00266 
00267                         const Point2 dstSize( srcRodSize * scale );
00268                         rod.x1 = 0;
00269                         rod.y1 = 0;
00270                         rod.x2 = dstSize.x;
00271                         rod.y2 = dstSize.y;
00272                         /*
00273                         const Point2 outA( center + ((inA - center) * scale) );
00274                         const Point2 outB( center + ((inB - center) * scale) );
00275                         rod.x1 = outA.x;
00276                         rod.y1 = outA.y;
00277                         rod.x2 = outB.x;
00278                         rod.y2 = outB.y;
00279                         */
00280                         
00281                         
00282 
00283                         return true;
00284                 }
00285         }
00286 
00287 //      TUTTLE_LOG_INFO( rod.x1 << ", " << rod.y1 << " || " << rod.x2 << ", " << rod.y2 );
00288         return false;
00289 }
00290 
00291 void ResizePlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois )
00292 {
00293         /*OfxRectD srcRoi;
00294         const OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time );
00295         srcRoi.x1 = srcRod.x1 - 1;
00296         srcRoi.y1 = srcRod.y1 - 1;
00297         srcRoi.x2 = srcRod.x2 + 1;
00298         srcRoi.y2 = srcRod.y2 + 1;
00299         rois.setRegionOfInterest( *_clipSrc, srcRoi );
00300 */
00301         /*ResizeProcessParams<Scalar> params = getProcessParams();
00302         OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time );
00303 //
00304         OfxRectD srcRoi;
00305         srcRoi.x1 = srcRod.x1 - 1;
00306         srcRoi.y1 = srcRod.y1 - 1;
00307         srcwRoi.x2 = srcRod.x2 + 1;
00308         srcRoi.y2 = srcRod.y2 + 1;
00309         rois.setRegionOfInterest( *_clipSrc, srcRoi );*/
00310         /*
00311         OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time );
00312         OfxRectD dstRod = _clipDst->getCanonicalRod( args.time );
00313 
00314         ResizeProcessParams<Scalar> params = getProcessParams();
00315 
00316         OfxRectD outputRoi = args.regionOfInterest;
00317         outputRoi.x1 -= dstRod.x1; // to dest rod coordinates
00318         outputRoi.y1 -= dstRod.y1;
00319         outputRoi.x2 -= dstRod.x1;
00320         outputRoi.y2 -= dstRod.y1;
00321         OfxRectD srcRoi = ;
00322         srcRoi.x1    += srcRod.x1; // to RoW coordinates
00323         srcRoi.y1    += srcRod.y1;
00324         srcRoi.x2    += srcRod.x1;
00325         srcRoi.y2    += srcRod.y1;
00326         outputRoi.x1 += dstRod.x1; // to RoW coordinates
00327         outputRoi.y1 += dstRod.y1;
00328         outputRoi.x2 += dstRod.x1;
00329         outputRoi.y2 += dstRod.y1;
00330         //    srcRoi.x1 += 2; // if we remove 2 pixels to the needed RoI the plugin crash, because it tries to access to this pixels
00331         //    srcRoi.y1 += 2; // so the calcul of the RoI has a precision of one pixel
00332         //    srcRoi.x2 -= 2;
00333         //    srcRoi.y2 -= 2;
00334         OfxRectD srcRealRoi = rectanglesIntersection( srcRoi, srcRod );
00335         srcRealRoi = srcRod;*/
00336 
00337         //rois.setRegionOfInterest( *_clipSrc, outputRoi );
00338 /*
00339         if( _debugDisplayRoi->getValue() )
00340         {
00341                 _srcRealRoi = srcRealRoi;
00342                 _srcRoi     = srcRoi;
00343                 _dstRoi     = outputRoi;
00344         }*/
00345 }
00346 
00347 bool ResizePlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, double& identityTime )
00348 {
00349 //      ResizeProcessParams<Scalar> params = getProcessParams();
00350 //      if( params._in == params._out )
00351 //      {
00352 //              identityClip = _clipSrc;
00353 //              identityTime = args.time;
00354 //              return true;
00355 //      }
00356         return false;
00357 }
00358 
00359 /**
00360  * @brief The overridden render function
00361  * @param[in]   args     Rendering parameters
00362  */
00363 void ResizePlugin::render( const OFX::RenderArguments &args )
00364 {
00365         doGilRender<ResizeProcess>( *this, args );
00366 }
00367 
00368 
00369 }
00370 }
00371 }