diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20a898dfb..e4ecf0903 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -245,7 +245,6 @@ pkg_check_modules (LCMS REQUIRED lcms2)
find_package (EXPAT REQUIRED expat>=2.0)
pkg_check_modules (FFTW3F REQUIRED fftw3f)
pkg_check_modules (IPTCDATA REQUIRED libiptcdata)
-pkg_check_modules(FFTW3 fftw3)
find_package (JPEG REQUIRED)
find_package (PNG REQUIRED)
find_package (TIFF REQUIRED)
@@ -311,7 +310,7 @@ set(OOSB_FILES "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" "${PROJECT_SOU
if (OUT_OF_SOURCE_BUILD)
foreach(f ${OOSB_FILES})
file (REMOVE "${f}")
- endforeach(f)
+ endforeach(f)
endif ()
# check for generated files in the source tree which should not be there when
@@ -322,7 +321,7 @@ if (OUT_OF_SOURCE_BUILD)
if (EXISTS "${f}")
message (SEND_ERROR "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now.")
endif ()
- endforeach(f)
+ endforeach(f)
endif ()
## BEGIN: Generating AboutThisBuild.txt
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 6bedd3443..69cc20327 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -670,6 +670,7 @@ HISTORY_MSG_436;Retinex - M - Radius
HISTORY_MSG_437;Retinex - M - Method
HISTORY_MSG_438;Retinex - M - Equalizer
HISTORY_MSG_439;Retinex - Preview
+HISTORY_MSG_440;CbDL - method
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -1203,9 +1204,13 @@ TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending
TP_BWMIX_TCMODE_STANDARD;B&W Standard
TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard
TP_BWMIX_VAL;L
-TP_CACORRECTION_BLUE;Blue
-TP_CACORRECTION_LABEL;Chromatic Aberration Correction
-TP_CACORRECTION_RED;Red
+TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space.
+TP_CBDL_AFT;After Black-and-White
+TP_CBDL_BEF;Before Black-and-White
+TP_CBDL_METHOD;Process located
+TP_CBDL_METHOD_TOOLTIP;"After Black and White" located the tool in L*a*b process.\n"Before Black and White" located the tool at the beginning of rgb process.\nObviously this can lead to differences.
+TP_CBDL_AFT;After Black and White
+TP_CBDL_BEF;Before Black and White
TP_CHMIXER_BLUE;Blue channel
TP_CHMIXER_GREEN;Green channel
TP_CHMIXER_LABEL;Channel Mixer
diff --git a/rtengine/color.cc b/rtengine/color.cc
index 82eecb3eb..f5a8c86a3 100644
--- a/rtengine/color.cc
+++ b/rtengine/color.cc
@@ -884,6 +884,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
float somm;
float som = mixerRed + mixerGreen + mixerBlue;
+ if(som >= 0.f && som < 1.f) {
+ som = 1.f;
+ }
+
+ if(som < 0.f && som > -1.f) {
+ som = -1.f;
+ }
+
+
// rM = mixerRed, gM = mixerGreen, bM = mixerBlue !
//presets
if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") {
@@ -945,6 +954,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
bbm = mixerBlue;
somm = mixerRed + mixerGreen + mixerBlue;
+
+ if(somm >= 0.f && somm < 1.f) {
+ somm = 1.f;
+ }
+
+ if(somm < 0.f && somm > -1.f) {
+ somm = -1.f;
+ }
+
mixerRed = mixerRed / somm;
mixerGreen = mixerGreen / somm;
mixerBlue = mixerBlue / somm;
@@ -1160,6 +1178,10 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
mixerGreen = mixerGreen * filgreen;
mixerBlue = mixerBlue * filblue;
+ if(mixerRed + mixerGreen + mixerBlue == 0) {
+ mixerRed += 1.f;
+ }
+
mixerRed = filcor * mixerRed / (mixerRed + mixerGreen + mixerBlue);
mixerGreen = filcor * mixerGreen / (mixerRed + mixerGreen + mixerBlue);
mixerBlue = filcor * mixerBlue / (mixerRed + mixerGreen + mixerBlue);
@@ -1167,6 +1189,14 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
if(filter != "None") {
som = mixerRed + mixerGreen + mixerBlue;
+ if(som >= 0.f && som < 1.f) {
+ som = 1.f;
+ }
+
+ if(som < 0.f && som > -1.f) {
+ som = -1.f;
+ }
+
if(setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") {
kcorec = kcorec * som;
}
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index 89e39c1da..77f0598b4 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -705,6 +705,17 @@ void Crop::update (int todo)
transCrop = NULL;
}
+ if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
+
+ const int W = baseCrop->getWidth();
+ const int H = baseCrop->getHeight();
+ LabImage labcbdl(W, H);
+ parent->ipf.rgb2lab(*baseCrop, labcbdl, params.icm.working);
+ parent->ipf.dirpyrequalizer (&labcbdl, skip);
+ parent->ipf.lab2rgb(labcbdl, *baseCrop, params.icm.working);
+
+ }
+
// blurmap for shadow & highlights
if ((todo & M_BLURMAP) && params.sh.enabled) {
double radius = sqrt (double(SKIPS(parent->fw, skip) * SKIPS(parent->fw, skip) + SKIPS(parent->fh, skip) * SKIPS(parent->fh, skip))) / 2.0;
@@ -725,6 +736,7 @@ void Crop::update (int todo)
}
}
+
// shadows & highlights & tone curve & convert to cielab
/*int xref,yref;
xref=000;yref=000;
@@ -831,12 +843,13 @@ void Crop::update (int todo)
// if (skip==1) {
WaveletParams WaveParams = params.wavelet;
- if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
- parent->ipf.dirpyrequalizer (labnCrop, skip);
- // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip);
+ if(params.dirpyrequalizer.cbdlMethod == "aft") {
+ if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) {
+ parent->ipf.dirpyrequalizer (labnCrop, skip);
+ // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip);
+ }
}
-
int kall = 0;
int minwin = min(labnCrop->W, labnCrop->H);
int maxlevelcrop = 10;
diff --git a/rtengine/imagedimensions.h b/rtengine/imagedimensions.h
index 0b50d71c1..e3b98f7c5 100644
--- a/rtengine/imagedimensions.h
+++ b/rtengine/imagedimensions.h
@@ -48,11 +48,11 @@ public:
{
return height;
}
- int getWidth ()
+ int getWidth () const
{
return width;
}
- int getHeight ()
+ int getHeight () const
{
return height;
}
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index ee75e831a..2f14c1ded 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -242,7 +242,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
- if ((todo & (M_RETINEX|M_INIT)) && params.retinex.enabled) {
+ if ((todo & (M_RETINEX | M_INIT)) && params.retinex.enabled) {
bool dehacontlutili = false;
bool mapcontlutili = false;
bool useHsl = false;
@@ -388,8 +388,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(),
imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false);
- readyphase++;
+ if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
+ const int W = oprevi->getWidth();
+ const int H = oprevi->getHeight();
+ LabImage labcbdl(W, H);
+ ipf.rgb2lab(*oprevi, labcbdl, params.icm.working);
+ ipf.dirpyrequalizer (&labcbdl, scale);
+ ipf.lab2rgb(labcbdl, *oprevi, params.icm.working);
+ }
+ readyphase++;
progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases);
if ((todo & M_BLURMAP) && params.sh.enabled) {
@@ -407,6 +415,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale);
}
+
+
readyphase++;
if (todo & M_AUTOEXP) {
@@ -439,6 +449,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale == 1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1);
+
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
@@ -656,15 +667,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
*/
- //if (scale==1) {
- if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
- progress ("Pyramid wavelet...", 100 * readyphase / numofphases);
- ipf.dirpyrequalizer (nprevl, scale);
- //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale);
- readyphase++;
+ if(params.dirpyrequalizer.cbdlMethod == "aft") {
+ if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ) {
+ progress ("Pyramid wavelet...", 100 * readyphase / numofphases);
+ ipf.dirpyrequalizer (nprevl, scale);
+ //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale);
+ readyphase++;
+ }
}
- //}
wavcontlutili = false;
//CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip);
@@ -782,6 +793,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
}
+
// Update the monitor color transform if necessary
if (todo & M_MONITOR) {
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 4c1e4ef2f..339f5e07a 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -52,17 +52,6 @@ namespace rtengine
using namespace procparams;
-#undef ABS
-#undef CLIPS
-#undef CLIPC
-
-#define ABS(a) ((a)<0?-(a):(a))
-#define CLIPS(a) ((a)>-32768?((a)<32767?(a):32767):-32768)
-#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000)
-#define CLIP2(a) ((a)0.0?((a)<65535.5?(a):65535.5):0.0)
-
-
extern const Settings* settings;
ImProcFunctions::~ImProcFunctions ()
@@ -3394,10 +3383,22 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f;
}
- if (hasColorToning || blackwhite) {
+ if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) {
tmpImage = new Imagefloat(working->width, working->height);
}
+ int W = working->width;
+ int H = working->height;
+
+
+
+
+
+
+
+
+
+
#define TS 112
#ifdef _OPENMP
@@ -4190,48 +4191,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
}
}
- //Film Simulations
- if ( colorLUT ) {
- for (int i = istart, ti = 0; i < tH; i++, ti++) {
- for (int j = jstart, tj = 0; j < tW; j++, tj++) {
- float &sourceR = rtemp[ti * TS + tj];
- float &sourceG = gtemp[ti * TS + tj];
- float &sourceB = btemp[ti * TS + tj];
-
- if (!clutAndWorkingProfilesAreSame) {
- //convert from working to clut profile
- float x, y, z;
- Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz );
- Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut );
- }
-
- //appply gamma sRGB (default RT)
- sourceR = CLIP( Color::gamma_srgb( sourceR ) );
- sourceG = CLIP( Color::gamma_srgb( sourceG ) );
- sourceB = CLIP( Color::gamma_srgb( sourceB ) );
-
- float r, g, b;
- colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b );
- // apply strength
- sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength;
- sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength;
- sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength;
- // apply inverse gamma sRGB
- sourceR = Color::igamma_srgb( sourceR );
- sourceG = Color::igamma_srgb( sourceG );
- sourceB = Color::igamma_srgb( sourceB );
-
- if (!clutAndWorkingProfilesAreSame) {
- //convert from clut to working profile
- float x, y, z;
- Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz );
- Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work );
- }
-
- }
- }
- }
-
//black and white
if(blackwhite) {
if (hasToneCurvebw1) {
@@ -4378,6 +4337,50 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
}
}
+
+ //Film Simulations
+ if ( colorLUT ) {
+ for (int i = istart, ti = 0; i < tH; i++, ti++) {
+ for (int j = jstart, tj = 0; j < tW; j++, tj++) {
+ float &sourceR = rtemp[ti * TS + tj];
+ float &sourceG = gtemp[ti * TS + tj];
+ float &sourceB = btemp[ti * TS + tj];
+
+ if (!clutAndWorkingProfilesAreSame) {
+ //convert from working to clut profile
+ float x, y, z;
+ Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz );
+ Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut );
+ }
+
+ //appply gamma sRGB (default RT)
+ sourceR = CLIP( Color::gamma_srgb( sourceR ) );
+ sourceG = CLIP( Color::gamma_srgb( sourceG ) );
+ sourceB = CLIP( Color::gamma_srgb( sourceB ) );
+
+ float r, g, b;
+ colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b );
+ // apply strength
+ sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength;
+ sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength;
+ sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength;
+ // apply inverse gamma sRGB
+ sourceR = Color::igamma_srgb( sourceR );
+ sourceG = Color::igamma_srgb( sourceG );
+ sourceB = Color::igamma_srgb( sourceB );
+
+ if (!clutAndWorkingProfilesAreSame) {
+ //convert from clut to working profile
+ float x, y, z;
+ Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz );
+ Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work );
+ }
+
+ }
+ }
+ }
+
+
if(!blackwhite) {
// ready, fill lab
for (int i = istart, ti = 0; i < tH; i++, ti++) {
@@ -6456,7 +6459,6 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl
void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale)
{
-
if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) {
float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
@@ -7064,8 +7066,79 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si
}
}
+void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace)
+{
+ TMatrix wprof = iccStore->workingSpaceMatrix( workingSpace );
+ const float wp[3][3] = {
+ {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])},
+ {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])},
+ {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])}
+ };
+
+ const int W = src.getWidth();
+ const int H = src.getHeight();
+
+#ifdef _OPENMP
+ #pragma omp parallel for schedule(dynamic,16)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float X, Y, Z;
+ Color::rgbxyz(src.r(i, j), src.g(i, j), src.b(i, j), X, Y, Z, wp);
+ //convert Lab
+ Color::XYZ2Lab(X, Y, Z, dst.L[i][j], dst.a[i][j], dst.b[i][j]);
+ }
+ }
+}
+
+SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace)
+{
+ TMatrix wiprof = iccStore->workingSpaceInverseMatrix( workingSpace );
+ const float wip[3][3] = {
+ {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])},
+ {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])},
+ {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])}
+ };
+
+ const int W = dst.getWidth();
+ const int H = dst.getHeight();
+#ifdef __SSE2__
+ vfloat wipv[3][3];
+
+ for(int i = 0; i < 3; i++) {
+ for(int j = 0; j < 3; j++) {
+ wipv[i][j] = F2V(wiprof[i][j]);
+ }
+ }
+#endif
+
+#ifdef _OPENMP
+ #pragma omp parallel for schedule(dynamic,16)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ int j = 0;
+#ifdef __SSE2__
+ for(; j < W - 3; j += 4) {
+ vfloat X, Y, Z;
+ vfloat R,G,B;
+ Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z);
+ Color::xyz2rgb(X, Y, Z, R, G, B, wipv);
+ STVFU(dst.r(i, j), R);
+ STVFU(dst.g(i, j), G);
+ STVFU(dst.b(i, j), B);
+ }
+
+#endif
+ for(; j < W; j++) {
+ float X, Y, Z;
+ Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z);
+ Color::xyz2rgb(X, Y, Z, dst.r(i, j), dst.g(i, j), dst.b(i, j), wip);
+ }
+ }
+}
+
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}
-#undef PIX_SORT
-#undef med3x3
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index 74cd10ce9..90a046149 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -282,6 +282,7 @@ public:
void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise
void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet
+
void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0);
float *CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed);
void ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx);
@@ -379,6 +380,8 @@ public:
static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh);
static double getAutoDistor (const Glib::ustring& fname, int thumb_size);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL);
+ void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace);
+ void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace);
};
}
#endif
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 558f509c2..3d4f90af1 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -466,7 +466,9 @@ enum ProcEvent {
EvmapMethod = 436,
EvRetinexmapcurve = 437,
EvviewMethod = 438,
+ EvcbdlMethod = 439,
NUMOFEVENTS
+
};
}
#endif
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 8b3723168..bbe5daeaa 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -1217,6 +1217,8 @@ void ProcParams::setDefaults ()
dirpyrequalizer.enabled = false;
dirpyrequalizer.gamutlab = false;
+ dirpyrequalizer.cbdlMethod = "bef";
+
for(int i = 0; i < 6; i ++) {
dirpyrequalizer.mult[i] = 1.0;
@@ -3030,6 +3032,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab);
}
+ if (!pedited || pedited->dirpyrequalizer.cbdlMethod) {
+ keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod);
+ }
+
for(int i = 0; i < 6; i++) {
std::stringstream ss;
ss << "Mult" << i;
@@ -6616,6 +6622,16 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+
+ if (keyFile.has_key ("Directional Pyramid Equalizer", "cbdlMethod")) {
+ dirpyrequalizer.cbdlMethod = keyFile.get_string ("Directional Pyramid Equalizer", "cbdlMethod");
+
+ if (pedited) {
+ pedited->dirpyrequalizer.cbdlMethod = true;
+ }
+ }
+
+
// if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; }
if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) {
Glib::ArrayHandle thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin");
@@ -7888,6 +7904,7 @@ bool ProcParams::operator== (const ProcParams& other)
// && dirpyrequalizer.algo == other.dirpyrequalizer.algo
&& dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin
&& dirpyrequalizer.threshold == other.dirpyrequalizer.threshold
+ && dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod
&& dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect
&& hsvequalizer.hcurve == other.hsvequalizer.hcurve
&& hsvequalizer.scurve == other.hsvequalizer.scurve
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 47b8f1cf1..b68db845c 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1106,7 +1106,7 @@ public:
double skinprotect;
Threshold hueskin;
//Glib::ustring algo;
-
+ Glib::ustring cbdlMethod;
DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {};
};
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 6a2925be9..1bcaf3fa3 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
ALLNORAW, // EvDPDNLuma,
ALLNORAW, // EvDPDNChroma,
ALLNORAW, // EvDPDNGamma,
- DIRPYREQUALIZER, // EvDirPyrEqualizer,
- DIRPYREQUALIZER, // EvDirPyrEqlEnabled,
+ ALLNORAW, // EvDirPyrEqualizer,
+ ALLNORAW, // EvDirPyrEqlEnabled,
LUMINANCECURVE, // EvLSaturation,
LUMINANCECURVE, // EvLaCurve,
LUMINANCECURVE, // EvLbCurve,
@@ -200,7 +200,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvLLCCurve
LUMINANCECURVE, // EvLLCredsk
ALLNORAW, // EvDPDNLdetail
- LUMINANCECURVE, // EvCATEnabled
+ ALLNORAW, // EvCATEnabled
LUMINANCECURVE, // EvCATDegree
LUMINANCECURVE, // EvCATMethodsur
LUMINANCECURVE, // EvCATAdapscen
@@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvLCLCurve
LUMINANCECURVE, // EvLLHCurve
LUMINANCECURVE, // EvLHHCurve
- DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold
+ ALLNORAW, // EvDirPyrEqualizerThreshold
ALLNORAW, // EvDPDNenhance
RGBCURVE, // EvBWMethodalg
- DIRPYREQUALIZER, // EvDirPyrEqualizerSkin
- DIRPYREQUALIZER, // EvDirPyrEqlgamutlab
- DIRPYREQUALIZER, // EvDirPyrEqualizerHueskin
+ ALLNORAW, // EvDirPyrEqualizerSkin
+ ALLNORAW, // EvDirPyrEqlgamutlab
+ ALLNORAW, // EvDirPyrEqualizerHueskin
ALLNORAW, // EvDPDNmedian
ALLNORAW, // EvDPDNmedmet
RGBCURVE, // EvColorToningEnabled
@@ -465,6 +465,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLradius
RETINEX, // EvmapMethod
DEMOSAIC, // EvRetinexmapcurve
- DEMOSAIC // EvviewMethod
+ DEMOSAIC, // EvviewMethod
+ ALLNORAW // EvcbdlMethod
};
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 9ae940980..c03addb42 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -739,6 +739,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
baseImg = trImg;
}
+
+ if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
+ const int W = baseImg->getWidth();
+ const int H = baseImg->getHeight();
+ LabImage labcbdl(W, H);
+ ipf.rgb2lab(*baseImg, labcbdl, params.icm.working);
+ ipf.dirpyrequalizer (&labcbdl, 1);
+ ipf.lab2rgb(labcbdl, *baseImg, params.icm.working);
+ }
+
// update blurmap
SHMap* shmap = NULL;
@@ -982,9 +992,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL );
+
// directional pyramid wavelet
- if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) {
- ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one
+ if(params.dirpyrequalizer.cbdlMethod == "aft") {
+ if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) {
+ ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one
+ }
}
int kall = 2;
diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc
index 5d8a7011e..7996a340e 100644
--- a/rtgui/dirpyrequalizer.cc
+++ b/rtgui/dirpyrequalizer.cc
@@ -51,6 +51,24 @@ DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer",
Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b);
milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5
+ Gtk::VBox * cbVBox = Gtk::manage ( new Gtk::VBox());
+ cbVBox->set_border_width(4);
+ cbVBox->set_spacing(2);
+
+ cdbox = Gtk::manage (new Gtk::HBox ());
+ labmcd = Gtk::manage (new Gtk::Label (M("TP_CBDL_METHOD") + ":"));
+ cdbox->pack_start (*labmcd, Gtk::PACK_SHRINK, 1);
+
+ cbdlMethod = Gtk::manage (new MyComboBoxText ());
+ cbdlMethod->append_text (M("TP_CBDL_BEF"));
+ cbdlMethod->append_text (M("TP_CBDL_AFT"));
+ cbdlMethod->set_active(0);
+ cbdlMethodConn = cbdlMethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrEqualizer::cbdlMethodChanged) );
+ cbdlMethod->set_tooltip_markup (M("TP_CBDL_METHOD_TOOLTIP"));
+ cdbox->pack_start(*cbdlMethod);
+ cbVBox->pack_start(*cdbox);
+ pack_start(*cbVBox);
+
setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP"));
Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10));
@@ -146,12 +164,17 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited)
{
disableListener ();
+ cbdlMethodConn.block(true);
if (pedited) {
set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled);
gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab);
+ if (!pedited->dirpyrequalizer.cbdlMethod) {
+ cbdlMethod->set_active_text(M("GENERAL_UNCHANGED"));
+ }
+
for(int i = 0; i < 6; i++) {
multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited);
}
@@ -187,6 +210,15 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited)
skinprotect->setValue(pp->dirpyrequalizer.skinprotect);
hueskin->setValue(pp->dirpyrequalizer.hueskin);
+ if (pp->dirpyrequalizer.cbdlMethod == "bef") {
+ cbdlMethod->set_active (0);
+ } else if (pp->dirpyrequalizer.cbdlMethod == "aft") {
+ cbdlMethod->set_active (1);
+ }
+
+ cbdlMethodChanged ();
+ cbdlMethodConn.block(false);
+
enableListener ();
}
@@ -208,6 +240,7 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited)
pedited->dirpyrequalizer.enabled = !get_inconsistent();
pedited->dirpyrequalizer.hueskin = hueskin->getEditedState ();
+ pedited->dirpyrequalizer.cbdlMethod = cbdlMethod->get_active_text() != M("GENERAL_UNCHANGED");
for(int i = 0; i < 6; i++) {
pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState();
@@ -218,6 +251,13 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited)
// pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED");
}
+
+ if (cbdlMethod->get_active_row_number() == 0) {
+ pp->dirpyrequalizer.cbdlMethod = "bef";
+ } else if (cbdlMethod->get_active_row_number() == 1) {
+ pp->dirpyrequalizer.cbdlMethod = "aft";
+ }
+
/* if (algo->get_active_row_number()==0)
pp->dirpyrequalizer.algo = "FI";
else if (algo->get_active_row_number()==1)
@@ -282,6 +322,16 @@ void DirPyrEqualizer::setBatchMode (bool batchMode)
// algo->append_text (M("GENERAL_UNCHANGED"));
}
+void DirPyrEqualizer::cbdlMethodChanged()
+{
+
+ if (listener) {
+ listener->panelChanged (EvcbdlMethod, cbdlMethod->get_active_text ());
+ }
+}
+
+
+
void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval)
{
diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h
index 6c0a4613d..9b806989c 100644
--- a/rtgui/dirpyrequalizer.h
+++ b/rtgui/dirpyrequalizer.h
@@ -45,6 +45,10 @@ protected:
sigc::connection lumaneutralPressedConn;
sigc::connection lumacontrastPlusPressedConn;
sigc::connection lumacontrastMinusPressedConn;
+ sigc::connection cbdlMethodConn;
+ Gtk::Label* labmcd;
+ Gtk::HBox* cdbox;
+ MyComboBoxText* cbdlMethod;
bool lastgamutlab;
@@ -61,7 +65,7 @@ public:
void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight);
// void algoChanged ();
-
+ void cbdlMethodChanged();
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged();
void gamutlabToggled ();
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 062c61ba2..30d44f476 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -487,6 +487,8 @@ void ParamsEdited::set (bool v)
dirpyrequalizer.enabled = v;
dirpyrequalizer.gamutlab = v;
+ dirpyrequalizer.cbdlMethod = v;
+
for(int i = 0; i < 6; i++) {
dirpyrequalizer.mult[i] = v;
@@ -973,6 +975,7 @@ void ParamsEdited::initFrom (const std::vector
dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled;
dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab;
+ dirpyrequalizer.cbdlMethod = dirpyrequalizer.cbdlMethod && p.dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod;
for(int i = 0; i < 6; i++) {
dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i];
@@ -2700,6 +2703,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab;
}
+ if (dirpyrequalizer.cbdlMethod) {
+ toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod;
+ }
+
for(int i = 0; i < 6; i++) {
if(dirpyrequalizer.mult[i]) {
toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i];
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 261da1753..3a0105c55 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -647,7 +647,7 @@ public:
bool enabled;
bool gamutlab;
bool mult[6];
-
+ bool cbdlMethod;
bool threshold;
bool skinprotect;
bool hueskin;