TuttleOFX
1
|
00001 #include "ColorTransferPluginFactory.hpp" 00002 #include "ColorTransferPlugin.hpp" 00003 #include "ColorTransferDefinitions.hpp" 00004 #include "ofxsImageEffect.h" 00005 00006 #include <limits> 00007 00008 namespace tuttle { 00009 namespace plugin { 00010 namespace colorTransfer { 00011 00012 /** 00013 * @brief Function called to describe the plugin main features. 00014 * @param[in, out] desc Effect descriptor 00015 */ 00016 void ColorTransferPluginFactory::describe( OFX::ImageEffectDescriptor& desc ) 00017 { 00018 desc.setLabels( 00019 "TuttleColorTransfer", 00020 "ColorTransfer", 00021 "ColorTransfer" ); 00022 desc.setPluginGrouping( "tuttle/image/process/color" ); 00023 00024 desc.setDescription( 00025 "ColorTransfer\n" 00026 "\n" 00027 "The standard usage of this node is to impose one image's color characteristics to another.\n" 00028 "If srcRef input clip is not the same as the source clip, " 00029 "it applies the tranformation from srcRef to dstRef on the source clip.\n" 00030 "\n" 00031 "Warning: pixel values <= 0.0001 will be clamp, because these values " 00032 "are undefined in the colorspace used for the transformation.\n" 00033 "\n" 00034 "Technically, the node modify the statistics of the image in a particular colorspace lambda-alpha-beta.\n" 00035 "This colorspace, created by Rederman and al., is closed to the human perception and minimizes " 00036 "the correlation between channels for many natural scenes.\n" 00037 "However, a choice parameter allows the user to choose in which colorspace the color transfer should be processed: " 00038 "LMS, lambda-alpha-beta or original/source colorspace. \n" 00039 "According to the chosen colorspace, result varies (more or less colorfull, or dense...).\n\n" 00040 "For more details see the article:\n" 00041 "'Color Transfert between images' by Erik Reinhard, Michael Ashikhmin, Bruce Gooch and Peter Shirley. University of Utah.\n" 00042 ); 00043 00044 // add the supported contexts, only filter at the moment 00045 desc.addSupportedContext( OFX::eContextFilter ); 00046 desc.addSupportedContext( OFX::eContextGeneral ); 00047 00048 // add supported pixel depths 00049 desc.addSupportedBitDepth( OFX::eBitDepthUByte ); 00050 desc.addSupportedBitDepth( OFX::eBitDepthUShort ); 00051 desc.addSupportedBitDepth( OFX::eBitDepthFloat ); 00052 00053 // plugin flags 00054 desc.setSupportsTiles( true ); 00055 desc.setRenderThreadSafety( OFX::eRenderInstanceSafe ); 00056 } 00057 00058 /** 00059 * @brief Function called to describe the plugin controls and features. 00060 * @param[in, out] desc Effect descriptor 00061 * @param[in] context Application context 00062 */ 00063 void ColorTransferPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc, 00064 OFX::EContext context ) 00065 { 00066 OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); 00067 srcClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00068 srcClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00069 // srcClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00070 srcClip->setSupportsTiles( true ); 00071 00072 // Create the mandated output clip 00073 OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName ); 00074 dstClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00075 dstClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00076 // dstClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00077 dstClip->setSupportsTiles( true ); 00078 00079 OFX::ClipDescriptor* srcRefClip = desc.defineClip( kClipSrcRef ); 00080 srcRefClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00081 srcRefClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00082 // srcRefClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00083 srcRefClip->setSupportsTiles( false ); 00084 srcRefClip->setOptional( true ); 00085 00086 OFX::ClipDescriptor* dstRefClip = desc.defineClip( kClipDstRef ); 00087 dstRefClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00088 dstRefClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00089 // dstRefClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00090 dstRefClip->setSupportsTiles( false ); 00091 00092 OFX::ChoiceParamDescriptor* colorspace = desc.defineChoiceParam( kParamColorspace ); 00093 colorspace->setLabel( "Transformation colorspace" ); 00094 colorspace->setHint( "Select colorspace in which to apply the transformation" ); 00095 colorspace->appendOption( kParamColorspaceNone, "without colorspace transformation" ); 00096 colorspace->appendOption( kParamColorspaceLMS, "apply correction in LMS colorspace" ); 00097 colorspace->appendOption( kParamColorspaceLab, "apply correction in L(alpha)(beta) colorspace" ); 00098 colorspace->setDefault( eColorspaceLab ); 00099 00100 OFX::DoubleParamDescriptor* averageCoef = desc.defineDoubleParam( kParamAverageCoef ); 00101 averageCoef->setLabel( "Average color coef" ); 00102 averageCoef->setDisplayRange( 0.0, 1.0 ); 00103 averageCoef->setDefault( 0.8 ); 00104 averageCoef->setHint( 00105 "Percentage of correction of the average color.\n" 00106 "It is often advantageous to reduce this ratio, " 00107 "especially if the two images are very different. " 00108 "Typical values are between 0.5 and 0.8." 00109 ); 00110 00111 OFX::DoubleParamDescriptor* dynamicCoef = desc.defineDoubleParam( kParamDynamicCoef ); 00112 dynamicCoef->setLabel( "Dynamic coef" ); 00113 dynamicCoef->setDisplayRange( 0.0, 1.0 ); 00114 dynamicCoef->setDefault( 1.0 ); 00115 dynamicCoef->setHint( 00116 "Percentage of correction of the standard deviation." 00117 ); 00118 00119 // // output region 00120 // OFX::Double2DParamDescriptor* regionA = desc.defineDouble2DParam( kParamRegionA ); 00121 // regionA->setLabel( "Region" ); 00122 // regionA->setDefault( -0.5, -0.5 ); 00123 // regionA->setIsSecret( true ); ///< @todo 00124 // OFX::Double2DParamDescriptor* regionB = desc.defineDouble2DParam( kParamRegionB ); 00125 // regionB->setLabel( "" ); 00126 // regionB->setDefault( 0.5, 0.5 ); 00127 // regionB->setIsSecret( true ); ///< @todo 00128 // 00129 // // same region 00130 // OFX::BooleanParamDescriptor* sameRegion = desc.defineBooleanParam( kParamSameRegion ); 00131 // sameRegion->setDefault( true ); 00132 // sameRegion->setIsSecret( true ); ///< @todo 00133 // 00134 // // input region 00135 // OFX::Double2DParamDescriptor* inputRegionA = desc.defineDouble2DParam( kParamInputRegionA ); 00136 // inputRegionA->setLabel( "Input region" ); 00137 // inputRegionA->setDefault( -0.5, -0.5 ); 00138 // inputRegionA->setIsSecret( true ); ///< @todo 00139 // OFX::Double2DParamDescriptor* inputRegionB = desc.defineDouble2DParam( kParamInputRegionB ); 00140 // inputRegionB->setLabel( "" ); 00141 // inputRegionB->setDefault( 0.5, 0.5 ); 00142 // inputRegionB->setIsSecret( true ); ///< @todo 00143 } 00144 00145 /** 00146 * @brief Function called to create a plugin effect instance 00147 * @param[in] handle Effect handle 00148 * @param[in] context Application context 00149 * @return plugin instance 00150 */ 00151 OFX::ImageEffect* ColorTransferPluginFactory::createInstance( OfxImageEffectHandle handle, 00152 OFX::EContext context ) 00153 { 00154 return new ColorTransferPlugin( handle ); 00155 } 00156 00157 } 00158 } 00159 } 00160