diff --git a/rtdata/languages/default b/rtdata/languages/default
index 6bedd3443..553fc4a4b 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
@@ -1206,6 +1207,10 @@ TP_BWMIX_VAL;L
TP_CACORRECTION_BLUE;Blue
TP_CACORRECTION_LABEL;Chromatic Aberration Correction
TP_CACORRECTION_RED;Red
+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 c0dbab4d3..56880833b 100644
--- a/rtengine/color.cc
+++ b/rtengine/color.cc
@@ -808,6 +808,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") {
@@ -869,6 +878,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;
@@ -1084,6 +1102,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);
@@ -1091,6 +1113,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 2220f68c5..6eb60988c 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -712,6 +712,75 @@ void Crop::update (int todo)
transCrop = NULL;
}
+ if ((todo && (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) {
+
+ if( (!params.colorappearance.enabled )) {
+ TMatrix wprof, wiprof;
+ wprof = iccStore->workingSpaceMatrix( params.icm.working );
+ wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working );
+ double wip[3][3] = {
+ {wiprof[0][0], wiprof[0][1], wiprof[0][2]},
+ {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
+ {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
+ };
+
+ double wp[3][3] = {
+ {wprof[0][0], wprof[0][1], wprof[0][2]},
+ {wprof[1][0], wprof[1][1], wprof[1][2]},
+ {wprof[2][0], wprof[2][1], wprof[2][2]}
+ };
+
+ int W = baseCrop->getWidth();
+ int H = baseCrop->getHeight();
+ LabImage * labcbdl;
+ labcbdl = new LabImage(W, H);
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float r = baseCrop->r(i, j);
+ float g = baseCrop->g(i, j);
+ float b = baseCrop->b(i, j);
+ float X, Y, Z;
+ float L, aa, bb;
+ Color::rgbxyz(r, g, b, X, Y, Z, wp);
+ //convert Lab
+ Color::XYZ2Lab(X, Y, Z, L, aa, bb);
+ labcbdl->L[i][j] = L;
+ labcbdl->a[i][j] = aa;
+ labcbdl->b[i][j] = bb;
+ }
+ }
+
+ parent->ipf.dirpyrequalizer (labcbdl, skip, 0);
+
+
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float L = labcbdl->L[i][j];
+ float a = labcbdl->a[i][j];
+ float b = labcbdl->b[i][j];
+ float x1, y1, z1;
+ float R, G, B;
+ Color::Lab2XYZ(L, a, b, x1, y1, z1);
+ Color::xyz2rgb(x1, y1, z1, R, G, B, wip);
+ baseCrop->r(i, j) = R;
+ baseCrop->g(i, j) = G;
+ baseCrop->b(i, j) = B;
+ }
+ }
+
+ delete labcbdl;
+
+ }
+ }
+
// 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;
@@ -732,6 +801,7 @@ void Crop::update (int todo)
}
}
+
// shadows & highlights & tone curve & convert to cielab
/*int xref,yref;
xref=000;yref=000;
@@ -838,12 +908,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, 1);
+ // 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/improccoordinator.cc b/rtengine/improccoordinator.cc
index ee75e831a..84b4412ba 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;
@@ -392,6 +392,73 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases);
+ if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) {
+ if(((!params.colorappearance.enabled))) {
+ TMatrix wprof, wiprof;
+ wprof = iccStore->workingSpaceMatrix( params.icm.working );
+ wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working );
+ double wip[3][3] = {
+ {wiprof[0][0], wiprof[0][1], wiprof[0][2]},
+ {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
+ {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
+ };
+
+ double wp[3][3] = {
+ {wprof[0][0], wprof[0][1], wprof[0][2]},
+ {wprof[1][0], wprof[1][1], wprof[1][2]},
+ {wprof[2][0], wprof[2][1], wprof[2][2]}
+ };
+
+ int W = oprevi->getWidth();
+ int H = oprevi->getHeight();
+ LabImage * labcbdl;
+ labcbdl = new LabImage(W, H);
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float r = oprevi->r(i, j);
+ float g = oprevi->g(i, j);
+ float b = oprevi->b(i, j);
+ float X, Y, Z;
+ float L, aa, bb;
+ Color::rgbxyz(r, g, b, X, Y, Z, wp);
+ //convert Lab
+ Color::XYZ2Lab(X, Y, Z, L, aa, bb);
+ labcbdl->L[i][j] = L;
+ labcbdl->a[i][j] = aa;
+ labcbdl->b[i][j] = bb;
+ }
+ }
+
+ ipf.dirpyrequalizer (labcbdl, scale, 0);
+
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float L = labcbdl->L[i][j];
+ float a = labcbdl->a[i][j];
+ float b = labcbdl->b[i][j];
+ float x1, y1, z1;
+ float R, G, B;
+ Color::Lab2XYZ(L, a, b, x1, y1, z1);
+ Color::xyz2rgb(x1, y1, z1, R, G, B, wip);
+ oprevi->r(i, j) = R;
+ oprevi->g(i, j) = G;
+ oprevi->b(i, j) = B;
+ }
+ }
+
+ delete labcbdl;
+
+ }
+ }
+
if ((todo & M_BLURMAP) && params.sh.enabled) {
double radius = sqrt (double(pW * pW + pH * pH)) / 2.0;
double shradius = params.sh.radius;
@@ -407,6 +474,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 +508,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 +726,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, 1);
+ //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 +852,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 b1f47c3a9..87c51dd64 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -3421,10 +3421,22 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
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
@@ -4217,48 +4229,48 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
}
}
- //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];
+ /* //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 );
- }
+ 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 ) );
+ //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 );
+ 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 (!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) {
@@ -4405,6 +4417,50 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
}
}
+
+ //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++) {
@@ -6481,8 +6537,9 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl
}
}
-void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale)
+void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale, int mode)
{
+ printf("mode=%d\n", mode);
if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) {
float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index 44224fa2e..f69f04e19 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -284,7 +284,8 @@ public:
void impulse_nrcam (CieImage* ncie, double thresh, float **buffers[3]);
void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise
- void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet
+ void dirpyrequalizer (LabImage* lab, int scale, int mode);//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);
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 f79f51c91..fcdd9fa0f 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -1219,7 +1219,9 @@ void ProcParams::setDefaults ()
dirpyrequalizer.enabled = false;
dirpyrequalizer.gamutlab = false;
+ dirpyrequalizer.cbdlMethod = "aft";
+
for(int i = 0; i < 6; i ++) {
dirpyrequalizer.mult[i] = 1.0;
}
@@ -3028,6 +3030,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;
@@ -6610,6 +6616,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");
@@ -7880,6 +7896,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..292a54133 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,
@@ -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..06bd755e4 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -739,6 +739,74 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
baseImg = trImg;
}
+
+ if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) {
+ if(((!params.colorappearance.enabled))) {
+ TMatrix wprof, wiprof;
+ wprof = iccStore->workingSpaceMatrix( params.icm.working );
+ wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working );
+ double wip[3][3] = {
+ {wiprof[0][0], wiprof[0][1], wiprof[0][2]},
+ {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
+ {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
+ };
+
+ double wp[3][3] = {
+ {wprof[0][0], wprof[0][1], wprof[0][2]},
+ {wprof[1][0], wprof[1][1], wprof[1][2]},
+ {wprof[2][0], wprof[2][1], wprof[2][2]}
+ };
+
+ int W = baseImg->getWidth();
+ int H = baseImg->getHeight();
+ LabImage * labcbdl;
+ labcbdl = new LabImage(W, H);
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float r = baseImg->r(i, j);
+ float g = baseImg->g(i, j);
+ float b = baseImg->b(i, j);
+ float X, Y, Z;
+ float L, aa, bb;
+ Color::rgbxyz(r, g, b, X, Y, Z, wp);
+ //convert Lab
+ Color::XYZ2Lab(X, Y, Z, L, aa, bb);
+ labcbdl->L[i][j] = L;
+ labcbdl->a[i][j] = aa;
+ labcbdl->b[i][j] = bb;
+ }
+ }
+
+ ipf.dirpyrequalizer (labcbdl, 1, 0);
+
+#ifndef _DEBUG
+ #pragma omp parallel for schedule(dynamic, 10)
+#endif
+
+ for(int i = 0; i < H; i++) {
+ for(int j = 0; j < W; j++) {
+ float L = labcbdl->L[i][j];
+ float a = labcbdl->a[i][j];
+ float b = labcbdl->b[i][j];
+ float x1, y1, z1;
+ float R, G, B;
+ Color::Lab2XYZ(L, a, b, x1, y1, z1);
+ Color::xyz2rgb(x1, y1, z1, R, G, B, wip);
+ baseImg->r(i, j) = R;
+ baseImg->g(i, j) = G;
+ baseImg->b(i, j) = B;
+ }
+ }
+
+ delete labcbdl;
+
+ }
+ }
+
// update blurmap
SHMap* shmap = NULL;
@@ -982,9 +1050,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, 2); //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;