diff --git a/rtdata/languages/default b/rtdata/languages/default
index fda54dd4d..c25bf79ff 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -725,6 +725,11 @@ 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_494;Local Contrast
+HISTORY_MSG_495;Local Contrast - Radius
+HISTORY_MSG_496;Local Contrast - Amount
+HISTORY_MSG_497;Local Contrast - Darkness
+HISTORY_MSG_498;Local Contrast - Lightness
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -1679,6 +1684,11 @@ TP_LENSPROFILE_LABEL;Profiled Lens Correction
TP_LENSPROFILE_USECA;Chromatic aberration correction
TP_LENSPROFILE_USEDIST;Distortion correction
TP_LENSPROFILE_USEVIGN;Vignetting correction
+TP_LOCALCONTRAST_LABEL;Local Contrast
+TP_LOCALCONTRAST_RADIUS;Radius
+TP_LOCALCONTRAST_AMOUNT;Amount
+TP_LOCALCONTRAST_DARKNESS;Darkness level
+TP_LOCALCONTRAST_LIGHTNESS;Lightness level
TP_NEUTRAL;Reset
TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not.
TP_PCVIGNETTE_FEATHER;Feather
diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt
index 70416af62..3e5eb15e4 100644
--- a/rtengine/CMakeLists.txt
+++ b/rtengine/CMakeLists.txt
@@ -115,6 +115,7 @@ set(RTENGINESOURCEFILES
utils.cc
rtlensfun.cc
tmo_fattal02.cc
+ iplocalcontrast.cc
)
if(LENSFUN_HAS_LOAD_DIRECTORY)
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 5223a7f85..2c92e1321 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -3427,6 +3427,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
int tW;
int tH;
+ // zero out the buffers
+ memset(buffer, 0, 3 * sizeof (float) * TS * TS + 20 * 64 + 63);
+
// Allocating buffer for the PipetteBuffer
float *editIFloatTmpR = nullptr, *editIFloatTmpG = nullptr, *editIFloatTmpB = nullptr, *editWhateverTmp = nullptr;
@@ -4965,6 +4968,11 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (vCurveEnabled) {
delete vCurve;
}
+
+ if (params->localContrast.enabled) {
+ // Alberto's local contrast
+ localContrast(lab);
+ }
}
/**
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index 08c3fa4cc..b7e7a7545 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -345,6 +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);
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/iplocalcontrast.cc b/rtengine/iplocalcontrast.cc
new file mode 100644
index 000000000..10b5cd2b9
--- /dev/null
+++ b/rtengine/iplocalcontrast.cc
@@ -0,0 +1,67 @@
+/* -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Ported from G'MIC by Alberto Griggio
+ *
+ * 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 .
+ */
+
+#ifdef _OPENMP
+#include
+#endif
+
+#include "improcfun.h"
+#include "settings.h"
+#include "gauss.h"
+#include "boxblur.h"
+#include "array2D.h"
+
+namespace rtengine {
+
+void ImProcFunctions::localContrast(LabImage *lab)
+{
+ if (!params->localContrast.enabled) {
+ return;
+ }
+
+ const int width = lab->W;
+ const int height = lab->H;
+ const float a = -params->localContrast.amount;
+ const float half = 0.5f;
+ const float dark = params->localContrast.darkness;
+ const float light = params->localContrast.lightness;
+ array2D buf(width, height);
+ const float sigma = params->localContrast.radius / scale;
+
+ gaussianBlur(lab->L, buf, width, height, sigma);
+
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ buf[y][x] -= lab->L[y][x];
+ buf[y][x] *= a;
+
+ if (dark != 1 || light != 1) {
+ buf[y][x] = max(buf[y][x], half) * light + min(buf[y][x], half) * dark;
+ }
+
+ lab->L[y][x] += buf[y][x];
+ }
+ }
+}
+
+} // namespace rtengine
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index f4dfd7dfb..faffbe780 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -520,6 +520,11 @@ enum ProcEvent {
EvWBEnabled = 490,
EvRGBEnabled = 491,
EvLEnabled = 492,
+ EvLocalContrastEnabled = 493,
+ EvLocalContrastRadius = 494,
+ EvLocalContrastAmount = 495,
+ EvLocalContrastDarkness = 496,
+ EvLocalContrastLightness = 497,
NUMOFEVENTS
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index ccdafec5c..d04003af1 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -590,6 +590,34 @@ bool RGBCurvesParams::operator !=(const RGBCurvesParams& other) const
return !(*this == other);
}
+
+LocalContrastParams::LocalContrastParams():
+ enabled(false),
+ radius(80),
+ amount(0.2),
+ darkness(1.0),
+ lightness(1.0)
+{
+}
+
+
+bool LocalContrastParams::operator==(const LocalContrastParams &other) const
+{
+ return
+ enabled == other.enabled
+ && radius == other.radius
+ && amount == other.amount
+ && darkness == other.darkness
+ && lightness == other.lightness;
+}
+
+
+bool LocalContrastParams::operator!=(const LocalContrastParams &other) const
+{
+ return !(*this == other);
+}
+
+
ColorToningParams::ColorToningParams() :
enabled(false),
autosat(true),
@@ -2588,6 +2616,8 @@ void ProcParams::setDefaults ()
rgbCurves = RGBCurvesParams();
+ localContrast = LocalContrastParams();
+
colorToning = ColorToningParams();
sharpenEdge = SharpenEdgeParams();
@@ -2755,6 +2785,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->retinex.transmissionCurve, "Retinex", "TransmissionCurve", retinex.transmissionCurve, keyFile);
saveToKeyfile(!pedited || pedited->retinex.gaintransmissionCurve, "Retinex", "GainTransmissionCurve", retinex.gaintransmissionCurve, keyFile);
+// Local contrast
+ saveToKeyfile(!pedited || pedited->localContrast.enabled, "Local Contrast", "Enabled", localContrast.enabled, keyFile);
+ saveToKeyfile(!pedited || pedited->localContrast.radius, "Local Contrast", "Radius", localContrast.radius, keyFile);
+ saveToKeyfile(!pedited || pedited->localContrast.amount, "Local Contrast", "Amount", localContrast.amount, keyFile);
+ saveToKeyfile(!pedited || pedited->localContrast.darkness, "Local Contrast", "Darkness", localContrast.darkness, keyFile);
+ saveToKeyfile(!pedited || pedited->localContrast.lightness, "Local Contrast", "Lightness", localContrast.lightness, keyFile);
+
+
// Channel mixer
saveToKeyfile(!pedited || pedited->chmixer.enabled, "Channel Mixer", "Enabled", chmixer.enabled, keyFile);
if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) {
@@ -3590,6 +3628,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Retinex", "GainTransmissionCurve", pedited, retinex.gaintransmissionCurve, pedited->retinex.gaintransmissionCurve);
}
+ if (keyFile.has_group("Local Contrast")) {
+ assignFromKeyfile(keyFile, "Local Contrast", "Enabled", pedited, localContrast.enabled, pedited->localContrast.enabled);
+ assignFromKeyfile(keyFile, "Local Contrast", "Radius", pedited, localContrast.radius, pedited->localContrast.radius);
+ assignFromKeyfile(keyFile, "Local Contrast", "Amount", pedited, localContrast.amount, pedited->localContrast.amount);
+ assignFromKeyfile(keyFile, "Local Contrast", "Darkness", pedited, localContrast.darkness, pedited->localContrast.darkness);
+ assignFromKeyfile(keyFile, "Local Contrast", "Lightness", pedited, localContrast.lightness, pedited->localContrast.lightness);
+ }
+
if (keyFile.has_group ("Luminance Curve")) {
if (ppVersion >= 329) {
assignFromKeyfile(keyFile, "Luminance Curve", "Enabled", pedited, labCurve.enabled, pedited->labCurve.enabled);
@@ -4716,6 +4762,7 @@ bool ProcParams::operator ==(const ProcParams& other) const
return
toneCurve == other.toneCurve
&& retinex == other.retinex
+ && localContrast == other.localContrast
&& labCurve == other.labCurve
&& sharpenEdge == other.sharpenEdge
&& sharpenMicro == other.sharpenMicro
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 39d84ac12..bbe73f1bc 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -364,6 +364,24 @@ struct LCurveParams
bool operator !=(const LCurveParams& other) const;
};
+
+/**
+ * Parameters for local contrast
+ */
+struct LocalContrastParams {
+ bool enabled;
+ int radius;
+ double amount;
+ double darkness;
+ double lightness;
+
+ LocalContrastParams();
+
+ bool operator==(const LocalContrastParams &other) const;
+ bool operator!=(const LocalContrastParams &other) const;
+};
+
+
/**
* Parameters of the RGB curves
*/
@@ -1340,6 +1358,7 @@ public:
ToneCurveParams toneCurve; ///< Tone curve parameters
LCurveParams labCurve; ///< CIELAB luminance curve parameters
RetinexParams retinex; ///< Retinex parameters
+ LocalContrastParams localContrast; ////< Local contrast parameters
RGBCurvesParams rgbCurves; ///< RGB curves parameters
ColorToningParams colorToning; ///< Color Toning parameters
SharpeningParams sharpening; ///< Sharpening parameters
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 6105bb508..96575b464 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -519,6 +519,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
HDR, // EvTMFattalAmount
ALLNORAW, // EvWBEnabled
RGBCURVE, // EvRGBEnabled
- LUMINANCECURVE // EvLEnabled
+ LUMINANCECURVE, // EvLEnabled
+ RGBCURVE, // EvLocalContastEnabled
+ RGBCURVE, // EvLocalContrastRadius
+ RGBCURVE, // EvLocalContrastAmount
+ RGBCURVE, // EvLocalContrastDarkness
+ RGBCURVE // EvLocalContrastLightness
};
diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt
index 36c7a4034..e42666625 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -148,6 +148,7 @@ set(NONCLISOURCEFILES
xtransrawexposure.cc
zoompanel.cc
fattaltonemap.cc
+ localcontrast.cc
)
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/rtgui/localcontrast.cc b/rtgui/localcontrast.cc
new file mode 100644
index 000000000..3c2d47786
--- /dev/null
+++ b/rtgui/localcontrast.cc
@@ -0,0 +1,157 @@
+/** -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2017 Alberto Griggio
+ *
+ * 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 "localcontrast.h"
+#include
+#include
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+LocalContrast::LocalContrast(): FoldableToolPanel(this, "localcontrast", M("TP_LOCALCONTRAST_LABEL"), false, true)
+{
+ radius = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 3., 200., 1., 8.));
+ amount = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_AMOUNT"), 0., 1., 0.01, 0.2));
+ darkness = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_DARKNESS"), 0., 4., 0.1, 1.));
+ lightness = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_LIGHTNESS"), 0., 4., 0.1, 1.));
+
+ radius->setAdjusterListener(this);
+ amount->setAdjusterListener(this);
+ darkness->setAdjusterListener(this);
+ lightness->setAdjusterListener(this);
+
+ radius->show();
+ amount->show();
+ darkness->show();
+ lightness->show();
+
+ pack_start(*radius);
+ pack_start(*amount);
+ pack_start(*darkness);
+ pack_start(*lightness);
+}
+
+
+void LocalContrast::read(const ProcParams *pp, const ParamsEdited *pedited)
+{
+ disableListener();
+
+ if (pedited) {
+ radius->setEditedState(pedited->localContrast.radius ? Edited : UnEdited);
+ amount->setEditedState(pedited->localContrast.amount ? Edited : UnEdited);
+ darkness->setEditedState(pedited->localContrast.darkness ? Edited : UnEdited);
+ lightness->setEditedState(pedited->localContrast.lightness ? Edited : UnEdited);
+ set_inconsistent(multiImage && !pedited->localContrast.enabled);
+ }
+
+ setEnabled(pp->localContrast.enabled);
+ radius->setValue(pp->localContrast.radius);
+ amount->setValue(pp->localContrast.amount);
+ darkness->setValue(pp->localContrast.darkness);
+ lightness->setValue(pp->localContrast.lightness);
+
+ enableListener();
+}
+
+
+void LocalContrast::write(ProcParams *pp, ParamsEdited *pedited)
+{
+ pp->localContrast.radius = radius->getValue();
+ pp->localContrast.amount = amount->getValue();
+ pp->localContrast.darkness = darkness->getValue();
+ pp->localContrast.lightness = lightness->getValue();
+ pp->localContrast.enabled = getEnabled();
+
+ if (pedited) {
+ pedited->localContrast.radius = radius->getEditedState();
+ pedited->localContrast.amount = amount->getEditedState();
+ pedited->localContrast.darkness = darkness->getEditedState();
+ pedited->localContrast.lightness = lightness->getEditedState();
+ pedited->localContrast.enabled = !get_inconsistent();
+ }
+}
+
+void LocalContrast::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited)
+{
+ radius->setDefault(defParams->localContrast.radius);
+ amount->setDefault(defParams->localContrast.amount);
+ darkness->setDefault(defParams->localContrast.darkness);
+ lightness->setDefault(defParams->localContrast.lightness);
+
+ if (pedited) {
+ radius->setDefaultEditedState(pedited->localContrast.radius ? Edited : UnEdited);
+ amount->setDefaultEditedState(pedited->localContrast.amount ? Edited : UnEdited);
+ darkness->setDefaultEditedState(pedited->localContrast.darkness ? Edited : UnEdited);
+ lightness->setDefaultEditedState(pedited->localContrast.lightness ? Edited : UnEdited);
+ } else {
+ radius->setDefaultEditedState(Irrelevant);
+ amount->setDefaultEditedState(Irrelevant);
+ darkness->setDefaultEditedState(Irrelevant);
+ lightness->setDefaultEditedState(Irrelevant);
+ }
+}
+
+
+void LocalContrast::adjusterChanged(Adjuster* a, double newval)
+{
+ if (listener && getEnabled()) {
+ if (a == radius) {
+ listener->panelChanged(EvLocalContrastRadius, a->getTextValue());
+ } else if (a == amount) {
+ listener->panelChanged(EvLocalContrastAmount, a->getTextValue());
+ } else if (a == darkness) {
+ listener->panelChanged(EvLocalContrastDarkness, a->getTextValue());
+ } else if (a == lightness) {
+ listener->panelChanged(EvLocalContrastLightness, a->getTextValue());
+ }
+ }
+}
+
+
+void LocalContrast::enabledChanged ()
+{
+ if (listener) {
+ if (get_inconsistent()) {
+ listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_UNCHANGED"));
+ } else if (getEnabled()) {
+ listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_ENABLED"));
+ } else {
+ listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_DISABLED"));
+ }
+ }
+}
+
+
+void LocalContrast::setBatchMode(bool batchMode)
+{
+ ToolPanel::setBatchMode(batchMode);
+
+ radius->showEditedCB();
+ amount->showEditedCB();
+ darkness->showEditedCB();
+ lightness->showEditedCB();
+}
+
+
+// void LocalContrast::setAdjusterBehavior (bool alphaAdd, bool betaAdd)
+// {
+// threshold->setAddMode(alphaAdd);
+// amount->setAddMode(betaAdd);
+// }
+
diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h
new file mode 100644
index 000000000..858d860a3
--- /dev/null
+++ b/rtgui/localcontrast.h
@@ -0,0 +1,47 @@
+/** -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2017 Alberto Griggio
+ *
+ * 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 .
+ */
+#pragma once
+
+#include
+#include "adjuster.h"
+#include "toolpanel.h"
+
+class LocalContrast: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel
+{
+protected:
+ Adjuster *radius;
+ Adjuster *amount;
+ Adjuster *darkness;
+ Adjuster *lightness;
+
+public:
+
+ LocalContrast();
+
+ void read(const rtengine::procparams::ProcParams *pp, const ParamsEdited *pedited=nullptr);
+ void write(rtengine::procparams::ProcParams *pp, ParamsEdited *pedited=nullptr);
+ void setDefaults(const rtengine::procparams::ProcParams *defParams, const ParamsEdited *pedited=nullptr);
+ void setBatchMode(bool batchMode);
+
+ void adjusterChanged(Adjuster *a, double newval);
+ void enabledChanged();
+ // void setAdjusterBehavior(bool alphaAdd, bool betaAdd);
+};
+
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 391438cd6..eabf4c63d 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -98,6 +98,11 @@ void ParamsEdited::set (bool v)
labCurve.avoidcolorshift = v;
labCurve.rstprotection = v;
labCurve.lcredsk = v;
+ localContrast.enabled = v;
+ localContrast.radius = v;
+ localContrast.amount = v;
+ localContrast.darkness = v;
+ localContrast.lightness = v;
rgbCurves.enabled = v;
rgbCurves.lumamode = v;
rgbCurves.rcurve = v;
@@ -643,6 +648,13 @@ 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.lcredsk = labCurve.lcredsk && p.labCurve.lcredsk == other.labCurve.lcredsk;
+
+ localContrast.enabled = localContrast.enabled && p.localContrast.enabled == other.localContrast.enabled;
+ localContrast.radius = localContrast.radius && p.localContrast.radius == other.localContrast.radius;
+ localContrast.amount = localContrast.amount && p.localContrast.amount == other.localContrast.amount;
+ localContrast.darkness = localContrast.darkness && p.localContrast.darkness == other.localContrast.darkness;
+ localContrast.lightness = localContrast.lightness && p.localContrast.lightness == other.localContrast.lightness;
+
rgbCurves.enabled = rgbCurves.enabled && p.rgbCurves.enabled == other.rgbCurves.enabled;
rgbCurves.lumamode = rgbCurves.lumamode && p.rgbCurves.lumamode == other.rgbCurves.lumamode;
rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve;
@@ -1370,6 +1382,22 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.labCurve.lcredsk = mods.labCurve.lcredsk;
}
+ if (localContrast.enabled) {
+ toEdit.localContrast.enabled = mods.localContrast.enabled;
+ }
+ if (localContrast.radius) {
+ toEdit.localContrast.radius = mods.localContrast.radius;
+ }
+ if (localContrast.amount) {
+ toEdit.localContrast.amount = mods.localContrast.amount;
+ }
+ if (localContrast.darkness) {
+ toEdit.localContrast.darkness = mods.localContrast.darkness;
+ }
+ if (localContrast.lightness) {
+ toEdit.localContrast.lightness = mods.localContrast.lightness;
+ }
+
if (rgbCurves.enabled) {
toEdit.rgbCurves.enabled = mods.rgbCurves.enabled;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index fcb3a0b49..b8d1e480b 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -118,6 +118,17 @@ public:
bool clcurve;
};
+
+class LocalContrastParamsEdited {
+public:
+ bool enabled;
+ bool radius;
+ bool amount;
+ bool darkness;
+ bool lightness;
+};
+
+
class RGBCurvesParamsEdited
{
@@ -793,6 +804,7 @@ public:
GeneralParamsEdited general;
ToneCurveParamsEdited toneCurve;
LCurveParamsEdited labCurve;
+ LocalContrastParamsEdited localContrast;
RGBCurvesParamsEdited rgbCurves;
ColorToningEdited colorToning;
RetinexParamsEdited retinex;
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 9153c6fb4..1b77379bb 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -41,6 +41,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), hasChan
coarse = Gtk::manage (new CoarsePanel ());
toneCurve = Gtk::manage (new ToneCurve ());
shadowshighlights = Gtk::manage (new ShadowsHighlights ());
+ localContrast = Gtk::manage(new LocalContrast());
impulsedenoise = Gtk::manage (new ImpulseDenoise ());
defringe = Gtk::manage (new Defringe ());
dirpyrdenoise = Gtk::manage (new DirPyrDenoise ());
@@ -106,6 +107,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), hasChan
addPanel (colorPanel, vibrance);
addPanel (colorPanel, chmixer);
addPanel (colorPanel, blackwhite);
+ addPanel (exposurePanel, localContrast);
addPanel (exposurePanel, shadowshighlights);
addPanel (detailsPanel, sharpening);
addPanel (detailsPanel, sharpenEdge);
diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h
index 3da061b99..7c4b94ed9 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -79,6 +79,7 @@
#include "filmsimulation.h"
#include "prsharpening.h"
#include "fattaltonemap.h"
+#include "localcontrast.h"
#include "guiutils.h"
class ImageEditorCoordinator;
@@ -120,6 +121,7 @@ protected:
Crop* crop;
ToneCurve* toneCurve;
ShadowsHighlights* shadowshighlights;
+ LocalContrast *localContrast;
Defringe* defringe;
ImpulseDenoise* impulsedenoise;
DirPyrDenoise* dirpyrdenoise;