示例#1
0
void
CImgFilterPluginHelperBase::describeInContextEnd(OFX::ImageEffectDescriptor &desc,
                                                 OFX::ContextEnum /*context*/,
                                                 OFX::PageParamDescriptor* page)
{
    ofxsPremultDescribeParams(desc, page);
    ofxsMaskMixDescribeParams(desc, page);

    {
        OFX::BooleanParamDescriptor* param = desc.defineBooleanParam(kParamPremultChanged);
        param->setDefault(false);
        param->setIsSecret(true);
        param->setAnimates(false);
        param->setEvaluateOnChange(false);
        if (page) {
            page->addChild(*param);
        }
    }
}
示例#2
0
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void CropPluginFactory::describeInContext(OFX::ImageEffectDescriptor& desc, OFX::EContext context)
{
    OFX::ClipDescriptor* srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);

    srcClip->addSupportedComponent(OFX::ePixelComponentRGBA);
    srcClip->addSupportedComponent(OFX::ePixelComponentRGB);
    srcClip->addSupportedComponent(OFX::ePixelComponentAlpha);
    srcClip->setSupportsTiles(kSupportTiles);

    OFX::ClipDescriptor* dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
    dstClip->addSupportedComponent(OFX::ePixelComponentRGBA);
    dstClip->addSupportedComponent(OFX::ePixelComponentRGB);
    dstClip->addSupportedComponent(OFX::ePixelComponentAlpha);
    dstClip->setSupportsTiles(kSupportTiles);

    OFX::ChoiceParamDescriptor* mode = desc.defineChoiceParam(kParamMode);
    mode->setLabel("Mode");
    mode->appendOption(kParamModeCrop);
    mode->appendOption(kParamModeFillColor);
    //	mode->appendOption( kParamModeResize ); // good idea or not?
    mode->setDefault(eParamModeCrop);

    OFX::RGBAParamDescriptor* fillColor = desc.defineRGBAParam(kParamFillColor);
    fillColor->setLabel("Color");
    fillColor->setHint("Color to fill bands");
    fillColor->setDefault(0.0, 0.0, 0.0, 1.0);

    OFX::ChoiceParamDescriptor* axis = desc.defineChoiceParam(kParamAxis);
    axis->setLabel("Axis");
    axis->appendOption(kParamAxisXY);
    axis->appendOption(kParamAxisX);
    axis->appendOption(kParamAxisY);
    axis->setDefault(eParamAxisY);
    axis->setEvaluateOnChange(false);

    OFX::ChoiceParamDescriptor* symmetric = desc.defineChoiceParam(kParamSymmetric);
    symmetric->setLabel("Symmetric");
    symmetric->appendOption(kParamSymmetricNone);
    symmetric->appendOption(kParamSymmetricXY);
    symmetric->appendOption(kParamSymmetricX);
    symmetric->appendOption(kParamSymmetricY);
    symmetric->setHint("Is the crop region symmetric around image center?");
    symmetric->setDefault(true);
    symmetric->setEvaluateOnChange(false);

    OFX::BooleanParamDescriptor* fixedRatio = desc.defineBooleanParam(kParamFixedRatio);
    fixedRatio->setLabel("Fixed ratio");
    fixedRatio->setHint("Constrain the cropped region to this ratio.");
    fixedRatio->setDefault(true);
    fixedRatio->setEvaluateOnChange(false);

    OFX::ChoiceParamDescriptor* preset = desc.defineChoiceParam(kParamPreset);
    preset->setLabel("Preset");
    preset->appendOption(kParamPreset_custom);
    preset->appendOption(kParamPreset_1_33);
    preset->appendOption(kParamPreset_1_77);
    preset->appendOption(kParamPreset_1_85);
    preset->appendOption(kParamPreset_2_35);
    preset->appendOption(kParamPreset_2_40);
    preset->setDefault(0);
    preset->setEvaluateOnChange(false);

    OFX::DoubleParamDescriptor* ratio = desc.defineDoubleParam(kParamRatio);
    ratio->setLabel("Ratio");
    ratio->setRange(0, std::numeric_limits<double>::max());
    ratio->setDisplayRange(0, 3);
    ratio->setDefault(2.0);
    ratio->setHint("Ratio X/Y of the cropped region.");

    OFX::BooleanParamDescriptor* overlay = desc.defineBooleanParam(kParamOverlay);
    overlay->setLabel("Overlay");
    overlay->setHint("Display overlay rectangle");
    overlay->setDefault(false);
    overlay->setEvaluateOnChange(false);

    OFX::GroupParamDescriptor* cropRegion = desc.defineGroupParam(kParamGroupCropRegion);

    OFX::IntParamDescriptor* xMin = desc.defineIntParam(kParamXMin);
    xMin->setLabel("X min");
    //	xMin->setRange( 0, std::numeric_limits<int>::max() );
    xMin->setDisplayRange(0, 3000);
    xMin->setDefault(0);
    xMin->setParent(*cropRegion);

    OFX::IntParamDescriptor* yMin = desc.defineIntParam(kParamYMin);
    yMin->setLabel("Y min");
    //	yMin->setRange( 0, std::numeric_limits<int>::max() );
    yMin->setDisplayRange(0, 3000);
    yMin->setDefault(0);
    yMin->setParent(*cropRegion);

    OFX::IntParamDescriptor* xMax = desc.defineIntParam(kParamXMax);
    xMax->setLabel("X max");
    //	xMax->setRange( 0, std::numeric_limits<int>::max() );
    xMax->setDisplayRange(0, 3000);
    xMax->setDefault(0);
    xMax->setParent(*cropRegion);

    OFX::IntParamDescriptor* yMax = desc.defineIntParam(kParamYMax);
    yMax->setLabel("Y max");
    //	yMax->setRange( 0, std::numeric_limits<int>::max() );
    yMax->setDisplayRange(0, 3000);
    yMax->setDefault(0);
    yMax->setParent(*cropRegion);
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void LensDistortPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc, OFX::EContext context )
{
	// Create the mandated output clip
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );

	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( true );

	// create the mandated source clip
	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( true );

	// declare an optional clip reference for RoD
	OFX::ClipDescriptor* srcRefClip = desc.defineClip( kClipOptionalSourceRef );
	srcRefClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcRefClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcRefClip->setSupportsTiles( true );
	srcRefClip->setOptional( true );
	srcRefClip->setLabel( "ref" );

	OFX::BooleanParamDescriptor* reverse = desc.defineBooleanParam( kParamReverse );
	reverse->setLabel( "Reverse" );
	reverse->setDefault( false );
	reverse->setHint( "Invert the effect.\n"
	                  "Distort becomes undistort, and vice versa." );

	// Controls
	OFX::BooleanParamDescriptor* displaySource = desc.defineBooleanParam( kParamDisplaySource );
	displaySource->setLabel( "displaySource" );
	displaySource->setDefault( false );
	displaySource->setHint( "Display the image source (usefull to parameter the distortion with lines overlays on the source image)." );

	OFX::ChoiceParamDescriptor* lensType = desc.defineChoiceParam( kParamLensType );
	lensType->setLabel( "Lens type" );
	lensType->appendOption( kParamLensTypeStandard );
	#ifndef TUTTLE_PRODUCTION
	lensType->appendOption( kParamLensTypeFishEye ); // not implemented yet...
	lensType->appendOption( kParamLensTypeAdvanced ); // not implemented yet...
	lensType->setIsSecret( true );
	#endif
	lensType->setDefault( 0 );

	OFX::DoubleParamDescriptor* coef1 = desc.defineDoubleParam( kParamCoef1 );
	coef1->setScriptName( "Main" );
	coef1->setDefault( 0.1 );
	coef1->setDisplayRange( -1.0, 1.0 );
	coef1->setHint( "Main distortion coeffecient\n"
	                ">0 : Barrel distortion\n"
	                "<0 : Pincushion distortion\n"
	                );

	OFX::DoubleParamDescriptor* coef2 = desc.defineDoubleParam( kParamCoef2 );
	coef2->setLabel( "Secondary" );
	coef2->setDefault( 0.0 );
	coef2->setDisplayRange( -1.0, 1.0 );
	coef2->setHint( "Secondary distortion coeffecient (usefull for fisheyes only)\n"
	                ">0 : Barrel distortion\n"
	                "<0 : Pincushion distortion\n"
	                );
	#ifdef TUTTLE_PRODUCTION
	coef2->setIsSecret( true );
	#endif

	OFX::DoubleParamDescriptor* squeeze = desc.defineDoubleParam( kParamSqueeze );
	squeeze->setLabel( "Squeeze" );
	#ifdef TUTTLE_PRODUCTION
	squeeze->setIsSecret( true );
	#endif
	//    squeeze->setDoubleType( eDoubleTypeNormalisedX );
	squeeze->setDefault( 1.0 );
	squeeze->setRange( 0.00001, 1.0 );
	squeeze->setDisplayRange( 0.01, 1.0 );
	squeeze->setHint( "Squeeze distortion coeffecient (usefull for bad quality lens...)" );

	OFX::Double2DParamDescriptor* asymmetric = desc.defineDouble2DParam( kParamAsymmetric );
	asymmetric->setLabel( "Asymmetric" );
	#ifdef TUTTLE_PRODUCTION
	asymmetric->setIsSecret( true );
	#endif
	//    asymmetric->setDoubleType( eDoubleTypeNormalisedXY );
	asymmetric->setDefault( 0.0, 0.0 );
	asymmetric->setRange( 0.0, 0.0, 1.0, 1.0 );
	asymmetric->setDisplayRange( 0.0, 0.0, 1.0, 1.0 );
	asymmetric->setHint( "asymmetric distortion coeffecient (usefull for bad quality lens...)" );

	OFX::Double2DParamDescriptor* center = desc.defineDouble2DParam( kParamCenter );
	center->setLabel( "Center" );
	center->setDoubleType( OFX::eDoubleTypePlain );
	center->setDefault( 0.0, 0.0 );
	center->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	center->setHint( "Center parameter allows you to shift the center of distortion." );

	OFX::BooleanParamDescriptor* centerOverlay = desc.defineBooleanParam( kParamCenterOverlay );
	centerOverlay->setLabel( "Display distortion center" );
	centerOverlay->setDefault( false );
	centerOverlay->setEvaluateOnChange( false );
	centerOverlay->setHint( "Active distortion center point overlay." );

	OFX::ChoiceParamDescriptor* centerType = desc.defineChoiceParam( kParamCenterType );
	centerType->setLabel( "Center type" );
	#ifdef TUTTLE_PRODUCTION
	centerType->setIsSecret( true );
	#endif
	centerType->appendOption( kParamCenterTypeSource );
	centerType->appendOption( kParamCenterTypeRoW );
	centerType->setDefault( 0 );
	centerType->setHint( "Centered on source or output image." );

	OFX::DoubleParamDescriptor* preScale = desc.defineDoubleParam( kParamPreScale );
	preScale->setLabel( "Pre-scale" );
	//    preScale->setDoubleType( eDoubleTypeNormalisedXY );
	preScale->setDefault( 1.0 );
	preScale->setRange( 0.00001, std::numeric_limits<double>::max() );
	preScale->setDisplayRange( 0.0, 2.5 );
	preScale->setHint( "If the transformation of optics is high, you may need to change the scale of the result to be globally closer to the source image or preserve a good resolution." );

	OFX::DoubleParamDescriptor* postScale = desc.defineDoubleParam( kParamPostScale );
	postScale->setLabel( "Post-scale" );
	//    scale->setDoubleType( eDoubleTypeNormalisedXY );
	postScale->setDefault( 1.0 );
	postScale->setRange( 0.00001, std::numeric_limits<double>::max() );
	postScale->setDisplayRange( 0.0, 2.5 );
	postScale->setHint( "If the transformation of optics is high, you may need to change the scale of the result to be globally closer to the source image or preserve a good resolution." );

	OFX::ChoiceParamDescriptor* interpolation = desc.defineChoiceParam( kParamInterpolation );
	interpolation->setLabel( "Interpolation" );
	interpolation->appendOption( kParamInterpolationNearest );
	interpolation->appendOption( kParamInterpolationBilinear );
	interpolation->setDefault( 1 );
	interpolation->setHint( "Interpolation method" );

	OFX::ChoiceParamDescriptor* resizeRod = desc.defineChoiceParam( kParamResizeRod );
	resizeRod->setLabel( "Resize RoD" );
	resizeRod->appendOption( kParamResizeRodNo );
	resizeRod->appendOption( kParamResizeRodSourceRef );
	resizeRod->appendOption( kParamResizeRodMin );
	resizeRod->appendOption( kParamResizeRodMax );
	resizeRod->appendOption( kParamResizeRodManual );
	resizeRod->setDefault( 0 );
	resizeRod->setHint( "Resize output RoD" );

	OFX::DoubleParamDescriptor* scaleRod = desc.defineDoubleParam( kParamResizeRodManualScale );
	scaleRod->setLabel( "Scale RoD" );
	//    scaleRod->setDoubleType( eDoubleTypeNormalisedXY );
	//    scaleRod->setIsSecret( true );
	//    scaleRod->setEnabled( false );
	scaleRod->setDefault( 1.0 );
	scaleRod->setRange( 0.0, std::numeric_limits<double>::max() );
	scaleRod->setDisplayRange( 0, 2.5 );
	scaleRod->setHint( "Adjust the output RoD." );

	OFX::GroupParamDescriptor* displayOptions = desc.defineGroupParam( kParamDisplayOptions );
	displayOptions->setLabel( "Display options" );
	displayOptions->setHint( "Display options (change nothing on the image)" );

	OFX::BooleanParamDescriptor* displayGrid = desc.defineBooleanParam( kParamGridOverlay );
	displayGrid->setLabel( "Display grid" );
	displayGrid->setParent( *displayOptions );
	displayGrid->setDefault( false );
	displayGrid->setEvaluateOnChange( false );
	displayGrid->setHint( "Display the grid" );

	OFX::Double2DParamDescriptor* gridCenter = desc.defineDouble2DParam( kParamGridCenter );
	gridCenter->setLabel( "Grid center" );
	gridCenter->setDoubleType( OFX::eDoubleTypePlain );
	gridCenter->setParent( *displayOptions );
	gridCenter->setDefault( 0.0, 0.0 );
	gridCenter->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	gridCenter->setEvaluateOnChange( false );
	gridCenter->setHint( "Allows you to shift the center of the  display grid." );

	OFX::BooleanParamDescriptor* gridCenterOverlay = desc.defineBooleanParam( kParamGridCenterOverlay );
	gridCenterOverlay->setLabel( "Display grid center" );
	gridCenterOverlay->setParent( *displayOptions );
	gridCenterOverlay->setDefault( false );
	gridCenterOverlay->setEvaluateOnChange( false );
	gridCenterOverlay->setHint( "Active grid center point overlay." );

	OFX::Double2DParamDescriptor* gridScale = desc.defineDouble2DParam( kParamGridScale );
	gridScale->setLabel( "Grid scale" );
	gridScale->setDoubleType( OFX::eDoubleTypePlain );
	gridScale->setParent( *displayOptions );
	gridScale->setDefault( 1.0, 1.0 );
	gridScale->setDisplayRange( -10.0, -10.0, 10.0, 10.0 );
	gridScale->setEvaluateOnChange( false );
	gridScale->setHint( "Allows you to scale the display grid." );

	OFX::GroupParamDescriptor* debugOptions = desc.defineGroupParam( kParamDebugOptions );
	debugOptions->setLabel( "Debug options" );
	debugOptions->setHint( "Debug options" );
	debugOptions->setParent( *displayOptions );
	#ifdef TUTTLE_PRODUCTION
	debugOptions->setIsSecret( true );
	#endif

	OFX::BooleanParamDescriptor* debugDisplayRoi = desc.defineBooleanParam( kParamDebugDisplayRoi );
	debugDisplayRoi->setLabel( "Display RoI" );
	#ifdef TUTTLE_PRODUCTION
	debugDisplayRoi->setIsSecret( true );
	#endif
	debugDisplayRoi->setParent( *debugOptions );
	debugDisplayRoi->setDefault( false );
	debugDisplayRoi->setEvaluateOnChange( false );
	debugDisplayRoi->setHint( "Display RoI" );

	OFX::PushButtonParamDescriptor* helpButton = desc.definePushButtonParam( kParamHelp );
	helpButton->setLabel( "Help" );
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void HistogramKeyerPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,OFX::EContext context )
{
	
	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGB );
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( kSupportTiles );

	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	//global display
	OFX::BooleanParamDescriptor* boolGLOBAL = desc.defineBooleanParam(kGlobalDisplay);
	boolGLOBAL->setHint("Display global overlay on screen.");
	boolGLOBAL->setDefault(true);
		
    // if parametric parameters are supported
	if( OFX::getImageEffectHostDescription()->supportsParametricParameter )
	{
		OFX::ParametricParamDescriptor* curvesRGB = desc.defineParametricParam( kParamRGBColorSelection );
		OFX::ParametricParamDescriptor* curvesHSL = desc.defineParametricParam( kParamHSLColorSelection );
		
		//Group Param (RGB & HSL)
		OFX::GroupParamDescriptor *groupRGB = desc.defineGroupParam(kGroupRGB);
		groupRGB->setLabel(kGroupRGBLabel);
		OFX::GroupParamDescriptor *groupHSL = desc.defineGroupParam(kGroupHSL);
		groupHSL->setLabel(kGroupHSLLabel);

		//define the graphic aspect
		curvesRGB->setRange( 0.0, 1.0 );		//set range on RGB curve
		curvesHSL->setRange( 0.0, 1.0 );		//set range on HSL curve
		curvesRGB->setDimension(nbCurvesRGB);	//3 curves on RGB
		curvesHSL->setDimension(nbCurvesHSL);	//3 curves on HSL

		//Add curves RGB
		curvesRGB->setDimensionLabel( kParamColorSelectionRed, 0 );			// 0 on RGB is red
		curvesRGB->setDimensionLabel( kParamColorSelectionGreen, 1 );		// 1 on RGB is green
		curvesRGB->setDimensionLabel( kParamColorSelectionBlue, 2 );		// 2 on RGB is blue
		//Add curves HSL
		curvesHSL->setDimensionLabel( kParamColorSelectionHue, 0 );			// 0 on HSL is hue
		curvesHSL->setDimensionLabel( kParamColorSelectionSaturation, 1 );	// 1 on HSL is saturation
		curvesHSL->setDimensionLabel( kParamColorSelectionLightness, 2 );	// 2 on HSK is lightness
		//define curves color RGB 
		curvesRGB->setHint( "Color selection" );		
		static const OfxRGBColourD red   = {1,0,0};		//set red color to red curve
		static const OfxRGBColourD green = {0,1,0};		//set green color to green curve
		static const OfxRGBColourD blue  = {0,0,1};		//set blue color to blue curve
		curvesRGB->setUIColour( 0, red );
		curvesRGB->setUIColour( 1, green );
		curvesRGB->setUIColour( 2, blue );
		//define curves color HSL 
		curvesHSL->setHint( "Color selection" );
		curvesHSL->setUIColour( 0, red );		//set red color on hue curve
		curvesHSL->setUIColour( 1, green );		//set green color on saturation curve
		curvesHSL->setUIColour( 2, blue );		//set lightness color on saturation curve
		
		curvesRGB->setInteractDescriptor( new OFX::DefaultParamInteractWrap<RGBParamOverlayDescriptor>() );	//attach parametric curve to RGBOverlay
		curvesHSL->setInteractDescriptor( new OFX::DefaultParamInteractWrap<HSLParamOverlayDescriptor>() );	//attach parametric curve to HSLOverlay
		
		//add curves to their groups
		curvesRGB->setParent(groupRGB);	//add RGB curves to RGB group
		curvesHSL->setParent(groupHSL); //add HSL curves to HSL group 
		
		//Set each curves to initial value
		curvesRGB->setIdentity();
		curvesHSL->setIdentity();
		//add 2 control points (0,1) and (1,1) for each channel
		for(unsigned int i=0; i< nbCurvesRGB; ++i)
		{
			//curvesRGB->addControlPoint( i, 0.0, 0.0, 1.0, false );
			curvesRGB->addControlPoint( i, 0.0, 1.0, 1.0, false );
		}
		for(unsigned int i=0; i< nbCurvesHSL; ++i)
		{
			//curvesHSL->addControlPoint( i, 0.0, 0.0, 1.0, false );
			curvesHSL->addControlPoint( i, 0.0, 1.0, 1.0, false );
		}
		
		//Channels checkboxes (RGB)
		OFX::BooleanParamDescriptor* boolR = desc.defineBooleanParam(kBoolRed);
		boolR->setDefault(false);							//red channel is not selected by default
		boolR->setHint("Activate Red channel");
		boolR->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolR->setParent(groupRGB);
		//red multiplier
		OFX::DoubleParamDescriptor* redMultiplier = desc.defineDoubleParam(kMultiplierRed);
		redMultiplier->setLabel(kMultiplierLabel);
		redMultiplier->setHint("Determinate curve from selection precision.");
		redMultiplier->setRange(1, 1000);
		redMultiplier->setDisplayRange(0,5);
		redMultiplier->setDefault(1);
		redMultiplier->setParent(groupRGB);
		
		
		OFX::BooleanParamDescriptor* boolG = desc.defineBooleanParam(kBoolGreen);
		boolG->setDefault(false);						//green channel is not selected by default
		boolG->setHint("Activate Green channel");
		boolG->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolG->setParent(groupRGB);
		//green multiplier
		OFX::DoubleParamDescriptor* greenMultiplier = desc.defineDoubleParam(kMultiplierGreen);
		greenMultiplier->setLabel(kMultiplierLabel);
		greenMultiplier->setHint("Determinate curve from selection precision.");
		greenMultiplier->setRange(1, 1000);
		greenMultiplier->setDisplayRange(0,5);
		greenMultiplier->setDefault(1);
		greenMultiplier->setParent(groupRGB);
		
		
		OFX::BooleanParamDescriptor* boolB = desc.defineBooleanParam(kBoolBlue);
		boolB->setHint("Activate Blue channel");
		boolB->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolB->setDefault(false);						   //blue channel is not selected by default
		boolB->setParent(groupRGB);
		//blue multiplier
		OFX::DoubleParamDescriptor* blueMultiplier = desc.defineDoubleParam(kMultiplierBlue);
		blueMultiplier->setLabel(kMultiplierLabel);
		blueMultiplier->setHint("Determinate curve from selection precision.");
		blueMultiplier->setRange(1, 1000);
		blueMultiplier->setDisplayRange(0,5);
		blueMultiplier->setDefault(1);
		blueMultiplier->setParent(groupRGB);
		
		
		
		//Channels check box (HSL)
		OFX::BooleanParamDescriptor* boolH = desc.defineBooleanParam(kBoolHue);
		boolH->setDefault(false);
		boolH->setHint("Activate Hue channel");
		boolH->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolH->setParent(groupHSL);
		//Hue multiplier
		OFX::DoubleParamDescriptor* hueMultiplier = desc.defineDoubleParam(kMultiplierHue);
		hueMultiplier->setLabel(kMultiplierLabel);
		hueMultiplier->setHint("Determinate curve from selection precision.");
		hueMultiplier->setRange(1, 1000);
		hueMultiplier->setDisplayRange(0,5);
		hueMultiplier->setDefault(1);
		hueMultiplier->setParent(groupHSL);
		
		
		OFX::BooleanParamDescriptor* boolS = desc.defineBooleanParam(kBoolSaturation);
		boolS->setDefault(false);
		boolS->setHint("Activate Saturation channel");
		boolS->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolS->setParent(groupHSL);
		//Saturation multiplier
		OFX::DoubleParamDescriptor* saturationMultiplier = desc.defineDoubleParam(kMultiplierSaturation);
		saturationMultiplier->setLabel(kMultiplierLabel);
		saturationMultiplier->setHint("Determinate curve from selection precision.");
		saturationMultiplier->setRange(1, 1000);
		saturationMultiplier->setDisplayRange(0,5);
		saturationMultiplier->setDefault(1);
		saturationMultiplier->setParent(groupHSL);
		
		OFX::BooleanParamDescriptor* boolL = desc.defineBooleanParam(kBoolLightness);
		boolL->setHint("Activate Lightness channel");
		boolL->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolL->setDefault(false);
		boolL->setParent(groupHSL);
		//Lightness multiplier
		OFX::DoubleParamDescriptor* lightnessMultiplier = desc.defineDoubleParam(kMultiplierLightness);
		lightnessMultiplier->setLabel(kMultiplierLabel);
		lightnessMultiplier->setHint("Determinate curve from selection precision.");
		lightnessMultiplier->setRange(1, 1000);
		lightnessMultiplier->setDisplayRange(0,5);
		lightnessMultiplier->setDefault(1);
		lightnessMultiplier->setParent(groupHSL);
		
		//Clean Button (RGB)
		OFX::PushButtonParamDescriptor* resetButtonRGB = desc.definePushButtonParam(kButtonResetRGB);
		resetButtonRGB->setLabel(kButtonResetRGBLabel);
		resetButtonRGB->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		resetButtonRGB->setHint("Reset the selected RGB curves. \n Warning : the curves may not be refreshed click on overlay to refresh.");
		resetButtonRGB->setParent(groupRGB);
		
		//Selection To Curves Button (RGB)
		OFX::PushButtonParamDescriptor* selectionToCurveButtonRGB = desc.definePushButtonParam(kButtonSelectionToCurveRGB);
		selectionToCurveButtonRGB->setLabel(kButtonSelectionToCurveRGBLabel);
		selectionToCurveButtonRGB->setHint("Load selected RGB curves with selection data. \n Warning : the curves may not be refreshed click on overlay to refresh.");
		selectionToCurveButtonRGB->setParent(groupRGB);
		
		//Append selection to curves button (RGB)
		OFX::PushButtonParamDescriptor* appendSelectionToCurveRGB = desc.definePushButtonParam(kButtonAppendSelectionToCurveRGB);
		appendSelectionToCurveRGB->setLabel(kButtonAppendSelectionToCurveRGBLabel);				//add label
		appendSelectionToCurveRGB->setHint("Append current selection to selected RGB channels");//help
		appendSelectionToCurveRGB->setParent(groupRGB);											//add to RGB group
		
		//Clean Button (HSL)
		OFX::PushButtonParamDescriptor* resetButtonHSL = desc.definePushButtonParam(kButtonResetHSL);
		resetButtonHSL->setLabel(kButtonResetHSLLabel);
		resetButtonHSL->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		resetButtonHSL->setHint("Reset the selected HSL curves \n Warning : the curves may not be refreshed click on overlay to refresh.");
		resetButtonHSL->setParent(groupHSL);
		
		//Selection To Curves Button (HSL)
		OFX::PushButtonParamDescriptor* selectionToCurveButtonHSL = desc.definePushButtonParam(kButtonSelectionToCurveHSL);
		selectionToCurveButtonHSL->setLabel(kButtonSelectionToCurveHSLLabel);
		selectionToCurveButtonHSL->setHint("Load selected HSL curves with selection data. \n Warning : the curves may not be refreshed click on overlay to refresh.");
		selectionToCurveButtonHSL->setParent(groupHSL);
		
		//Append selection to curves button (HSL)
		OFX::PushButtonParamDescriptor* appendSelectionToCurveHSL = desc.definePushButtonParam(kButtonAppendSelectionToCurveHSL);
		appendSelectionToCurveHSL->setLabel(kButtonAppendSelectionToCurveHSLLabel);				//add label
		appendSelectionToCurveHSL->setHint("Append current selection to selected HSL channels");//help
		appendSelectionToCurveHSL->setParent(groupHSL);											//add to HSL group
		
		
		//Close RGB group (group states by default on screen)
		groupRGB->setOpen(false);
		groupHSL->setOpen(true);
	}
	
	//Selection group
	{
		OFX::GroupParamDescriptor *groupSelection = desc.defineGroupParam(kGroupSelection);
		groupSelection->setLabel(kGroupSelectionLabel);
		groupSelection->setOpen(false);
		groupSelection->setAsTab();
		//display selection
		OFX::BooleanParamDescriptor* boolDisplaySelection = desc.defineBooleanParam(kBoolSelection);
		boolDisplaySelection->setDefault(true);
		boolDisplaySelection->setEvaluateOnChange(false);// don't need to recompute on change
		boolDisplaySelection->setHint("Display the selected zone on screen.");
		boolDisplaySelection->setParent(groupSelection);
		//clear selection
		OFX::PushButtonParamDescriptor* resetSelectionButton = desc.definePushButtonParam(kButtonResetSelection);
		resetSelectionButton->setLabel(kButtonResetSelectionLabel);
		resetSelectionButton->setHint("Reset user's selection.");
		resetSelectionButton->setParent(groupSelection);
		//selection mode
		OFX::ChoiceParamDescriptor* selectionMode = desc.defineChoiceParam(kSelectionModeListParamLabel);
		selectionMode->setLabel(kSelectionModeListParamLabel);
		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");
		selectionMode->appendOption(kSelectionModeListParamOpt2);
		selectionMode->appendOption(kSelectionModeListParamOpt1);
		selectionMode->appendOption(kSelectionModeListParamOpt3);
		selectionMode->setParent(groupSelection);
		//Precision of selection to curve
		OFX::IntParamDescriptor* precisionSelectionToCurve = desc.defineIntParam(kprecisionCurveFromSelection);
		precisionSelectionToCurve->setLabel(kprecisionCurveFromSelectionLabel);
		precisionSelectionToCurve->setHint("Determinate curve from selection precision.");
		precisionSelectionToCurve->setRange(1, 1000);
		precisionSelectionToCurve->setDisplayRange(1, 300.0 );
		precisionSelectionToCurve->setDefault(curveFromSelection);
		precisionSelectionToCurve->setEvaluateOnChange(false); // don't need to recompute on change
		precisionSelectionToCurve->setParent(groupSelection);
	}
	
	//Histogram overlay group
	{
		OFX::GroupParamDescriptor *groupHistogramOverlay = desc.defineGroupParam(kGroupHistogramOverlay);
		groupHistogramOverlay->setLabel(kGroupHistogramOverlayLabel);
		groupHistogramOverlay->setOpen(true);
		groupHistogramOverlay->setAsTab();

		//Histogram display settings
		OFX::ChoiceParamDescriptor* gammaType = desc.defineChoiceParam(kHistoDisplayListParamLabel);
		gammaType->setLabel(kHistoDisplayListParamLabel);
		gammaType->setEvaluateOnChange(false); // don't need to recompute on change
		gammaType->setHint("Histogram display \n -global : normalize all of channels \n -by channel : keep proportions between channels");
		gammaType->appendOption(kHistoDisplayListParamOpt2);
		gammaType->appendOption(kHistoDisplayListParamOpt1);
		gammaType->setParent(groupHistogramOverlay);	

		//Clean all Button
		OFX::PushButtonParamDescriptor* resetButtonAll = desc.definePushButtonParam(kButtonResetAll);
		resetButtonAll->setLabel(kButtonResetAllLabel);
		resetButtonAll->setHint("Reset all curves. \n Waring : the curves may not be refreshed click on overlay to refresh.");
		resetButtonAll->setParent(groupHistogramOverlay);
	}
	
	///Advanced group
	{
		OFX::GroupParamDescriptor *groupAdvanced = desc.defineGroupParam(kGroupAdvanced);
		groupAdvanced->setLabel(kGroupAdvancedLabel);
		groupAdvanced->setOpen(false);
		groupAdvanced->setAsTab();
		
		//nbOfstep (advanced group)
		OFX::IntParamDescriptor* nbStepRange = desc.defineIntParam(knbStepRange);
		nbStepRange->setLabel(knbStepRangeLabel);
		nbStepRange->setHint("Determinate histogram overlay precision.");
		nbStepRange->setRange(1, 1000);
		nbStepRange->setDisplayRange(1, 600.0 );
		nbStepRange->setDefault(255);
		nbStepRange->setEvaluateOnChange(false); // don't need to recompute on change
		nbStepRange->setParent(groupAdvanced);
		//selection multiplier (advanced group)
		OFX::DoubleParamDescriptor* selectionMultiplier = desc.defineDoubleParam(kselectionMultiplier);
		selectionMultiplier->setLabel(kselectionMultiplierLabel);
		selectionMultiplier->setHint("With high values, small selection are more visible.");
		selectionMultiplier->setRange(0.001,1000.0);
		selectionMultiplier->setDisplayRange(0.0, 100.0 );
		selectionMultiplier->setDefault(2.0);
		selectionMultiplier->setEvaluateOnChange(false); // don't need to recompute on change
		selectionMultiplier->setParent(groupAdvanced);

		//Refresh histograms overlay Button
		OFX::PushButtonParamDescriptor* refreshOverlayButton = desc.definePushButtonParam(kButtonRefreshOverlay);
		refreshOverlayButton->setLabel(kButtonRefreshOverlayLabel);
		refreshOverlayButton->setHint("Refresh histogram overlay.");
		refreshOverlayButton->setParent(groupAdvanced);
		
		//clamp values to 0 and 1
		OFX::BooleanParamDescriptor* clampCurveValues = desc.defineBooleanParam(kBoolClampValues);
		clampCurveValues->setHint("Clamp curve value : values superior to 1 or inferior to 0 will be clamp in process.");
		clampCurveValues->setDefault(true);
		clampCurveValues->setParent(groupAdvanced);
	}
	//Output settings
	OFX::ChoiceParamDescriptor* outputType = desc.defineChoiceParam(kOutputListParamLabel);
	outputType->setLabel(kOutputListParamLabel);
	outputType->setHint( "Output type \n Alpha channel or Black and White");
	outputType->appendOption(kOutputListParamOpt1);
	outputType->appendOption(kOutputListParamOpt2);
	outputType->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished

	//Reverse mask
	OFX::BooleanParamDescriptor* boolReverseMask = desc.defineBooleanParam(kBoolReverseMask);
	boolReverseMask->setDefault(false);
	boolReverseMask->setHint("Revert alpha mask");
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void PinningPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
                                                  OFX::EContext context )
{

	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); // clip de source nomme source
	//OFX::ClipDescriptor* toto = desc.defineClip( "toto" );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );	//proprietes de la source
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( kSupportTiles );

	// Create the mandated output clip
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName ); 	//sortie, laisser comme ca et pi c'est tout
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	OFX::GroupParamDescriptor* grpSrc = desc.defineGroupParam( kParamGroupSource );	//groupe source
	grpSrc->setLabel( "Points de départ" );
	grpSrc->setHint( "Selectionnez 4 points de départ" );

	OFX::Double2DParamDescriptor* src0 = desc.defineDouble2DParam( kParamPointSource + "0" );	//kpa... nom utilisé par le plug
	src0->setLabel( "src0" );	//nom que voit l'utilisateur	
	src0->setDefault( 0, 0 );
	src0->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src1 = desc.defineDouble2DParam( kParamPointSource + "1" );
	src1->setLabel( "src1" );
	src1->setDefault( 0, 1 );
	src1->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src2 = desc.defineDouble2DParam( kParamPointSource + "2" );
	src2->setLabel( "src2" );
	src2->setDefault( 1, 1 );
	src2->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src3 = desc.defineDouble2DParam( kParamPointSource + "3" );
	src3->setLabel( "src3" );
	src3->setDefault( 1, 0 );
	src3->setParent(grpSrc);
	
	OFX::GroupParamDescriptor* grpDst = desc.defineGroupParam( kParamGroupDestination );	//groupe destination
	grpDst->setLabel( "Points d'arrivée" );
	grpDst->setHint( "Selectionnez 4 points d'arrivée" );

	OFX::Double2DParamDescriptor* dest0 = desc.defineDouble2DParam( kParamPointDestination + "0" );	//kpa... nom utilisé par le plug
	dest0->setLabel( "dst0" );	//nom que voit l'utilisateur	
	dest0->setDefault( 0, 0 );
	dest0->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest1 = desc.defineDouble2DParam( kParamPointDestination + "1" );
	dest1->setLabel( "dst1" );
	dest1->setDefault( 0, 1 );
	dest1->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest2 = desc.defineDouble2DParam( kParamPointDestination + "2" );
	dest2->setLabel( "dst2" );
	dest2->setDefault( 1, 1 );
	dest2->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest3 = desc.defineDouble2DParam( kParamPointDestination + "3" );
	dest3->setLabel( "dst3" );
	dest3->setDefault( 1, 0 );
	dest3->setParent(grpDst);
	
	OFX::PushButtonParamDescriptor* helpButton = desc.definePushButtonParam( kParamHelpButton );	//cree un bouton help
	//helpButton->setHint( "bla bla" );
	helpButton->setLabel( "Help" );

	OFX::GroupParamDescriptor* displayOptions = desc.defineGroupParam( kParamDisplayOptions );
	displayOptions->setLabel( "Options d'affichage" );
	displayOptions->setHint( "Options d'affichage (Ne change rien sur l'image)" );

	OFX::BooleanParamDescriptor* displayGrid = desc.defineBooleanParam( kParamGridOverlay );
	displayGrid->setLabel( "Afficher la grille" );
	displayGrid->setParent( *displayOptions );
	displayGrid->setDefault( false );
	displayGrid->setEvaluateOnChange( false );
	displayGrid->setHint( "Afficher la grille" );

	OFX::Double2DParamDescriptor* gridCenter = desc.defineDouble2DParam( kParamGridCenter );
	gridCenter->setLabel( "Centre de la grille" );
	gridCenter->setDoubleType( OFX::eDoubleTypePlain );
	gridCenter->setParent( *displayOptions );
	gridCenter->setDefault( 0.0, 0.0 );
	gridCenter->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	gridCenter->setEvaluateOnChange( false );
	gridCenter->setHint( "Allows you to shift the center of the  display grid." );

	OFX::Double2DParamDescriptor* center = desc.defineDouble2DParam( kParamCenter );
	center->setLabel( "Center" );
	center->setDoubleType( OFX::eDoubleTypePlain );
	center->setDefault( 0.0, 0.0 );
	center->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	center->setHint( "Center parameter allows you to shift the center of distortion." );


	OFX::Double2DParamDescriptor* gridScale = desc.defineDouble2DParam( kParamGridScale );
	gridScale->setLabel( "Echelle de la grille" );
	gridScale->setDoubleType( OFX::eDoubleTypePlain );
	gridScale->setParent( *displayOptions );
	gridScale->setDefault( 1.0, 1.0 );
	gridScale->setDisplayRange( -10.0, -10.0, 10.0, 10.0 );
	gridScale->setEvaluateOnChange( false );
	gridScale->setHint( "Allows you to scale the display grid." );

																				//kParamhelpButton : appelle un pluging
	//OFX::PushButtonParamDescriptor* poussoir = desc.definePushButtonParam( kParamPoussoir );	//cree un bouton help
	//poussoir->setLabel( "poussoir" );
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void HistogramPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,OFX::EContext context )
{
	
	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGB );
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( kSupportTiles );

	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	//global display
	OFX::BooleanParamDescriptor* boolGLOBAL = desc.defineBooleanParam(kGlobalDisplay);
	boolGLOBAL->setHint("Display global overlay on screen.");
	boolGLOBAL->setDefault(true);
	
    // RGB / HSL
	{
		//Group Param (RGB & HSL)
		OFX::GroupParamDescriptor *groupRGB = desc.defineGroupParam(kGroupRGB);
		groupRGB->setLabel(kGroupRGBLabel);
		OFX::GroupParamDescriptor *groupHSL = desc.defineGroupParam(kGroupHSL);
		groupHSL->setLabel(kGroupHSLLabel);

		//Channels checkboxes (RGB)
		OFX::BooleanParamDescriptor* boolR = desc.defineBooleanParam(kBoolRed);
		boolR->setDefault(true);							//red channel is not selected by default
		boolR->setHint("Activate Red channel");
		boolR->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolR->setParent(groupRGB);
		//red multiplier
		OFX::DoubleParamDescriptor* redMultiplier = desc.defineDoubleParam(kMultiplierRed);
		redMultiplier->setLabel(kMultiplierLabel);
		redMultiplier->setHint("Determinate curve from selection precision.");
		redMultiplier->setRange(1, 1000);
		redMultiplier->setDisplayRange(0,5);
		redMultiplier->setDefault(1);
		redMultiplier->setParent(groupRGB);
		
		OFX::BooleanParamDescriptor* boolG = desc.defineBooleanParam(kBoolGreen);
		boolG->setDefault(true);						//green channel is not selected by default
		boolG->setHint("Activate Green channel");
		boolG->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolG->setParent(groupRGB);
		//green multiplier
		OFX::DoubleParamDescriptor* greenMultiplier = desc.defineDoubleParam(kMultiplierGreen);
		greenMultiplier->setLabel(kMultiplierLabel);
		greenMultiplier->setHint("Determinate curve from selection precision.");
		greenMultiplier->setRange(1, 1000);
		greenMultiplier->setDisplayRange(0,5);
		greenMultiplier->setDefault(1);
		greenMultiplier->setParent(groupRGB);
		
		OFX::BooleanParamDescriptor* boolB = desc.defineBooleanParam(kBoolBlue);
		boolB->setHint("Activate Blue channel");
		boolB->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolB->setDefault(true);						   //blue channel is not selected by default
		boolB->setParent(groupRGB);
		//blue multiplier
		OFX::DoubleParamDescriptor* blueMultiplier = desc.defineDoubleParam(kMultiplierBlue);
		blueMultiplier->setLabel(kMultiplierLabel);
		blueMultiplier->setHint("Determinate curve from selection precision.");
		blueMultiplier->setRange(1, 1000);
		blueMultiplier->setDisplayRange(0,5);
		blueMultiplier->setDefault(1);
		blueMultiplier->setParent(groupRGB);
		
		//Channels check box (HSL)
		OFX::BooleanParamDescriptor* boolH = desc.defineBooleanParam(kBoolHue);
		boolH->setDefault(true);
		boolH->setHint("Activate Hue channel");
		boolH->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolH->setParent(groupHSL);
		//Hue multiplier
		OFX::DoubleParamDescriptor* hueMultiplier = desc.defineDoubleParam(kMultiplierHue);
		hueMultiplier->setLabel(kMultiplierLabel);
		hueMultiplier->setHint("Determinate curve from selection precision.");
		hueMultiplier->setRange(1, 1000);
		hueMultiplier->setDisplayRange(0,5);
		hueMultiplier->setDefault(1);
		hueMultiplier->setParent(groupHSL);
		
		OFX::BooleanParamDescriptor* boolS = desc.defineBooleanParam(kBoolSaturation);
		boolS->setDefault(true);
		boolS->setHint("Activate Saturation channel");
		boolS->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolS->setParent(groupHSL);
		//Saturation multiplier
		OFX::DoubleParamDescriptor* saturationMultiplier = desc.defineDoubleParam(kMultiplierSaturation);
		saturationMultiplier->setLabel(kMultiplierLabel);
		saturationMultiplier->setHint("Determinate curve from selection precision.");
		saturationMultiplier->setRange(1, 1000);
		saturationMultiplier->setDisplayRange(0,5);
		saturationMultiplier->setDefault(1);
		saturationMultiplier->setParent(groupHSL);
		
		OFX::BooleanParamDescriptor* boolL = desc.defineBooleanParam(kBoolLightness);
		boolL->setHint("Activate Lightness channel");
		boolL->setLayoutHint( OFX::eLayoutHintNoNewLine ); //line is not finished
		boolL->setDefault(true);
		boolL->setParent(groupHSL);
		//Lightness multiplier
		OFX::DoubleParamDescriptor* lightnessMultiplier = desc.defineDoubleParam(kMultiplierLightness);
		lightnessMultiplier->setLabel(kMultiplierLabel);
		lightnessMultiplier->setHint("Determinate curve from selection precision.");
		lightnessMultiplier->setRange(1, 1000);
		lightnessMultiplier->setDisplayRange(0,5);
		lightnessMultiplier->setDefault(1);
		lightnessMultiplier->setParent(groupHSL);
		
		//Close RGB group (group states by default on screen)
		groupRGB->setOpen(true);
		groupHSL->setOpen(true);
	}
	
	//Histogram overlay group
	{
		OFX::GroupParamDescriptor *groupHistogramOverlay = desc.defineGroupParam(kGroupHistogramOverlay);
		groupHistogramOverlay->setLabel(kGroupHistogramOverlayLabel);
		groupHistogramOverlay->setOpen(true);
//		groupHistogramOverlay->setAsTab();

		//Histogram display settings
		OFX::ChoiceParamDescriptor* gammaType = desc.defineChoiceParam(kHistoDisplayListParamLabel);
		gammaType->setLabel(kHistoDisplayListParamLabel);
		gammaType->setEvaluateOnChange(false); // don't need to recompute on change
		gammaType->setHint("Histogram display \n -global : normalize all of channels \n -by channel : keep proportions between channels");
		gammaType->appendOption(kHistoDisplayListParamOpt2);
		gammaType->appendOption(kHistoDisplayListParamOpt1);
		gammaType->setParent(groupHistogramOverlay);	

		//nbOfstep (advanced group)
		OFX::IntParamDescriptor* nbStepRange = desc.defineIntParam(knbStepRange);
		nbStepRange->setLabel(knbStepRangeLabel);
		nbStepRange->setHint("Determinate histogram overlay precision.");
		nbStepRange->setRange(1, 1000);
		nbStepRange->setDisplayRange(1, 600.0 );
		nbStepRange->setDefault(255);
		nbStepRange->setEvaluateOnChange(false); // don't need to recompute on change
		nbStepRange->setParent(groupHistogramOverlay);

		//selection multiplier (advanced group)
		OFX::DoubleParamDescriptor* selectionMultiplier = desc.defineDoubleParam(kselectionMultiplier);
		selectionMultiplier->setLabel(kselectionMultiplierLabel);
		selectionMultiplier->setHint("With high values, small selection are more visible.");
		selectionMultiplier->setRange(0.001,1000.0);
		selectionMultiplier->setDisplayRange(0.0, 100.0 );
		selectionMultiplier->setDefault(2.0);
		selectionMultiplier->setEvaluateOnChange(false); // don't need to recompute on change
		selectionMultiplier->setParent(groupHistogramOverlay);

		//Refresh histograms overlay Button
		OFX::PushButtonParamDescriptor* refreshOverlayButton = desc.definePushButtonParam(kButtonRefreshOverlay);
		refreshOverlayButton->setLabel(kButtonRefreshOverlayLabel);
		refreshOverlayButton->setHint("Refresh histogram overlay.");
		refreshOverlayButton->setParent(groupHistogramOverlay);
	}
	
	//Selection group
	{
		OFX::GroupParamDescriptor *groupSelection = desc.defineGroupParam(kGroupSelection);
		groupSelection->setLabel(kGroupSelectionLabel);
		groupSelection->setOpen(false);
//		groupSelection->setAsTab();
		//display selection
		OFX::BooleanParamDescriptor* boolDisplaySelection = desc.defineBooleanParam(kBoolSelection);
		boolDisplaySelection->setDefault(true);
		boolDisplaySelection->setEvaluateOnChange(false);// don't need to recompute on change
		boolDisplaySelection->setHint("Display the selected zone on screen.");
		boolDisplaySelection->setParent(groupSelection);
		//clear selection
		OFX::PushButtonParamDescriptor* resetSelectionButton = desc.definePushButtonParam(kButtonResetSelection);
		resetSelectionButton->setLabel(kButtonResetSelectionLabel);
		resetSelectionButton->setHint("Reset user's selection.");
		resetSelectionButton->setParent(groupSelection);
		//selection mode
		OFX::ChoiceParamDescriptor* selectionMode = desc.defineChoiceParam(kSelectionModeListParamLabel);
		selectionMode->setLabel(kSelectionModeListParamLabel);
		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");
		selectionMode->appendOption(kSelectionModeListParamOpt2);
		selectionMode->appendOption(kSelectionModeListParamOpt1);
		selectionMode->appendOption(kSelectionModeListParamOpt3);
		selectionMode->setParent(groupSelection);
	}
}