TuttleOFX
1
|
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 }