diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf53dec3..97c0c74a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,6 +306,10 @@ if (OPTION_OMP) endif (OPENMP_FOUND) endif (OPTION_OMP) +if (UNIX) + install (PROGRAMS rtstart DESTINATION ${BINDIR}) +endif (UNIX) + install (FILES AUTHORS.txt DESTINATION ${CREDITSDIR}) install (FILES LICENSE.txt DESTINATION ${LICENCEDIR}) install (FILES AboutThisBuild.txt DESTINATION ${CREDITSDIR}) diff --git a/rtdata/languages/default b/rtdata/languages/default index 0dccc00d3..c6ea80166 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -351,6 +351,9 @@ HISTORY_MSG_159;Edge stopping HISTORY_MSG_160;Scale HISTORY_MSG_161;Reweighting iterates HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;RGB Curves - R +HISTORY_MSG_164;RGB Curves - G +HISTORY_MSG_165;RGB Curves - B HISTORY_NEWSNAPSHOTAS;As... HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: @@ -557,6 +560,7 @@ PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations PARTIALPASTE_RAW_DMETHOD;Demosaic Method PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_RGBCURVES;RGB curves PARTIALPASTE_ROTATION;Rotation PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights PARTIALPASTE_SHARPENEDGE;Edges @@ -957,6 +961,7 @@ TP_RESIZE_SCALE;Scale TP_RESIZE_SPECIFY;Specify: TP_RESIZE_WIDTH;Width TP_RESIZE_W;W: +TP_RGBCURVES_LABEL;RGB Curves TP_ROTATE_DEGREE;Degree TP_ROTATE_LABEL;Rotate TP_ROTATE_SELECTLINE; Select Straight Line diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 225fa750d..27fec7a69 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -421,7 +421,7 @@ namespace rtengine { DiagonalCurve* tcurve = NULL; if (curvePoints.size()>0 && curvePoints[0]!=0) { tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); - if (outBeforeCCurveHistogram && histogramCropped) + if (outBeforeCCurveHistogram /*&& histogramCropped*/) histNeeded = true; } if (tcurve && tcurve->isIdentity()) { @@ -434,11 +434,12 @@ namespace rtengine { if (histNeeded) { float fi=i; - float hval = dcurve[shCurve[hlCurve[i]*fi]*fi]; + float hval = hlCurve[i]*fi; + hval = dcurve[shCurve[hval]*hval]; //if (needigamma) // hval = igamma2 (hval); int hi = (int)(255.0*(hval)); - outBeforeCCurveHistogram[hi] += histogramCropped[i] ; + outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ; } // apply custom/parametric/NURBS curve, if any @@ -585,7 +586,7 @@ namespace rtengine { bool histNeeded = false; if (curvePoints.size()>0 && curvePoints[0]!=0) { tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); - if (outBeforeCCurveHistogram && histogramCropped) + if (outBeforeCCurveHistogram /*&& histogramCropped*/) histNeeded = true; } if (tcurve && tcurve->isIdentity()) { @@ -601,7 +602,7 @@ namespace rtengine { if (histNeeded) { float hval = dcurve[i]; int hi = (int)(255.0*CLIPD(hval)); - outBeforeCCurveHistogram[hi]+=histogramCropped[i] ; + outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ; } // apply custom/parametric/NURBS curve, if any @@ -617,7 +618,7 @@ namespace rtengine { if (histNeeded) { float hval = dcurve[i]; int hi = (int)(255.0*CLIPD(hval)); - outBeforeCCurveHistogram[hi]+=histogramCropped[i] ; + outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ; } outCurve[i] = 32767.0*dcurve[i]; @@ -636,7 +637,47 @@ namespace rtengine { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void CurveFactory::RGBCurve (const std::vector& curvePoints, LUTf & outCurve, int skip) { + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create a curve if needed + DiagonalCurve* tcurve = NULL; + bool histNeeded = false; + if (curvePoints.size()>0 && curvePoints[0]!=0) { + tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); + } + if (tcurve && tcurve->isIdentity()) { + delete tcurve; + tcurve = NULL; + } + + if (tcurve) { + for (int i=0; i<65536; i++) { + // apply custom/parametric/NURBS curve, if any + float val = tcurve->getVal ((float)i/65536.0f); + outCurve[i] = (65536.0f * val); + } + } + else { + // Skip the slow getval method if no curve is used (or an identity curve) + for (int i=0; i<65536; i++) { + outCurve[i] = i; + } + } + + if (tcurve) + delete tcurve; + } + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + LUTf CurveFactory::gammatab; LUTf CurveFactory::igammatab_srgb; diff --git a/rtengine/curves.h b/rtengine/curves.h index 5ebcf4af6..10e849d92 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -193,12 +193,14 @@ class CurveFactory { } public: - static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, double gamma_, bool igamma_, const std::vector& curvePoints, - LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1); + static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, \ + double gamma_, bool igamma_, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, \ + LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1); static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector& acurvePoints, \ const std::vector& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1); - static void complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, - LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip); + static void complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, \ + LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip); + static void RGBCurve (const std::vector& curvePoints, LUTf & outCurve, int skip); }; class Curve { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 60986517b..845f0214e 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -128,7 +128,7 @@ void Crop::update (int todo) { } // shadows & highlights & tone curve & convert to cielab - int xref,yref; + /*int xref,yref; xref=000;yref=000; if (colortest && cropw>115 && croph>115) for(int j=1;j<5;j++){ @@ -138,12 +138,13 @@ void Crop::update (int todo) { baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256, \ baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256, parent->imgsrc->getGamma()); - } + }*/ if (todo & M_RGBCURVE) - parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, params.toneCurve.saturation); + parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, \ + params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve ); - xref=000;yref=000; + /*xref=000;yref=000; if (colortest && cropw>115 && croph>115) for(int j=1;j<5;j++){ xref+=j*30;yref+=j*30; @@ -157,7 +158,7 @@ void Crop::update (int todo) { laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, \ laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); } - } + }*/ // apply luminance operations if (todo & (M_LUMINANCE+M_COLOR)) { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 9edca5e51..b60ecbb03 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -55,7 +55,13 @@ ImProcCoordinator::ImProcCoordinator () histToneCurve(256); histLCurve(256); bcabhist(256); - + + rCurve(65536,0); + rcurvehist(256); rcurvehistCropped(256); rbeforehist(256); + gCurve(65536,0); + gcurvehist(256); gcurvehistCropped(256); gbeforehist(256); + bCurve(65536,0); + bcurvehist(256); bcurvehistCropped(256); bbeforehist(256); } void ImProcCoordinator::assign (ImageSource* imgsrc) { @@ -225,10 +231,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, \ imgsrc->getGamma(), true, params.toneCurve.curve, \ vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, scale==1 ? 1 : 1); - + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1); + // if it's just crop we just need the histogram, no image updates if ( todo!=CROP ) { - ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation); + ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, \ + rCurve, gCurve, bCurve); } // compute L channel histogram diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 08daee83f..e77807b52 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -73,7 +73,15 @@ class ImProcCoordinator : public StagedImageProcessor { LUTf chroma_acurve; LUTf chroma_bcurve; LUTf satcurve; - + + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; + + LUTu rcurvehist, rcurvehistCropped, rbeforehist; + LUTu gcurvehist, gcurvehistCropped, gbeforehist; + LUTu bcurvehist, bcurvehistCropped, bbeforehist; + LUTu vhist16; LUTu lhist16,lhist16Cropped; LUTu histCropped; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 4bfac6ac7..77f00b8ae 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -207,7 +207,8 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par } // Process RGB image and convert to LAB space -void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat) { +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, \ + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve) { int h_th, s_th; if (shmap) { @@ -334,9 +335,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone b *= tonefactor; //brightness/contrast and user tone curve - r = tonecurve[r]; - g = tonecurve[g]; - b = tonecurve[b]; + r = rCurve[tonecurve[r]]; + g = gCurve[tonecurve[g]]; + b = bCurve[tonecurve[b]]; //if (r<0 || g<0 || b<0) { // printf("negative values row=%d col=%d r=%f g=%f b=%f \n", i,j,r,g,b); @@ -505,7 +506,7 @@ void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf & a } -#include "cubic.cc" +//#include "cubic.cc" void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) { @@ -811,18 +812,18 @@ fclose(f);*/ contr = MAX(0,MIN(100,contr)); //diagnostics - printf ("**************** AUTO LEVELS ****************\n"); - printf ("gain1= %f gain2= %f gain= %f\n",expcomp1,expcomp2,gain); - printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave); + //printf ("**************** AUTO LEVELS ****************\n"); + //printf ("gain1= %f gain2= %f gain= %f\n",expcomp1,expcomp2,gain); + //printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave); //printf ("average: %f\n",ave); //printf ("median/average: %f\n",median/ave); - printf ("lodev: %f hidev: %f hidev/lodev: %f\n",lodev,hidev,hidev/lodev); + //printf ("lodev: %f hidev: %f hidev/lodev: %f\n",lodev,hidev,hidev/lodev); //printf ("lodev: %f\n",lodev); //printf ("hidev: %f\n",hidev); - printf ("rawmax= %d whiteclip= %d gain= %f\n",rawmax,whiteclip,gain); + //printf ("rawmax= %d whiteclip= %d gain= %f\n",rawmax,whiteclip,gain); - printf ("octiles: %f %f %f %f %f %f %f %f\n",octile[0],octile[1],octile[2],octile[3],octile[4],octile[5],octile[6],octile[7]); - printf ("ospread= %f\n",ospread); + //printf ("octiles: %f %f %f %f %f %f %f %f\n",octile[0],octile[1],octile[2],octile[3],octile[4],octile[5],octile[6],octile[7]); + //printf ("ospread= %f\n",ospread); /* diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 04deff004..641c6f495 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -111,7 +111,8 @@ class ImProcFunctions { bool needsTransform (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma); - void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat); + void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, \ + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve); void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve); void vibrance (LabImage* lab);//Jacques' vibrance diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 838af9b99..d3d1bae11 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -184,7 +184,10 @@ enum ProcEvent { EvEPDScale=159, EvEPDReweightingIterates=160, EvEPDEnabled=161, - NUMOFEVENTS=162 + EvRGBrCurve=162, + EvRGBgCurve=163, + EvRGBbCurve=164, + NUMOFEVENTS=165 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 50e52a8cc..cc76b8c72 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -91,7 +91,15 @@ void ProcParams::setDefaults () { labCurve.acurve.push_back(DCT_Linear); labCurve.bcurve.clear (); labCurve.bcurve.push_back(DCT_Linear); - + + rgbCurves.rcurve.clear (); + rgbCurves.rcurve.push_back(DCT_Linear); + rgbCurves.gcurve.clear (); + rgbCurves.gcurve.push_back(DCT_Linear); + rgbCurves.bcurve.clear (); + rgbCurves.bcurve.push_back(DCT_Linear); + + sharpenEdge.enabled = false; sharpenEdge.passes = 2; sharpenEdge.amount = 50.0; @@ -521,6 +529,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2) const { keyFile.set_double_list("HSV Equalizer", "SCurve", scurve); keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); + Glib::ArrayHandle RGBrcurve = rgbCurves.rcurve; + Glib::ArrayHandle RGBgcurve = rgbCurves.gcurve; + Glib::ArrayHandle RGBbcurve = rgbCurves.bcurve; + keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve); + keyFile.set_double_list("RGB Curves", "gCurve", RGBgcurve); + keyFile.set_double_list("RGB Curves", "bCurve", RGBbcurve); + // save RAW parameters keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame ); keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); @@ -906,6 +921,13 @@ if (keyFile.has_group ("HSV Equalizer")) { } } +// load RGB curves +if (keyFile.has_group ("RGB Curves")) { +if (keyFile.has_key ("RGB Curves", "rCurve")) rgbCurves.rcurve = keyFile.get_double_list ("RGB Curves", "rCurve"); +if (keyFile.has_key ("RGB Curves", "gCurve")) rgbCurves.gcurve = keyFile.get_double_list ("RGB Curves", "gCurve"); +if (keyFile.has_key ("RGB Curves", "bCurve")) rgbCurves.bcurve = keyFile.get_double_list ("RGB Curves", "bCurve"); +} + // load raw settings if (keyFile.has_group ("RAW")) { if (keyFile.has_key ("RAW", "DarkFrame")) raw.dark_frame = keyFile.get_string ("RAW", "DarkFrame" ); @@ -1148,6 +1170,9 @@ bool ProcParams::operator== (const ProcParams& other) { && hsvequalizer.hcurve == other.hsvequalizer.hcurve && hsvequalizer.scurve == other.hsvequalizer.scurve && hsvequalizer.vcurve == other.hsvequalizer.vcurve + && rgbCurves.rcurve == other.rgbCurves.rcurve + && rgbCurves.gcurve == other.rgbCurves.gcurve + && rgbCurves.bcurve == other.rgbCurves.bcurve && exif==other.exif && iptc==other.iptc && raw.expos==other.raw.expos diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 528a91324..d52378c26 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -61,6 +61,17 @@ class LCurveParams { double saturationlimit; }; +/** + * Parameters of the RGB curves + */ +class RGBCurvesParams { + + public: + std::vector rcurve; + std::vector gcurve; + std::vector bcurve; +}; + /** * Parameters of the sharpening */ @@ -476,6 +487,7 @@ class ProcParams { public: ToneCurveParams toneCurve; ///< Tone curve parameters LCurveParams labCurve; ///< CIELAB luminance curve parameters + RGBCurvesParams rgbCurves; ///< RGB curves parameters SharpeningParams sharpening; ///< Sharpening parameters SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 27404eb0d..2a091f8b3 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -67,6 +67,11 @@ PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median +#define med5(a0,a1,a2,a3,a4,median) { \ +p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \ +PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \ +PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \ +PIX_SORT(p[1],p[2]) ; median=p[2] ;} RawImageSource::RawImageSource () @@ -1303,9 +1308,8 @@ void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH, for (int j=0; jW-3) {jnext=j-2;} else {jnext=j+2;} - med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext], \ - rawData[i][jprev],rawData[i][j],rawData[i][jnext], \ - rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],cfatmp[i*W+j]); + med5(rawData[iprev][j], rawData[i][jprev],rawData[i][j], \ + rawData[i][jnext], rawData[inext][j],cfatmp[i*W+j]); } } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 05b020e93..c1eb15775 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -181,7 +181,10 @@ SHARPENING, // EvEPDStrength SHARPENING, // EvEPDEdgeStopping SHARPENING, // EvEPDScale SHARPENING, // EvEPDReweightingIterates -SHARPENING // EvEPDEnabled - +SHARPENING, // EvEPDEnabled +RGBCURVE, // EvRGBrCurve +RGBCURVE, // EvRGBgCurve +RGBCURVE // EvRGBbCurve + }; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 54a95c376..a3bc67cb0 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -733,6 +733,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei LUTf curve2 (65536); LUTf curve (65536); LUTf satcurve (65536); + LUTf rCurve (65536); + LUTf gCurve (65536); + LUTf bCurve (65536); LUTu dummy; //CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, \ @@ -742,10 +745,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei params.toneCurve.shcompr, bright, contr, gamma, true, params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy, 16); + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16); LabImage* labView = new LabImage (fw,fh); - ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve ); if (shmap) delete shmap; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index ce629952c..1f283f982 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -159,14 +159,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf curve2 (65536,0); LUTf curve (65536,0); LUTf satcurve (65536,0); + LUTf rCurve (65536,0); + LUTf gCurve (65536,0); + LUTf bCurve (65536,0); LUTu dummy; CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, bright, params.toneCurve.contrast, imgsrc->getGamma(), true, params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); LabImage* labView = new LabImage (fw,fh); - ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve); // Freeing baseImg because not used anymore delete baseImg; diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 42f70afa0..2f81dec82 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -9,7 +9,7 @@ set (BASESOURCEFILES resize.cc icmpanel.cc crop.cc shadowshighlights.cc impulsedenoise.cc dirpyrdenoise.cc epd.cc exifpanel.cc toolpanel.cc - sharpening.cc vibrance.cc + sharpening.cc vibrance.cc rgbcurves.cc whitebalance.cc vignetting.cc rotate.cc distortion.cc crophandler.cc dirbrowser.cc curveeditor.cc curveeditorgroup.cc diagonalcurveeditorsubgroup.cc flatcurveeditorsubgroup.cc diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 98f86d7d6..26cdace77 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1307,7 +1307,7 @@ void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & his LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { if (histogramPanel) histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); - tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve); + tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma); } bool EditorPanel::CheckSidePanelsVisibility() { diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index d61fa1fc6..61f5ed783 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -328,9 +328,9 @@ void LCurve::setBatchMode (bool batchMode) { } -void LCurve::updateCurveBackgroundHistogram (LUTu & hist) { +void LCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){ - lshape->updateBackgroundHistogram (hist); + lshape->updateBackgroundHistogram (histLCurve); } void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) { diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index 109dfc76e..b0f6f116d 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -62,7 +62,7 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPan void adjusterChanged (Adjuster* a, double newval); void avoidclip_toggled (); void enablelimiter_toggled (); - void updateCurveBackgroundHistogram (LUTu & hist); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); virtual void colorForValue (double valX, double valY); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 29cc1d41b..ad3f3fdf1 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -48,6 +48,9 @@ void ParamsEdited::set (bool v) { labCurve.avoidclip = v; labCurve.enable_saturationlimiter = v; labCurve.saturationlimit = v; + rgbCurves.rcurve = v; + rgbCurves.gcurve = v; + rgbCurves.bcurve = v; sharpening.enabled = v; sharpening.radius = v; sharpening.amount = v; @@ -231,7 +234,10 @@ void ParamsEdited::initFrom (const std::vector labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation; labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; labCurve.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter; - labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; + labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; + rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve; + rgbCurves.gcurve = rgbCurves.gcurve && p.rgbCurves.gcurve == other.rgbCurves.gcurve; + rgbCurves.bcurve = rgbCurves.bcurve && p.rgbCurves.bcurve == other.rgbCurves.bcurve; sharpenEdge.enabled = sharpenEdge.enabled && p.sharpenEdge.enabled == other.sharpenEdge.enabled; sharpenEdge.passes = sharpenEdge.passes && p.sharpenEdge.passes == other.sharpenEdge.passes; sharpenEdge.amount = sharpenEdge.amount && p.sharpenEdge.amount == other.sharpenEdge.amount; @@ -413,6 +419,11 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip; if (labCurve.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter; if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit; + + if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; + if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; + if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; + if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes; if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c436c9e82..93d157ecc 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -54,6 +54,14 @@ class LCurveParamsEdited { bool bcurve; }; +class RGBCurvesParamsEdited { + + public: + bool rcurve; + bool gcurve; + bool bcurve; +}; + class SharpenEdgeParamsEdited { public : @@ -361,6 +369,7 @@ class ParamsEdited { public: ToneCurveParamsEdited toneCurve; LCurveParamsEdited labCurve; + RGBCurvesParamsEdited rgbCurves; SharpeningParamsEdited sharpening; SharpenEdgeParamsEdited sharpenEdge; SharpenMicroParamsEdited sharpenMicro; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index acbdbeb03..2f0666120 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -63,7 +63,8 @@ PartialPasteDlg::PartialPasteDlg () { chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER"))); dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE"))); hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER"))); - + rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES"))); + // options in lens: distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION"))); cacorr = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CACORRECTION"))); @@ -140,6 +141,7 @@ PartialPasteDlg::PartialPasteDlg () { vboxes[2]->pack_start (*vibrance, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*chmixer, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*rgbcurves, Gtk::PACK_SHRINK, 2); vboxes[3]->pack_start (*lens, Gtk::PACK_SHRINK, 2); vboxes[3]->pack_start (*hseps[3], Gtk::PACK_SHRINK, 2); @@ -252,7 +254,8 @@ PartialPasteDlg::PartialPasteDlg () { vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); - + rgbcurvesConn = rgbcurves->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); cacorrConn = cacorr->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); vignettingConn = vignetting->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); @@ -468,17 +471,20 @@ void PartialPasteDlg::colorToggled () { vibranceConn.block (true); chmixerConn.block (true); hsveqConn.block (true); + rgbcurvesConn.block (true); gamcsconn.block (true); color->set_inconsistent (false); vibrance->set_active (color->get_active ()); chmixer->set_active (color->get_active ()); hsveq->set_active (color->get_active ()); + rgbcurves->set_active (color->get_active ()); icm->set_active (color->get_active ()); vibranceConn.block (false); chmixerConn.block (false); hsveqConn.block (false); + rgbcurvesConn.block (false); gamcsconn.block (false); } @@ -566,6 +572,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r if (vibrance->get_active ()) dst->vibrance = src->vibrance; if (chmixer->get_active ()) dst->chmixer = src->chmixer; if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer; + if (rgbcurves->get_active ()) dst->rgbCurves = src->rgbCurves; if (icm->get_active ()) dst->icm = src->icm; if (distortion->get_active ()) dst->distortion = src->distortion; diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 87b8d1b7e..fff6c54ad 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -59,6 +59,7 @@ class PartialPasteDlg : public Gtk::Dialog { Gtk::CheckButton* vibrance; Gtk::CheckButton* chmixer; Gtk::CheckButton* hsveq; + Gtk::CheckButton* rgbcurves; // Gtk::CheckButton* icm; // options in lens: @@ -107,7 +108,7 @@ class PartialPasteDlg : public Gtk::Dialog { sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn; sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, edgePreservingDecompositionUIConn, dirpyreqConn; - sigc::connection vibranceConn, chmixerConn, hsveqConn; + sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn; sigc::connection distortionConn, cacorrConn, vignettingConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; sigc::connection exifchConn, iptcConn, icmConn, gamcsconn; diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc new file mode 100644 index 000000000..34e5a8dde --- /dev/null +++ b/rtgui/rgbcurves.cc @@ -0,0 +1,141 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "rgbcurves.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) { + + curveEditorG = new CurveEditorGroup (); + curveEditorG->setCurveListener (this); + curveEditorG->setColorProvider (this); + + Rshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "R"); + Gshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "G"); + Bshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "B"); + + // This will add the reset button at the end of the curveType buttons + curveEditorG->curveListComplete(); + + pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + +} + +RGBCurves::~RGBCurves () { + delete curveEditorG; +} + +void RGBCurves::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + Rshape->setUnChanged (!pedited->rgbCurves.rcurve); + Gshape->setUnChanged (!pedited->rgbCurves.gcurve); + Bshape->setUnChanged (!pedited->rgbCurves.bcurve); + } + + Rshape->setCurve (pp->rgbCurves.rcurve); + Gshape->setCurve (pp->rgbCurves.gcurve); + Bshape->setCurve (pp->rgbCurves.bcurve); + + // Open up the first curve if selected + bool active = Rshape->openIfNonlinear(); + if (!active) Gshape->openIfNonlinear(); + if (!active) Bshape->openIfNonlinear(); + + enableListener (); +} + +void RGBCurves::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->rgbCurves.rcurve = Rshape->getCurve (); + pp->rgbCurves.gcurve = Gshape->getCurve (); + pp->rgbCurves.bcurve = Bshape->getCurve (); + + if (pedited) { + pedited->rgbCurves.rcurve = !Rshape->isUnChanged (); + pedited->rgbCurves.gcurve = !Gshape->isUnChanged (); + pedited->rgbCurves.bcurve = !Bshape->isUnChanged (); + } +} + + +/* + * Curve listener + * + * If more than one curve has been added, the curve listener is automatically + * set to 'multi=true', and send a pointer of the modified curve in a parameter + */ +void RGBCurves::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == Rshape) + listener->panelChanged (EvRGBrCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == Gshape) + listener->panelChanged (EvRGBgCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == Bshape) + listener->panelChanged (EvRGBbCurve, M("HISTORY_CUSTOMCURVE")); + } +} + + +//!!! TODO: change +void RGBCurves::colorForValue (double valX, double valY) { + + CurveEditor* ce = curveEditorG->getDisplayedCurve(); + + if (ce == Rshape) { // L = f(L) + red = (double)valY; + green = (double)valY; + blue = (double)valY; + } + else if (ce == Gshape) { // a = f(a) + // TODO: To be implemented + red = (double)valY; + green = (double)valY; + blue = (double)valY; + } + else if (ce == Bshape) { // b = f(b) + red = (double)valY; + green = (double)valY; + blue = (double)valY; + } + else { + printf("Error: no curve displayed!\n"); + } + +} + +void RGBCurves::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + curveEditorG->setBatchMode (batchMode); +} + + +void RGBCurves::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { + + //Rshape->updateBackgroundHistogram (histRed); + //Gshape->updateBackgroundHistogram (histGreen); + //Bshape->updateBackgroundHistogram (histBlue); +} + diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h new file mode 100644 index 000000000..efced4eb3 --- /dev/null +++ b/rtgui/rgbcurves.h @@ -0,0 +1,52 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _RGBCURVES_H_ +#define _RGBCURVES_H_ + +#include +#include +#include +#include +#include +#include + +class RGBCurves : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider { + + protected: + CurveEditorGroup* curveEditorG; + DiagonalCurveEditor* Rshape; + DiagonalCurveEditor* Gshape; + DiagonalCurveEditor* Bshape; + + public: + + RGBCurves (); + ~RGBCurves (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void curveChanged (CurveEditor* ce); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + + virtual void colorForValue (double valX, double valY); +}; + +#endif diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 30f7adc63..1cf81a1cd 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -410,7 +410,7 @@ void ToneCurve::trimValues (rtengine::procparams::ProcParams* pp) { saturation->trimValue(pp->toneCurve.saturation); } -void ToneCurve::updateCurveBackgroundHistogram (LUTu & hist) { +void ToneCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { - shape->updateBackgroundHistogram (hist); + shape->updateBackgroundHistogram (histToneCurve); } diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index bb9ec1bf2..3c0da969d 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -78,7 +78,7 @@ class ToneCurve : public Gtk::VBox, public AdjusterListener, public FoldableTool void curveChanged (); void expandCurve (bool isExpanded); bool isCurveExpanded (); - void updateCurveBackgroundHistogram (LUTu & hist); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); }; #endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index a5279fe1f..ecbec5853 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -50,6 +50,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { sharpenEdge = Gtk::manage (new SharpenEdge ()); sharpenMicro = Gtk::manage (new SharpenMicro ()); lcurve = Gtk::manage (new LCurve ()); + rgbcurves = Gtk::manage (new RGBCurves ()); lensgeom = Gtk::manage (new LensGeometry ()); distortion = Gtk::manage (new Distortion ()); rotate = Gtk::manage (new Rotate ()); @@ -84,6 +85,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL")); toolPanels.push_back (sharpenEdge); addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); toolPanels.push_back (sharpenMicro); addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer); + addPanel (colorPanel, rgbcurves, M("TP_RGBCURVES_LABEL")); toolPanels.push_back (rgbcurves); addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI); addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve); addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise); @@ -492,10 +494,11 @@ int ToolPanelCoordinator::getSpotWBRectSize () { return whitebalance->getSize (); } -void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu &histToneCurve, LUTu &histLCurve) { +void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { - toneCurve->updateCurveBackgroundHistogram (histToneCurve); - lcurve->updateCurveBackgroundHistogram (histLCurve); + toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma); + rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve,histRed,histGreen, histBlue, histLuma); + lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma); } void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection) { diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 348f4dadd..e77cfbae7 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -62,6 +62,8 @@ #include #include #include +#include "rgbcurves.h" + class ImageEditorCoordinator; class ToolPanelCoordinator : public ToolPanelListener, @@ -101,6 +103,7 @@ class ToolPanelCoordinator : public ToolPanelListener, SharpenEdge* sharpenEdge; SharpenMicro* sharpenMicro; LCurve* lcurve; + RGBCurves* rgbcurves; DirPyrEqualizer * dirpyrequalizer; HSVEqualizer * hsvequalizer; RawProcess* rawprocess; @@ -172,7 +175,7 @@ class ToolPanelCoordinator : public ToolPanelListener, ~ToolPanelCoordinator (); bool getChangedState () { return hasChanged; } - void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurves); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); void foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection); // multiple listeners can be added that are notified on changes (typical: profile panel and the history)