From d7195e6c38041af5c04b665eea9fa94b6eea27ee Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 16 Feb 2013 22:16:06 -0500 Subject: [PATCH] RGB curves: option for luminosity mode (issue 1607) Thanks for help, Jacques! --- rtdata/languages/default | 4 +- rtdata/profiles/BW-1.pp3 | 1 + rtdata/profiles/BW-2.pp3 | 1 + rtdata/profiles/BW-3.pp3 | 1 + rtdata/profiles/BW-4.pp3 | 1 + rtdata/profiles/Default-ISO-High.pp3 | 1 + rtdata/profiles/Default-ISO-Medium.pp3 | 1 + rtdata/profiles/Default.pp3 | 1 + rtdata/profiles/Highkey-1.pp3 | 1 + rtdata/profiles/Natural-1.pp3 | 1 + rtdata/profiles/Natural-2.pp3 | 1 + rtdata/profiles/Neutral.pp3 | 1 + rtdata/profiles/Punchy-1.pp3 | 1 + rtdata/profiles/Punchy-2.pp3 | 1 + rtengine/improcfun.cc | 103 +++++++++++++++++++------ rtengine/procevents.h | 2 +- rtengine/procparams.cc | 5 ++ rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 2 +- rtengine/settings.h | 1 + rtgui/options.cc | 3 + rtgui/paramsedited.cc | 5 +- rtgui/paramsedited.h | 1 + rtgui/rgbcurves.cc | 44 +++++++++++ rtgui/rgbcurves.h | 5 ++ 25 files changed, 160 insertions(+), 29 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 1f44a7966..0311978b3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -311,7 +311,7 @@ HISTORY_MSG_82;Profile Changed HISTORY_MSG_83;High Quality Shadows/Highlights HISTORY_MSG_84;Perspective Correction HISTORY_MSG_85;Lens Correction Profile -HISTORY_MSG_86;Wavelet Equalizer +HISTORY_MSG_86;RGB Curves - Luminosity Mode HISTORY_MSG_87;Impulse Noise Reduction HISTORY_MSG_88;Impulse NR Threshold HISTORY_MSG_89;Noise Reduction @@ -1181,6 +1181,8 @@ TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Channel TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;RGB Curves +TP_RGBCURVES_LUMAMODE;Luminosity Mode +TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminosity Mode allows to vary the contribution of R, G an B channels to the Luminosity of the image, without altering image color. TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;Degree TP_ROTATE_LABEL;Rotate diff --git a/rtdata/profiles/BW-1.pp3 b/rtdata/profiles/BW-1.pp3 index ffeab7fd0..5cef081f4 100644 --- a/rtdata/profiles/BW-1.pp3 +++ b/rtdata/profiles/BW-1.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/BW-2.pp3 b/rtdata/profiles/BW-2.pp3 index 279125605..fbf50f751 100644 --- a/rtdata/profiles/BW-2.pp3 +++ b/rtdata/profiles/BW-2.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/BW-3.pp3 b/rtdata/profiles/BW-3.pp3 index 86eaed06e..154c6c24e 100644 --- a/rtdata/profiles/BW-3.pp3 +++ b/rtdata/profiles/BW-3.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/BW-4.pp3 b/rtdata/profiles/BW-4.pp3 index 35d552397..69ee7b63e 100644 --- a/rtdata/profiles/BW-4.pp3 +++ b/rtdata/profiles/BW-4.pp3 @@ -231,6 +231,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Default-ISO-High.pp3 b/rtdata/profiles/Default-ISO-High.pp3 index 0d12bcd76..8cc4b2024 100644 --- a/rtdata/profiles/Default-ISO-High.pp3 +++ b/rtdata/profiles/Default-ISO-High.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Default-ISO-Medium.pp3 b/rtdata/profiles/Default-ISO-Medium.pp3 index 791f37c84..cac669ff2 100644 --- a/rtdata/profiles/Default-ISO-Medium.pp3 +++ b/rtdata/profiles/Default-ISO-Medium.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 index 8c77e006a..d1c4594f3 100644 --- a/rtdata/profiles/Default.pp3 +++ b/rtdata/profiles/Default.pp3 @@ -231,6 +231,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Highkey-1.pp3 b/rtdata/profiles/Highkey-1.pp3 index 172054215..4afa7b764 100644 --- a/rtdata/profiles/Highkey-1.pp3 +++ b/rtdata/profiles/Highkey-1.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Natural-1.pp3 b/rtdata/profiles/Natural-1.pp3 index 571a0aa75..8f2dc2abf 100644 --- a/rtdata/profiles/Natural-1.pp3 +++ b/rtdata/profiles/Natural-1.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Natural-2.pp3 b/rtdata/profiles/Natural-2.pp3 index 6af558fd3..f929be739 100644 --- a/rtdata/profiles/Natural-2.pp3 +++ b/rtdata/profiles/Natural-2.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Neutral.pp3 b/rtdata/profiles/Neutral.pp3 index a72420069..63fc9d05f 100644 --- a/rtdata/profiles/Neutral.pp3 +++ b/rtdata/profiles/Neutral.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Punchy-1.pp3 b/rtdata/profiles/Punchy-1.pp3 index 269572028..cc40db5de 100644 --- a/rtdata/profiles/Punchy-1.pp3 +++ b/rtdata/profiles/Punchy-1.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtdata/profiles/Punchy-2.pp3 b/rtdata/profiles/Punchy-2.pp3 index 5dfb270a9..3e7f3c033 100644 --- a/rtdata/profiles/Punchy-2.pp3 +++ b/rtdata/profiles/Punchy-2.pp3 @@ -230,6 +230,7 @@ SCurve=0; VCurve=0; [RGB Curves] +LumaMode=false rCurve=0; gCurve=0; bCurve=0; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 4d72c05d3..53cd8be6c 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1748,6 +1748,13 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone } }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + //inverse matrix user select + double wip[3][3] = { + {wiprof[0][0],wiprof[0][1],wiprof[0][2]}, + {wiprof[1][0],wiprof[1][1],wiprof[1][2]}, + {wiprof[2][0],wiprof[2][1],wiprof[2][2]} + }; bool mixchannels = (params->chmixer.red[0]!=100 || params->chmixer.red[1]!=0 || params->chmixer.red[2]!=0 || params->chmixer.green[0]!=0 || params->chmixer.green[1]!=100 || params->chmixer.green[2]!=0 || @@ -2048,43 +2055,89 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone } } - if (rCurve) { + if (rCurve || gCurve || bCurve) { // if any of the RGB curves is engaged + if (!params->rgbCurves.lumamode){ // normal RGB mode + #ifdef _OPENMP #pragma omp for schedule(dynamic, 5) #endif - for (int i=0; ir(i,j) = rCurve[ tmpImage->r(i,j) ]; + for (int i=0; ir(i,j) = rCurve[ tmpImage->r(i,j) ]; + // individual G tone curve + if (gCurve) tmpImage->g(i,j) = gCurve[ tmpImage->g(i,j) ]; + // individual B tone curve + if (bCurve) tmpImage->b(i,j) = bCurve[ tmpImage->b(i,j) ]; + } } - } } + else { //params->rgbCurves.lumamode==true (Luminosity mode) + // rCurve.dump("r_curve");//debug - if (gCurve) { #ifdef _OPENMP #pragma omp for schedule(dynamic, 5) #endif - for (int i=0; ig(i,j) = gCurve[ tmpImage->g(i,j) ]; - } + for (int i=0; ihlrecovery.enabled;//Get the value if "highlight reconstruction" is activated + + float r1,g1,b1, r2,g2,b2, L_1,L_2, Lfactor,a_1,b_1,x_,y_,z_,R,G,B ; + float y,fy, yy,fyy,x,z,fx,fz; + + // rgb values before RGB curves + r1 = tmpImage->r(i,j) ; + g1 = tmpImage->g(i,j) ; + b1 = tmpImage->b(i,j) ; + //convert to Lab to get a&b before RGB curves + x = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; + y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; + z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; + + fx = (x<65535.0f ? cachef[std::max(x,0.f)] : (327.68f*float(exp(log(x/MAXVALF)/3.0f )))); + fy = (y<65535.0f ? cachef[std::max(y,0.f)] : (327.68f*float(exp(log(y/MAXVALF)/3.0f )))); + fz = (z<65535.0f ? cachef[std::max(z,0.f)] : (327.68f*float(exp(log(z/MAXVALF)/3.0f )))); + + L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; + a_1 = (500.0f * (fx - fy) ); + b_1 = (200.0f * (fy - fz) ); + + // rgb values after RGB curves + if (rCurve) r2 = rCurve[ tmpImage->r(i,j)]; else r2=r1; + if (gCurve) g2 = gCurve[ tmpImage->g(i,j)]; else g2=g1; + if (bCurve) b2 = bCurve[ tmpImage->b(i,j)]; else b2=b1; + + // Luminosity after + // only Luminance in Lab + yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2; + fyy = (yy<65535.0f ? cachef[std::max(yy,0.f)] : (327.68f*float(exp(log(yy/MAXVALF)/3.0f )))); + L_2 = (116.0f * fyy - 5242.88f); + + //gamut control + if(settings->rgbcurveslumamode_gamut) { + float RR,GG,BB; + float HH, Lpro, Chpro; + Lpro=L_2/327.68f; + Chpro=sqrt(SQR(a_1/327.68f) + SQR(b_1/327.68f)); + HH=atan2(b_1,a_1); + Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); + L_2=Lpro*327.68f; + a_1=327.68f*Chpro*cos(HH); + b_1=327.68f*Chpro*sin(HH); + } //end of gamut control + + //calculate RGB with L_2 and old value of a and b + Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; + Color::xyz2rgb(x_,y_,z_,R,G,B,wip); + + tmpImage->r(i,j) =R; + tmpImage->g(i,j) =G; + tmpImage->b(i,j) =B; + } + } } } - if (bCurve) { -#ifdef _OPENMP -#pragma omp for schedule(dynamic, 5) -#endif - for (int i=0; ib(i,j) = bCurve[ tmpImage->b(i,j) ]; - } - } - } - - if (sat!=0 || hCurveEnabled || sCurveEnabled || vCurveEnabled) { #ifdef _OPENMP #pragma omp for schedule(dynamic, 5) diff --git a/rtengine/procevents.h b/rtengine/procevents.h index febfb1d42..7e99d2940 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -107,7 +107,7 @@ enum ProcEvent { EvSHHighQuality=82, EvPerspCorr=83, EvLCPFile=84, - EvEqlEnabled=85,// obsolete + EvRGBrCurveLumamode=85, EvIDNEnabled=86, EvIDNThresh=87, EvDPDNEnabled=88, diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9ef9dcc44..272d5176d 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -164,6 +164,7 @@ void ProcParams::setDefaults () { labCurve.lccurve.clear (); labCurve.lccurve.push_back(DCT_Linear); + rgbCurves.lumamode = false; rgbCurves.rcurve.clear (); rgbCurves.rcurve.push_back(DCT_Linear); rgbCurves.gcurve.clear (); @@ -792,6 +793,9 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); } + + if (!pedited || pedited->rgbCurves.lumamode) keyFile.set_boolean ("RGB Curves", "LumaMode", rgbCurves.lumamode); + if (!pedited || pedited->rgbCurves.rcurve) { Glib::ArrayHandle RGBrcurve = rgbCurves.rcurve; keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve); @@ -1319,6 +1323,7 @@ if (keyFile.has_group ("HSV Equalizer")) { // load RGB curves if (keyFile.has_group ("RGB Curves")) { + if (keyFile.has_key ("RGB Curves", "LumaMode")) { rgbCurves.lumamode = keyFile.get_boolean ("RGB Curves", "LumaMode"); if (pedited) pedited->rgbCurves.lumamode = true; } if (keyFile.has_key ("RGB Curves", "rCurve")) { rgbCurves.rcurve = keyFile.get_double_list ("RGB Curves", "rCurve"); if (pedited) pedited->rgbCurves.rcurve = true; } if (keyFile.has_key ("RGB Curves", "gCurve")) { rgbCurves.gcurve = keyFile.get_double_list ("RGB Curves", "gCurve"); if (pedited) pedited->rgbCurves.gcurve = true; } if (keyFile.has_key ("RGB Curves", "bCurve")) { rgbCurves.bcurve = keyFile.get_double_list ("RGB Curves", "bCurve"); if (pedited) pedited->rgbCurves.bcurve = true; } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6872bd448..476b2c7b7 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -231,6 +231,7 @@ class LCurveParams { class RGBCurvesParams { public: + bool lumamode; std::vector rcurve; std::vector gcurve; std::vector bcurve; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 5a22d365b..4be692890 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -105,7 +105,7 @@ ALL, // EvProfileChangeNotification RETINEX, // EvShrHighQuality TRANSFORM, // EvPerspCorr DARKFRAME, // EvLCPFile -0, // EvEqlEnabled:obsolete +RGBCURVE, // EvRGBrCurveLumamode IMPULSEDENOISE, // EvIDNEnabled, IMPULSEDENOISE, // EvIDNThresh, ALLNORAW, // EvDPDNEnabled, diff --git a/rtengine/settings.h b/rtengine/settings.h index 0fd851f2c..963687a9b 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -32,6 +32,7 @@ namespace rtengine { Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; + bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode bool verbose; Glib::ustring darkFramesPath; ///< The default directory for dark frames Glib::ustring flatFieldsPath; ///< The default directory for flat fields diff --git a/rtgui/options.cc b/rtgui/options.cc index 1c3a13a71..8155b965f 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -448,6 +448,7 @@ void Options::setDefaults () { rtSettings.protectredh = 0.3; rtSettings.CRI_color =0; rtSettings.autocielab=true; + rtSettings.rgbcurveslumamode_gamut=true; lastIccDir = rtSettings.iccDirectory; lastDarkframeDir = rtSettings.darkFramesPath; lastFlatfieldDir = rtSettings.flatFieldsPath; @@ -654,6 +655,7 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "AutoMonitorProfile")) rtSettings.autoMonitorProfile = keyFile.get_boolean ("Color Management", "AutoMonitorProfile"); if (keyFile.has_key ("Color Management", "Autocielab")) rtSettings.autocielab = keyFile.get_boolean ("Color Management", "Autocielab"); if (keyFile.has_key ("Color Management", "Ciencamfloat")) rtSettings.ciecamfloat = keyFile.get_boolean ("Color Management", "Ciecamfloat"); + if (keyFile.has_key ("Color Management", "RGBcurvesLumamode_Gamut")) rtSettings.rgbcurveslumamode_gamut = keyFile.get_boolean ("Color Management", "RGBcurvesLumamode_Gamut"); if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); if (keyFile.has_key ("Color Management", "CRI")) rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); @@ -902,6 +904,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); + keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 1e95c0a86..bac73d126 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -59,6 +59,7 @@ void ParamsEdited::set (bool v) { labCurve.rstprotection = v; labCurve.bwtoning = v; labCurve.lcredsk = v; + rgbCurves.lumamode = v; rgbCurves.rcurve = v; rgbCurves.gcurve = v; rgbCurves.bcurve = v; @@ -290,7 +291,8 @@ void ParamsEdited::initFrom (const std::vector labCurve.avoidcolorshift = labCurve.avoidcolorshift && p.labCurve.avoidcolorshift == other.labCurve.avoidcolorshift; labCurve.rstprotection = labCurve.rstprotection && p.labCurve.rstprotection == other.labCurve.rstprotection; labCurve.bwtoning = labCurve.bwtoning && p.labCurve.bwtoning == other.labCurve.bwtoning; - labCurve.lcredsk = labCurve.lcredsk && p.labCurve.lcredsk == other.labCurve.lcredsk; + labCurve.lcredsk = labCurve.lcredsk && p.labCurve.lcredsk == other.labCurve.lcredsk; + rgbCurves.lumamode = rgbCurves.lumamode && p.rgbCurves.lumamode == other.rgbCurves.lumamode; 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; @@ -523,6 +525,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.bwtoning) toEdit.labCurve.bwtoning = mods.labCurve.bwtoning; if (labCurve.lcredsk) toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; + if (rgbCurves.lumamode) toEdit.rgbCurves.lumamode = mods.rgbCurves.lumamode; 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; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3b3472ffc..7e75f02b5 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -72,6 +72,7 @@ class LCurveParamsEdited { class RGBCurvesParamsEdited { public: + bool lumamode; bool rcurve; bool gcurve; bool bcurve; diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index d7dbd14f8..1b77e8597 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -26,6 +26,18 @@ RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) { set_border_width(4); + lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_RGBCURVES_LUMAMODE"))); + lumamode->set_tooltip_markup (M("TP_RGBCURVES_LUMAMODE_TOOLTIP")); + lumamode->set_active (false); + lumamode->show (); + pack_start (*lumamode); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + lumamodeConn = lumamode->signal_toggled().connect( sigc::mem_fun(*this, &RGBCurves::lumamodeChanged) ); + std::vector milestones; curveEditorG = new CurveEditorGroup (options.lastRgbCurvesDir, M("TP_RGBCURVES_CHANNEL")); @@ -66,8 +78,15 @@ void RGBCurves::read (const ProcParams* pp, const ParamsEdited* pedited) { Rshape->setUnChanged (!pedited->rgbCurves.rcurve); Gshape->setUnChanged (!pedited->rgbCurves.gcurve); Bshape->setUnChanged (!pedited->rgbCurves.bcurve); + lumamode->set_inconsistent (!pedited->rgbCurves.lumamode); } + lumamodeConn.block (true); + lumamode->set_active (pp->rgbCurves.lumamode); + lumamodeConn.block (false); + + lastLumamode = pp->rgbCurves.lumamode; + Rshape->setCurve (pp->rgbCurves.rcurve); Gshape->setCurve (pp->rgbCurves.gcurve); Bshape->setCurve (pp->rgbCurves.bcurve); @@ -87,11 +106,13 @@ void RGBCurves::write (ProcParams* pp, ParamsEdited* pedited) { pp->rgbCurves.rcurve = Rshape->getCurve (); pp->rgbCurves.gcurve = Gshape->getCurve (); pp->rgbCurves.bcurve = Bshape->getCurve (); + pp->rgbCurves.lumamode = lumamode->get_active(); if (pedited) { pedited->rgbCurves.rcurve = !Rshape->isUnChanged (); pedited->rgbCurves.gcurve = !Gshape->isUnChanged (); pedited->rgbCurves.bcurve = !Bshape->isUnChanged (); + pedited->rgbCurves.lumamode = !lumamode->get_inconsistent(); } } @@ -114,6 +135,29 @@ void RGBCurves::curveChanged (CurveEditor* ce) { } } +void RGBCurves::lumamodeChanged () { + + if (batchMode) { + if (lumamode->get_inconsistent()) { + lumamode->set_inconsistent (false); + lumamodeConn.block (true); + lumamode->set_active (false); + lumamodeConn.block (false); + } + else if (lastLumamode) + lumamode->set_inconsistent (true); + + lastLumamode = lumamode->get_active (); + } + + if (listener) { + if (lumamode->get_active ()) + listener->panelChanged (EvRGBrCurveLumamode, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvRGBrCurveLumamode, M("GENERAL_DISABLED")); + } +} + void RGBCurves::setBatchMode (bool batchMode) { ToolPanel::setBatchMode (batchMode); diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h index ee32d0077..938e2145d 100644 --- a/rtgui/rgbcurves.h +++ b/rtgui/rgbcurves.h @@ -34,6 +34,10 @@ class RGBCurves : public Gtk::VBox, public AdjusterListener, public FoldableTool DiagonalCurveEditor* Gshape; DiagonalCurveEditor* Bshape; + Gtk::CheckButton* lumamode; + bool lastLumamode; + sigc::connection lumamodeConn; + public: RGBCurves (); @@ -46,6 +50,7 @@ class RGBCurves : public Gtk::VBox, public AdjusterListener, public FoldableTool void curveChanged (CurveEditor* ce); void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + void lumamodeChanged (); }; #endif