diff --git a/rtdata/languages/default b/rtdata/languages/default
index 270973878..1c6814753 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -741,7 +741,6 @@ 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 - Bottom
HISTORY_MSG_495;Local - Right
HISTORY_MSG_496;Local - Center
HISTORY_MSG_497;Local - Lightness/
@@ -842,7 +841,13 @@ HISTORY_MSG_592;Local - Warm Cool
HISTORY_MSG_593;Local - Noise lum detail
HISTORY_MSG_594;Local - Noise chro detail
HISTORY_MSG_595;Local - Noise Scope
-HISTORY_MSG_596;Local L*a*b*
+HISTORY_MSG_597;Local L*a*b*
+HISTORY_MSG_598;Local - Bottom
+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
@@ -1024,6 +1029,7 @@ PARTIALPASTE_LENSGROUP;Lens Related Settings
PARTIALPASTE_LOCALLAB;Local L*a*b*
PARTIALPASTE_LOCGROUP;Local
PARTIALPASTE_LENSPROFILE;Profiled lens correction
+PARTIALPASTE_LOCALCONTRAST;Local contrast
PARTIALPASTE_METAGROUP;Metadata
PARTIALPASTE_PCVIGNETTE;Vignette filter
PARTIALPASTE_PERSPECTIVE;Perspective
@@ -1813,6 +1819,7 @@ TP_LENSPROFILE_LABEL;Profiled Lens Correction
TP_LENSPROFILE_USECA;Chromatic aberration correction
TP_LENSPROFILE_USEDIST;Distortion correction
TP_LENSPROFILE_USEVIGN;Vignetting correction
+<<<<<<< HEAD
TP_LOCALLAB_ACTIV;Blur luminance only
TP_LOCALLAB_ADJBLUR;Adjust and Blur
TP_LOCALLAB_ARTIF;Reduce artifacts - Improve algoritm
@@ -1923,6 +1930,14 @@ TP_LOCAL_WIDTH;Right
TP_LOCAL_WIDTH_L;Left
TP_LOCRETI_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Equalize action.\nHigh = Reinforce high light.\n
TP_NEUTRAL;Neutral
+=======
+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
+>>>>>>> dev
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
TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center.
@@ -1972,7 +1987,7 @@ TP_RAW_DCBITERATIONS;Number of DCB iterations
TP_RAW_DMETHOD;Method
TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing...
TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement...
-TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look.\nPixel Shift is for Pentax Pixel Shift files. It falls back to AMaZE for non-Pixel Shift files.
+TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look.\nPixel Shift is for Pentax/Sony Pixel Shift files. It falls back to AMaZE for non-Pixel Shift files.
TP_RAW_EAHD;EAHD
TP_RAW_FALSECOLOR;False color suppression steps
TP_RAW_FAST;Fast
@@ -1981,7 +1996,7 @@ TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, bu
TP_RAW_HPHD;HPHD
TP_RAW_IGV;IGV
TP_RAW_IMAGENUM;Sub-image
-TP_RAW_IMAGENUM_TOOLTIP;Some raw files consist of several sub-images (Pentax Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel).\n\nWhen using any demosaicing method other than Pixel Shift, this selects which sub-image is used.\n\nWhen using the Pixel Shift demosaicing method on a Pixel Shift raw, all sub-images are used, and this selects which sub-image should be used for moving parts.
+TP_RAW_IMAGENUM_TOOLTIP;Some raw files consist of several sub-images (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel).\n\nWhen using any demosaicing method other than Pixel Shift, this selects which sub-image is used.\n\nWhen using the Pixel Shift demosaicing method on a Pixel Shift raw, all sub-images are used, and this selects which sub-image should be used for moving parts.
TP_RAW_LABEL;Demosaicing
TP_RAW_LMMSE;LMMSE
TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps
@@ -2003,6 +2018,7 @@ TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask
TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask
TP_RAW_PIXELSHIFTLMMSE;Use LMMSE for moving parts
TP_RAW_PIXELSHIFTLMMSE_TOOLTIP;Use LMMSE instead of AMaZE for areas of motion.\nUseful for high ISO images.
+TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP;Use one green instead of averaging two greens for regions without motion.
TP_RAW_PIXELSHIFTMASKTHRESHOLD;3x3 new threshold
TP_RAW_PIXELSHIFTMEDIAN;Use median for moving parts
TP_RAW_PIXELSHIFTMEDIAN3;Exclude selected frame from median
@@ -2021,6 +2037,7 @@ TP_RAW_PIXELSHIFTNONGREENCROSS2;Check green AMaZE
TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Check red/blue horizontal
TP_RAW_PIXELSHIFTNONGREENVERTICAL;Check red/blue vertical
TP_RAW_PIXELSHIFTNREADISO;nRead
+TP_RAW_PIXELSHIFTONEGREEN;Use one green instead of average
TP_RAW_PIXELSHIFTPRNU;PRNU (%)
TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Red&Blue weight
TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask
diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin
index bbc1de057..4ff90246d 100644
--- a/rtdata/options/options.lin
+++ b/rtdata/options/options.lin
@@ -12,8 +12,8 @@ MultiUser=true
[File Browser]
# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include)
-ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
-ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
+ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
+ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
[Output]
PathTemplate=%p1/converted/%f
diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx
index 25696cb85..9130ef9ad 100644
--- a/rtdata/options/options.osx
+++ b/rtdata/options/options.osx
@@ -12,8 +12,8 @@ MultiUser=true
[File Browser]
# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include)
-ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
-ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
+ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
+ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
[Output]
PathTemplate=%p1/converted/%f
diff --git a/rtdata/options/options.win b/rtdata/options/options.win
index 3f309fd16..33ab499be 100644
--- a/rtdata/options/options.win
+++ b/rtdata/options/options.win
@@ -14,8 +14,8 @@ UseSystemTheme=false
[File Browser]
# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include)
-ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
-ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
+ParseExtensions=3fr;arw;arq;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;
+ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;
[Output]
PathTemplate=%p1/converted/%f
diff --git a/rtdata/profiles/Pentax Pixel Shift/PS ISO High.pp3 b/rtdata/profiles/Pixel Shift/PS ISO High.pp3
similarity index 100%
rename from rtdata/profiles/Pentax Pixel Shift/PS ISO High.pp3
rename to rtdata/profiles/Pixel Shift/PS ISO High.pp3
diff --git a/rtdata/profiles/Pentax Pixel Shift/PS ISO Low.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3
similarity index 100%
rename from rtdata/profiles/Pentax Pixel Shift/PS ISO Low.pp3
rename to rtdata/profiles/Pixel Shift/PS ISO Low.pp3
diff --git a/rtdata/profiles/Pentax Pixel Shift/PS ISO Medium.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3
similarity index 100%
rename from rtdata/profiles/Pentax Pixel Shift/PS ISO Medium.pp3
rename to rtdata/profiles/Pixel Shift/PS ISO Medium.pp3
diff --git a/rtdata/profiles/Pentax Pixel Shift/PS No Motion.pp3 b/rtdata/profiles/Pixel Shift/PS No Motion.pp3
similarity index 100%
rename from rtdata/profiles/Pentax Pixel Shift/PS No Motion.pp3
rename to rtdata/profiles/Pixel Shift/PS No Motion.pp3
diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt
index 30880d7d8..6bc2881e6 100644
--- a/rtengine/CMakeLists.txt
+++ b/rtengine/CMakeLists.txt
@@ -116,6 +116,7 @@ set(RTENGINESOURCEFILES
utils.cc
rtlensfun.cc
tmo_fattal02.cc
+ iplocalcontrast.cc
)
if(LENSFUN_HAS_LOAD_DIRECTORY)
diff --git a/rtengine/camconst.json b/rtengine/camconst.json
index 5a3a18fd1..610a22310 100644
--- a/rtengine/camconst.json
+++ b/rtengine/camconst.json
@@ -2285,6 +2285,13 @@ Camera constants:
"ranges": { "black": 800, "white": 16300 }
},
+ { // Quality C,
+ "make_model": "Sony ILCE-7RM3",
+ "dcraw_matrix": [ 6640,-1847,-503,-5238,13010,2474,-993,1673,6527 ], // DNG_v10.1 D65
+ "raw_crop": [ 0, 0, -36, 0 ], // full raw frame 8000x5320 - 36 rightmost columns are garbage
+ "ranges": { "black": 512, "white": 16300 }
+ },
+
{ // Quality C, No proper color data, beta samples, frame set to official jpeg,
"make_model": [ "XIAOYI M1", "YI TECHNOLOGY M1" ],
"dcraw_matrix": [ 7158,-1911,-606,-3603,10669,2530,-659,1236,5530 ], // XIAO YI DNG D65
diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc
index 9ae313530..75891c589 100644
--- a/rtengine/dcraw.cc
+++ b/rtengine/dcraw.cc
@@ -2349,6 +2349,37 @@ void CLASS unpacked_load_raw()
&& (unsigned) (col-left_margin) < width) derror();
}
+
+// RT
+void CLASS sony_arq_load_raw()
+{
+ static unsigned frame2pos[] = { 0, 1, 3, 2 };
+ int row, col, bits=0;
+ ushort samples[4];
+ unsigned frame = frame2pos[shot_select];
+
+ while (1 << ++bits < maximum);
+ for (row=0; row < ((frame < 2) ? 1 : raw_height); row++) {
+ for (col=0; col < ((row == 0) ? raw_width : 1); col++) {
+ RAW(row,col) = 0;
+ }
+ }
+ for (row=0; row < raw_height; row++) {
+ int r = row + (frame & 1);
+ for (col=0; col < raw_width; col++) {
+ int c = col + ((frame >> 1) & 1);
+ read_shorts(samples, 4);
+ if (r < raw_height && c < raw_width) {
+ RAW(r,c) = samples[(2 * (r & 1)) + (c & 1)];
+ if ((RAW(r,c) >>= load_flags) >> bits
+ && (unsigned) (row-top_margin) < height
+ && (unsigned) (col-left_margin) < width) derror();
+ }
+ }
+ }
+}
+
+
void CLASS sinar_4shot_load_raw()
{
ushort *pixel;
@@ -6524,6 +6555,17 @@ void CLASS apply_tiff()
if (!strncmp(make,"OLYMPUS",7) &&
tiff_ifd[raw].bytes*7 > raw_width*raw_height)
load_raw = &CLASS olympus_load_raw;
+ // ------- RT -------
+ if (!strncmp(make,"SONY",4) &&
+ !strncmp(model,"ILCE-7RM3",9) &&
+ tiff_samples == 4 &&
+ tiff_ifd[raw].bytes == raw_width*raw_height*tiff_samples*2) {
+ load_raw = &CLASS sony_arq_load_raw;
+ colors = 3;
+ is_raw = 4;
+ filters = 0x94949494;
+ }
+ // ------------------
}
break;
case 6: case 7: case 99:
diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h
index 0a10f9732..5a2790801 100644
--- a/rtengine/dcraw.h
+++ b/rtengine/dcraw.h
@@ -409,6 +409,7 @@ sony_decrypt_t sony_decrypt;
void sony_load_raw();
void sony_arw_load_raw();
void sony_arw2_load_raw();
+void sony_arq_load_raw(); // RT
void smal_decode_segment (unsigned seg[2][2], int holes);
void smal_v6_load_raw();
diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc
index 47688fca6..f3516e5a8 100644
--- a/rtengine/imagedata.cc
+++ b/rtengine/imagedata.cc
@@ -473,7 +473,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
// ----------------------- Special file type detection (HDR, PixelShift) ------------------------
- uint16 bitspersample = 0, sampleformat = 0, photometric = 0, compression = 0;
+ uint16 bitspersample = 0, samplesperpixel = 0, sampleformat = 0, photometric = 0, compression = 0;
rtexif::Tag* bps = frameRootDir->findTag("BitsPerSample");
rtexif::Tag* spp = frameRootDir->findTag("SamplesPerPixel");
rtexif::Tag* sf = frameRootDir->findTag("SampleFormat");
@@ -535,6 +535,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
}
bitspersample = bps->toInt();
+ samplesperpixel = spp->toInt();
photometric = pi->toInt();
if (photometric == PHOTOMETRIC_LOGLUV) {
@@ -582,6 +583,26 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
sampleFormat = IIOSF_UNSIGNED_SHORT;
}
}
+ } else if (photometric == 34892 || photometric == 32892 /* Linear RAW (see DNG spec ; 32892 seem to be a flaw from Sony's ARQ files) */) {
+ if (sampleformat == SAMPLEFORMAT_IEEEFP) {
+ sampleFormat = IIOSF_FLOAT;
+ isHDR = true;
+#if PRINT_HDR_PS_DETECTION
+ printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat);
+#endif
+ } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) {
+ if (bitspersample == 8) { // shouldn't occur...
+ sampleFormat = IIOSF_UNSIGNED_CHAR;
+ } else if (bitspersample <= 16) {
+ sampleFormat = IIOSF_UNSIGNED_SHORT;
+ if (mnote && (!make.compare (0, 4, "SONY")) && bitspersample >= 12 && samplesperpixel == 4) {
+ isPixelShift = true;
+#if PRINT_HDR_PS_DETECTION
+ printf("PixelShift detected ! -> \"Make\" = SONY, bitsPerPixel > 8, samplesPerPixel == 4\n");
+#endif
+ }
+ }
+ }
} else if (photometric == PHOTOMETRIC_LOGLUV) {
if (compression == COMPRESSION_SGILOG24) {
sampleFormat = IIOSF_LOGLUV24;
@@ -764,7 +785,7 @@ FrameData *FramesData::getFrameData (unsigned int frame) const
bool FramesData::getPixelShift (unsigned int frame) const
{
- // So far only Pentax provide multi-frame HDR file.
+ // So far only Pentax and Sony provide multi-frame HDR file.
// Only the first frame contains the HDR tag
// If more brand have to be supported, this rule may need
// to evolve
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index c35e46cdc..3917b618d 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -4577,7 +4577,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 4fb7a8099..995da9996 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -3438,6 +3438,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;
@@ -4976,6 +4979,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 56acab9f2..334ead522 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -404,9 +404,11 @@ public:
void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float skinprot, float chrom);
void ToneMapFattal02(Imagefloat *rgb);
-
- 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);
+ //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);
// CieImage *ciec;
bool transCoord(int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = 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/pixelshift.cc b/rtengine/pixelshift.cc
index 256aaaf63..511e4c95d 100644
--- a/rtengine/pixelshift.cc
+++ b/rtengine/pixelshift.cc
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////
//
-// Algorithm for Pentax Pixel Shift raw files with motion detection
+// Algorithm for Pentax/Sony Pixel Shift raw files with motion detection
//
// Copyright (C) 2016 - 2017 Ingo Weyrich
//
@@ -294,12 +294,11 @@ void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUTsetProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)));
plistener->setProgress(0.0);
@@ -531,6 +566,9 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA
} else if(model.find("K-1") != string::npos) {
nRead = nReadK1[nReadIndex];
eperIsoModel = ePerIsoK1;
+ } else if(model.find("ILCE-7RM3") != string::npos) {
+ nRead = nReadILCE7RM3[nReadIndex];
+ eperIsoModel = ePerIsoILCE7RM3;
} else { // as long as we don't have values for Pentax KP, we use the values from K-70
nRead = nReadK70[nReadIndex];
eperIsoModel = ePerIsoK70;
@@ -887,11 +925,25 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA
const float blend = smoothFactor == 0.f ? 1.f : pow_F(std::max(psMask[i][j] - 1.f, 0.f), smoothFactor);
#endif
redDest[j + offsX] = intp(blend, redDest[j + offsX], psRed[i][j] );
- greenDest[j + offsX] = intp(blend, greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f);
+ if(bayerParams.pixelShiftOneGreen) {
+ int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset;
+ int greenJ = (1 - offset != 0) ? j : j + 1;
+ int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset;
+ greenDest[j + offsX] = intp(blend, greenDest[j + offsX], (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]);
+ } else {
+ greenDest[j + offsX] = intp(blend, greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f);
+ }
blueDest[j + offsX] = intp(blend, blueDest[j + offsX], psBlue[i][j]);
} else {
redDest[j + offsX] = psRed[i][j];
- greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f;
+ if(bayerParams.pixelShiftOneGreen) {
+ int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset;
+ int greenJ = (1 - offset != 0) ? j : j + 1;
+ int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset;
+ greenDest[j + offsX] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame];
+ } else {
+ greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f;
+ }
blueDest[j + offsX] = psBlue[i][j];
}
}
@@ -924,7 +976,14 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA
for(; j < winw - 1; ++j) {
// set red, green and blue values
- green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f;
+ if(bayerParams.pixelShiftOneGreen) {
+ int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset;
+ int greenJ = (1 - offset != 0) ? j : j + 1;
+ int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset;
+ green[i][j] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame];
+ } else {
+ green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f;
+ }
nonGreenDest0[j] = (*rawDataFrames[(offset << 1) + offset])[i][j + offset] * ngbright[ng][(offset << 1) + offset];
nonGreenDest1[j] = (*rawDataFrames[2 - offset])[i + 1][j - offset + 1] * ngbright[ng ^ 1][2 - offset];
offset ^= 1; // 0 => 1 or 1 => 0
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index b219beecf..e8311025d 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,
@@ -520,7 +520,7 @@ enum ProcEvent {
EvWBEnabled = 490,
EvRGBEnabled = 491,
EvLEnabled = 492,
- EvlocallablocY = 493,
+ EvPixelShiftOneGreen = 493,
EvlocallablocX = 494,
EvlocallabCenter = 495,
EvlocallabDegree = 496,
@@ -624,11 +624,32 @@ enum ProcEvent {
Evlocallabsensiden = 594,
Evlocallabhuerefblur = 595,
EvlocallabEnabled = 596,
-
+ EvlocallablocY = 597,
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 4a296f083..abe17d876 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -594,6 +594,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),
@@ -2721,6 +2749,7 @@ RAWParams::BayerSensor::BayerSensor() :
pixelShiftSmoothFactor(0.7),
pixelShiftExp0(false),
pixelShiftLmmse(false),
+ pixelShiftOneGreen(false),
pixelShiftEqualBright(false),
pixelShiftEqualBrightChannel(false),
pixelShiftNonGreenCross(true),
@@ -2770,6 +2799,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const
&& pixelShiftSmoothFactor == other.pixelShiftSmoothFactor
&& pixelShiftExp0 == other.pixelShiftExp0
&& pixelShiftLmmse == other.pixelShiftLmmse
+ && pixelShiftOneGreen == other.pixelShiftOneGreen
&& pixelShiftEqualBright == other.pixelShiftEqualBright
&& pixelShiftEqualBrightChannel == other.pixelShiftEqualBrightChannel
&& pixelShiftNonGreenCross == other.pixelShiftNonGreenCross
@@ -2808,6 +2838,7 @@ void RAWParams::BayerSensor::setPixelShiftDefaults()
pixelShiftSmoothFactor = 0.7;
pixelShiftExp0 = false;
pixelShiftLmmse = false;
+ pixelShiftOneGreen = false;
pixelShiftEqualBright = false;
pixelShiftEqualBrightChannel = false;
pixelShiftNonGreenCross = true;
@@ -2956,6 +2987,8 @@ void ProcParams::setDefaults()
rgbCurves = RGBCurvesParams();
+ localContrast = LocalContrastParams();
+
colorToning = ColorToningParams();
sharpenEdge = SharpenEdgeParams();
@@ -3125,6 +3158,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);
@@ -3824,6 +3865,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSmooth, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftExp0, "RAW Bayer", "pixelShiftExp0", raw.bayersensor.pixelShiftExp0, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftLmmse, "RAW Bayer", "pixelShiftLmmse", raw.bayersensor.pixelShiftLmmse, keyFile);
+ saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftOneGreen, "RAW Bayer", "pixelShiftOneGreen", raw.bayersensor.pixelShiftOneGreen, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBright, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBrightChannel, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, keyFile);
@@ -4081,6 +4123,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);
@@ -5269,6 +5319,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth);
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftExp0", pedited, raw.bayersensor.pixelShiftExp0, pedited->raw.bayersensor.pixelShiftExp0);
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftLmmse", pedited, raw.bayersensor.pixelShiftLmmse, pedited->raw.bayersensor.pixelShiftLmmse);
+ assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftOneGreen", pedited, raw.bayersensor.pixelShiftOneGreen, pedited->raw.bayersensor.pixelShiftOneGreen);
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright);
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel);
assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross);
@@ -5358,6 +5409,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 379da9692..1eab032a7 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -368,6 +368,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
*/
@@ -1380,6 +1398,7 @@ struct RAWParams {
double pixelShiftSmoothFactor;
bool pixelShiftExp0;
bool pixelShiftLmmse;
+ bool pixelShiftOneGreen;
bool pixelShiftEqualBright;
bool pixelShiftEqualBrightChannel;
bool pixelShiftNonGreenCross;
@@ -1476,6 +1495,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/rawimagesource.cc b/rtengine/rawimagesource.cc
index 33a1d9c53..8ef543f90 100644
--- a/rtengine/rawimagesource.cc
+++ b/rtengine/rawimagesource.cc
@@ -2045,7 +2045,7 @@ void RawImageSource::demosaic (const RAWParams &raw)
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE) ) {
amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue);
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) {
- pixelshift(0, 0, W, H, raw.bayersensor, currFrame, ri->get_model(), raw.expos);
+ pixelshift(0, 0, W, H, raw.bayersensor, currFrame, ri->get_maker(), ri->get_model(), raw.expos);
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCB) ) {
dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance);
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::EAHD)) {
diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h
index 4924b955a..d1496d4fd 100644
--- a/rtengine/rawimagesource.h
+++ b/rtengine/rawimagesource.h
@@ -269,7 +269,7 @@ protected:
void xtransborder_interpolate (int border);
void xtrans_interpolate (const int passes, const bool useCieLab);
void fast_xtrans_interpolate ();
- void pixelshift(int winx, int winy, int winw, int winh, const RAWParams::BayerSensor &bayerParams, unsigned int frame, const std::string &model, float rawWpCorrection);
+ void pixelshift(int winx, int winy, int winw, int winh, const RAWParams::BayerSensor &bayerParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection);
void hflip (Imagefloat* im);
void vflip (Imagefloat* im);
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B);
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 9cb5d24b6..3038bf6b1 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -520,7 +520,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
ALLNORAW, // EvWBEnabled
RGBCURVE, // EvRGBEnabled
LUMINANCECURVE, // EvLEnabled
- LUMINANCECURVE, // EvlocallablocY
+ DEMOSAIC, // EvPixelShiftOneGreen
LUMINANCECURVE, // EvlocallablocX
LUMINANCECURVE, // EvlocallabCenter
LUMINANCECURVE, // EvlocallabDegree
@@ -623,6 +623,49 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // Evlocallabnoisechrodetail
LUMINANCECURVE, // Evlocallabsensiden
LUMINANCECURVE, // Evlocallabhuerefblur
- LUMINANCECURVE // EvlocallabEnabled
+ LUMINANCECURVE, // EvlocallabEnabled
+ LUMINANCECURVE // EvlocallablocY
};
+
+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 8e6e62508..10e337913 100644
--- a/rtengine/rtengine.h
+++ b/rtengine/rtengine.h
@@ -120,7 +120,7 @@ public:
/** @return the orientation of the image */
virtual std::string getOrientation (unsigned int frame = 0) const = 0;
- /** @return true if the file is a PixelShift shot (Pentax bodies) */
+ /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */
virtual bool getPixelShift (unsigned int frame = 0) const = 0;
/** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */
virtual bool getHDR (unsigned int frame = 0) const = 0;
@@ -424,6 +424,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 002ed4ee2..964310d2f 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -149,6 +149,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 7ecd77f85..9cb9cccb5 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -195,6 +195,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]);
@@ -353,6 +354,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/bayerprocess.cc b/rtgui/bayerprocess.cc
index 9df7c106d..b294c9fee 100644
--- a/rtgui/bayerprocess.cc
+++ b/rtgui/bayerprocess.cc
@@ -225,6 +225,11 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
pixelShiftLmmse->set_tooltip_text (M("TP_RAW_PIXELSHIFTLMMSE_TOOLTIP"));
pixelShiftOptions->pack_start(*pixelShiftLmmse);
+// pixelShiftOneGreen = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTONEGREEN"), multiImage));
+// pixelShiftOneGreen->setCheckBoxListener (this);
+// pixelShiftOneGreen->set_tooltip_text (M("TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP"));
+// pixelShiftOptions->pack_start(*pixelShiftOneGreen);
+
#ifdef PIXELSHIFTDEV
pixelShiftMotion = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMOTION"), 0, 100, 1, 70));
pixelShiftMotion->setAdjusterListener (this);
@@ -376,6 +381,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
}
pixelShiftSmooth->setValue (pp->raw.bayersensor.pixelShiftSmoothFactor);
pixelShiftLmmse->setValue (pp->raw.bayersensor.pixelShiftLmmse);
+// pixelShiftOneGreen->setValue (pp->raw.bayersensor.pixelShiftOneGreen);
pixelShiftEqualBright->setValue (pp->raw.bayersensor.pixelShiftEqualBright);
pixelShiftEqualBrightChannel->set_sensitive (pp->raw.bayersensor.pixelShiftEqualBright);
pixelShiftEqualBrightChannel->setValue (pp->raw.bayersensor.pixelShiftEqualBrightChannel);
@@ -427,6 +433,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
pixelShiftBlur->setEdited (pedited->raw.bayersensor.pixelShiftBlur);
pixelShiftSmooth->setEditedState ( pedited->raw.bayersensor.pixelShiftSmooth ? Edited : UnEdited);
pixelShiftLmmse->setEdited (pedited->raw.bayersensor.pixelShiftLmmse);
+// pixelShiftOneGreen->setEdited (pedited->raw.bayersensor.pixelShiftOneGreen);
pixelShiftEqualBright->setEdited (pedited->raw.bayersensor.pixelShiftEqualBright);
pixelShiftEqualBrightChannel->setEdited (pedited->raw.bayersensor.pixelShiftEqualBrightChannel);
pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross);
@@ -531,6 +538,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
pp->raw.bayersensor.pixelShiftBlur = pixelShiftBlur->getLastActive ();
pp->raw.bayersensor.pixelShiftSmoothFactor = pixelShiftSmooth->getValue();
pp->raw.bayersensor.pixelShiftLmmse = pixelShiftLmmse->getLastActive ();
+// pp->raw.bayersensor.pixelShiftOneGreen = pixelShiftOneGreen->getLastActive ();
pp->raw.bayersensor.pixelShiftEqualBright = pixelShiftEqualBright->getLastActive ();
pp->raw.bayersensor.pixelShiftEqualBrightChannel = pixelShiftEqualBrightChannel->getLastActive ();
pp->raw.bayersensor.pixelShiftNonGreenCross = pixelShiftNonGreenCross->getLastActive ();
@@ -583,6 +591,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
pedited->raw.bayersensor.pixelShiftBlur = !pixelShiftBlur->get_inconsistent();
pedited->raw.bayersensor.pixelShiftSmooth = pixelShiftSmooth->getEditedState();
pedited->raw.bayersensor.pixelShiftLmmse = !pixelShiftLmmse->get_inconsistent();
+// pedited->raw.bayersensor.pixelShiftOneGreen = !pixelShiftOneGreen->get_inconsistent();
pedited->raw.bayersensor.pixelShiftEqualBright = !pixelShiftEqualBright->get_inconsistent();
pedited->raw.bayersensor.pixelShiftEqualBrightChannel = !pixelShiftEqualBrightChannel->get_inconsistent();
pedited->raw.bayersensor.pixelShiftNonGreenCross = !pixelShiftNonGreenCross->get_inconsistent();
@@ -849,6 +858,10 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval)
if (listener) {
listener->panelChanged (EvPixelShiftLmmse, pixelShiftLmmse->getValueAsStr ());
}
+// } else if (c == pixelShiftOneGreen) {
+// if (listener) {
+// listener->panelChanged (EvPixelShiftOneGreen, pixelShiftOneGreen->getValueAsStr ());
+// }
} else if (c == pixelShiftEqualBright) {
if (!batchMode) {
pixelShiftEqualBrightChannel->set_sensitive(newval != CheckValue::off);
diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h
index 6d9dd6062..e1a620474 100644
--- a/rtgui/bayerprocess.h
+++ b/rtgui/bayerprocess.h
@@ -49,6 +49,7 @@ protected:
CheckBox* pixelShiftBlur;
CheckBox* pixelShiftHoleFill;
CheckBox* pixelShiftMedian;
+// CheckBox* pixelShiftOneGreen;
CheckBox* pixelShiftLmmse;
CheckBox* pixelShiftEqualBright;
CheckBox* pixelShiftEqualBrightChannel;
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 95b1c9f4f..7a3efd2ef 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;
@@ -237,7 +238,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 a0d56909e..f70f33aa3 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;
@@ -528,6 +533,7 @@ void ParamsEdited::set(bool v)
raw.bayersensor.pixelShiftSmooth = v;
raw.bayersensor.pixelShiftExp0 = v;
raw.bayersensor.pixelShiftLmmse = v;
+ raw.bayersensor.pixelShiftOneGreen = v;
raw.bayersensor.pixelShiftEqualBright = v;
raw.bayersensor.pixelShiftEqualBrightChannel = v;
raw.bayersensor.pixelShiftNonGreenCross = v;
@@ -756,6 +762,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;
@@ -1187,6 +1200,7 @@ void ParamsEdited::initFrom(const std::vector&
raw.bayersensor.pixelShiftSmooth = raw.bayersensor.pixelShiftSmooth && p.raw.bayersensor.pixelShiftSmoothFactor == other.raw.bayersensor.pixelShiftSmoothFactor;
raw.bayersensor.pixelShiftExp0 = raw.bayersensor.pixelShiftExp0 && p.raw.bayersensor.pixelShiftExp0 == other.raw.bayersensor.pixelShiftExp0;
raw.bayersensor.pixelShiftLmmse = raw.bayersensor.pixelShiftLmmse && p.raw.bayersensor.pixelShiftLmmse == other.raw.bayersensor.pixelShiftLmmse;
+ raw.bayersensor.pixelShiftOneGreen = raw.bayersensor.pixelShiftOneGreen && p.raw.bayersensor.pixelShiftOneGreen == other.raw.bayersensor.pixelShiftOneGreen;
raw.bayersensor.pixelShiftEqualBright = raw.bayersensor.pixelShiftEqualBright && p.raw.bayersensor.pixelShiftEqualBright == other.raw.bayersensor.pixelShiftEqualBright;
raw.bayersensor.pixelShiftEqualBrightChannel = raw.bayersensor.pixelShiftEqualBrightChannel && p.raw.bayersensor.pixelShiftEqualBrightChannel == other.raw.bayersensor.pixelShiftEqualBrightChannel;
raw.bayersensor.pixelShiftNonGreenCross = raw.bayersensor.pixelShiftNonGreenCross && p.raw.bayersensor.pixelShiftNonGreenCross == other.raw.bayersensor.pixelShiftNonGreenCross;
@@ -1595,6 +1609,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
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;
}
@@ -3202,6 +3232,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.raw.bayersensor.pixelShiftLmmse = mods.raw.bayersensor.pixelShiftLmmse;
}
+ if (raw.bayersensor.pixelShiftOneGreen) {
+ toEdit.raw.bayersensor.pixelShiftOneGreen = mods.raw.bayersensor.pixelShiftOneGreen;
+ }
+
if (raw.bayersensor.pixelShiftEqualBright) {
toEdit.raw.bayersensor.pixelShiftEqualBright = mods.raw.bayersensor.pixelShiftEqualBright;
}
@@ -3734,7 +3768,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const
return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq
&& pixelShiftMotion && pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod && pixelShiftStddevFactorGreen && pixelShiftStddevFactorRed && pixelShiftStddevFactorBlue && pixelShiftEperIso
&& pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly
- && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel
+ && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftOneGreen && pixelShiftEqualBright && pixelShiftEqualBrightChannel
&& linenoise && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index a47cfb3cb..246b67e91 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
{
@@ -852,6 +863,7 @@ public:
bool pixelShiftSmooth;
bool pixelShiftExp0;
bool pixelShiftLmmse;
+ bool pixelShiftOneGreen;
bool pixelShiftEqualBright;
bool pixelShiftEqualBrightChannel;
bool pixelShiftNonGreenCross;
@@ -908,6 +920,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 3ae11260d..e03fec91d 100644
--- a/rtgui/partialpastedlg.cc
+++ b/rtgui/partialpastedlg.cc
@@ -49,16 +49,17 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
loc ->set_name ("PartialPasteHeader");
// options in basic:
- wb = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_WHITEBALANCE")));
- exposure = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_EXPOSURE")));
- 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")));
- retinex = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_RETINEX")));
- pcvignette = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_PCVIGNETTE")));
- gradient = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_GRADIENT")));
- labcurve = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_LABCURVE")));
- colorappearance = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_COLORAPP")));
+ 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")));
+ retinex = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RETINEX")));
+ pcvignette = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PCVIGNETTE")));
+ gradient = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_GRADIENT")));
+ labcurve = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LABCURVE")));
+ colorappearance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORAPP")));
// options in detail:
sharpen = Gtk::manage (new Gtk::CheckButton (M ("PARTIALPASTE_SHARPENING")));
@@ -146,6 +147,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);
@@ -296,39 +298,41 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
// This can be improved
// there is currently no binding of subsettings to CheckButton 'everything' for its inconsistent status
- everythingConn = everything->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::everythingToggled));
- basicConn = basic->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::basicToggled));
- detailConn = detail->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::detailToggled));
- colorConn = color->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::colorToggled));
- lensConn = lens->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::lensToggled));
- compositionConn = composition->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::compositionToggled));
- metaConn = meta->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::metaToggled));
- rawConn = raw->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::rawToggled));
- wavConn = wav->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::wavToggled));
+ everythingConn = everything->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::everythingToggled));
+ basicConn = basic->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::basicToggled));
+ detailConn = detail->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::detailToggled));
+ colorConn = color->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::colorToggled));
+ lensConn = lens->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::lensToggled));
+ compositionConn = composition->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::compositionToggled));
+ metaConn = meta->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaToggled));
+ rawConn = raw->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::rawToggled));
+ wavConn = wav->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::wavToggled));
// locConn = loc->signal_toggled().connect (sigc::mem_fun (*this, &PartialPasteDlg::locToggled));
- 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));
- 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));
- retinexConn = retinex->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
- pcvignetteConn = pcvignette->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
- gradientConn = gradient->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
- labcurveConn = labcurve->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
- colorappearanceConn = colorappearance->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
+ 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));
+ retinexConn = retinex->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
+ pcvignetteConn = pcvignette->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
+ gradientConn = gradient->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
+ labcurveConn = labcurve->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
+ colorappearanceConn = colorappearance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true));
- sharpenConn = sharpen->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- gradsharpenConn = sharpenedge->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- microcontrastConn = sharpenmicro->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- impdenConn = impden->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- dirpyrdenConn = dirpyrden->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
- defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun (*detail, &Gtk::CheckButton::set_inconsistent), true));
-
- waveletConn = wavelet->signal_toggled().connect (sigc::bind (sigc::mem_fun (*wav, &Gtk::CheckButton::set_inconsistent), true));
+ sharpenConn = sharpen->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ gradsharpenConn = sharpenedge->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ microcontrastConn = sharpenmicro->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ impdenConn = impden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ dirpyrdenConn = dirpyrden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
+ defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
// locallabConn = locallab->signal_toggled().connect (sigc::bind (sigc::mem_fun (*basic, &Gtk::CheckButton::set_inconsistent), true));
- icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun (*color, &Gtk::CheckButton::set_inconsistent), true));
+
+ waveletConn = wavelet->signal_toggled().connect (sigc::bind (sigc::mem_fun(*wav, &Gtk::CheckButton::set_inconsistent), true));
+
+ icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
//gamcsconn = gam->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun (*color, &Gtk::CheckButton::set_inconsistent), true));
chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun (*color, &Gtk::CheckButton::set_inconsistent), true));
@@ -488,6 +492,7 @@ void PartialPasteDlg::basicToggled ()
ConnectionBlocker wbBlocker(wbConn);
ConnectionBlocker exposureBlocker(exposureConn);
+ ConnectionBlocker localcontrastBlocker(localcontrastConn);
ConnectionBlocker shBlocker(shConn);
ConnectionBlocker epdBlocker(epdConn);
ConnectionBlocker fattalBlocker(fattalConn);
@@ -502,6 +507,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 ());
@@ -673,6 +679,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 bb31ce4a4..45500237e 100644
--- a/rtgui/partialpastedlg.h
+++ b/rtgui/partialpastedlg.h
@@ -45,6 +45,7 @@ public:
// options in basic:
Gtk::CheckButton* wb;
Gtk::CheckButton* exposure;
+ Gtk::CheckButton* localcontrast;
Gtk::CheckButton* sh;
Gtk::CheckButton* epd;
Gtk::CheckButton* fattal;
@@ -128,7 +129,7 @@ public:
sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, wavConn, locConn;
- sigc::connection wbConn, exposureConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn, locallabConn;
+ sigc::connection wbConn, exposureConn, localcontrastConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn, locallabConn;
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 fbcd1b683..b9869af7c 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 82327293f..c5bdce9ff 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -42,6 +42,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 ());
@@ -110,6 +111,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);
@@ -328,7 +330,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 ();
@@ -340,7 +342,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);
}
}
@@ -462,7 +464,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 1f6f69760..44a93ac38 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -80,6 +80,7 @@
#include "filmsimulation.h"
#include "prsharpening.h"
#include "fattaltonemap.h"
+#include "localcontrast.h"
#include "guiutils.h"
class ImageEditorCoordinator;
@@ -122,6 +123,7 @@ protected:
Crop* crop;
ToneCurve* toneCurve;
ShadowsHighlights* shadowshighlights;
+ LocalContrast *localContrast;
Defringe* defringe;
ImpulseDenoise* impulsedenoise;
DirPyrDenoise* dirpyrdenoise;