diff --git a/rtdata/languages/default b/rtdata/languages/default
index ee6952559..aeb5664e8 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -641,7 +641,7 @@ HISTORY_MSG_408;Retinex - Neighboring
HISTORY_MSG_409;Retinex - Gain
HISTORY_MSG_410;Retinex - Offset
HISTORY_MSG_411;Retinex - Strength
-HISTORY_MSG_412;Retinex - Scales
+HISTORY_MSG_412;Retinex - G. Gradient
HISTORY_MSG_413;Retinex - Variance
HISTORY_MSG_414;Retinex - Histogram - Lab
HISTORY_MSG_415;Retinex - Transmission
@@ -656,6 +656,8 @@ HISTORY_MSG_423;Retinex - Gamma slope
HISTORY_MSG_424;Retinex - HL threshold
HISTORY_MSG_425;Retinex - Log base
HISTORY_MSG_426;Retinex - Hue equalizer
+HISTORY_MSG_427;Retinex - Iterations
+HISTORY_MSG_428;Retinex - T. Gradient
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOTS;Snapshots
@@ -1654,6 +1656,10 @@ TP_RETINEX_HIGHLIG;Highlight
TP_RETINEX_HIGH;High
TP_RETINEX_HSLSPACE_LIN;HSL-Linear
TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic
+TP_RETINEX_ITER;Iterations (Tone-mapping)
+TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator\nHigh values increase the processing time
+TP_RETINEX_GRAD;Transmission gradient
+TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Variance and Threshold are reduce when iteration increases and conversely
TP_RETINEX_LABEL;Retinex
TP_RETINEX_LABSPACE;L*a*b*
TP_RETINEX_LOW;Low
@@ -1667,6 +1673,8 @@ TP_RETINEX_NEUTRAL;Reset
TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values.
TP_RETINEX_OFFSET;Offset
TP_RETINEX_SETTINGS;Settings
+TP_RETINEX_SCALES;Gaussian gradient
+TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Scale and Neighboring pixels are reduce when iteration increases and conversely
TP_RETINEX_SLOPE;Free gamma slope
TP_RETINEX_STRENGTH;Strength
TP_RETINEX_THRESHOLD;Threshold
diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc
index 54d5d3515..1f6602b62 100644
--- a/rtengine/ipretinex.cc
+++ b/rtengine/ipretinex.cc
@@ -217,10 +217,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
float gain2 = (float) deh.gain / 100.f; //def =1 not use
gain2 = useHslLin ? gain2 * 0.5f : gain2;
float offse = (float) deh.offs; //def = 0 not use
- int scal = deh.scal; //def=3
- scal = 3;//disabled scal
+ int iter = deh.iter;
+ int gradient = deh.scal;
+ int scal = 3;//disabled scal
int nei = (int) 2.8f * deh.neigh; //def = 220
float vart = (float)deh.vart / 100.f;//variance
+ float gradvart = (float)deh.grad;
float strength = (float) deh.str / 100.f; // Blend with original L channel data
float limD = (float) deh.limd;
limD = pow(limD, 1.7f);//about 2500 enough
@@ -271,283 +273,342 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
if (deh.retinexMethod == "highli" || deh.retinexMethod == "highliplus") {
moderetinex = 3;
}
-
- float aahi = 49.f / 99.f; ////reduce sensibility 50%
- float bbhi = 1.f - aahi;
- float high;
- high = bbhi + aahi * (float) deh.highl;
- retinex_scales( RetinexScales, scal, moderetinex, nei, high );
-
- int H_L = height;
- int W_L = width;
-
- float *src[H_L] ALIGNED16;
- float *srcBuffer = new float[H_L * W_L];
-
- for (int i = 0; i < H_L; i++) {
- src[i] = &srcBuffer[i * W_L];
- }
-
-#ifdef _OPENMP
- #pragma omp parallel for
-#endif
-
- for (int i = 0; i < H_L; i++)
- for (int j = 0; j < W_L; j++) {
- src[i][j] = luminance[i][j] + eps;
- luminance[i][j] = 0.f;
+ for(int it=1; it= 0; scale-- ) {
- if(scale == scal - 1) {
- gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer);
- } else { // reuse result of last iteration
- gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
+ else if(gradient==1) {
+ grad=0.25f*it+0.75f;
+ sc=-0.5f*it+4.5f;
+ }
+ else if(gradient==2) {
+ grad=0.5f*it+0.5f;
+ sc=-it+6.f;
+ }
+ else if(gradient==3) {
+ grad=0.666f*it+0.333f;
+ sc=-it+6.f;
+ }
+ else if(gradient==4) {
+ grad=0.8f*it+0.2f;
+ sc=-it+6.f;
+ }
+ else if(gradient==5) {
+ grad=0.9f*it+0.1f;
+ sc=-it+6.f;
+ }
+ else if(gradient==-1) {
+ grad=-0.125f*it+1.125f;
+ sc=3.f;
+ }
+ float varx;
+ float limdx, ilimdx;
+ if(gradvart!=0) {
+ if(gradvart==1) {
+ varx=vart*(-0.125f*it+1.125f);
+ limdx=limD*(-0.125f*it+1.125f);
+ ilimdx=1.f/limdx;
}
-
-#ifdef __SSE2__
- vfloat pondv = F2V(pond);
- vfloat limMinv = F2V(ilimD);
- vfloat limMaxv = F2V(limD);
-
-#endif
-#ifdef _OPENMP
- #pragma omp for
-#endif
-
- for (int i = 0; i < H_L; i++) {
- int j = 0;
-
-#ifdef __SSE2__
-
- if(useHslLin) {
- for (; j < W_L - 3; j += 4) {
- _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) ));
- }
- } else {
- for (; j < W_L - 3; j += 4) {
- _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) ));
- }
- }
-
-#endif
-
- if(useHslLin) {
- for (; j < W_L; j++) {
- luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimD, limD));
- }
- } else {
- for (; j < W_L; j++) {
- luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimD, limD)); // /logt ?
- }
- }
+ else if(gradvart==2) {
+ varx=vart*(-0.2f*it+1.2f);
+ limdx=limD*(-0.2f*it+1.2f);
+ ilimdx=1.f/limdx;
+ }
+ else if(gradvart==-1) {
+ varx=vart*(0.125f*it+0.875f);
+ limdx=limD*(0.125f*it+0.875f);
+ ilimdx=1.f/limdx;
+ }
+ else if(gradvart==-2) {
+ varx=vart*(0.4f*it+0.6f);
+ limdx=limD*(0.4f*it+0.6f);
+ ilimdx=1.f/limdx;
}
}
- }
- delete [] buffer;
- delete [] outBuffer;
- delete [] srcBuffer;
+ else {
+ varx=vart;
+ limdx=limD;
+ ilimdx=ilimD;
+ }
+ scal=round(sc);
+ float aahi = 49.f / 99.f; ////reduce sensibility 50%
+ float bbhi = 1.f - aahi;
+ float high;
+ high = bbhi + aahi * (float) deh.highl;
+ retinex_scales( RetinexScales, scal, moderetinex, nei/grad, high );
- mean = 0.f;
- stddv = 0.f;
- // I call mean_stddv2 instead of mean_stddv ==> logBetaGain
+ int H_L = height;
+ int W_L = width;
- mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
-// printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr);
+ float *src[H_L] ALIGNED16;
+ float *srcBuffer = new float[H_L * W_L];
- // mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr);
- if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve
- float asig = 0.166666f / stddv;
- float bsig = 0.5f - asig * mean;
- float amax = 0.333333f / (maxtr - mean - stddv);
- float bmax = 1.f - amax * maxtr;
- float amin = 0.333333f / (mean - stddv - mintr);
- float bmin = -amin * mintr;
+ for (int i = 0; i < H_L; i++) {
+ src[i] = &srcBuffer[i * W_L];
+ }
- asig *= 500.f;
- bsig *= 500.f;
- amax *= 500.f;
- bmax *= 500.f;
- amin *= 500.f;
- bmin *= 500.f;
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+
+ for (int i = 0; i < H_L; i++)
+ for (int j = 0; j < W_L; j++) {
+ src[i][j] = luminance[i][j] + eps;
+ luminance[i][j] = 0.f;
+ }
+
+ float *out[H_L] ALIGNED16;
+ float *outBuffer = new float[H_L * W_L];
+
+ for (int i = 0; i < H_L; i++) {
+ out[i] = &outBuffer[i * W_L];
+ }
+
+ const float logBetaGain = xlogf(16384.f);
+ float pond = logBetaGain / (float) scal;
+
+ if(!useHslLin) {
+ pond /= log(elogt);
+ }
+
+ float *buffer = new float[W_L * H_L];;
#ifdef _OPENMP
#pragma omp parallel
#endif
{
- float absciss;
+ for ( int scale = scal - 1; scale >= 0; scale-- ) {
+ if(scale == scal - 1) {
+ gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer);
+ } else { // reuse result of last iteration
+ gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
+ }
+
+#ifdef __SSE2__
+ vfloat pondv = F2V(pond);
+ vfloat limMinv = F2V(ilimdx);
+ vfloat limMaxv = F2V(limdx);
+
+#endif
#ifdef _OPENMP
- #pragma omp for schedule(dynamic,16)
+ #pragma omp for
#endif
- for (int i = 0; i < H_L; i++ )
- for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission
- if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) {
- absciss = asig * luminance[i][j] + bsig;
- } else if (luminance[i][j] >= mean) {
- absciss = amax * luminance[i][j] + bmax;
- } else { /*if(luminance[i][j] <= mean - stddv)*/
- absciss = amin * luminance[i][j] + bmin;
+ for (int i = 0; i < H_L; i++) {
+ int j = 0;
+
+#ifdef __SSE2__
+
+ if(useHslLin) {
+ for (; j < W_L - 3; j += 4) {
+ _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) ));
+ }
+ } else {
+ for (; j < W_L - 3; j += 4) {
+ _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) ));
+ }
}
- luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission
- }
- }
-
- // median filter on transmission ==> reduce artifacts
- if (deh.medianmap) {
- int wid = W_L;
- int hei = H_L;
- float *tmL[hei] ALIGNED16;
- float *tmLBuffer = new float[wid * hei];
- int borderL = 1;
-
- for (int i = 0; i < hei; i++) {
- tmL[i] = &tmLBuffer[i * wid];
- }
-
-#ifdef _OPENMP
- #pragma omp parallel for
#endif
- for (int i = borderL; i < hei - borderL; i++) {
- float pp[9], temp;
-
- for (int j = borderL; j < wid - borderL; j++) {
- med3(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1], tmL[i][j]); //3x3
+ if(useHslLin) {
+ for (; j < W_L; j++) {
+ luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimdx, limdx));
+ }
+ } else {
+ for (; j < W_L; j++) {
+ luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ?
+ }
+ }
}
}
-
-#ifdef _OPENMP
- #pragma omp parallel for
-#endif
-
- for (int i = borderL; i < hei - borderL; i++ ) {
- for (int j = borderL; j < wid - borderL; j++) {
- luminance[i][j] = tmL[i][j];
- }
- }
-
- delete [] tmLBuffer;
-
}
+ delete [] buffer;
+ delete [] outBuffer;
+ delete [] srcBuffer;
+ mean = 0.f;
+ stddv = 0.f;
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
- // mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr);
+
mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
+// printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr);
- }
-
- float epsil = 0.1f;
-
- mini = mean - vart * stddv;
-
- if (mini < mintr) {
- mini = mintr + epsil;
- }
-
- maxi = mean + vart * stddv;
-
- if (maxi > maxtr) {
- maxi = maxtr - epsil;
- }
-
- delta = maxi - mini;
- // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr);
-
- if ( !delta ) {
- delta = 1.0f;
- }
-
- float cdfactor = gain2 * 32768.f / delta;
- maxCD = -9999999.f;
- minCD = 9999999.f;
-
-
-
+ // mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr);
+ if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve
+ float asig = 0.166666f / stddv;
+ float bsig = 0.5f - asig * mean;
+ float amax = 0.333333f / (maxtr - mean - stddv);
+ float bmax = 1.f - amax * maxtr;
+ float amin = 0.333333f / (mean - stddv - mintr);
+ float bmin = -amin * mintr;
+ asig *= 500.f;
+ bsig *= 500.f;
+ amax *= 500.f;
+ bmax *= 500.f;
+ amin *= 500.f;
+ bmin *= 500.f;
#ifdef _OPENMP
- #pragma omp parallel
+ #pragma omp parallel
#endif
- {
- float cdmax = -999999.f, cdmin = 999999.f;
-
+ {
+ float absciss;
#ifdef _OPENMP
- #pragma omp for
+ #pragma omp for schedule(dynamic,16)
#endif
- for ( int i = 0; i < H_L; i ++ )
- for (int j = 0; j < W_L; j++) {
- // float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse;
- float cd = cdfactor * ( luminance[i][j] - mini ) + offse;
-
- if(cd > cdmax) {
- cdmax = cd;
- }
-
- if(cd < cdmin) {
- cdmin = cd;
- }
-
- float str = strength;
-
- if(lhutili) { // S=f(H)
- {
- float HH = exLuminance[i][j];
- float valparam;
-
- if(useHsl || useHslLin) {
- valparam = float((shcurve->getVal(HH) - 0.5f));
- } else {
- valparam = float((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f));
+ for (int i = 0; i < H_L; i++ )
+ for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission
+ if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) {
+ absciss = asig * luminance[i][j] + bsig;
+ } else if (luminance[i][j] >= mean) {
+ absciss = amax * luminance[i][j] + bmax;
+ } else { /*if(luminance[i][j] <= mean - stddv)*/
+ absciss = amin * luminance[i][j] + bmin;
}
- str *= (1.f + 2.f * valparam);
+ luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission
+ }
+ }
+
+ // median filter on transmission ==> reduce artifacts
+ if (deh.medianmap && it==1) {//only one time
+ int wid = W_L;
+ int hei = H_L;
+ float *tmL[hei] ALIGNED16;
+ float *tmLBuffer = new float[wid * hei];
+ int borderL = 1;
+
+ for (int i = 0; i < hei; i++) {
+ tmL[i] = &tmLBuffer[i * wid];
+ }
+
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+
+ for (int i = borderL; i < hei - borderL; i++) {
+ float pp[9], temp;
+
+ for (int j = borderL; j < wid - borderL; j++) {
+ med3(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1], tmL[i][j]); //3x3
}
}
- // if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig;
- luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j];
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+
+ for (int i = borderL; i < hei - borderL; i++ ) {
+ for (int j = borderL; j < wid - borderL; j++) {
+ luminance[i][j] = tmL[i][j];
+ }
+ }
+
+ delete [] tmLBuffer;
+
}
-#ifdef _OPENMP
- #pragma omp critical
-#endif
- {
- maxCD = maxCD > cdmax ? maxCD : cdmax;
- minCD = minCD < cdmin ? minCD : cdmin;
+ // I call mean_stddv2 instead of mean_stddv ==> logBetaGain
+ // mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr);
+ mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
+
}
- }
- // printf("cdmin=%f cdmax=%f\n",minCD, maxCD);
- Tmean = mean;
- Tsigma = stddv;
- Tmin = mintr;
- Tmax = maxtr;
+ float epsil = 0.1f;
- if (shcurve) {
- delete shcurve;
- }
+ mini = mean - varx * stddv;
+ if (mini < mintr) {
+ mini = mintr + epsil;
+ }
+
+ maxi = mean + varx * stddv;
+
+ if (maxi > maxtr) {
+ maxi = maxtr - epsil;
+ }
+
+ delta = maxi - mini;
+ // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr);
+
+ if ( !delta ) {
+ delta = 1.0f;
+ }
+
+ float cdfactor = gain2 * 32768.f / delta;
+ maxCD = -9999999.f;
+ minCD = 9999999.f;
+
+
+
+
+#ifdef _OPENMP
+ #pragma omp parallel
+#endif
+ {
+ float cdmax = -999999.f, cdmin = 999999.f;
+
+#ifdef _OPENMP
+ #pragma omp for
+#endif
+
+ for ( int i = 0; i < H_L; i ++ )
+ for (int j = 0; j < W_L; j++) {
+ // float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse;
+ float cd = cdfactor * ( luminance[i][j] - mini ) + offse;
+
+ if(cd > cdmax) {
+ cdmax = cd;
+ }
+
+ if(cd < cdmin) {
+ cdmin = cd;
+ }
+
+ float str = strength;
+
+ if(lhutili) { // S=f(H)
+ {
+ float HH = exLuminance[i][j];
+ float valparam;
+
+ if(useHsl || useHslLin) {
+ valparam = float((shcurve->getVal(HH) - 0.5f));
+ } else {
+ valparam = float((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f));
+ }
+
+ str *= (1.f + 2.f * valparam);
+ }
+ }
+
+ // if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig;
+ luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j];
+ }
+
+#ifdef _OPENMP
+ #pragma omp critical
+#endif
+ {
+ maxCD = maxCD > cdmax ? maxCD : cdmax;
+ minCD = minCD < cdmin ? minCD : cdmin;
+ }
+
+ }
+ // printf("cdmin=%f cdmax=%f\n",minCD, maxCD);
+ Tmean = mean;
+ Tsigma = stddv;
+ Tmin = mintr;
+ Tmax = maxtr;
+
+ if (shcurve) {
+ delete shcurve;
+ }
+ }
}
}
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 4dbbad07c..ae348316f 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -454,6 +454,8 @@ enum ProcEvent {
EvLbaselog = 424,
// EvLgrbl = 425,
EvRetinexlhcurve = 425,
+ EvLiter = 426,
+ EvLgrad = 427,
NUMOFEVENTS
};
}
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index becd8932e..ed57f50d3 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -142,6 +142,8 @@ void RetinexParams::setDefaults()
enabled = false;
str = 20;
scal = 3;
+ iter = 1;
+ grad = 1;
gam = 1.30;
slope = 3.;
neigh = 80;
@@ -1444,6 +1446,14 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_integer ("Retinex", "Scal", retinex.scal);
}
+ if (!pedited || pedited->retinex.iter) {
+ keyFile.set_integer ("Retinex", "Iter", retinex.iter);
+ }
+
+ if (!pedited || pedited->retinex.grad) {
+ keyFile.set_integer ("Retinex", "Grad", retinex.iter);
+ }
+
if (!pedited || pedited->retinex.gam) {
keyFile.set_double ("Retinex", "Gam", retinex.gam);
}
@@ -3851,6 +3861,22 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Retinex", "Iter")) {
+ retinex.iter = keyFile.get_integer ("Retinex", "Iter");
+
+ if (pedited) {
+ pedited->retinex.iter = true;
+ }
+ }
+
+ if (keyFile.has_key ("Retinex", "Grad")) {
+ retinex.grad = keyFile.get_integer ("Retinex", "Grad");
+
+ if (pedited) {
+ pedited->retinex.grad = true;
+ }
+ }
+
if (keyFile.has_key ("Retinex", "Gam")) {
retinex.gam = keyFile.get_double ("Retinex", "Gam");
@@ -7322,6 +7348,8 @@ bool ProcParams::operator== (const ProcParams& other)
&& retinex.transmissionCurve == other.retinex.transmissionCurve
&& retinex.str == other.retinex.str
&& retinex.scal == other.retinex.scal
+ && retinex.iter == other.retinex.iter
+ && retinex.grad == other.retinex.grad
&& retinex.gam == other.retinex.gam
&& retinex.slope == other.retinex.slope
&& retinex.neigh == other.retinex.neigh
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index d46fd4181..1226d1584 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -275,6 +275,8 @@ public:
std::vector transmissionCurve;
int str;
int scal;
+ int iter;
+ int grad;
double gam;
double slope;
int neigh;
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 3505da24f..88338f06c 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -453,6 +453,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLhighl
DEMOSAIC, // EvLbaselog
// DEMOSAIC, // EvLgrbl
- DEMOSAIC // EvRetinexlhcurve
+ DEMOSAIC, // EvRetinexlhcurve
+ RETINEX, // EvLiter
+ RETINEX // EvLgrad
+
};
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index ac2fe6523..600a68af4 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -58,6 +58,8 @@ void ParamsEdited::set (bool v)
retinex.enabled = v;
retinex.str = v;
retinex.scal = v;
+ retinex.iter = v;
+ retinex.grad = v;
retinex.gam = v;
retinex.slope = v;
retinex.neigh = v;
@@ -535,6 +537,8 @@ void ParamsEdited::initFrom (const std::vector
retinex.gammaretinex = retinex.gammaretinex && p.retinex.gammaretinex == other.retinex.gammaretinex;
retinex.str = retinex.str && p.retinex.str == other.retinex.str;
retinex.scal = retinex.scal && p.retinex.scal == other.retinex.scal;
+ retinex.iter = retinex.iter && p.retinex.iter == other.retinex.iter;
+ retinex.grad = retinex.grad && p.retinex.grad == other.retinex.grad;
retinex.gam = retinex.gam && p.retinex.gam == other.retinex.gam;
retinex.slope = retinex.slope && p.retinex.slope == other.retinex.slope;
retinex.neigh = retinex.neigh && p.retinex.neigh == other.retinex.neigh;
@@ -1082,6 +1086,18 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str;
}
+ if (retinex.scal) {
+ toEdit.retinex.scal = mods.retinex.scal;
+ }
+
+ if (retinex.iter) {
+ toEdit.retinex.iter = mods.retinex.iter;
+ }
+
+ if (retinex.grad) {
+ toEdit.retinex.grad = mods.retinex.grad;
+ }
+
// if (retinex.scal) {
// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal;
// }
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 3fa753013..ed1f07aec 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -61,6 +61,8 @@ public:
bool enabled;
bool str;
bool scal;
+ bool iter;
+ bool grad;
bool gam;
bool slope;
bool neigh;
diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc
index b964ecbb5..0578c3e57 100644
--- a/rtgui/retinex.cc
+++ b/rtgui/retinex.cc
@@ -144,7 +144,9 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
transLabels->set_tooltip_markup (M("TP_RETINEX_TLABEL_TOOLTIP"));
transLabels2 = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER));
- scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), 1, 8., 1., 3.));
+ scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), -1, 5., 1., 3.));
+ iter = Gtk::manage (new Adjuster (M("TP_RETINEX_ITER"), 1, 5., 1., 1.));
+ grad = Gtk::manage (new Adjuster (M("TP_RETINEX_GRAD"), -2., 2., 1., 1.));
gain = Gtk::manage (new Adjuster (M("TP_RETINEX_GAIN"), 20, 200, 1, 50));
offs = Gtk::manage (new Adjuster (M("TP_RETINEX_OFFSET"), -10000, 10000, 1, 0));
// vart = Gtk::manage (new Adjuster (M("TP_RETINEX_VARIANCE"), 50, 500, 1, 125));
@@ -153,6 +155,8 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
// grbl = Gtk::manage (new Adjuster (M("TP_RETINEX_HIGHLIGHT3"), 1, 100, 1, 50));
gain->set_tooltip_markup (M("TP_RETINEX_GAIN_TOOLTIP"));
scal->set_tooltip_markup (M("TP_RETINEX_SCALES_TOOLTIP"));
+ iter->set_tooltip_markup (M("TP_RETINEX_ITER_TOOLTIP"));
+ grad->set_tooltip_markup (M("TP_RETINEX_GRAD_TOOLTIP"));
// vart->set_tooltip_markup (M("TP_RETINEX_VARIANCE_TOOLTIP"));
limd->set_tooltip_markup (M("TP_RETINEX_THRESHOLD_TOOLTIP"));
baselog->set_tooltip_markup (M("TP_RETINEX_BASELOG_TOOLTIP"));
@@ -211,8 +215,14 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
slope->show ();
-// settingsVBox->pack_start (*scal);
-// scal->show ();
+ settingsVBox->pack_start (*iter);
+ iter->show ();
+
+ settingsVBox->pack_start (*scal);
+ scal->show ();
+
+ settingsVBox->pack_start (*grad);
+ grad->show ();
settingsVBox->pack_start (*gain);
gain->show ();
@@ -267,6 +277,18 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
scal->delay = 200;
}
+ iter->setAdjusterListener (this);
+
+ if (iter->delay < 200) {
+ iter->delay = 200;
+ }
+
+ grad->setAdjusterListener (this);
+
+ if (grad->delay < 200) {
+ grad->delay = 200;
+ }
+
gam->setAdjusterListener (this);
if (gam->delay < 500) {
@@ -354,6 +376,8 @@ void Retinex::neutral_pressed ()
offs->resetValue(false);
str->resetValue(false);
scal->resetValue(false);
+ iter->resetValue(false);
+ grad->resetValue(false);
vart->resetValue(false);
limd->resetValue(false);
highl->resetValue(false);
@@ -477,6 +501,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
if (pedited) {
scal->setEditedState (pedited->retinex.scal ? Edited : UnEdited);
+ iter->setEditedState (pedited->retinex.iter ? Edited : UnEdited);
+ grad->setEditedState (pedited->retinex.grad ? Edited : UnEdited);
neigh->setEditedState (pedited->retinex.neigh ? Edited : UnEdited);
gam->setEditedState (pedited->retinex.gam ? Edited : UnEdited);
slope->setEditedState (pedited->retinex.slope ? Edited : UnEdited);
@@ -515,6 +541,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
offs->setValue (pp->retinex.offs);
str->setValue (pp->retinex.str);
scal->setValue (pp->retinex.scal);
+ iter->setValue (pp->retinex.iter);
+ grad->setValue (pp->retinex.grad);
vart->setValue (pp->retinex.vart);
limd->setValue (pp->retinex.limd);
gam->setValue (pp->retinex.gam);
@@ -522,10 +550,17 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
highl->setValue (pp->retinex.highl);
baselog->setValue (pp->retinex.baselog);
// grbl->setValue (pp->retinex.grbl);
+ if(pp->retinex.iter == 1) {
+ grad->set_sensitive(false);
+ scal->set_sensitive(false);
+ }
+ else {
+ grad->set_sensitive(true);
+ scal->set_sensitive(true);
+ }
setEnabled (pp->retinex.enabled);
- medianmapConn.block (true);
medianmap->set_active (pp->retinex.medianmap);
medianmapConn.block (false);
lastmedianmap = pp->retinex.medianmap;
@@ -590,6 +625,8 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
pp->retinex.str = str->getValue ();
pp->retinex.scal = (int)scal->getValue ();
+ pp->retinex.iter = (int) iter->getValue ();
+ pp->retinex.grad = (int) grad->getValue ();
pp->retinex.gam = gam->getValue ();
pp->retinex.slope = slope->getValue ();
pp->retinex.neigh = neigh->getValue ();
@@ -615,6 +652,8 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
//%%%%%%%%%%%%%%%%%%%%%%
pedited->retinex.str = str->getEditedState ();
pedited->retinex.scal = scal->getEditedState ();
+ pedited->retinex.iter = iter->getEditedState ();
+ pedited->retinex.grad = grad->getEditedState ();
pedited->retinex.gam = gam->getEditedState ();
pedited->retinex.slope = slope->getEditedState ();
pedited->retinex.neigh = neigh->getEditedState ();
@@ -770,6 +809,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
offs->setDefault (defParams->retinex.offs);
str->setDefault (defParams->retinex.str);
scal->setDefault (defParams->retinex.scal);
+ iter->setDefault (defParams->retinex.iter);
+ grad->setDefault (defParams->retinex.grad);
vart->setDefault (defParams->retinex.vart);
limd->setDefault (defParams->retinex.limd);
highl->setDefault (defParams->retinex.highl);
@@ -784,6 +825,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
offs->setDefaultEditedState (pedited->retinex.offs ? Edited : UnEdited);
str->setDefaultEditedState (pedited->retinex.str ? Edited : UnEdited);
scal->setDefaultEditedState (pedited->retinex.scal ? Edited : UnEdited);
+ iter->setDefaultEditedState (pedited->retinex.iter ? Edited : UnEdited);
+ grad->setDefaultEditedState (pedited->retinex.grad ? Edited : UnEdited);
vart->setDefaultEditedState (pedited->retinex.vart ? Edited : UnEdited);
limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited);
highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited);
@@ -803,6 +846,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
// grbl->setDefaultEditedState (Irrelevant);
str->setDefaultEditedState (Irrelevant);
scal->setDefaultEditedState (Irrelevant);
+ iter->setDefaultEditedState (Irrelevant);
+ grad->setDefaultEditedState (Irrelevant);
gam->setDefaultEditedState (Irrelevant);
slope->setDefaultEditedState (Irrelevant);
}
@@ -827,6 +872,15 @@ void Retinex::adjusterChanged (Adjuster* a, double newval)
if (!listener || !getEnabled()) {
return;
}
+ if(iter->getTextValue() > "1") {
+ scal->set_sensitive(true);
+ grad->set_sensitive(true);
+ }
+ else {
+ scal->set_sensitive(false);
+ grad->set_sensitive(false);
+ }
+
if (a == neigh) {
listener->panelChanged (EvLneigh, neigh->getTextValue());
@@ -834,6 +888,10 @@ void Retinex::adjusterChanged (Adjuster* a, double newval)
listener->panelChanged (EvLstr, str->getTextValue());
} else if (a == scal) {
listener->panelChanged (EvLscal, scal->getTextValue());
+ } else if (a == iter) {
+ listener->panelChanged (EvLiter, iter->getTextValue());
+ } else if (a == grad) {
+ listener->panelChanged (EvLgrad, grad->getTextValue());
} else if (a == gain) {
listener->panelChanged (EvLgain, gain->getTextValue());
} else if (a == offs) {
@@ -902,6 +960,8 @@ void Retinex::trimValues (rtengine::procparams::ProcParams* pp)
{
str->trimValue(pp->retinex.str);
scal->trimValue(pp->retinex.scal);
+ iter->trimValue(pp->retinex.iter);
+ grad->trimValue(pp->retinex.grad);
neigh->trimValue(pp->retinex.neigh);
gain->trimValue(pp->retinex.gain);
offs->trimValue(pp->retinex.offs);
@@ -975,6 +1035,8 @@ void Retinex::setBatchMode (bool batchMode)
offs->showEditedCB ();
str->showEditedCB ();
scal->showEditedCB ();
+ iter->showEditedCB ();
+ grad->showEditedCB ();
gam->showEditedCB ();
slope->showEditedCB ();
vart->showEditedCB ();
diff --git a/rtgui/retinex.h b/rtgui/retinex.h
index 59001ce18..499b0ef0f 100644
--- a/rtgui/retinex.h
+++ b/rtgui/retinex.h
@@ -24,6 +24,8 @@ protected:
CurveEditorGroup* curveEditorGH;
Adjuster* str;
Adjuster* scal;
+ Adjuster* grad;
+ Adjuster* iter;
Adjuster* neigh;
Adjuster* gain;
Adjuster* offs;