TuttleOFX
1
|
00001 #include "HistogramKeyerPluginFactory.hpp" 00002 #include "HistogramKeyerPlugin.hpp" 00003 #include "HistogramKeyerDefinitions.hpp" 00004 #include "HistogramKeyerOverlay.hpp" 00005 00006 #include <limits> 00007 00008 namespace tuttle { 00009 namespace plugin { 00010 namespace histogramKeyer { 00011 00012 static const bool kSupportTiles = true; 00013 00014 00015 /** 00016 * @brief Function called to describe the plugin main features. 00017 * @param[in, out] desc Effect descriptor 00018 */ 00019 void HistogramKeyerPluginFactory::describe( OFX::ImageEffectDescriptor& desc ) 00020 { 00021 // describe the plugin 00022 desc.setLabels( "TuttleHistogramKeyer", "HistogramKeyer", 00023 "HistogramKeyer" ); 00024 desc.setPluginGrouping( "tuttle/image/process/color" ); 00025 00026 desc.setDescription( 00027 "HistogramKeyer\n" 00028 "This histogram keyer plugin allows user to create an alpha mask using HSL & RGB curves. Output can be in gray scale or directly in alpha channel (RGBA)." 00029 "There are some selection parameters which could help you to refine your maniplulation (control points unders histograms and quantity)." 00030 "A reverse output mask is also implemented.\n" 00031 "\n" 00032 ); 00033 00034 // add the supported contexts, only filter at the moment 00035 desc.addSupportedContext( OFX::eContextFilter ); 00036 desc.addSupportedContext( OFX::eContextGeneral ); 00037 00038 // add supported pixel depths 00039 desc.addSupportedBitDepth( OFX::eBitDepthUByte ); 00040 desc.addSupportedBitDepth( OFX::eBitDepthUShort ); 00041 desc.addSupportedBitDepth( OFX::eBitDepthFloat ); 00042 00043 // plugin flags 00044 desc.setSupportsTiles( kSupportTiles ); 00045 desc.setRenderThreadSafety( OFX::eRenderFullySafe ); 00046 00047 desc.setOverlayInteractDescriptor( new OFX::DefaultEffectOverlayWrap<HistogramKeyerOverlayDescriptor>() ); 00048 00049 if( ! OFX::getImageEffectHostDescription()->supportsParametricParameter ) 00050 { 00051 BOOST_THROW_EXCEPTION( exception::MissingHostFeature( "Parametric parameter" ) ); 00052 } 00053 } 00054 00055 /** 00056 * @brief Function called to describe the plugin controls and features. 00057 * @param[in, out] desc Effect descriptor 00058 * @param[in] context Application context 00059 */ 00060 void HistogramKeyerPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,OFX::EContext context ) 00061 { 00062 00063 OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); 00064 srcClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00065 srcClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00066 srcClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00067 srcClip->setSupportsTiles( kSupportTiles ); 00068 00069 OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName ); 00070 dstClip->addSupportedComponent( OFX::ePixelComponentRGBA ); 00071 dstClip->addSupportedComponent( OFX::ePixelComponentRGB ); 00072 dstClip->addSupportedComponent( OFX::ePixelComponentAlpha ); 00073 dstClip->setSupportsTiles( kSupportTiles ); 00074 00075 //global display 00076 OFX::BooleanParamDescriptor* boolGLOBAL = desc.defineBooleanParam(kGlobalDisplay); 00077 boolGLOBAL->setHint("Display global overlay on screen."); 00078 boolGLOBAL->setDefault(true); 00079 00080 // if parametric parameters are supported 00081 if( OFX::getImageEffectHostDescription()->supportsParametricParameter ) 00082 { 00083 OFX::ParametricParamDescriptor* curvesRGB = desc.defineParametricParam( kParamRGBColorSelection ); 00084 OFX::ParametricParamDescriptor* curvesHSL = desc.defineParametricParam( kParamHSLColorSelection ); 00085 00086 //Group Param (RGB & HSL) 00087 OFX::GroupParamDescriptor *groupRGB = desc.defineGroupParam(kGroupRGB); 00088 groupRGB->setLabel(kGroupRGBLabel); 00089 OFX::GroupParamDescriptor *groupHSL = desc.defineGroupParam(kGroupHSL); 00090 groupHSL->setLabel(kGroupHSLLabel); 00091 00092 //define the graphic aspect 00093 curvesRGB->setRange( 0.0, 1.0 ); //set range on RGB curve 00094 curvesHSL->setRange( 0.0, 1.0 ); //set range on HSL curve 00095 curvesRGB->setDimension(nbCurvesRGB); //3 curves on RGB 00096 curvesHSL->setDimension(nbCurvesHSL); //3 curves on HSL 00097 00098 //Add curves RGB 00099 curvesRGB->setDimensionLabel( kParamColorSelectionRed, 0 ); // 0 on RGB is red 00100 curvesRGB->setDimensionLabel( kParamColorSelectionGreen, 1 ); // 1 on RGB is green 00101 curvesRGB->setDimensionLabel( kParamColorSelectionBlue, 2 ); // 2 on RGB is blue 00102 //Add curves HSL 00103 curvesHSL->setDimensionLabel( kParamColorSelectionHue, 0 ); // 0 on HSL is hue 00104 curvesHSL->setDimensionLabel( kParamColorSelectionSaturation, 1 ); // 1 on HSL is saturation 00105 curvesHSL->setDimensionLabel( kParamColorSelectionLightness, 2 ); // 2 on HSK is lightness 00106 //define curves color RGB 00107 curvesRGB->setHint( "Color selection" ); 00108 static const OfxRGBColourD red = {1,0,0}; //set red color to red curve 00109 static const OfxRGBColourD green = {0,1,0}; //set green color to green curve 00110 static const OfxRGBColourD blue = {0,0,1}; //set blue color to blue curve 00111 curvesRGB->setUIColour( 0, red ); 00112 curvesRGB->setUIColour( 1, green ); 00113 curvesRGB->setUIColour( 2, blue ); 00114 //define curves color HSL 00115 curvesHSL->setHint( "Color selection" ); 00116 curvesHSL->setUIColour( 0, red ); //set red color on hue curve 00117 curvesHSL->setUIColour( 1, green ); //set green color on saturation curve 00118 curvesHSL->setUIColour( 2, blue ); //set lightness color on saturation curve 00119 00120 curvesRGB->setInteractDescriptor( new OFX::DefaultParamInteractWrap<RGBParamOverlayDescriptor>() ); //attach parametric curve to RGBOverlay 00121 curvesHSL->setInteractDescriptor( new OFX::DefaultParamInteractWrap<HSLParamOverlayDescriptor>() ); //attach parametric curve to HSLOverlay 00122 00123 //add curves to their groups 00124 curvesRGB->setParent(groupRGB); //add RGB curves to RGB group 00125 curvesHSL->setParent(groupHSL); //add HSL curves to HSL group 00126 00127 //Set each curves to initial value 00128 curvesRGB->setIdentity(); 00129 curvesHSL->setIdentity(); 00130 //add 2 control points (0,1) and (1,1) for each channel 00131 for(unsigned int i=0; i< nbCurvesRGB; ++i) 00132 { 00133 //curvesRGB->addControlPoint( i, 0.0, 0.0, 1.0, false ); 00134 curvesRGB->addControlPoint( i, 0.0, 1.0, 1.0, false ); 00135 } 00136 for(unsigned int i=0; i< nbCurvesHSL; ++i) 00137 { 00138 //curvesHSL->addControlPoint( i, 0.0, 0.0, 1.0, false ); 00139 curvesHSL->addControlPoint( i, 0.0, 1.0, 1.0, false ); 00140 } 00141 00142 //Channels checkboxes (RGB) 00143 OFX::BooleanParamDescriptor* boolR = desc.defineBooleanParam(kBoolRed); 00144 boolR->setDefault(false); //red channel is not selected by default 00145 boolR->setHint("Activate Red channel"); 00146 boolR->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00147 boolR->setParent(groupRGB); 00148 //red multiplier 00149 OFX::DoubleParamDescriptor* redMultiplier = desc.defineDoubleParam(kMultiplierRed); 00150 redMultiplier->setLabel(kMultiplierLabel); 00151 redMultiplier->setHint("Determinate curve from selection precision."); 00152 redMultiplier->setRange(1, 1000); 00153 redMultiplier->setDisplayRange(0,5); 00154 redMultiplier->setDefault(1); 00155 redMultiplier->setParent(groupRGB); 00156 00157 00158 OFX::BooleanParamDescriptor* boolG = desc.defineBooleanParam(kBoolGreen); 00159 boolG->setDefault(false); //green channel is not selected by default 00160 boolG->setHint("Activate Green channel"); 00161 boolG->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00162 boolG->setParent(groupRGB); 00163 //green multiplier 00164 OFX::DoubleParamDescriptor* greenMultiplier = desc.defineDoubleParam(kMultiplierGreen); 00165 greenMultiplier->setLabel(kMultiplierLabel); 00166 greenMultiplier->setHint("Determinate curve from selection precision."); 00167 greenMultiplier->setRange(1, 1000); 00168 greenMultiplier->setDisplayRange(0,5); 00169 greenMultiplier->setDefault(1); 00170 greenMultiplier->setParent(groupRGB); 00171 00172 00173 OFX::BooleanParamDescriptor* boolB = desc.defineBooleanParam(kBoolBlue); 00174 boolB->setHint("Activate Blue channel"); 00175 boolB->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00176 boolB->setDefault(false); //blue channel is not selected by default 00177 boolB->setParent(groupRGB); 00178 //blue multiplier 00179 OFX::DoubleParamDescriptor* blueMultiplier = desc.defineDoubleParam(kMultiplierBlue); 00180 blueMultiplier->setLabel(kMultiplierLabel); 00181 blueMultiplier->setHint("Determinate curve from selection precision."); 00182 blueMultiplier->setRange(1, 1000); 00183 blueMultiplier->setDisplayRange(0,5); 00184 blueMultiplier->setDefault(1); 00185 blueMultiplier->setParent(groupRGB); 00186 00187 00188 00189 //Channels check box (HSL) 00190 OFX::BooleanParamDescriptor* boolH = desc.defineBooleanParam(kBoolHue); 00191 boolH->setDefault(false); 00192 boolH->setHint("Activate Hue channel"); 00193 boolH->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00194 boolH->setParent(groupHSL); 00195 //Hue multiplier 00196 OFX::DoubleParamDescriptor* hueMultiplier = desc.defineDoubleParam(kMultiplierHue); 00197 hueMultiplier->setLabel(kMultiplierLabel); 00198 hueMultiplier->setHint("Determinate curve from selection precision."); 00199 hueMultiplier->setRange(1, 1000); 00200 hueMultiplier->setDisplayRange(0,5); 00201 hueMultiplier->setDefault(1); 00202 hueMultiplier->setParent(groupHSL); 00203 00204 00205 OFX::BooleanParamDescriptor* boolS = desc.defineBooleanParam(kBoolSaturation); 00206 boolS->setDefault(false); 00207 boolS->setHint("Activate Saturation channel"); 00208 boolS->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00209 boolS->setParent(groupHSL); 00210 //Saturation multiplier 00211 OFX::DoubleParamDescriptor* saturationMultiplier = desc.defineDoubleParam(kMultiplierSaturation); 00212 saturationMultiplier->setLabel(kMultiplierLabel); 00213 saturationMultiplier->setHint("Determinate curve from selection precision."); 00214 saturationMultiplier->setRange(1, 1000); 00215 saturationMultiplier->setDisplayRange(0,5); 00216 saturationMultiplier->setDefault(1); 00217 saturationMultiplier->setParent(groupHSL); 00218 00219 OFX::BooleanParamDescriptor* boolL = desc.defineBooleanParam(kBoolLightness); 00220 boolL->setHint("Activate Lightness channel"); 00221 boolL->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00222 boolL->setDefault(false); 00223 boolL->setParent(groupHSL); 00224 //Lightness multiplier 00225 OFX::DoubleParamDescriptor* lightnessMultiplier = desc.defineDoubleParam(kMultiplierLightness); 00226 lightnessMultiplier->setLabel(kMultiplierLabel); 00227 lightnessMultiplier->setHint("Determinate curve from selection precision."); 00228 lightnessMultiplier->setRange(1, 1000); 00229 lightnessMultiplier->setDisplayRange(0,5); 00230 lightnessMultiplier->setDefault(1); 00231 lightnessMultiplier->setParent(groupHSL); 00232 00233 //Clean Button (RGB) 00234 OFX::PushButtonParamDescriptor* resetButtonRGB = desc.definePushButtonParam(kButtonResetRGB); 00235 resetButtonRGB->setLabel(kButtonResetRGBLabel); 00236 resetButtonRGB->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00237 resetButtonRGB->setHint("Reset the selected RGB curves. \n Warning : the curves may not be refreshed click on overlay to refresh."); 00238 resetButtonRGB->setParent(groupRGB); 00239 00240 //Selection To Curves Button (RGB) 00241 OFX::PushButtonParamDescriptor* selectionToCurveButtonRGB = desc.definePushButtonParam(kButtonSelectionToCurveRGB); 00242 selectionToCurveButtonRGB->setLabel(kButtonSelectionToCurveRGBLabel); 00243 selectionToCurveButtonRGB->setHint("Load selected RGB curves with selection data. \n Warning : the curves may not be refreshed click on overlay to refresh."); 00244 selectionToCurveButtonRGB->setParent(groupRGB); 00245 00246 //Append selection to curves button (RGB) 00247 OFX::PushButtonParamDescriptor* appendSelectionToCurveRGB = desc.definePushButtonParam(kButtonAppendSelectionToCurveRGB); 00248 appendSelectionToCurveRGB->setLabel(kButtonAppendSelectionToCurveRGBLabel); //add label 00249 appendSelectionToCurveRGB->setHint("Append current selection to selected RGB channels");//help 00250 appendSelectionToCurveRGB->setParent(groupRGB); //add to RGB group 00251 00252 //Clean Button (HSL) 00253 OFX::PushButtonParamDescriptor* resetButtonHSL = desc.definePushButtonParam(kButtonResetHSL); 00254 resetButtonHSL->setLabel(kButtonResetHSLLabel); 00255 resetButtonHSL->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00256 resetButtonHSL->setHint("Reset the selected HSL curves \n Warning : the curves may not be refreshed click on overlay to refresh."); 00257 resetButtonHSL->setParent(groupHSL); 00258 00259 //Selection To Curves Button (HSL) 00260 OFX::PushButtonParamDescriptor* selectionToCurveButtonHSL = desc.definePushButtonParam(kButtonSelectionToCurveHSL); 00261 selectionToCurveButtonHSL->setLabel(kButtonSelectionToCurveHSLLabel); 00262 selectionToCurveButtonHSL->setHint("Load selected HSL curves with selection data. \n Warning : the curves may not be refreshed click on overlay to refresh."); 00263 selectionToCurveButtonHSL->setParent(groupHSL); 00264 00265 //Append selection to curves button (HSL) 00266 OFX::PushButtonParamDescriptor* appendSelectionToCurveHSL = desc.definePushButtonParam(kButtonAppendSelectionToCurveHSL); 00267 appendSelectionToCurveHSL->setLabel(kButtonAppendSelectionToCurveHSLLabel); //add label 00268 appendSelectionToCurveHSL->setHint("Append current selection to selected HSL channels");//help 00269 appendSelectionToCurveHSL->setParent(groupHSL); //add to HSL group 00270 00271 00272 //Close RGB group (group states by default on screen) 00273 groupRGB->setOpen(false); 00274 groupHSL->setOpen(true); 00275 } 00276 00277 //Selection group 00278 { 00279 OFX::GroupParamDescriptor *groupSelection = desc.defineGroupParam(kGroupSelection); 00280 groupSelection->setLabel(kGroupSelectionLabel); 00281 groupSelection->setOpen(false); 00282 groupSelection->setAsTab(); 00283 //display selection 00284 OFX::BooleanParamDescriptor* boolDisplaySelection = desc.defineBooleanParam(kBoolSelection); 00285 boolDisplaySelection->setDefault(true); 00286 boolDisplaySelection->setEvaluateOnChange(false);// don't need to recompute on change 00287 boolDisplaySelection->setHint("Display the selected zone on screen."); 00288 boolDisplaySelection->setParent(groupSelection); 00289 //clear selection 00290 OFX::PushButtonParamDescriptor* resetSelectionButton = desc.definePushButtonParam(kButtonResetSelection); 00291 resetSelectionButton->setLabel(kButtonResetSelectionLabel); 00292 resetSelectionButton->setHint("Reset user's selection."); 00293 resetSelectionButton->setParent(groupSelection); 00294 //selection mode 00295 OFX::ChoiceParamDescriptor* selectionMode = desc.defineChoiceParam(kSelectionModeListParamLabel); 00296 selectionMode->setLabel(kSelectionModeListParamLabel); 00297 selectionMode->setHint( "Selection mode \n - unique : reset past selection before selection \n - additive : add pixels to current selection \n -subtractive : remote pixel from current selection"); 00298 selectionMode->appendOption(kSelectionModeListParamOpt2); 00299 selectionMode->appendOption(kSelectionModeListParamOpt1); 00300 selectionMode->appendOption(kSelectionModeListParamOpt3); 00301 selectionMode->setParent(groupSelection); 00302 //Precision of selection to curve 00303 OFX::IntParamDescriptor* precisionSelectionToCurve = desc.defineIntParam(kprecisionCurveFromSelection); 00304 precisionSelectionToCurve->setLabel(kprecisionCurveFromSelectionLabel); 00305 precisionSelectionToCurve->setHint("Determinate curve from selection precision."); 00306 precisionSelectionToCurve->setRange(1, 1000); 00307 precisionSelectionToCurve->setDisplayRange(1, 300.0 ); 00308 precisionSelectionToCurve->setDefault(curveFromSelection); 00309 precisionSelectionToCurve->setEvaluateOnChange(false); // don't need to recompute on change 00310 precisionSelectionToCurve->setParent(groupSelection); 00311 } 00312 00313 //Histogram overlay group 00314 { 00315 OFX::GroupParamDescriptor *groupHistogramOverlay = desc.defineGroupParam(kGroupHistogramOverlay); 00316 groupHistogramOverlay->setLabel(kGroupHistogramOverlayLabel); 00317 groupHistogramOverlay->setOpen(true); 00318 groupHistogramOverlay->setAsTab(); 00319 00320 //Histogram display settings 00321 OFX::ChoiceParamDescriptor* gammaType = desc.defineChoiceParam(kHistoDisplayListParamLabel); 00322 gammaType->setLabel(kHistoDisplayListParamLabel); 00323 gammaType->setEvaluateOnChange(false); // don't need to recompute on change 00324 gammaType->setHint("Histogram display \n -global : normalize all of channels \n -by channel : keep proportions between channels"); 00325 gammaType->appendOption(kHistoDisplayListParamOpt2); 00326 gammaType->appendOption(kHistoDisplayListParamOpt1); 00327 gammaType->setParent(groupHistogramOverlay); 00328 00329 //Clean all Button 00330 OFX::PushButtonParamDescriptor* resetButtonAll = desc.definePushButtonParam(kButtonResetAll); 00331 resetButtonAll->setLabel(kButtonResetAllLabel); 00332 resetButtonAll->setHint("Reset all curves. \n Waring : the curves may not be refreshed click on overlay to refresh."); 00333 resetButtonAll->setParent(groupHistogramOverlay); 00334 } 00335 00336 ///Advanced group 00337 { 00338 OFX::GroupParamDescriptor *groupAdvanced = desc.defineGroupParam(kGroupAdvanced); 00339 groupAdvanced->setLabel(kGroupAdvancedLabel); 00340 groupAdvanced->setOpen(false); 00341 groupAdvanced->setAsTab(); 00342 00343 //nbOfstep (advanced group) 00344 OFX::IntParamDescriptor* nbStepRange = desc.defineIntParam(knbStepRange); 00345 nbStepRange->setLabel(knbStepRangeLabel); 00346 nbStepRange->setHint("Determinate histogram overlay precision."); 00347 nbStepRange->setRange(1, 1000); 00348 nbStepRange->setDisplayRange(1, 600.0 ); 00349 nbStepRange->setDefault(255); 00350 nbStepRange->setEvaluateOnChange(false); // don't need to recompute on change 00351 nbStepRange->setParent(groupAdvanced); 00352 //selection multiplier (advanced group) 00353 OFX::DoubleParamDescriptor* selectionMultiplier = desc.defineDoubleParam(kselectionMultiplier); 00354 selectionMultiplier->setLabel(kselectionMultiplierLabel); 00355 selectionMultiplier->setHint("With high values, small selection are more visible."); 00356 selectionMultiplier->setRange(0.001,1000.0); 00357 selectionMultiplier->setDisplayRange(0.0, 100.0 ); 00358 selectionMultiplier->setDefault(2.0); 00359 selectionMultiplier->setEvaluateOnChange(false); // don't need to recompute on change 00360 selectionMultiplier->setParent(groupAdvanced); 00361 00362 //Refresh histograms overlay Button 00363 OFX::PushButtonParamDescriptor* refreshOverlayButton = desc.definePushButtonParam(kButtonRefreshOverlay); 00364 refreshOverlayButton->setLabel(kButtonRefreshOverlayLabel); 00365 refreshOverlayButton->setHint("Refresh histogram overlay."); 00366 refreshOverlayButton->setParent(groupAdvanced); 00367 00368 //clamp values to 0 and 1 00369 OFX::BooleanParamDescriptor* clampCurveValues = desc.defineBooleanParam(kBoolClampValues); 00370 clampCurveValues->setHint("Clamp curve value : values superior to 1 or inferior to 0 will be clamp in process."); 00371 clampCurveValues->setDefault(true); 00372 clampCurveValues->setParent(groupAdvanced); 00373 } 00374 //Output settings 00375 OFX::ChoiceParamDescriptor* outputType = desc.defineChoiceParam(kOutputListParamLabel); 00376 outputType->setLabel(kOutputListParamLabel); 00377 outputType->setHint( "Output type \n Alpha channel or Black and White"); 00378 outputType->appendOption(kOutputListParamOpt1); 00379 outputType->appendOption(kOutputListParamOpt2); 00380 outputType->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished 00381 00382 //Reverse mask 00383 OFX::BooleanParamDescriptor* boolReverseMask = desc.defineBooleanParam(kBoolReverseMask); 00384 boolReverseMask->setDefault(false); 00385 boolReverseMask->setHint("Revert alpha mask"); 00386 } 00387 00388 /** 00389 * @brief Function called to create a plugin effect instance 00390 * @param[in] handle Effect handle 00391 * @param[in] context Application context 00392 * @return plugin instance 00393 */ 00394 OFX::ImageEffect* HistogramKeyerPluginFactory::createInstance( OfxImageEffectHandle handle,OFX::EContext context ) 00395 { 00396 return new HistogramKeyerPlugin( handle ); 00397 } 00398 00399 } 00400 } 00401 } 00402