From 041990d2167ea7df15e58c0f1106ea4fb04e34f3 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 8 Jan 2018 00:19:36 +0100 Subject: [PATCH] Added new color toning mode "L*a*b* color correction grid", adapted from DT's color correction module --- rtdata/languages/default | 2 + rtengine/improcfun.cc | 43 +++++- rtengine/improcfun.h | 2 +- rtengine/procparams.cc | 21 ++- rtengine/procparams.h | 7 + rtgui/colortoning.cc | 298 +++++++++++++++++++++++++++++++++++++++ rtgui/colortoning.h | 5 + rtgui/paramsedited.cc | 24 ++++ rtgui/paramsedited.h | 5 + 9 files changed, 403 insertions(+), 4 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index dd0a63fc6..7d95b85d2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -723,6 +723,7 @@ HISTORY_MSG_490;HDR TM - Amount HISTORY_MSG_491;White Balance HISTORY_MSG_492;RGB Curves HISTORY_MSG_493;L*a*b* Adjustments +HISTORY_MSG_COLORTONING_LABGRID_VALUE;L*a*b* color correction HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast @@ -1405,6 +1406,7 @@ TP_COLORTONING_HIGHLIGHT;Highlights TP_COLORTONING_HUE;Hue TP_COLORTONING_LAB;L*a*b* blending TP_COLORTONING_LABEL;Color Toning +TP_COLORTONING_LABGRID;L*a*b* color correction grid TP_COLORTONING_LUMA;Luminance TP_COLORTONING_LUMAMODE;Preserve luminance TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 7e8e153b1..42cbb6f20 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -3477,7 +3477,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer userToneCurve.initApplyState (ptc2ApplyState, params->icm.working); } - bool hasColorToning = params->colorToning.enabled && bool (ctOpacityCurve) && bool (ctColorCurve); + bool hasColorToning = params->colorToning.enabled && bool (ctOpacityCurve) && bool (ctColorCurve) && params->colorToning.method != "LabGrid"; // float satLimit = float(params->colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; // float satLimitOpacity = 1.f-(float(params->colorToning.saturatedOpacity)/100.f); float strProtect = (float (params->colorToning.strength) / 100.f); @@ -4952,6 +4952,10 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer delete vCurve; } + if (params->colorToning.enabled && params->colorToning.method == "LabGrid") { + colorToningLabGrid(lab); + } + if (params->localContrast.enabled) { // Alberto's local contrast localContrast(lab); @@ -7175,4 +7179,41 @@ SSEFUNCTION void ImProcFunctions::lab2rgb (const LabImage &src, Imagefloat &dst, //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// adapted from the "color correction" module of Darktable. Original copyright follows +/* + copyright (c) 2009--2010 johannes hanika. + + darktable 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. + + darktable 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 darktable. If not, see . +*/ +void ImProcFunctions::colorToningLabGrid(LabImage *lab) +{ + const float factor = ColorToningParams::LABGRID_CORR_MAX * 1.6f; + float a_scale = (params->colorToning.labgridAHigh - params->colorToning.labgridALow) / factor; + float a_base = params->colorToning.labgridALow; + float b_scale = (params->colorToning.labgridBHigh - params->colorToning.labgridBLow) / factor; + float b_base = params->colorToning.labgridBLow; + +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int y = 0; y < lab->H; ++y) { + for (int x = 0; x < lab->W; ++x) { + lab->a[y][x] += lab->L[y][x] * a_scale + a_base; + lab->b[y][x] += lab->L[y][x] * b_scale + b_base; + } + } +} + } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index b7e7a7545..1adc2fc5f 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -345,8 +345,8 @@ public: void BadpixelsLab (LabImage * src, LabImage * dst, double radius, int thresh, int mode, float skinprot, float chrom); void ToneMapFattal02(Imagefloat *rgb); - //void localContrast(float *r, float *g, float *b, int width, int height); void localContrast(LabImage *lab); + void colorToningLabGrid(LabImage *lab); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga = nullptr); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 8fbab7a8d..336f32379 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -688,7 +688,11 @@ ColorToningParams::ColorToningParams() : bluehigh(0.0), satlow(0.0), sathigh(0.0), - lumamode(true) + lumamode(true), + labgridALow(0.0), + labgridBLow(0.0), + labgridAHigh(0.0), + labgridBHigh(0.0) { } @@ -720,7 +724,11 @@ bool ColorToningParams::operator ==(const ColorToningParams& other) const && bluehigh == other.bluehigh && satlow == other.satlow && sathigh == other.sathigh - && lumamode == other.lumamode; + && lumamode == other.lumamode + && labgridALow == other.labgridALow + && labgridBLow == other.labgridBLow + && labgridAHigh == other.labgridAHigh + && labgridBHigh == other.labgridBHigh; } bool ColorToningParams::operator !=(const ColorToningParams& other) const @@ -3337,6 +3345,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->colorToning.shadowsColSat, "ColorToning", "ShadowsColorSaturation", colorToning.shadowsColSat.toVector(), keyFile); saveToKeyfile(!pedited || pedited->colorToning.clcurve, "ColorToning", "ClCurve", colorToning.clcurve, keyFile); saveToKeyfile(!pedited || pedited->colorToning.cl2curve, "ColorToning", "Cl2Curve", colorToning.cl2curve, keyFile); + saveToKeyfile(!pedited || pedited->colorToning.labgridALow, "ColorToning", "LabGridALow", colorToning.labgridALow, keyFile); + saveToKeyfile(!pedited || pedited->colorToning.labgridBLow, "ColorToning", "LabGridBLow", colorToning.labgridBLow, keyFile); + saveToKeyfile(!pedited || pedited->colorToning.labgridAHigh, "ColorToning", "LabGridAHigh", colorToning.labgridAHigh, keyFile); + saveToKeyfile(!pedited || pedited->colorToning.labgridBHigh, "ColorToning", "LabGridBHigh", colorToning.labgridBHigh, keyFile); // Raw saveToKeyfile(!pedited || pedited->raw.darkFrame, "RAW", "DarkFrame", relativePathIfInside (fname, fnameAbsolute, raw.dark_frame), keyFile); @@ -4585,6 +4597,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "ColorToning", "Redhigh", pedited, colorToning.redhigh, pedited->colorToning.redhigh); assignFromKeyfile(keyFile, "ColorToning", "Greenhigh", pedited, colorToning.greenhigh, pedited->colorToning.greenhigh); assignFromKeyfile(keyFile, "ColorToning", "Bluehigh", pedited, colorToning.bluehigh, pedited->colorToning.bluehigh); + + assignFromKeyfile(keyFile, "ColorToning", "LabGridALow", pedited, colorToning.labgridALow, pedited->colorToning.labgridALow); + assignFromKeyfile(keyFile, "ColorToning", "LabGridBLow", pedited, colorToning.labgridBLow, pedited->colorToning.labgridBLow); + assignFromKeyfile(keyFile, "ColorToning", "LabGridAHigh", pedited, colorToning.labgridAHigh, pedited->colorToning.labgridAHigh); + assignFromKeyfile(keyFile, "ColorToning", "LabGridBHigh", pedited, colorToning.labgridBHigh, pedited->colorToning.labgridBHigh); } if (keyFile.has_group ("RAW")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 58cc2cdfc..7aed263ea 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -424,6 +424,7 @@ struct ColorToningParams { * Lch : * RGBSliders : * RGBCurves : + * LabGrid : */ Glib::ustring method; @@ -447,6 +448,12 @@ struct ColorToningParams { double sathigh; bool lumamode; + double labgridALow; + double labgridBLow; + double labgridAHigh; + double labgridBHigh; + static constexpr double LABGRID_CORR_MAX = 8000.f; + ColorToningParams(); bool operator ==(const ColorToningParams& other) const; diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 180b4235a..38e0630d4 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -4,10 +4,258 @@ #include "colortoning.h" #include "mycurve.h" #include "rtimage.h" +#include "eventmapper.h" using namespace rtengine; using namespace rtengine::procparams; +namespace { + +// adapted from the "color correction" module of Darktable. Original copyright follows +/* + copyright (c) 2009--2010 johannes hanika. + + darktable 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. + + darktable 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 darktable. If not, see . +*/ +class LabGrid: public Gtk::DrawingArea { +private: + rtengine::ProcEvent evt_; + enum State { OFF, HIGH, LOW }; + State selected_; + float low_a_; + float high_a_; + float low_b_; + float high_b_; + float saturation_; + ToolPanelListener *listener_; + bool edited_; + static const int inset = 2; + + void notify_listener() + { + if (listener_) { + auto fmt = [](float f) -> Glib::ustring + { + return Glib::ustring::format(std::setw(4), std::fixed, std::setprecision(3), f); + }; + listener_->panelChanged(evt_, Glib::ustring::compose("%1, %2, %3, %4", fmt(low_a_), fmt(low_b_), fmt(high_a_), fmt(high_b_))); + } + } + +public: + LabGrid(rtengine::ProcEvent evt): + Gtk::DrawingArea(), + evt_(evt), selected_(OFF), + low_a_(0.f), high_a_(0.f), low_b_(0.f), high_b_(0.f), + listener_(nullptr), + edited_(false) + { + set_can_focus(true); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK); + } + + void get_params(double &la, double &lb, double &ha, double &hb) const + { + la = low_a_; + ha = high_a_; + lb = low_b_; + hb = high_b_; + } + + void set_params(double la, double lb, double ha, double hb) + { + low_a_ = la; + low_b_ = lb; + high_a_ = ha; + high_b_ = hb; + queue_draw(); + } + + void set_edited(bool yes) + { + edited_ = yes; + } + + + bool get_edited() const + { + return edited_; + } + + void set_listener(ToolPanelListener *l) + { + listener_ = l; + } + + bool on_draw(const ::Cairo::RefPtr &crf) + { + int width = get_allocated_width(); + int height = get_allocated_height(); + Cairo::RefPtr cst = + Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, width, height); + Cairo::RefPtr cr = Cairo::Context::create(cst); + // clear bg + cr->set_source_rgb(.2, .2, .2); + cr->paint(); + + cr->translate(inset, inset); + cr->set_antialias(Cairo::ANTIALIAS_NONE); + width -= 2 * inset; + height -= 2 * inset; + // flip y: + cr->translate(0, height); + cr->scale(1., -1.); + const int cells = 8; + float step = rtengine::ColorToningParams::LABGRID_CORR_MAX / float(cells/2); + for (int j = 0; j < cells; j++) { + for(int i = 0; i < cells; i++) { + float R, G, B; + float x, y, z; + int ii = i - cells/2; + int jj = j - cells/2; + float a = step * (ii + 0.5) * 1.5; + float b = step * (jj + 0.5) * 1.5; + Color::Lab2XYZ(25000.f, a, b, x, y, z); + Color::xyz2srgb(x, y, z, R, G, B); + cr->set_source_rgb(R / 65535.f, G / 65535.f, B / 65535.f); + cr->rectangle(width * i / (float)cells, height * j / (float)cells, + width / (float)cells - 1, + height / (float)cells - 1); + cr->fill(); + } + } + cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); + float loa, hia, lob, hib; + loa = .5f * (width + width * low_a_ / rtengine::ColorToningParams::LABGRID_CORR_MAX); + hia = .5f * (width + width * high_a_ / rtengine::ColorToningParams::LABGRID_CORR_MAX); + lob = .5f * (height + height * low_b_ / rtengine::ColorToningParams::LABGRID_CORR_MAX); + hib = .5f * (height + height * high_b_ / rtengine::ColorToningParams::LABGRID_CORR_MAX); + cr->set_line_width(2.); + cr->set_source_rgb(0.6, 0.6, 0.6); + cr->move_to(loa, lob); + cr->line_to(hia, hib); + cr->stroke(); + + cr->set_source_rgb(0.1, 0.1, 0.1); + if (selected_ == LOW) { + cr->arc(loa, lob, 5, 0, 2. * M_PI); + } else { + cr->arc(loa, lob, 3, 0, 2. * M_PI); + } + cr->fill(); + + cr->set_source_rgb(0.9, 0.9, 0.9); + if (selected_ == HIGH) { + cr->arc(hia, hib, 5, 0, 2. * M_PI); + } else { + cr->arc(hia, hib, 3, 0, 2. * M_PI); + } + cr->fill(); + + crf->set_source(cst, 0, 0); + crf->paint(); + + return true; + } + + bool on_button_release_event(GdkEventButton *event) + { + if (selected_ != OFF) { + edited_ = true; + notify_listener(); + } + return true; + } + + bool on_button_press_event(GdkEventButton *event) + { + if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { + switch (selected_) { + case OFF: + low_a_ = low_b_ = high_a_ = high_b_ = 0.f; + break; + case LOW: + low_a_ = low_b_ = 0.f; + break; + case HIGH: + high_a_ = high_b_ = 0.f; + break; + } + edited_ = true; + notify_listener(); + } + return true; + } + + bool on_motion_notify_event(GdkEventMotion *event) + { + int width = get_allocated_width() - 2 * inset, height = get_allocated_height() - 2 * inset; + const float mouse_x = std::min(std::max(event->x - inset, 0.), double(width)); + const float mouse_y = std::min(std::max(height - 1 - event->y + inset, 0.), double(height)); + const float ma = (2.0 * mouse_x - width) / (float)width; + const float mb = (2.0 * mouse_y - height) / (float)height; + if (event->state & GDK_BUTTON1_MASK) { + if (selected_ == LOW) { + low_a_ = ma * rtengine::ColorToningParams::LABGRID_CORR_MAX; + low_b_ = mb * rtengine::ColorToningParams::LABGRID_CORR_MAX; + } else if (selected_ == HIGH) { + high_a_ = ma * rtengine::ColorToningParams::LABGRID_CORR_MAX; + high_b_ = mb * rtengine::ColorToningParams::LABGRID_CORR_MAX; + } + } else { + selected_ = OFF; + float la = low_a_ / rtengine::ColorToningParams::LABGRID_CORR_MAX; + float lb = low_b_ / rtengine::ColorToningParams::LABGRID_CORR_MAX; + float ha = high_a_ / rtengine::ColorToningParams::LABGRID_CORR_MAX; + float hb = high_b_ / rtengine::ColorToningParams::LABGRID_CORR_MAX; + const float thrs = 0.05f; + const float distlo = (la - ma) * (la - ma) + (lb - mb) * (lb - mb); + const float disthi = (ha - ma) * (ha - ma) + (hb - mb) * (hb - mb); + if (distlo < thrs * thrs && distlo < disthi) { + selected_ = LOW; + } else if (disthi < thrs * thrs && disthi <= distlo) { + selected_ = HIGH; + } + } + if (selected_ != OFF) { + grab_focus(); + } + queue_draw(); + return true; + } + + Gtk::SizeRequestMode get_request_mode_vfunc() const + { + return Gtk::SIZE_REQUEST_HEIGHT_FOR_WIDTH; + } + + void get_preferred_width_vfunc(int &minimum_width, int &natural_width) const + { + minimum_width = 100; + natural_width = 200; + } + + void get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const + { + minimum_height = natural_height = width; + } +}; + + +} // namespace + + ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLORTONING_LABEL"), false, true) { nextbw = 0; @@ -21,6 +269,7 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR method->append (M("TP_COLORTONING_RGBCURVES")); method->append (M("TP_COLORTONING_SPLITCOCO")); method->append (M("TP_COLORTONING_SPLITLR")); + method->append(M("TP_COLORTONING_LABGRID")); method->set_active (0); method->set_tooltip_text (M("TP_COLORTONING_METHOD_TOOLTIP")); @@ -312,6 +561,14 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR greenhigh->setAdjusterListener (this); bluehigh->setAdjusterListener (this); + //------------------------------------------------------------------------ + // LAB grid + auto m = ProcEventMapper::getInstance(); + EvColorToningLabGridValue = m->newEvent(RGBCURVE, "HISTORY_MSG_COLORTONING_LABGRID_VALUE"); + labgridArea = Gtk::manage(new LabGrid(EvColorToningLabGridValue)); + pack_start(*labgridArea, Gtk::PACK_EXPAND_WIDGET, 4); + //------------------------------------------------------------------------ + show_all(); disableListener(); @@ -329,6 +586,13 @@ ColorToning::~ColorToning() delete cl2CurveEditorG; } + +void ColorToning::setListener(ToolPanelListener *tpl) +{ + ToolPanel::setListener(tpl); + static_cast(labgridArea)->set_listener(tpl); +} + /* void ColorToning::neutralCurves_pressed () { disableListener(); @@ -400,6 +664,8 @@ void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) clshape->setUnChanged (!pedited->colorToning.clcurve); cl2shape->setUnChanged (!pedited->colorToning.cl2curve); lumamode->set_inconsistent (!pedited->colorToning.lumamode); + + static_cast(labgridArea)->set_edited(pedited->colorToning.labgridALow || pedited->colorToning.labgridBLow || pedited->colorToning.labgridAHigh || pedited->colorToning.labgridBHigh); } redlow->setValue (pp->colorToning.redlow); @@ -431,6 +697,8 @@ void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) lastLumamode = pp->colorToning.lumamode; + static_cast(labgridArea)->set_params(pp->colorToning.labgridALow, pp->colorToning.labgridBLow, pp->colorToning.labgridAHigh, pp->colorToning.labgridBHigh); + if (pedited && !pedited->colorToning.method) { method->set_active (5); } else if (pp->colorToning.method == "Lab") { @@ -443,6 +711,8 @@ void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) method->set_active (3); } else if (pp->colorToning.method == "Splitlr") { method->set_active (4); + } else if (pp->colorToning.method == "LabGrid") { + method->set_active(5); } methodChanged(); @@ -495,6 +765,8 @@ void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) pp->colorToning.saturatedOpacity = saturatedOpacity->getIntValue(); pp->colorToning.strength = strength->getIntValue(); + static_cast(labgridArea)->get_params(pp->colorToning.labgridALow, pp->colorToning.labgridBLow, pp->colorToning.labgridAHigh, pp->colorToning.labgridBHigh); + if (pedited) { pedited->colorToning.redlow = redlow->getEditedState (); pedited->colorToning.greenlow = greenlow->getEditedState (); @@ -519,6 +791,8 @@ void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) pedited->colorToning.hlColSat = hlColSat->getEditedState (); pedited->colorToning.shadowsColSat = shadowsColSat->getEditedState (); + + pedited->colorToning.labgridALow = pedited->colorToning.labgridBLow = pedited->colorToning.labgridAHigh = pedited->colorToning.labgridBHigh = static_cast(labgridArea)->get_edited(); } if (method->get_active_row_number() == 0) { @@ -531,6 +805,8 @@ void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) pp->colorToning.method = "Splitco"; } else if (method->get_active_row_number() == 4) { pp->colorToning.method = "Splitlr"; + } else if (method->get_active_row_number() == 5) { + pp->colorToning.method = "LabGrid"; } if (twocolor->get_active_row_number() == 0) { @@ -782,6 +1058,8 @@ void ColorToning::methodChanged () { if (!batchMode) { + labgridArea->hide(); + if (method->get_active_row_number() == 0) { // Lab colorSep->show(); colorCurveEditorG->show(); @@ -929,6 +1207,26 @@ void ColorToning::methodChanged () chanMixerBox->hide(); neutrHBox->hide(); lumamode->show(); + } else if (method->get_active_row_number() == 5) { // Lab Grid + colorSep->hide(); + colorCurveEditorG->hide(); + twocolor->hide(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + hlColSat->hide(); + shadowsColSat->hide(); + balance->hide(); + p1Frame->hide(); + autosat->hide(); + satProtectionThreshold->hide(); + saturatedOpacity->hide(); + strength->hide(); + chanMixerBox->hide(); + neutrHBox->hide(); + lumamode->hide(); + + labgridArea->show(); } } diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index 347cfd126..31c1650cf 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -49,6 +49,8 @@ public: void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + void setListener(ToolPanelListener *tpl); + private: //Gtk::HSeparator* satLimiterSep; Gtk::HSeparator* colorSep; @@ -101,6 +103,9 @@ private: bool lastLumamode; sigc::connection lumamodeConn; + rtengine::ProcEvent EvColorToningLabGridValue; + Gtk::DrawingArea *labgridArea; + IdleRegister idle_register; }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index fc302299c..5355c88da 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -134,6 +134,10 @@ void ParamsEdited::set (bool v) colorToning.greenhigh = v; colorToning.bluehigh = v; colorToning.lumamode = v; + colorToning.labgridALow = v; + colorToning.labgridBLow = v; + colorToning.labgridAHigh = v; + colorToning.labgridBHigh = v; sharpening.enabled = v; sharpening.radius = v; @@ -687,6 +691,10 @@ void ParamsEdited::initFrom (const std::vector colorToning.greenhigh = colorToning.greenhigh && p.colorToning.greenhigh == other.colorToning.greenhigh; colorToning.bluehigh = colorToning.bluehigh && p.colorToning.bluehigh == other.colorToning.bluehigh; colorToning.lumamode = colorToning.lumamode && p.colorToning.lumamode == other.colorToning.lumamode; + colorToning.labgridALow = colorToning.labgridALow && p.colorToning.labgridALow == other.colorToning.labgridALow; + colorToning.labgridBLow = colorToning.labgridBLow && p.colorToning.labgridBLow == other.colorToning.labgridBLow; + colorToning.labgridAHigh = colorToning.labgridAHigh && p.colorToning.labgridAHigh == other.colorToning.labgridAHigh; + colorToning.labgridBHigh = colorToning.labgridBHigh && p.colorToning.labgridBHigh == other.colorToning.labgridBHigh; 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; @@ -1532,6 +1540,22 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.colorToning.bluehigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluehigh + mods.colorToning.bluehigh : mods.colorToning.bluehigh; } + if (colorToning.labgridALow) { + toEdit.colorToning.labgridALow = mods.colorToning.labgridALow; + } + if (colorToning.labgridALow) { + toEdit.colorToning.labgridALow = mods.colorToning.labgridALow; + } + if (colorToning.labgridBLow) { + toEdit.colorToning.labgridBLow = mods.colorToning.labgridBLow; + } + if (colorToning.labgridAHigh) { + toEdit.colorToning.labgridAHigh = mods.colorToning.labgridAHigh; + } + if (colorToning.labgridBHigh) { + toEdit.colorToning.labgridBHigh = mods.colorToning.labgridBHigh; + } + if (sharpenEdge.enabled) { toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 5a835bf05..c49b60eaa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -170,6 +170,11 @@ public: bool satlow; bool sathigh; bool lumamode; + bool labgridALow; + bool labgridBLow; + bool labgridAHigh; + bool labgridBHigh; + bool labgridSaturation; }; class SharpenEdgeParamsEdited