TuttleOFX  1
WriterPlugin.cpp
Go to the documentation of this file.
00001 #include "WriterPlugin.hpp"
00002 
00003 #include <ofxCore.h>
00004 
00005 #include <boost/scoped_ptr.hpp>
00006 
00007 #include <cstdio>
00008 
00009 namespace tuttle {
00010 namespace plugin {
00011 
00012 namespace bfs = boost::filesystem;
00013 
00014 WriterPlugin::WriterPlugin( OfxImageEffectHandle handle )
00015 : ImageEffectGilPlugin( handle )
00016 , _oneRender( false )
00017 , _oneRenderAtTime( 0 )
00018 {
00019         _clipSrc = fetchClip( kOfxImageEffectSimpleSourceClipName );
00020         _clipDst = fetchClip( kOfxImageEffectOutputClipName );
00021         _paramFilepath = fetchStringParam( kTuttlePluginFilename );
00022         _paramRenderButton = fetchPushButtonParam( kParamWriterRender );
00023         _paramRenderAlways = fetchBooleanParam( kParamWriterRenderAlways );
00024         _paramBitDepth = fetchChoiceParam( kTuttlePluginBitDepth );
00025         _paramPremult = fetchBooleanParam( kParamPremultiplied );
00026         _paramForceNewRender = fetchIntParam( kParamWriterForceNewRender );
00027         _isSequence = _filePattern.initFromDetection( _paramFilepath->getValue( ) );
00028 }
00029 
00030 WriterPlugin::~WriterPlugin( )
00031 {
00032 }
00033 
00034 void WriterPlugin::changedParam( const OFX::InstanceChangedArgs& args, const std::string& paramName )
00035 {
00036         if( paramName == kTuttlePluginFilename )
00037         {
00038                 _isSequence = _filePattern.initFromDetection( _paramFilepath->getValue( ) );
00039         }
00040         else if( paramName == kParamWriterRender )
00041         {
00042                 _oneRender = true;
00043                 _oneRenderAtTime = args.time;
00044                 // modify the plugin to force a new render
00045                 _paramForceNewRender->setValue( _paramForceNewRender->getValue( ) + 1 );
00046         }
00047 }
00048 
00049 void WriterPlugin::getClipPreferences( OFX::ClipPreferencesSetter& clipPreferences )
00050 {
00051         // If pattern detected (frame varying on time)
00052         clipPreferences.setOutputFrameVarying( varyOnTime( ) );
00053 }
00054 
00055 bool WriterPlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, OfxTime& identityTime )
00056 {
00057         // little hack for the push button Render
00058         if( _oneRender && _oneRenderAtTime == args.time )
00059         {
00060                 return false;
00061         }
00062         if( OFX::getImageEffectHostDescription( )->hostIsBackground )
00063         {
00064                 return false;
00065         }
00066         if( _paramRenderAlways->getValue( ) )
00067         {
00068                 return false;
00069         }
00070         identityClip = _clipSrc;
00071         identityTime = args.time;
00072         return true;
00073 }
00074 
00075 void WriterPlugin::beginSequenceRender( const OFX::BeginSequenceRenderArguments& args )
00076 {
00077         boost::filesystem::path dir( getAbsoluteDirectory( ) );
00078         if( !boost::filesystem::exists( dir ) )
00079         {
00080                 boost::filesystem::create_directories( dir );
00081         }
00082 }
00083 
00084 void WriterPlugin::render( const OFX::RenderArguments& args )
00085 {
00086         _oneRender = false;
00087 
00088         TUTTLE_LOG_INFO( "        --> " << getAbsoluteFilenameAt( args.time ) );
00089 
00090         boost::scoped_ptr<OFX::Image> src( _clipSrc->fetchImage( args.time ) );
00091         boost::scoped_ptr<OFX::Image> dst( _clipDst->fetchImage( args.time ) );
00092         
00093         // Copy buffer
00094         const OfxRectI bounds = dst->getBounds();
00095         TUTTLE_TLOG_VAR( TUTTLE_TRACE, bounds );
00096         if( src->isLinearBuffer() && dst->isLinearBuffer() )
00097         {
00098                 TUTTLE_TLOG( TUTTLE_TRACE, "isLinearBuffer" );
00099                 const std::size_t imageDataBytes = dst->getBoundsImageDataBytes();
00100                 TUTTLE_TLOG_VAR( TUTTLE_TRACE, imageDataBytes );
00101                 if( imageDataBytes )
00102                 {
00103                         void* dataSrcPtr = src->getPixelAddress( bounds.x1, bounds.y1 );
00104                         void* dataDstPtr = dst->getPixelAddress( bounds.x1, bounds.y1 );
00105                         memcpy( dataDstPtr, dataSrcPtr, imageDataBytes );
00106                 }
00107         }
00108         else
00109         {
00110                 const std::size_t rowBytesToCopy = dst->getBoundsRowDataBytes();
00111                 for( int y = bounds.y1; y < bounds.y2; ++y )
00112                 {
00113                         void* dataSrcPtr = src->getPixelAddress( bounds.x1, y );
00114                         void* dataDstPtr = dst->getPixelAddress( bounds.x1, y );
00115                         memcpy( dataDstPtr, dataSrcPtr, rowBytesToCopy );
00116                 }
00117         }
00118 }
00119 
00120 }
00121 }