diff --git a/rtdata/languages/default b/rtdata/languages/default
index 739fb6d71..cd7f1634e 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_LOCALCONTRAST_ENABLED;Local Contrast
+HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius
+HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount
+HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness
+HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -902,6 +907,7 @@ PARTIALPASTE_IPTCINFO;IPTC
PARTIALPASTE_LABCURVE;L*a*b* adjustments
PARTIALPASTE_LENSGROUP;Lens Related Settings
PARTIALPASTE_LENSPROFILE;Profiled lens correction
+PARTIALPASTE_LOCALCONTRAST;Local contrast
PARTIALPASTE_METAGROUP;Metadata
PARTIALPASTE_PCVIGNETTE;Vignette filter
PARTIALPASTE_PERSPECTIVE;Perspective
@@ -1679,6 +1685,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/improccoordinator.cc b/rtengine/improccoordinator.cc
index 9c80eed9e..6403612d6 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -1378,7 +1378,8 @@ ProcParams* ImProcCoordinator::beginUpdateParams ()
void ImProcCoordinator::endUpdateParams (ProcEvent change)
{
- endUpdateParams ( refreshmap[ (int)change] );
+ int action = RefreshMapper::getInstance()->getAction(change);
+ endUpdateParams(action);
}
void ImProcCoordinator::endUpdateParams (int changeFlags)
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..24739fb6b
--- /dev/null
+++ b/rtengine/iplocalcontrast.cc
@@ -0,0 +1,70 @@
+/* -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Ported from G'MIC by Alberto Griggio
+ *
+ * The original implementation in G'MIC was authored by Arto Huotari, and was
+ * released under the CeCILL free software license (see
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.html)
+ *
+ * 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 "gauss.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 dark = params->localContrast.darkness;
+ const float light = params->localContrast.lightness;
+ array2D buf(width, height);
+ const float sigma = params->localContrast.radius / scale;
+
+#ifdef _OPENMP
+ #pragma omp parallel if(multiThread)
+#endif
+ gaussianBlur(lab->L, buf, width, height, sigma);
+
+#ifdef _OPENMP
+ #pragma omp parallel for if(multiThread)
+#endif
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ float bufval = (lab->L[y][x] - buf[y][x]) * a;
+
+ if (dark != 1 || light != 1) {
+ bufval *= (bufval > 0.f) ? light : dark;
+ }
+
+ lab->L[y][x] += bufval;
+ }
+ }
+}
+
+} // namespace rtengine
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index b4bb6be73..f5751c7d0 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -26,7 +26,7 @@ namespace rtengine
// Aligned so the first entry starts on line 30
-enum ProcEvent {
+enum ProcEventCode {
EvPhotoLoaded = 0,
EvProfileLoaded = 1,
EvProfileChanged = 2,
@@ -525,6 +525,27 @@ enum ProcEvent {
NUMOFEVENTS
};
+
+
+class ProcEvent {
+public:
+ ProcEvent(): code_(0) {}
+ ProcEvent(ProcEventCode code): code_(code) {}
+ explicit ProcEvent(int code): code_(code) {}
+ operator int() { return code_; }
+
+private:
+ int code_;
+};
+
+
+inline bool operator==(ProcEvent a, ProcEvent b) { return int(a) == int(b); }
+inline bool operator==(ProcEvent a, ProcEventCode b) { return int(a) == int(b); }
+inline bool operator==(ProcEventCode a, ProcEvent b) { return int(a) == int(b); }
+inline bool operator!=(ProcEvent a, ProcEvent b) { return int(a) != int(b); }
+inline bool operator!=(ProcEvent a, ProcEventCode b) { return int(a) != int(b); }
+inline bool operator!=(ProcEventCode a, ProcEvent b) { return int(a) != int(b); }
+
}
#endif
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 64a3fc67f..4c8aa349e 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),
@@ -2591,6 +2619,8 @@ void ProcParams::setDefaults ()
rgbCurves = RGBCurvesParams();
+ localContrast = LocalContrastParams();
+
colorToning = ColorToningParams();
sharpenEdge = SharpenEdgeParams();
@@ -2758,6 +2788,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]) {
@@ -3594,6 +3632,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);
@@ -4721,6 +4767,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 6c95b3a7f..a2514ef1b 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
*/
@@ -1341,6 +1359,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 06879fb26..e76338fc0 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -523,3 +523,45 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
DEMOSAIC // EvPixelShiftOneGreen
};
+
+namespace rtengine {
+
+RefreshMapper::RefreshMapper():
+ next_event_(rtengine::NUMOFEVENTS)
+{
+ for (int event = 0; event < rtengine::NUMOFEVENTS; ++event) {
+ actions_[event] = refreshmap[event];
+ }
+}
+
+
+ProcEvent RefreshMapper::newEvent()
+{
+ return ProcEvent(++next_event_);
+}
+
+
+void RefreshMapper::mapEvent(ProcEvent event, int action)
+{
+ actions_[event] = action;
+}
+
+
+int RefreshMapper::getAction(ProcEvent event) const
+{
+ auto it = actions_.find(event);
+ if (it == actions_.end()) {
+ return 0;
+ } else {
+ return it->second;
+ }
+}
+
+
+RefreshMapper *RefreshMapper::getInstance()
+{
+ static RefreshMapper instance;
+ return &instance;
+}
+
+} // namespace rtengine
diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h
index cea6b3c8e..09059470b 100644
--- a/rtengine/refreshmap.h
+++ b/rtengine/refreshmap.h
@@ -19,6 +19,9 @@
#ifndef __REFRESHMAP__
#define __REFRESHMAP__
+#include
+#include "procevents.h"
+
// Use M_VOID if you wish to update the proc params without updating the preview at all !
#define M_VOID (1<<17)
// Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview")
@@ -74,4 +77,23 @@
#define OUTPUTPROFILE M_MONITOR
extern int refreshmap[];
+
+namespace rtengine {
+
+class RefreshMapper {
+public:
+ static RefreshMapper *getInstance();
+ ProcEvent newEvent();
+ void mapEvent(ProcEvent event, int action);
+ int getAction(ProcEvent event) const;
+
+private:
+ RefreshMapper();
+
+ int next_event_;
+ std::unordered_map actions_;
+};
+
+} // namespace rtengine
+
#endif
diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h
index 5c1343cc3..f7bdc36cb 100644
--- a/rtengine/rtengine.h
+++ b/rtengine/rtengine.h
@@ -413,6 +413,7 @@ public:
* The image update starts immediately in the background. If it is ready, the result is passed to a PreviewImageListener
* and to a DetailedCropListener (if enabled). */
virtual void endUpdateParams (ProcEvent change) = 0;
+ void endUpdateParams(ProcEventCode change) { endUpdateParams(ProcEvent(change)); }
virtual void endUpdateParams (int changeFlags) = 0;
// Starts a minimal update
virtual void startProcessing (int changeCode) = 0;
diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt
index 36c7a4034..222ee2550 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -148,6 +148,8 @@ set(NONCLISOURCEFILES
xtransrawexposure.cc
zoompanel.cc
fattaltonemap.cc
+ localcontrast.cc
+ eventmapper.cc
)
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h
index 07cf47d18..509b00610 100644
--- a/rtgui/addsetids.h
+++ b/rtgui/addsetids.h
@@ -129,6 +129,10 @@ enum {
ADDSET_EPD_REWEIGHTINGITERATES,
ADDSET_FATTAL_ALPHA,
ADDSET_FATTAL_BETA,
+ ADDSET_LOCALCONTRAST_RADIUS,
+ ADDSET_LOCALCONTRAST_AMOUNT,
+ ADDSET_LOCALCONTRAST_DARKNESS,
+ ADDSET_LOCALCONTRAST_LIGHTNESS,
ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!!
};
diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc
index a854db612..c2422a566 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -193,6 +193,7 @@ void BatchToolPanelCoordinator::initSession ()
prsharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_RADIUS], options.baBehav[ADDSET_SHARP_AMOUNT], options.baBehav[ADDSET_SHARP_DAMPING], options.baBehav[ADDSET_SHARP_ITER], options.baBehav[ADDSET_SHARP_EDGETOL], options.baBehav[ADDSET_SHARP_HALOCTRL]);
epd->setAdjusterBehavior (options.baBehav[ADDSET_EPD_STRENGTH], options.baBehav[ADDSET_EPD_GAMMA], options.baBehav[ADDSET_EPD_EDGESTOPPING], options.baBehav[ADDSET_EPD_SCALE], options.baBehav[ADDSET_EPD_REWEIGHTINGITERATES]);
fattal->setAdjusterBehavior (options.baBehav[ADDSET_FATTAL_ALPHA], options.baBehav[ADDSET_FATTAL_BETA]);
+ localContrast->setAdjusterBehavior(options.baBehav[ADDSET_LOCALCONTRAST_RADIUS], options.baBehav[ADDSET_LOCALCONTRAST_AMOUNT], options.baBehav[ADDSET_LOCALCONTRAST_DARKNESS], options.baBehav[ADDSET_LOCALCONTRAST_LIGHTNESS]);
sharpenEdge->setAdjusterBehavior (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT], options.baBehav[ADDSET_SHARPENEDGE_PASS]);
sharpenMicro->setAdjusterBehavior (options.baBehav[ADDSET_SHARPENMICRO_AMOUNT], options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY]);
@@ -351,6 +352,9 @@ void BatchToolPanelCoordinator::initSession ()
if (options.baBehav[ADDSET_RAWFFCLIPCONTROL]) { pparams.raw.ff_clipControl = 0; }
if (options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]) { pparams.raw.bayersensor.greenthresh = 0; }
if (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE]) { pparams.raw.bayersensor.linenoise = 0; }
+ if (options.baBehav[ADDSET_LOCALCONTRAST_AMOUNT]) { pparams.localContrast.amount = 0; }
+ if (options.baBehav[ADDSET_LOCALCONTRAST_DARKNESS]) { pparams.localContrast.darkness = 0; }
+ if (options.baBehav[ADDSET_LOCALCONTRAST_LIGHTNESS]) { pparams.localContrast.lightness = 0; }
// *INDENT-ON*
}
diff --git a/rtgui/eventmapper.cc b/rtgui/eventmapper.cc
new file mode 100644
index 000000000..de5258413
--- /dev/null
+++ b/rtgui/eventmapper.cc
@@ -0,0 +1,63 @@
+/* -*- 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 "eventmapper.h"
+
+
+ProcEventMapper::ProcEventMapper()
+{
+ for (int event = 0; event < rtengine::NUMOFEVENTS; ++event) {
+ history_msgs_[event] = "HISTORY_MSG_" + std::to_string(event + 1);
+ }
+}
+
+
+ProcEventMapper *ProcEventMapper::getInstance()
+{
+ static ProcEventMapper instance;
+ return &instance;
+}
+
+
+rtengine::ProcEvent ProcEventMapper::newEvent(int action, const std::string &history_msg)
+{
+ rtengine::ProcEvent event = rtengine::RefreshMapper::getInstance()->newEvent();
+ rtengine::RefreshMapper::getInstance()->mapEvent(event, action);
+
+ if (history_msg.empty()) {
+ history_msgs_[event] = "HISTORY_MSG_" + std::to_string(event + 1);
+ } else {
+ history_msgs_[event] = history_msg;
+ }
+
+ return event;
+}
+
+
+const std::string &ProcEventMapper::getHistoryMsg(rtengine::ProcEvent event) const
+{
+ static std::string empty;
+ auto it = history_msgs_.find(event);
+ if (it == history_msgs_.end()) {
+ return empty;
+ } else {
+ return it->second;
+ }
+}
diff --git a/rtgui/eventmapper.h b/rtgui/eventmapper.h
new file mode 100644
index 000000000..87ccc1d9b
--- /dev/null
+++ b/rtgui/eventmapper.h
@@ -0,0 +1,37 @@
+/* -*- 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
+#include "../rtengine/refreshmap.h"
+
+
+class ProcEventMapper {
+public:
+ static ProcEventMapper *getInstance();
+ rtengine::ProcEvent newEvent(int action, const std::string &history_msg="");
+ const std::string &getHistoryMsg(rtengine::ProcEvent event) const;
+
+private:
+ ProcEventMapper();
+
+ std::unordered_map history_msgs_;
+};
diff --git a/rtgui/history.cc b/rtgui/history.cc
index d62fcdb30..6b07ee7b2 100644
--- a/rtgui/history.cc
+++ b/rtgui/history.cc
@@ -20,6 +20,7 @@
#include "multilangmgr.h"
#include "rtimage.h"
#include "guiutils.h"
+#include "eventmapper.h"
using namespace rtengine;
using namespace rtengine::procparams;
@@ -231,7 +232,7 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring
}
// construct formatted list content
- Glib::ustring text = M("HISTORY_MSG_" + std::to_string(ev + 1));
+ Glib::ustring text = M(ProcEventMapper::getInstance()->getHistoryMsg(ev));
Glib::RefPtr selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
diff --git a/rtgui/localcontrast.cc b/rtgui/localcontrast.cc
new file mode 100644
index 000000000..727479c34
--- /dev/null
+++ b/rtgui/localcontrast.cc
@@ -0,0 +1,167 @@
+/** -*- 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 "eventmapper.h"
+#include
+#include
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+LocalContrast::LocalContrast(): FoldableToolPanel(this, "localcontrast", M("TP_LOCALCONTRAST_LABEL"), false, true)
+{
+ auto m = ProcEventMapper::getInstance();
+ EvLocalContrastEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_ENABLED");
+ EvLocalContrastRadius = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_RADIUS");
+ EvLocalContrastAmount = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_AMOUNT");
+ EvLocalContrastDarkness = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_DARKNESS");
+ EvLocalContrastLightness = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_LIGHTNESS");
+
+ radius = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 20., 200., 1., 80.));
+ 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., 3., 0.01, 1.));
+ lightness = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_LIGHTNESS"), 0., 3., 0.01, 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 radiusAdd, bool amountAdd, bool darknessAdd, bool lightnessAdd)
+{
+ radius->setAddMode(radiusAdd);
+ amount->setAddMode(amountAdd);
+ darkness->setAddMode(darknessAdd);
+ lightness->setAddMode(lightnessAdd);
+}
+
diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h
new file mode 100644
index 000000000..4f6f872af
--- /dev/null
+++ b/rtgui/localcontrast.h
@@ -0,0 +1,53 @@
+/** -*- 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
+{
+private:
+ Adjuster *radius;
+ Adjuster *amount;
+ Adjuster *darkness;
+ Adjuster *lightness;
+
+ rtengine::ProcEvent EvLocalContrastEnabled;
+ rtengine::ProcEvent EvLocalContrastRadius;
+ rtengine::ProcEvent EvLocalContrastAmount;
+ rtengine::ProcEvent EvLocalContrastDarkness;
+ rtengine::ProcEvent EvLocalContrastLightness;
+
+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 radiusAdd, bool amountAdd, bool darknessAdd, bool lightnessAdd);
+};
+
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index ea29079a0..954a42954 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;
@@ -644,6 +649,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;
@@ -1372,6 +1384,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 2727f01ec..2dcbedaf8 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
{
@@ -794,6 +805,7 @@ public:
GeneralParamsEdited general;
ToneCurveParamsEdited toneCurve;
LCurveParamsEdited labCurve;
+ LocalContrastParamsEdited localContrast;
RGBCurvesParamsEdited rgbCurves;
ColorToningEdited colorToning;
RetinexParamsEdited retinex;
diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc
index 4b5c7a857..898b6dad5 100644
--- a/rtgui/partialpastedlg.cc
+++ b/rtgui/partialpastedlg.cc
@@ -49,6 +49,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
// options in basic:
wb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WHITEBALANCE")));
exposure = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXPOSURE")));
+ localcontrast = Gtk::manage(new Gtk::CheckButton(M("PARTIALPASTE_LOCALCONTRAST")));
sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS")));
epd = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EPD")));
fattal = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_TM_FATTAL")));
@@ -142,6 +143,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
vboxes[0]->pack_start (*hseps[0], Gtk::PACK_SHRINK, 2);
vboxes[0]->pack_start (*wb, Gtk::PACK_SHRINK, 2);
vboxes[0]->pack_start (*exposure, Gtk::PACK_SHRINK, 2);
+ vboxes[0]->pack_start (*localcontrast, Gtk::PACK_SHRINK, 2);
vboxes[0]->pack_start (*sh, Gtk::PACK_SHRINK, 2);
vboxes[0]->pack_start (*epd, Gtk::PACK_SHRINK, 2);
vboxes[0]->pack_start (*fattal, Gtk::PACK_SHRINK, 2);
@@ -298,6 +300,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
wbConn = wb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
exposureConn = exposure->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
+ localcontrastConn = localcontrast->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
shConn = sh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
epdConn = epd->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
fattalConn = fattal->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
@@ -472,6 +475,7 @@ void PartialPasteDlg::basicToggled ()
ConnectionBlocker wbBlocker(wbConn);
ConnectionBlocker exposureBlocker(exposureConn);
+ ConnectionBlocker localcontrastBlocker(localcontrastConn);
ConnectionBlocker shBlocker(shConn);
ConnectionBlocker epdBlocker(epdConn);
ConnectionBlocker fattalBlocker(fattalConn);
@@ -485,6 +489,7 @@ void PartialPasteDlg::basicToggled ()
wb->set_active (basic->get_active ());
exposure->set_active (basic->get_active ());
+ localcontrast->set_active(basic->get_active());
sh->set_active (basic->get_active ());
epd->set_active (basic->get_active ());
fattal->set_active (basic->get_active ());
@@ -629,6 +634,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
filterPE.toneCurve = falsePE.toneCurve;
}
+ if (!localcontrast->get_active()) {
+ filterPE.localContrast = falsePE.localContrast;
+ }
+
if (!sh->get_active ()) {
filterPE.sh = falsePE.sh;
}
diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h
index baef6b9aa..d1ae056c3 100644
--- a/rtgui/partialpastedlg.h
+++ b/rtgui/partialpastedlg.h
@@ -44,6 +44,7 @@ public:
// options in basic:
Gtk::CheckButton* wb;
Gtk::CheckButton* exposure;
+ Gtk::CheckButton* localcontrast;
Gtk::CheckButton* sh;
Gtk::CheckButton* epd;
Gtk::CheckButton* fattal;
@@ -124,7 +125,7 @@ public:
sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, wavConn;
- sigc::connection wbConn, exposureConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn;
+ sigc::connection wbConn, exposureConn, localcontrastConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn;
sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, defringeConn, epdConn, fattalConn, dirpyreqConn, waveletConn, retinexConn;
sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn;
sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn;
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index e66edce29..e0a5747d9 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -187,6 +187,14 @@ Gtk::Widget* Preferences::getBatchProcPanel ()
appendBehavList (mi, M ("TP_EXPOSURE_CONTRAST"), ADDSET_TC_CONTRAST, false);
appendBehavList (mi, M ("TP_EXPOSURE_SATURATION"), ADDSET_TC_SATURATION, false);
+ mi = behModel->append();
+ mi->set_value(behavColumns.label, M("TP_LOCALCONTRAST_LABEL"));
+ appendBehavList(mi, M("TP_LOCALCONTRAST_RADIUS"), ADDSET_LOCALCONTRAST_RADIUS, false);
+ appendBehavList(mi, M("TP_LOCALCONTRAST_AMOUNT"), ADDSET_LOCALCONTRAST_AMOUNT, false);
+ appendBehavList(mi, M("TP_LOCALCONTRAST_DARKNESS"), ADDSET_LOCALCONTRAST_DARKNESS, false);
+ appendBehavList(mi, M("TP_LOCALCONTRAST_LIGHTNESS"), ADDSET_LOCALCONTRAST_LIGHTNESS, false);
+
+
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_EPD_LABEL"));
appendBehavList (mi, M ("TP_EPD_STRENGTH"), ADDSET_EPD_STRENGTH, false);
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 9153c6fb4..318ebf55b 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);
@@ -313,7 +315,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
return;
}
- int changeFlags = refreshmap[ (int)event];
+ int changeFlags = rtengine::RefreshMapper::getInstance()->getAction(event);
ProcParams* params = ipc->beginUpdateParams ();
@@ -325,7 +327,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
if (event == rtengine::EvCTHFlip || event == rtengine::EvCTVFlip) {
if (fabs (params->rotate.degree) > 0.001) {
params->rotate.degree *= -1;
- changeFlags |= refreshmap[ (int)rtengine::EvROTDegree];
+ changeFlags |= rtengine::RefreshMapper::getInstance()->getAction(rtengine::EvROTDegree);
rotate->read (params);
}
}
@@ -444,7 +446,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi
// start the IPC processing
if (filterRawRefresh) {
- ipc->endUpdateParams ( refreshmap[ (int)event] & ALLNORAW );
+ ipc->endUpdateParams ( rtengine::RefreshMapper::getInstance()->getAction(event) & ALLNORAW );
} else {
ipc->endUpdateParams (event);
}
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;