TuttleOFX  1
MergePluginFactory.cpp
Go to the documentation of this file.
00001 #include "MergePluginFactory.hpp"
00002 #include "MergePlugin.hpp"
00003 #include "MergeDefinitions.hpp"
00004 
00005 #include <tuttle/plugin/global.hpp>
00006 #include <tuttle/plugin/exceptions.hpp>
00007 
00008 #include <ofxsImageEffect.h>
00009 #include <ofxsMultiThread.h>
00010 
00011 namespace tuttle {
00012 namespace plugin {
00013 namespace merge {
00014 
00015 /**
00016  * @brief Function called to describe the plugin main features.
00017  * @param[in, out]   desc     Effect descriptor
00018  */
00019 void MergePluginFactory::describe( OFX::ImageEffectDescriptor& desc )
00020 {
00021         desc.setLabels( "TuttleMerge", "Merge",
00022                         "Merge two images" );
00023         desc.setPluginGrouping( "tuttle/image/process/transition" );
00024 
00025         desc.setDescription( "Clip merging\n"
00026                              "Plugin is used to merge two clips A and B." );
00027 
00028         // add the supported contexts
00029         desc.addSupportedContext( OFX::eContextGeneral );
00030         
00031         // add supported pixel depths
00032         desc.addSupportedBitDepth( OFX::eBitDepthUByte );
00033         desc.addSupportedBitDepth( OFX::eBitDepthUShort );
00034         desc.addSupportedBitDepth( OFX::eBitDepthFloat );
00035 
00036         // plugin flags
00037         desc.setSupportsTiles( kSupportTiles );
00038         desc.setRenderThreadSafety( OFX::eRenderFullySafe );
00039 }
00040 
00041 /**
00042  * @brief Function called to describe the plugin controls and features.
00043  * @param[in, out]   desc       Effect descriptor
00044  * @param[in]        context    Application context
00045  */
00046 void MergePluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
00047                                             OFX::EContext               context )
00048 {
00049         OFX::ClipDescriptor* srcClipB = desc.defineClip( kParamSourceB );
00050         srcClipB->addSupportedComponent( OFX::ePixelComponentRGBA );
00051         srcClipB->addSupportedComponent( OFX::ePixelComponentRGB );
00052         srcClipB->addSupportedComponent( OFX::ePixelComponentAlpha );
00053         srcClipB->setSupportsTiles( kSupportTiles );
00054         srcClipB->setOptional( false );
00055 
00056         OFX::ClipDescriptor* srcClipA = desc.defineClip( kParamSourceA );
00057         srcClipA->addSupportedComponent( OFX::ePixelComponentRGBA );
00058         srcClipA->addSupportedComponent( OFX::ePixelComponentRGB );
00059         srcClipA->addSupportedComponent( OFX::ePixelComponentAlpha );
00060         srcClipA->setSupportsTiles( kSupportTiles );
00061         srcClipA->setOptional( false );
00062 
00063         // Create the mandated output clip
00064         OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
00065         dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
00066         dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
00067         dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
00068         dstClip->setSupportsTiles( kSupportTiles );
00069 
00070         // Define some merging function
00071         OFX::ChoiceParamDescriptor* mergeFunction = desc.defineChoiceParam( kParamFunction );
00072         mergeFunction->setLabels( kParamFunctionLabel, kParamFunctionLabel, kParamFunctionLabel );
00073         mergeFunction->appendOption( "atop", "atop: Ab+B(1-a)" );
00074         mergeFunction->appendOption( "average", "average: (A+B)/2" );
00075         mergeFunction->appendOption( "color", "color: hue from B, saturation from B, lightness from A" );
00076         mergeFunction->appendOption( "color-burn", "color-burn: darken B towards A" );
00077         mergeFunction->appendOption( "color dodge inversed", "color dodge inversed: brighten B towards A" );
00078         mergeFunction->appendOption( "conjoint-over", "conjoint-over: A+B(1-a)/b, A if a > b" );
00079         mergeFunction->appendOption( "copy", "copy: A" );
00080         mergeFunction->appendOption( "difference", "difference: abs(A-B)" );
00081         mergeFunction->appendOption( "disjoint-over", "disjoint-over: A+B(1-a)/b, A+B if a+b < 1" );
00082         mergeFunction->appendOption( "divide", "divide: A/B, 0 if A < 0 and B < 0" );
00083         mergeFunction->appendOption( "exclusion", "exclusion: A+B-2AB" );
00084         mergeFunction->appendOption( "freeze", "freeze: 1-sqrt(1-A)/B" );
00085         mergeFunction->appendOption( "from", "from: B-A" );
00086         mergeFunction->appendOption( "geometric", "geometric: 2AB/(A+B)" );
00087         mergeFunction->appendOption( "hard-light", "hard-light: multiply if A < 0.5, screen if A > 0.5" );
00088         mergeFunction->appendOption( "hypot", "hypot: sqrt(A*A+B*B)" );
00089         mergeFunction->appendOption( "in", "in: Ab" );
00090         mergeFunction->appendOption( "interpolated", "interpolated: (like average but better and slower)" );
00091         mergeFunction->appendOption( "mask", "mask: Ba" );
00092         mergeFunction->appendOption( "matte", "matte: Aa + B(1-a) (unpremultiplied over)" );
00093         mergeFunction->appendOption( "lighten", "lighten: max(A, B)" );
00094         mergeFunction->appendOption( "darken", "darken: min(A, B)" );
00095         mergeFunction->appendOption( "minus", "minus: A-B" );
00096         mergeFunction->appendOption( "multiply", "multiply: AB, 0 if A < 0 and B < 0" );
00097         mergeFunction->appendOption( "out", "out: A(1-b)" );
00098         mergeFunction->appendOption( "over", "over: A+B(1-a)" );
00099         mergeFunction->appendOption( "overlay", "overlay: multiply if B<0.5, screen if B>0.5" );
00100         mergeFunction->appendOption( "pinlight", "pinlight: if B >= 0.5 then max(A, 2*B - 1), min(A, B * 2.0 ) else" );
00101         mergeFunction->appendOption( "plus", "plus: A+B" );
00102         mergeFunction->appendOption( "reflect", "reflect: a² / (1 - b)" );
00103         mergeFunction->appendOption( "screen", "screen: A+B-AB" );
00104         mergeFunction->appendOption( "stencil", "stencil: B(1-a)" );
00105         mergeFunction->appendOption( "under", "under: A(1-b)+B" );
00106         mergeFunction->appendOption( "xor", "xor: A(1-b)+B(1-a)" );
00107         mergeFunction->setDefault( eParamMergePlus );
00108         
00109         OFX::Int2DParamDescriptor* offsetA = desc.defineInt2DParam( kParamOffsetA );
00110         offsetA->setLabel( "A offset" );
00111         offsetA->setDefault( 0, 0 );
00112         offsetA->setDisplayRange( 0, 0, 300, 300 );
00113 
00114         OFX::Int2DParamDescriptor* offsetB = desc.defineInt2DParam( kParamOffsetB );
00115         offsetB->setLabel( "B offset" );
00116         offsetB->setDefault( 0, 0 );
00117         offsetB->setDisplayRange( 0, 0, 300, 300 );
00118 
00119         OFX::ChoiceParamDescriptor* rod = desc.defineChoiceParam( kParamRod );
00120         rod->appendOption( kParamRodIntersect );
00121         rod->appendOption( kParamRodUnion );
00122         rod->appendOption( kParamRodA );
00123         rod->appendOption( kParamRodB );
00124         rod->setDefault( eParamRodIntersect );
00125 }
00126 
00127 /**
00128  * @brief Function called to create a plugin effect instance
00129  * @param[in] handle  effect handle
00130  * @param[in] context    Application context
00131  * @return  plugin instance
00132  */
00133 OFX::ImageEffect* MergePluginFactory::createInstance( OfxImageEffectHandle handle,
00134                                                       OFX::EContext        context )
00135 {
00136         return new MergePlugin( handle );
00137 }
00138 
00139 }
00140 }
00141 }