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;