diff --git a/rtdata/languages/default b/rtdata/languages/default
index 2bc74bf8a..489ee5ec0 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -734,6 +734,8 @@ HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius
HISTORY_MSG_METADATA_MODE;Metadata copy mode
HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction
HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter
+HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
+HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
HISTORY_MSG_TM_FATTAL_ANCHOR;HDR TM - Anchor
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
@@ -945,6 +947,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/highlights
PARTIALPASTE_SHARPENEDGE;Edges
PARTIALPASTE_SHARPENING;Sharpening (USM/RL)
PARTIALPASTE_SHARPENMICRO;Microcontrast
+PARTIALPASTE_SOFTLIGHT;Soft light
PARTIALPASTE_TM_FATTAL;HDR Tone mapping
PARTIALPASTE_VIBRANCE;Vibrance
PARTIALPASTE_VIGNETTING;Vignetting correction
@@ -1969,6 +1972,8 @@ TP_SHARPENMICRO_AMOUNT;Quantity
TP_SHARPENMICRO_LABEL;Microcontrast
TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformity
+TP_SOFTLIGHT_LABEL;Soft Light
+TP_SOFTLIGHT_STRENGTH;Strength
TP_TM_FATTAL_AMOUNT;Amount
TP_TM_FATTAL_ANCHOR;Anchor
TP_TM_FATTAL_LABEL;HDR Tone Mapping
diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt
index 0693f919f..c75da9770 100644
--- a/rtengine/CMakeLists.txt
+++ b/rtengine/CMakeLists.txt
@@ -120,6 +120,7 @@ set(RTENGINESOURCEFILES
histmatching.cc
pdaflinesfilter.cc
gamutwarning.cc
+ ipsoftlight.cc
)
if(LENSFUN_HAS_LOAD_DIRECTORY)
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 08fe8db0e..b80a94147 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -3221,7 +3221,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
}
}
-
+ softLight(rtemp, gtemp, btemp, istart, jstart, tW, tH, TS);
+
if (!blackwhite) {
if (editImgFloat || editWhatever) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index fbddd491d..7c90d0632 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -344,6 +344,7 @@ public:
void ToneMapFattal02(Imagefloat *rgb);
void localContrast(LabImage *lab);
void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread);
+ void softLight(float *red, float *green, float *blue, int istart, int jstart, int tW, int tH, int TS);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings=true);
Imagefloat* lab2rgbOut (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga = nullptr);
diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc
new file mode 100644
index 000000000..35bf9577a
--- /dev/null
+++ b/rtengine/ipsoftlight.cc
@@ -0,0 +1,73 @@
+/* -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Copyright 2018 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"
+
+namespace rtengine {
+
+void ImProcFunctions::softLight(float *red, float *green, float *blue, int istart, int jstart, int tW, int tH, int TS)
+{
+ if (!params->softlight.enabled || !params->softlight.strength) {
+ return;
+ }
+
+ const float blend = params->softlight.strength / 100.f;
+ const float orig = 1.f - blend;
+
+ const auto apply =
+ [=](float x) -> float
+ {
+ if (!OOG(x)) {
+ float v = Color::gamma_srgb(x) / MAXVALF;
+ // Pegtop's formula from
+ // https://en.wikipedia.org/wiki/Blend_modes#Soft_Light
+ float v2 = v * v;
+ float v22 = v2 * 2.f;
+ v = v2 + v22 - v22 * v;
+ x = blend * Color::igamma_srgb(v * MAXVALF) + orig * x;
+ }
+ return x;
+ };
+
+#ifdef _OPENMP
+ #pragma omp parallel if (multiThread)
+#endif
+ {
+ int ti = 0;
+#ifdef _OPENMP
+ #pragma omp for
+#endif
+ for (int i = istart; i < tH; i++) {
+ for (int j = jstart, tj = 0; j < tW; j++, tj++) {
+ const int idx = ti * TS + tj;
+ red[idx] = apply(red[idx]);
+ green[idx] = apply(green[idx]);
+ blue[idx] = apply(blue[idx]);
+ }
+ ++ti;
+ }
+ }
+}
+
+} // namespace rtengine
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index eb8f29d07..773c7e5ea 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -2341,6 +2341,25 @@ bool FilmSimulationParams::operator !=(const FilmSimulationParams& other) const
return !(*this == other);
}
+
+SoftLightParams::SoftLightParams() :
+ enabled(false),
+ strength(30)
+{
+}
+
+bool SoftLightParams::operator ==(const SoftLightParams& other) const
+{
+ return
+ enabled == other.enabled
+ && strength == other.strength;
+}
+
+bool SoftLightParams::operator !=(const SoftLightParams& other) const
+{
+ return !(*this == other);
+}
+
RAWParams::BayerSensor::BayerSensor() :
method(getMethodString(Method::AMAZE)),
imageNum(0),
@@ -2711,6 +2730,8 @@ void ProcParams::setDefaults ()
filmSimulation = FilmSimulationParams();
+ softlight = SoftLightParams();
+
raw = RAWParams();
metadata = MetaDataParams();
@@ -3306,6 +3327,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->hsvequalizer.scurve, "HSV Equalizer", "SCurve", hsvequalizer.scurve, keyFile);
saveToKeyfile(!pedited || pedited->hsvequalizer.vcurve, "HSV Equalizer", "VCurve", hsvequalizer.vcurve, keyFile);
+// Soft Light
+ saveToKeyfile(!pedited || pedited->softlight.enabled, "SoftLight", "Enabled", softlight.enabled, keyFile);
+ saveToKeyfile(!pedited || pedited->softlight.strength, "SoftLight", "Strength", softlight.strength, keyFile);
+
// Film simulation
saveToKeyfile(!pedited || pedited->filmSimulation.enabled, "Film Simulation", "Enabled", filmSimulation.enabled, keyFile);
saveToKeyfile(!pedited || pedited->filmSimulation.clutFilename, "Film Simulation", "ClutFilename", filmSimulation.clutFilename, keyFile);
@@ -4512,6 +4537,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_group("SoftLight")) {
+ assignFromKeyfile(keyFile, "SoftLight", "Enabled", pedited, softlight.enabled, pedited->softlight.enabled);
+ assignFromKeyfile(keyFile, "SoftLight", "Strength", pedited, softlight.strength, pedited->softlight.strength);
+ }
+
if (keyFile.has_group ("Film Simulation")) {
assignFromKeyfile(keyFile, "Film Simulation", "Enabled", pedited, filmSimulation.enabled, pedited->filmSimulation.enabled);
assignFromKeyfile(keyFile, "Film Simulation", "ClutFilename", pedited, filmSimulation.clutFilename, pedited->filmSimulation.clutFilename);
@@ -4878,6 +4908,7 @@ bool ProcParams::operator ==(const ProcParams& other) const
&& dirpyrequalizer == other.dirpyrequalizer
&& hsvequalizer == other.hsvequalizer
&& filmSimulation == other.filmSimulation
+ && softlight == other.softlight
&& rgbCurves == other.rgbCurves
&& colorToning == other.colorToning
&& metadata == other.metadata
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 2cfc777b8..ec1490ba2 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1213,6 +1213,17 @@ struct FilmSimulationParams {
};
+struct SoftLightParams {
+ bool enabled;
+ int strength;
+
+ SoftLightParams();
+
+ bool operator==(const SoftLightParams &other) const;
+ bool operator!=(const SoftLightParams &other) const;
+};
+
+
/**
* Parameters for RAW demosaicing, common to all sensor type
*/
@@ -1430,6 +1441,7 @@ public:
DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid wavelet parameters
HSVEqualizerParams hsvequalizer; ///< hsv wavelet parameters
FilmSimulationParams filmSimulation; ///< film simulation parameters
+ SoftLightParams softlight; ///< softlight parameters
int rank; ///< Custom image quality ranking
int colorlabel; ///< Custom color label
bool inTrash; ///< Marks deleted image
diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt
index c39ed004c..f2167c654 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -154,6 +154,7 @@ set(NONCLISOURCEFILES
eventmapper.cc
metadatapanel.cc
labgrid.cc
+ softlight.cc
)
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h
index 49eefc794..9a1d45ffd 100644
--- a/rtgui/addsetids.h
+++ b/rtgui/addsetids.h
@@ -134,6 +134,7 @@ enum {
ADDSET_LOCALCONTRAST_DARKNESS,
ADDSET_LOCALCONTRAST_LIGHTNESS,
ADDSET_FATTAL_ANCHOR,
+ ADDSET_SOFTLIGHT_STRENGTH,
ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!!
};
diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc
index d3c3fb4c6..8d7472391 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -201,6 +201,7 @@ void BatchToolPanelCoordinator::initSession ()
// colortoning->setAdjusterBehavior (options.baBehav[ADDSET_COLORTONING_SPLIT], options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD], options.baBehav[ADDSET_COLORTONING_SATOPACITY], options.baBehav[ADDSET_COLORTONING_STRPROTECT], options.baBehav[ADDSET_COLORTONING_BALANCE]);
colortoning->setAdjusterBehavior (options.baBehav[ADDSET_COLORTONING_SPLIT], options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD], options.baBehav[ADDSET_COLORTONING_SATOPACITY], options.baBehav[ADDSET_COLORTONING_STRENGTH], options.baBehav[ADDSET_COLORTONING_BALANCE]);
filmSimulation->setAdjusterBehavior(options.baBehav[ADDSET_FILMSIMULATION_STRENGTH]);
+ softlight->setAdjusterBehavior(options.baBehav[ADDSET_SOFTLIGHT_STRENGTH]);
retinex->setAdjusterBehavior (options.baBehav[ADDSET_RETI_STR], options.baBehav[ADDSET_RETI_NEIGH], options.baBehav[ADDSET_RETI_LIMD], options.baBehav[ADDSET_RETI_OFFS], options.baBehav[ADDSET_RETI_VART], options.baBehav[ADDSET_RETI_GAM], options.baBehav[ADDSET_RETI_SLO]);
chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER] );
@@ -289,6 +290,7 @@ void BatchToolPanelCoordinator::initSession ()
if (options.baBehav[ADDSET_COLORTONING_BALANCE]) { pparams.colorToning.balance = 0; }
if (options.baBehav[ADDSET_COLORTONING_STRENGTH]) { pparams.colorToning.strength = 0; }
if (options.baBehav[ADDSET_FILMSIMULATION_STRENGTH]) { pparams.filmSimulation.strength = 0; }
+ if (options.baBehav[ADDSET_SOFTLIGHT_STRENGTH]) { pparams.softlight.strength = 0; }
if (options.baBehav[ADDSET_ROTATE_DEGREE]) { pparams.rotate.degree = 0; }
if (options.baBehav[ADDSET_RESIZE_SCALE]) { pparams.resize.scale = 0; }
if (options.baBehav[ADDSET_DIST_AMOUNT]) { pparams.distortion.amount = 0; }
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index cf61c8aad..6e24ca2b4 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -572,6 +572,8 @@ void ParamsEdited::set (bool v)
filmSimulation.enabled = v;
filmSimulation.clutFilename = v;
filmSimulation.strength = v;
+ softlight.enabled = v;
+ softlight.strength = v;
metadata.mode = v;
exif = v;
@@ -1131,6 +1133,8 @@ void ParamsEdited::initFrom (const std::vector
filmSimulation.enabled = filmSimulation.enabled && p.filmSimulation.enabled == other.filmSimulation.enabled;
filmSimulation.clutFilename = filmSimulation.clutFilename && p.filmSimulation.clutFilename == other.filmSimulation.clutFilename;
filmSimulation.strength = filmSimulation.strength && p.filmSimulation.strength == other.filmSimulation.strength;
+ softlight.enabled = softlight.enabled && p.softlight.enabled == other.softlight.enabled;
+ softlight.strength = softlight.strength && p.softlight.strength == other.softlight.strength;
metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode;
// How the hell can we handle that???
@@ -3143,6 +3147,14 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.filmSimulation.strength = dontforceSet && options.baBehav[ADDSET_FILMSIMULATION_STRENGTH] ? toEdit.filmSimulation.strength + mods.filmSimulation.strength : mods.filmSimulation.strength;
}
+ if (softlight.enabled) {
+ toEdit.softlight.enabled = mods.softlight.enabled;
+ }
+
+ if (softlight.strength) {
+ toEdit.softlight.strength = dontforceSet && options.baBehav[ADDSET_SOFTLIGHT_STRENGTH] ? toEdit.softlight.strength + mods.softlight.strength : mods.softlight.strength;
+ }
+
if (metadata.mode) {
toEdit.metadata.mode = mods.metadata.mode;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 0b73d7daf..82d8bd89b 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -710,6 +710,13 @@ public:
bool strength;
};
+class SoftLightParamsEdited
+{
+public:
+ bool enabled;
+ bool strength;
+};
+
class RAWParamsEdited
{
@@ -861,6 +868,7 @@ public:
WaveletParamsEdited wavelet;
HSVEqualizerParamsEdited hsvequalizer;
FilmSimulationParamsEdited filmSimulation;
+ SoftLightParamsEdited softlight;
MetaDataParamsEdited metadata;
bool exif;
bool iptc;
diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc
index 4828e90dc..94046960c 100644
--- a/rtgui/partialpastedlg.cc
+++ b/rtgui/partialpastedlg.cc
@@ -78,6 +78,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
blackwhite = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXERBW")));
hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER")));
filmSimulation = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMSIMULATION")) );
+ softlight = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SOFTLIGHT")) );
rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES")));
colortoning = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORTONING")));
@@ -175,6 +176,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
vboxes[2]->pack_start (*blackwhite, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*filmSimulation, Gtk::PACK_SHRINK, 2);
+ vboxes[2]->pack_start (*softlight, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*rgbcurves, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*colortoning, Gtk::PACK_SHRINK, 2);
@@ -334,6 +336,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
chmixerbwConn = blackwhite->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
filmSimulationConn = filmSimulation->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
+ softlightConn = softlight->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
rgbcurvesConn = rgbcurves->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
colortoningConn = colortoning->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
@@ -557,6 +560,7 @@ void PartialPasteDlg::colorToggled ()
ConnectionBlocker chmixerbwBlocker(chmixerbwConn);
ConnectionBlocker hsveqBlocker(hsveqConn);
ConnectionBlocker filmSimulationBlocker(filmSimulationConn);
+ ConnectionBlocker softlightBlocker(softlightConn);
ConnectionBlocker rgbcurvesBlocker(rgbcurvesConn);
ConnectionBlocker colortoningBlocker(colortoningConn);
@@ -568,6 +572,7 @@ void PartialPasteDlg::colorToggled ()
blackwhite->set_active (color->get_active ());
hsveq->set_active (color->get_active ());
filmSimulation->set_active (color->get_active ());
+ softlight->set_active (color->get_active ());
rgbcurves->set_active (color->get_active ());
colortoning->set_active(color->get_active ());
}
@@ -743,6 +748,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
filterPE.filmSimulation = falsePE.filmSimulation;
}
+ if (!softlight->get_active ()) {
+ filterPE.softlight = falsePE.softlight;
+ }
+
if (!rgbcurves->get_active ()) {
filterPE.rgbCurves = falsePE.rgbCurves;
}
diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h
index b404db156..1492d0418 100644
--- a/rtgui/partialpastedlg.h
+++ b/rtgui/partialpastedlg.h
@@ -73,6 +73,7 @@ public:
Gtk::CheckButton* chmixer;
Gtk::CheckButton* blackwhite;
Gtk::CheckButton* hsveq;
+ Gtk::CheckButton* softlight;
Gtk::CheckButton* filmSimulation;
Gtk::CheckButton* rgbcurves;
Gtk::CheckButton* colortoning;
@@ -129,7 +130,7 @@ public:
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 vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn, softlightConn;
sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn;
sigc::connection metadataConn, exifchConn, iptcConn, icmConn;
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index 2c5154942..1c5a8db99 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -306,6 +306,10 @@ Gtk::Widget* Preferences::getBatchProcPanel ()
mi->set_value ( behavColumns.label, M ("TP_FILMSIMULATION_LABEL") );
appendBehavList ( mi, M ( "TP_FILMSIMULATION_STRENGTH" ), ADDSET_FILMSIMULATION_STRENGTH, true );
+ mi = behModel->append ();
+ mi->set_value ( behavColumns.label, M ("TP_SOFTLIGHT_LABEL") );
+ appendBehavList ( mi, M ( "TP_SOFTLIGHT_STRENGTH" ), ADDSET_SOFTLIGHT_STRENGTH, true );
+
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_COLORTONING_LABEL"));
appendBehavList (mi, M ("TP_COLORTONING_SPLITCOCO"), ADDSET_COLORTONING_SPLIT, true);
diff --git a/rtgui/softlight.cc b/rtgui/softlight.cc
new file mode 100644
index 000000000..cac534ce3
--- /dev/null
+++ b/rtgui/softlight.cc
@@ -0,0 +1,115 @@
+/** -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2018 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 "softlight.h"
+#include "eventmapper.h"
+#include
+#include
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+SoftLight::SoftLight(): FoldableToolPanel(this, "softlight", M("TP_SOFTLIGHT_LABEL"), false, true)
+{
+ auto m = ProcEventMapper::getInstance();
+ EvSoftLightEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_SOFTLIGHT_ENABLED");
+ EvSoftLightStrength = m->newEvent(RGBCURVE, "HISTORY_MSG_SOFTLIGHT_STRENGTH");
+
+ strength = Gtk::manage(new Adjuster(M("TP_SOFTLIGHT_STRENGTH"), 0., 100., 1., 30.));
+ strength->setAdjusterListener(this);
+ strength->show();
+
+ pack_start(*strength);
+}
+
+
+void SoftLight::read(const ProcParams *pp, const ParamsEdited *pedited)
+{
+ disableListener();
+
+ if (pedited) {
+ strength->setEditedState(pedited->softlight.strength ? Edited : UnEdited);
+ set_inconsistent(multiImage && !pedited->softlight.enabled);
+ }
+
+ setEnabled(pp->softlight.enabled);
+ strength->setValue(pp->softlight.strength);
+
+ enableListener();
+}
+
+
+void SoftLight::write(ProcParams *pp, ParamsEdited *pedited)
+{
+ pp->softlight.strength = strength->getValue();
+ pp->softlight.enabled = getEnabled();
+
+ if (pedited) {
+ pedited->softlight.strength = strength->getEditedState();
+ pedited->softlight.enabled = !get_inconsistent();
+ }
+}
+
+void SoftLight::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited)
+{
+ strength->setDefault(defParams->softlight.strength);
+
+ if (pedited) {
+ strength->setDefaultEditedState(pedited->softlight.strength ? Edited : UnEdited);
+ } else {
+ strength->setDefaultEditedState(Irrelevant);
+ }
+}
+
+
+void SoftLight::adjusterChanged(Adjuster* a, double newval)
+{
+ if (listener && getEnabled()) {
+ listener->panelChanged(EvSoftLightStrength, a->getTextValue());
+ }
+}
+
+
+void SoftLight::enabledChanged ()
+{
+ if (listener) {
+ if (get_inconsistent()) {
+ listener->panelChanged(EvSoftLightEnabled, M("GENERAL_UNCHANGED"));
+ } else if (getEnabled()) {
+ listener->panelChanged(EvSoftLightEnabled, M("GENERAL_ENABLED"));
+ } else {
+ listener->panelChanged(EvSoftLightEnabled, M("GENERAL_DISABLED"));
+ }
+ }
+}
+
+
+void SoftLight::setBatchMode(bool batchMode)
+{
+ ToolPanel::setBatchMode(batchMode);
+
+ strength->showEditedCB();
+}
+
+
+void SoftLight::setAdjusterBehavior(bool strengthAdd)
+{
+ strength->setAddMode(strengthAdd);
+}
+
diff --git a/rtgui/softlight.h b/rtgui/softlight.h
new file mode 100644
index 000000000..dc51ac730
--- /dev/null
+++ b/rtgui/softlight.h
@@ -0,0 +1,47 @@
+/** -*- C++ -*-
+ *
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2018 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 SoftLight: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel
+{
+private:
+ Adjuster *strength;
+
+ rtengine::ProcEvent EvSoftLightEnabled;
+ rtengine::ProcEvent EvSoftLightStrength;
+
+public:
+
+ SoftLight();
+
+ 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 strengthAdd);
+};
+
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 2899625fe..b29135472 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -76,6 +76,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), hasChan
dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ());
hsvequalizer = Gtk::manage (new HSVEqualizer ());
filmSimulation = Gtk::manage (new FilmSimulation ());
+ softlight = Gtk::manage(new SoftLight());
sensorbayer = Gtk::manage (new SensorBayer ());
sensorxtrans = Gtk::manage (new SensorXTrans ());
bayerprocess = Gtk::manage (new BayerProcess ());
@@ -111,6 +112,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), hasChan
addPanel (detailsPanel, sharpenMicro);
addPanel (colorPanel, hsvequalizer);
addPanel (colorPanel, filmSimulation);
+ addPanel (colorPanel, softlight);
addPanel (colorPanel, rgbcurves);
addPanel (colorPanel, colortoning);
addPanel (exposurePanel, epd);
diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h
index 5b9822ef2..372669d3c 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -79,6 +79,7 @@
#include "prsharpening.h"
#include "fattaltonemap.h"
#include "localcontrast.h"
+#include "softlight.h"
#include "guiutils.h"
class ImageEditorCoordinator;
@@ -134,6 +135,7 @@ protected:
Wavelet * wavelet;
DirPyrEqualizer* dirpyrequalizer;
HSVEqualizer* hsvequalizer;
+ SoftLight *softlight;
FilmSimulation *filmSimulation;
SensorBayer * sensorbayer;
SensorXTrans * sensorxtrans;