diff --git a/rtdata/languages/default b/rtdata/languages/default
index a6227a841..c361da52f 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -638,11 +638,11 @@ HISTORY_MSG_404;W - ES - Base amplification
HISTORY_MSG_405;W - Denoise - Level 4
HISTORY_MSG_406;W - ES - Neighboring pixels
HISTORY_MSG_407;Retinex - Method
-HISTORY_MSG_408;Retinex - Neighboring
-HISTORY_MSG_409;Retinex - Gain
-HISTORY_MSG_410;Retinex - Offset
+HISTORY_MSG_408;Retinex - Radius
+HISTORY_MSG_409;Retinex - Contrast
+HISTORY_MSG_410;Retinex - Brightness
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
@@ -658,6 +658,17 @@ HISTORY_MSG_424;Retinex - HL threshold
HISTORY_MSG_425;Retinex - Log base
HISTORY_MSG_426;Retinex - Hue equalizer
HISTORY_MSG_427;Output rendering intent
+HISTORY_MSG_428;Retinex - Iterations
+HISTORY_MSG_429;Retinex - T. Gradient
+HISTORY_MSG_430;Retinex - S. Gradient
+HISTORY_MSG_431;Retinex - Mask highlights
+HISTORY_MSG_432;Retinex - Mask TW highlights
+HISTORY_MSG_433;Retinex - Mask shadows
+HISTORY_MSG_434;Retinex - Mask TW shadows
+HISTORY_MSG_435;Retinex - Mask radius
+HISTORY_MSG_436;Retinex - Mask method
+HISTORY_MSG_437;Retinex - Mask curve
+HISTORY_MSG_438;Retinex - Preview
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -1644,6 +1655,9 @@ TP_RESIZE_WIDTH;Width
TP_RETINEX_CONTEDIT_HSL;Histogram equalizer HSL
TP_RETINEX_CONTEDIT_LAB;Histogram equalizer L*a*b*
TP_RETINEX_CONTEDIT_LH;Hue equalizer
+TP_RETINEX_CONTEDIT_MAP;Mask equalizer
+TP_RETINEX_CURVEEDITOR_MAP;L=f(L)
+TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This Curve can be applied alone or with gaussian mask or wavelet mask\nBe aware to artifacts
TP_RETINEX_CURVEEDITOR_CD;L=f(L)
TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorrect raw data to reduce halos and artifacts.
TP_RETINEX_CURVEEDITOR_LH;Strength=f(H)
@@ -1664,19 +1678,34 @@ TP_RETINEX_HIGHLIGHT;Highlight threshold
TP_RETINEX_HIGHLIGHT_TOOLTIP;Increase action of High algorithm.\nMay require you to re-adjust "Neighboring pixels" and to increase the "White-point correction" in the Raw tab -> Raw White Points tool.
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_GRADS;Strength gradient
+TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Strength is reduce when iteration increases and conversely
TP_RETINEX_LABEL;Retinex
TP_RETINEX_LABSPACE;L*a*b*
TP_RETINEX_LOW;Low
+TP_RETINEX_MAP;Mask method
+TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generate by Gaussian function above to reduce halos and artifacts\nCurve only: apply a diagonal contrast curve on mask, be aware to artifacts\nGaussian mask : generate and use a gaussian blur of the original mask (quick)\nSharp mask : generate and use a wavelet on the original mask (slow or very very slow)
+TP_RETINEX_MAP_NONE;none
+TP_RETINEX_MAP_CURV;Curve only
+TP_RETINEX_MAP_GAUS;Gaussian mask
+TP_RETINEX_MAP_MAPP;Sharp mask (wavelet partial)
+TP_RETINEX_MAP_MAPT;Sharp mask (wavelet total)
TP_RETINEX_MEDIAN;Transmission median filter
TP_RETINEX_METHOD;Method
TP_RETINEX_METHOD_TOOLTIP;Low = Reinforce low light,\nUniform = Equalize action,\nHigh = Reinforce high light,\nHighlights = Remove magenta in highlights.
TP_RETINEX_MLABEL;Restored haze-free Min=%1 Max=%2
TP_RETINEX_MLABEL_TOOLTIP;Should be near min=0 max=32768\nRestored image with no mixture.
-TP_RETINEX_NEIGHBOR;Neighboring pixels
+TP_RETINEX_NEIGHBOR;Radius
TP_RETINEX_NEUTRAL;Reset
TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values.
-TP_RETINEX_OFFSET;Offset
+TP_RETINEX_OFFSET;Brightness
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
@@ -1687,8 +1716,15 @@ TP_RETINEX_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Vari
TP_RETINEX_TRANSMISSION;Transmission map
TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction.
TP_RETINEX_UNIFORM;Uniform
-TP_RETINEX_VARIANCE;Variance
+TP_RETINEX_VARIANCE;Contrast
TP_RETINEX_VARIANCE_TOOLTIP;Low variance increase local contrast and saturation, but can lead to artifacts.
+TP_RETINEX_VIEW;Process (Preview)
+TP_RETINEX_VIEW_NONE;Standard
+TP_RETINEX_VIEW_MASK;Mask
+TP_RETINEX_VIEW_UNSHARP;Unsharp mask
+TP_RETINEX_VIEW_TRAN;Transmission (auto)
+TP_RETINEX_VIEW_TRAN2;Transmission (fixed)
+TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - normal display\nMask - display mask\nUnsharp mask - display image with high radius unsharp mask\nTransmission (auto - fixed) - displays the file transmission-map , before any action on contrast and brightness\nAttention, this does not correspond to reality, but a shift (or auto) to make it visible
TP_RGBCURVES_BLUE;B
TP_RGBCURVES_CHANNEL;Channel
TP_RGBCURVES_GREEN;G
diff --git a/rtengine/curves.cc b/rtengine/curves.cc
index 4ad1d06bd..d0b4c026f 100644
--- a/rtengine/curves.cc
+++ b/rtengine/curves.cc
@@ -504,6 +504,45 @@ void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurve
}
}
+void CurveFactory::mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram)
+{
+ bool needed = false;
+ DiagonalCurve* dCurve = NULL;
+ outBeforeCurveHistogram.clear();
+ bool histNeeded = false;
+
+ if (!mapcurvePoints.empty() && mapcurvePoints[0] != 0) {
+ dCurve = new DiagonalCurve (mapcurvePoints, CURVES_MIN_POLY_POINTS / skip);
+
+ if (outBeforeCurveHistogram) {
+ histNeeded = true;
+ }
+
+ if (dCurve && !dCurve->isIdentity()) {
+ needed = true;
+ mapcontlutili = true;
+ }
+ }
+
+ if (histNeeded) {
+ for (int i = 0; i < 32768; i++) {
+ double hval = CLIPD((double)i / 32767.0);
+ int hi = (int)(255.0 * hval);
+ outBeforeCurveHistogram[hi] += histogram[i] ;
+ }
+ }
+
+ fillCurveArray(dCurve, mapcurve, skip, needed);
+
+ if (dCurve) {
+ delete dCurve;
+ dCurve = NULL;
+ }
+}
+
+
+
+
void CurveFactory::curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram)
{
bool needed = false;
diff --git a/rtengine/curves.h b/rtengine/curves.h
index f0643c7a9..e55d7bc2a 100644
--- a/rtengine/curves.h
+++ b/rtengine/curves.h
@@ -283,6 +283,7 @@ public:
static void curveWavContL ( bool & wavcontlutili, const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip);
static void curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram);
+ static void mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram);
static void curveToningCL ( bool & clctoningutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip);
static void curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip);
diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h
index d9f088813..80fc53f23 100644
--- a/rtengine/imagesource.h
+++ b/rtengine/imagesource.h
@@ -69,14 +69,14 @@ public:
virtual int load (Glib::ustring fname, bool batch = false) = 0;
virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {};
virtual void demosaic (const RAWParams &raw) {};
- virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
- virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};
+ virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
+ virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};
virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {};
virtual void flushRawData () {};
virtual void flushRGB () {};
virtual void HLRecovery_Global (ToneCurveParams hrp) {};
virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {};
- virtual void MSR(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {};
+ virtual void MSR(LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {};
virtual bool IsrgbSourceModified() = 0; // tracks whether cached rgb output of demosaic has been modified
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 96a55989e..d12027c6d 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -244,12 +244,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
if ((todo & (M_RETINEX|M_INIT)) && params.retinex.enabled) {
bool dehacontlutili = false;
+ bool mapcontlutili = false;
bool useHsl = false;
LUTf cdcurve (65536, 0);
+ LUTf mapcurve (65536, 0);
- imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, lhist16RETI, histLRETI);
+ imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, lhist16RETI, histLRETI);
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
- imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex
+ imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex
if(dehaListener) {
dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
@@ -780,6 +782,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
}
+ // Update the monitor color transform if necessary
+ if (todo & M_MONITOR) {
+ ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);
+ }
// Update the monitor color transform if necessary
if (todo & M_MONITOR) {
diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc
index 54d5d3515..b24cc9bb3 100644
--- a/rtengine/ipretinex.cc
+++ b/rtengine/ipretinex.cc
@@ -32,6 +32,7 @@
* College of Physics and Information Engineering, Fuzhou University, Fuzhou, China
* inspired from 2003 Fabien Pelisson
+ * some ideas taken (use of mask) Russell Cottrell - The Retinex .8bf Plugin
*/
@@ -205,7 +206,7 @@ void mean_stddv( float **dst, float &mean, float &stddv, int W_L, int H_L, const
stddv = (float)sqrt(stddv);
}
-void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax)
+void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax)
{
if (deh.enabled) {//enabled
float mean, stddv, maxtr, mintr;
@@ -217,10 +218,13 @@ 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 gradstr = (float)deh.grads;
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
@@ -231,12 +235,18 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
bool higplus = false ;
float elogt;
float hl = deh.baselog;
-
+ SHMap* shmap;
if(hl >= 2.71828f) {
elogt = 2.71828f + SQR(SQR(hl - 2.71828f));
} else {
elogt = hl;
}
+ int H_L = height;
+ int W_L = width;
+
+ float *tran[H_L] ALIGNED16;
+ float *tranBuffer;
+ int viewmet=0;
elogt = 2.71828f;//disabled baselog
FlatCurve* shcurve = NULL;//curve L=f(H)
@@ -271,281 +281,501 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
if (deh.retinexMethod == "highli" || deh.retinexMethod == "highliplus") {
moderetinex = 3;
}
+ 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);
+
+ 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;
}
-#ifdef __SSE2__
- vfloat pondv = F2V(pond);
- vfloat limMinv = F2V(ilimD);
- vfloat limMaxv = F2V(limD);
+ float *out[H_L] ALIGNED16;
+ float *outBuffer = new float[H_L * W_L];
-#endif
-#ifdef _OPENMP
- #pragma omp for
-#endif
+ for (int i = 0; i < H_L; i++) {
+ out[i] = &outBuffer[i * W_L];
+ }
+
+ if(viewmet==3 || viewmet==2) {
+ tranBuffer = new float[H_L * W_L];
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 ?
- }
- }
+ tran[i] = &tranBuffer[i * W_L];
}
}
- }
- delete [] buffer;
- delete [] outBuffer;
- delete [] srcBuffer;
+ const float logBetaGain = xlogf(16384.f);
+ float pond = logBetaGain / (float) scal;
- mean = 0.f;
- stddv = 0.f;
- // I call mean_stddv2 instead of mean_stddv ==> logBetaGain
+ if(!useHslLin) {
+ pond /= log(elogt);
+ }
- 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);
+ if(mapmet > 1) shmap = new SHMap (W_L, H_L, true);
- // 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;
+
+ float *buffer = new float[W_L * H_L];;
#ifdef _OPENMP
#pragma omp parallel
#endif
{
- float absciss;
-#ifdef _OPENMP
- #pragma omp for schedule(dynamic,16)
+ 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);
+ }
+ //printf("scal=%d RetinexScales=%f\n",scale, RetinexScales[scale]);
+ printf("..");
+
+
+ if(mapmet==4) shradius /= 1.;
+ else shradius = 40.;
+
+ // if(shHighlights > 0 || shShadows > 0) {
+ if(mapmet==3) if(it==1) shmap->updateL (out, shradius, true, 1);//wav Total
+ if(mapmet==2 && scale >2) if(it==1) shmap->updateL (out, shradius, true, 1);//wav partial
+ if(mapmet==4) if(it==1) shmap->updateL (out, shradius, false, 1);//gauss
+ // }
+ if (shmap) {
+ h_th = shmap->max_f - deh.htonalwidth * (shmap->max_f - shmap->avg) / 100;
+ s_th = deh.stonalwidth * (shmap->avg - shmap->min_f) / 100;
+ }
+
+
+#ifdef __SSE2__
+ vfloat pondv = F2V(pond);
+ vfloat limMinv = F2V(ilimdx);
+ vfloat limMaxv = F2V(limdx);
+
#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;
+ if(mapmet > 0) {
+#ifdef _OPENMP
+ #pragma omp for
+#endif
+ for (int i = 0; i < H_L; i++) {
+ if(mapcontlutili) {
+ int j = 0;
+ for (; j < W_L; j++) {
+ if(it==1) out[i][j] = mapcurve[2.f * out[i][j]] / 2.f;
+ }
+ }
}
- 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;
+ // if(shHighlights > 0 || shShadows > 0) {
+ if(((mapmet == 2 && scale >2) || mapmet==3 || mapmet==4) && it==1) {
- for (int i = 0; i < hei; i++) {
- tmL[i] = &tmLBuffer[i * wid];
- }
#ifdef _OPENMP
- #pragma omp parallel for
+ #pragma omp for
#endif
+ for (int i = 0; i < H_L; i++) {
+ int j = 0;
+ for (; j < W_L; j++) {
+ double mapval = 1.0 + shmap->map[i][j];
+ double factor = 1.0;
- for (int i = borderL; i < hei - borderL; i++) {
- float pp[9], temp;
+ if (mapval > h_th) {
+ factor = (h_th + (100.0 - shHighlights) * (mapval - h_th) / 100.0) / mapval;
+ } else if (mapval < s_th) {
+ factor = (s_th - (100.0 - shShadows) * (s_th - mapval) / 100.0) / mapval;
+ }
+ out[i][j] *= factor;
- 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
+ }
+ }
}
- }
+ // }
#ifdef _OPENMP
- #pragma omp parallel for
+ #pragma omp for
#endif
- for (int i = borderL; i < hei - borderL; i++ ) {
- for (int j = borderL; j < wid - borderL; j++) {
- luminance[i][j] = tmL[i][j];
+ 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], ilimdx, limdx));
+ }
+ } else {
+ for (; j < W_L; j++) {
+ luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ?
+ }
+ }
}
}
-
- delete [] tmLBuffer;
-
}
+ printf(".\n");
+ if(mapmet > 1) {
+ if(shmap) {
+ delete shmap;
+ }
+ }
+ shmap = NULL;
+ 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
+ if(viewmet==3 || viewmet==2) tran[i][j]=luminance[i][j];
+ }
+ }
+
+ // 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;
+ // coeff for auto "transmission" with 2 sigma #95% datas
+ float aza=16300.f/(2.f*stddv);
+ float azb=-aza*(mean-2.f*stddv);
+ float bza=16300.f/(2.f*stddv);
+ float bzb=16300.f-bza*(mean);
+
+
+
+#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 = strengthx;
+
+ if(lhutili && it==1) { // 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;
+ if(viewmet==0) luminance[i][j]=clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j];
+ if(viewmet==1) luminance[i][j] = out[i][j];
+ if(viewmet==4) luminance[i][j] = (1.f + str) * originalLuminance[i][j] - str* out[i][j];//unsharp
+ if(viewmet==2) {
+ if(tran[i][j]<= mean) luminance[i][j] = azb + aza*tran[i][j];//auto values
+ else luminance[i][j] = bzb + bza*tran[i][j];
+ }
+ if(viewmet==3) luminance[i][j] = 1000.f + tran[i][j]*700.f;//arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5
+
+ }
+
+#ifdef _OPENMP
+ #pragma omp critical
+#endif
+ {
+ maxCD = maxCD > cdmax ? maxCD : cdmax;
+ minCD = minCD < cdmin ? minCD : cdmin;
+ }
+
+ }
+ delete [] outBuffer;
+ outBuffer = NULL;
+ // printf("cdmin=%f cdmax=%f\n",minCD, maxCD);
+ Tmean = mean;
+ Tsigma = stddv;
+ Tmin = mintr;
+ Tmax = maxtr;
+
+
+ if (shcurve && it==1) {
+ delete shcurve;
+ }
+ }
+ if(viewmet==3 || viewmet==2) {
+ delete [] tranBuffer;
+ tranBuffer = NULL;
}
}
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 21ecf5a83..be95686be 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -456,6 +456,17 @@ enum ProcEvent {
EvRetinexlhcurve = 425,
EvOIntent = 426,
EvMonitorTransform = 427,
+ EvLiter = 428,
+ EvLgrad = 429,
+ EvLgrads = 430,
+ EvLhighlights = 431,
+ EvLh_tonalwidth = 432,
+ EvLshadows = 433,
+ EvLs_tonalwidth = 434,
+ EvLradius = 435,
+ EvmapMethod = 436,
+ EvRetinexmapcurve = 437,
+ EvviewMethod = 438,
NUMOFEVENTS
};
}
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 613334469..90eafe375 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -142,6 +142,9 @@ void RetinexParams::setDefaults()
enabled = false;
str = 20;
scal = 3;
+ iter = 1;
+ grad = 1;
+ grads = 1;
gam = 1.30;
slope = 3.;
neigh = 80;
@@ -150,9 +153,17 @@ void RetinexParams::setDefaults()
vart = 200;
limd = 8;
highl = 4;
+ highlights = 0;
+ htonalwidth = 80;
+ shadows = 0;
+ stonalwidth = 80;
+ radius = 40;
+
baselog = 2.71828;
// grbl = 50;
retinexMethod = "high";
+ mapMethod = "none";
+ viewMethod = "none";
retinexcolorspace = "Lab";
gammaretinex = "none";
medianmap = false;
@@ -162,6 +173,8 @@ void RetinexParams::setDefaults()
cdHcurve.push_back(DCT_Linear);
lhcurve.clear();
lhcurve.push_back(DCT_Linear);
+ mapcurve.clear();
+ mapcurve.push_back(DCT_Linear);
getDefaulttransmissionCurve(transmissionCurve);
}
@@ -1445,6 +1458,18 @@ 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.grad);
+ }
+
+ if (!pedited || pedited->retinex.grads) {
+ keyFile.set_integer ("Retinex", "Grads", retinex.grads);
+ }
+
if (!pedited || pedited->retinex.gam) {
keyFile.set_double ("Retinex", "Gam", retinex.gam);
}
@@ -1499,6 +1524,14 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_string ("Retinex", "RetinexMethod", retinex.retinexMethod);
}
+ if (!pedited || pedited->retinex.mapMethod) {
+ keyFile.set_string ("Retinex", "mapMethod", retinex.mapMethod);
+ }
+
+ if (!pedited || pedited->retinex.viewMethod) {
+ keyFile.set_string ("Retinex", "viewMethod", retinex.viewMethod);
+ }
+
if (!pedited || pedited->retinex.retinexcolorspace) {
keyFile.set_string ("Retinex", "Retinexcolorspace", retinex.retinexcolorspace);
}
@@ -1512,6 +1545,11 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_double_list("Retinex", "CDCurve", cdcurve);
}
+ if (!pedited || pedited->retinex.mapcurve) {
+ Glib::ArrayHandle mapcurve = retinex.mapcurve;
+ keyFile.set_double_list("Retinex", "MAPCurve", mapcurve);
+ }
+
if (!pedited || pedited->retinex.cdHcurve) {
Glib::ArrayHandle cdHcurve = retinex.cdHcurve;
keyFile.set_double_list("Retinex", "CDHCurve", cdHcurve);
@@ -1522,6 +1560,26 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_double_list("Retinex", "LHCurve", lhcurve);
}
+ if (!pedited || pedited->retinex.highlights) {
+ keyFile.set_integer ("Retinex", "Highlights", retinex.highlights);
+ }
+
+ if (!pedited || pedited->retinex.htonalwidth) {
+ keyFile.set_integer ("Retinex", "HighlightTonalWidth", retinex.htonalwidth);
+ }
+
+ if (!pedited || pedited->retinex.shadows) {
+ keyFile.set_integer ("Retinex", "Shadows", retinex.shadows);
+ }
+
+ if (!pedited || pedited->retinex.stonalwidth) {
+ keyFile.set_integer ("Retinex", "ShadowTonalWidth", retinex.stonalwidth);
+ }
+
+ if (!pedited || pedited->retinex.radius) {
+ keyFile.set_integer ("Retinex", "Radius", retinex.radius);
+ }
+
if (!pedited || pedited->retinex.transmissionCurve) {
Glib::ArrayHandle transmissionCurve = retinex.transmissionCurve;
keyFile.set_double_list("Retinex", "TransmissionCurve", transmissionCurve);
@@ -3825,6 +3883,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Retinex", "mapMethod")) {
+ retinex.mapMethod = keyFile.get_string ("Retinex", "mapMethod");
+
+ if (pedited) {
+ pedited->retinex.mapMethod = true;
+ }
+ }
+
+ if (keyFile.has_key ("Retinex", "viewMethod")) {
+ retinex.viewMethod = keyFile.get_string ("Retinex", "viewMethod");
+
+ if (pedited) {
+ pedited->retinex.viewMethod = true;
+ }
+ }
+
+
if (keyFile.has_key ("Retinex", "Retinexcolorspace")) {
retinex.retinexcolorspace = keyFile.get_string ("Retinex", "Retinexcolorspace");
@@ -3873,6 +3948,30 @@ 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", "Grads")) {
+ retinex.grads = keyFile.get_integer ("Retinex", "Grads");
+
+ if (pedited) {
+ pedited->retinex.grads = true;
+ }
+ }
+
if (keyFile.has_key ("Retinex", "Gam")) {
retinex.gam = keyFile.get_double ("Retinex", "Gam");
@@ -3953,6 +4052,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Retinex", "MAPCurve")) {
+ retinex.mapcurve = keyFile.get_double_list ("Retinex", "MAPCurve");
+
+ if (pedited) {
+ pedited->retinex.mapcurve = true;
+ }
+ }
+
if (keyFile.has_key ("Retinex", "CDHCurve")) {
retinex.cdHcurve = keyFile.get_double_list ("Retinex", "CDHCurve");
@@ -3969,6 +4076,48 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Retinex", "Highlights")) {
+ retinex.highlights = keyFile.get_integer ("Retinex", "Highlights");
+
+ if (pedited) {
+ pedited->retinex.highlights = true;
+ }
+ }
+
+ if (keyFile.has_key ("Retinex", "HighlightTonalWidth")) {
+ retinex.htonalwidth = keyFile.get_integer ("Retinex", "HighlightTonalWidth");
+
+ if (pedited) {
+ pedited->retinex.htonalwidth = true;
+ }
+ }
+
+ if (keyFile.has_key ("Retinex", "Shadows")) {
+ retinex.shadows = keyFile.get_integer ("Retinex", "Shadows");
+
+ if (pedited) {
+ pedited->retinex.shadows = true;
+ }
+ }
+
+ if (keyFile.has_key ("Retinex", "ShadowTonalWidth")) {
+ retinex.stonalwidth = keyFile.get_integer ("Retinex", "ShadowTonalWidth");
+
+ if (pedited) {
+ pedited->retinex.stonalwidth = true;
+ }
+ }
+
+
+ if (keyFile.has_key ("Retinex", "Radius")) {
+ sh.radius = keyFile.get_integer ("Retinex", "Radius");
+
+ if (pedited) {
+ pedited->retinex.radius = true;
+ }
+ }
+
+
if (keyFile.has_key ("Retinex", "TransmissionCurve")) {
retinex.transmissionCurve = keyFile.get_double_list ("Retinex", "TransmissionCurve");
@@ -7356,21 +7505,33 @@ bool ProcParams::operator== (const ProcParams& other)
&& toneCurve.hrenabled == other.toneCurve.hrenabled
&& toneCurve.method == other.toneCurve.method
&& retinex.cdcurve == other.retinex.cdcurve
+ && retinex.mapcurve == other.retinex.mapcurve
&& retinex.cdHcurve == other.retinex.cdHcurve
&& retinex.lhcurve == other.retinex.lhcurve
&& 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.grads == other.retinex.grads
&& retinex.gam == other.retinex.gam
&& retinex.slope == other.retinex.slope
&& retinex.neigh == other.retinex.neigh
&& retinex.gain == other.retinex.gain
&& retinex.limd == other.retinex.limd
&& retinex.highl == other.retinex.highl
+ && retinex.highlights == other.retinex.highlights
+ && retinex.htonalwidth == other.retinex.htonalwidth
+ && retinex.shadows == other.retinex.shadows
+ && retinex.stonalwidth == other.retinex.stonalwidth
+ && retinex.radius == other.retinex.radius
+
&& retinex.baselog == other.retinex.baselog
// && retinex.grbl == other.retinex.grbl
&& retinex.offs == other.retinex.offs
&& retinex.retinexMethod == other.retinex.retinexMethod
+ && retinex.mapMethod == other.retinex.mapMethod
+ && retinex.viewMethod == other.retinex.viewMethod
&& retinex.retinexcolorspace == other.retinex.retinexcolorspace
&& retinex.gammaretinex == other.retinex.gammaretinex
&& retinex.vart == other.retinex.vart
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 1103d274d..47b8f1cf1 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -282,16 +282,28 @@ public:
std::vector cdHcurve;
std::vector lhcurve;
std::vector transmissionCurve;
+ std::vector mapcurve;
int str;
int scal;
+ int iter;
+ int grad;
+ int grads;
double gam;
double slope;
int neigh;
int gain;
int offs;
+ int highlights;
+ int htonalwidth;
+ int shadows;
+ int stonalwidth;
+ int radius;
+
Glib::ustring retinexMethod;
Glib::ustring retinexcolorspace;
Glib::ustring gammaretinex;
+ Glib::ustring mapMethod;
+ Glib::ustring viewMethod;
int vart;
int limd;
int highl;
diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc
index 02e851414..aadc011dd 100644
--- a/rtengine/rawimagesource.cc
+++ b/rtengine/rawimagesource.cc
@@ -2107,7 +2107,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
}
-void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI)
+void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI)
{
useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN");
@@ -2116,12 +2116,13 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc
} else {
CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI);
}
+ CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI);
retinexParams.getCurves(retinextransmissionCurve);
}
//void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI)
-void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI)
+void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI)
{
MyTime t4, t5;
@@ -2273,7 +2274,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
}
}
- MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
+ MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], mapcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
if(useHsl) {
if(chutili) {
diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h
index ee89dd079..10057d58a 100644
--- a/rtengine/rawimagesource.h
+++ b/rtengine/rawimagesource.h
@@ -152,8 +152,8 @@ public:
void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse);
void demosaic (const RAWParams &raw);
// void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili);
- void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
- void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
+ void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
+ void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI);
void flushRawData ();
void flushRGB ();
@@ -230,7 +230,7 @@ public:
void boxblur2(float** src, float** dst, float** temp, int H, int W, int box );
void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp );
- void MSR(float** luminance, float **originalLuminance, float **exLuminance, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax);
+ void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax);
// void MSR(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve);
//void boxblur_resamp(float **red, float **green, float **blue, int H, int W, float thresh[3], float max[3],
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index f31300a64..607aa1226 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -440,22 +440,32 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLstr
RETINEX, // EvLscal
RETINEX, // EvLvart
- RETINEX, // EvLCDCurve
+ DEMOSAIC, // EvLCDCurve
RETINEX, // EvRetinextransmission
DEMOSAIC, // EvRetinexEnabled
RETINEX, // EvRetinexmedianmap
RETINEX, // EvLlimd
DEMOSAIC, // Evretinexcolorspace
- RETINEX, // EvLCDHCurve
+ DEMOSAIC, // EvLCDHCurve
DEMOSAIC, // Evretinexgamma
DEMOSAIC, // EvLgam
DEMOSAIC, // EvLslope
RETINEX, // EvLhighl
DEMOSAIC, // EvLbaselog
-// DEMOSAIC, // EvLgrbl
- DEMOSAIC, // EvRetinexlhcurve
+// DEMOSAIC, // EvLgrbl
+ DEMOSAIC, // EvRetinexlhcurve
ALLNORAW, // EvOIntent
- MONITORTRANSFORM // EvMonitorTransform
-
+ MONITORTRANSFORM, // EvMonitorTransform
+ RETINEX, // EvLiter
+ RETINEX, // EvLgrad
+ RETINEX, // EvLgrads
+ RETINEX, //EvLhighlights
+ RETINEX, //EvLh_tonalwidth
+ RETINEX, //EvLshadows
+ RETINEX, //EvLs_tonalwidth
+ RETINEX, //EvLradius
+ RETINEX, //EvmapMethod
+ DEMOSAIC, //EvRetinexmapcurve
+ DEMOSAIC //EvviewMethod
};
diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc
index 34fadd5e7..2471b17a4 100644
--- a/rtengine/shmap.cc
+++ b/rtengine/shmap.cc
@@ -64,6 +64,20 @@ void SHMap::fillLuminance( Imagefloat * img, float **luminance, double lumi[3] )
}
+void SHMap::fillLuminanceL( float ** L, float **luminance) // fill with luminance
+{
+
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+
+ for (int i = 0; i < H; i++)
+ for (int j = 0; j < W; j++) {
+ luminance[i][j] = std::max(L[i][j], 0.f) ;//we can put here some enhancements Gamma, compression data,...
+ }
+
+}
+
void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip)
{
@@ -210,6 +224,154 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int
}
+void SHMap::updateL (float** L, double radius, bool hq, int skip)
+{
+
+ if (!hq) {
+ fillLuminanceL( L, map);
+#ifdef _OPENMP
+ #pragma omp parallel
+#endif
+ {
+ gaussianBlur (map, map, W, H, radius);
+ }
+ }
+
+ else
+
+ {
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ //experimental dirpyr shmap
+ float thresh = (100.f * radius); //1000;
+ int levrad = 16;
+ levrad=2;//for retinex - otherwise levrad = 16
+ // set up range function
+ // calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10)
+ // So we use this fact and the automatic clip of lut to reduce the size of lut and the number of calculations to fill the lut
+ // In past this lut had only integer precision with rangefn[i] = 0 for all i>=k
+ // We set the last element to a small epsilon 1e-15 instead of zero to avoid divisions by zero
+ const int lutSize = (int) thresh * sqrtf(10.f) + 1;
+ thresh *= thresh;
+ LUTf rangefn(lutSize);
+ for (int i = 0; i < lutSize - 1; i++) {
+ rangefn[i] = xexpf(-min(10.f, (static_cast(i) * i) / thresh )); //*intfactor;
+ }
+
+ rangefn[lutSize - 1] = 1e-15f;
+ //printf("lut=%d rf5=%f rfm=%f\n thre=%f",lutSize, rangefn[5],rangefn[lutSize-10],thresh );
+
+ // We need one temporary buffer
+ float ** buffer = allocArray (W, H);
+
+ // the final result has to be in map
+ // for an even number of levels that means: map => buffer, buffer => map
+ // for an odd number of levels that means: buffer => map, map => buffer, buffer => map
+ // so let's calculate the number of levels first
+ // There are at least two levels
+ int numLevels = 2;
+ int scale = 2;
+
+ while (skip * scale < levrad) {
+ scale *= 2;
+ numLevels++;
+ }
+ //printf("numlev=%d\n",numLevels);
+ float ** dirpyrlo[2];
+
+ if(numLevels & 1) { // odd number of levels, start with buffer
+ dirpyrlo[0] = buffer;
+ dirpyrlo[1] = map;
+ } else { // even number of levels, start with map
+ dirpyrlo[0] = map;
+ dirpyrlo[1] = buffer;
+ }
+
+ fillLuminanceL( L, dirpyrlo[0]);
+
+ scale = 1;
+ int level = 0;
+ int indx = 0;
+ dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale );
+ scale *= 2;
+ level ++;
+ indx = 1 - indx;
+
+ while (skip * scale < levrad) {
+ dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale );
+ scale *= 2;
+ level ++;
+ indx = 1 - indx;
+ }
+
+ dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale );
+
+ freeArray(buffer, H);
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ /*
+ // anti-alias filtering the result
+ #ifdef _OPENMP
+ #pragma omp for
+ #endif
+ for (int i=0; i0 && j>0 && i _max_f) {
+ _max_f = _val;
+ }
+
+ _avg += _val;
+ }
+
+#ifdef _OPENMP
+ #pragma omp critical
+#endif
+ {
+ if(_min_f < min_f ) {
+ min_f = _min_f;
+ }
+
+ if(_max_f > max_f ) {
+ max_f = _max_f;
+ }
+ }
+ }
+ _avg /= ((H) * (W));
+ avg = _avg;
+
+}
+
+
void SHMap::forceStat (float max_, float min_, float avg_)
{
@@ -236,7 +398,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i
#endif
{
#if defined( __SSE2__ ) && defined( __x86_64__ )
- __m128 dirwtv, valv, normv, dftemp1v, dftemp2v;
+ __m128 dirwtv, valv, normv, dftemp1v, dftemp2v, fg;
#endif // __SSE2__
int j;
#ifdef _OPENMP
@@ -252,6 +414,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i
for(int inbr = max(i - scalewin, i % scale); inbr <= min(i + scalewin, height - 1); inbr += scale) {
for (int jnbr = j % scale; jnbr <= j + scalewin; jnbr += scale) {
+ //printf("dat=%f ",abs(data_fine[inbr][jnbr] - data_fine[i][j]));
dirwt = ( rangefn[abs(data_fine[inbr][jnbr] - data_fine[i][j])] );
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
@@ -342,7 +505,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i
#endif
{
#if defined( __SSE2__ ) && defined( __x86_64__ )
- __m128 dirwtv, valv, normv, dftemp1v, dftemp2v;
+ __m128 dirwtv, valv, normv, dftemp1v, dftemp2v, fgg;
float domkerv[5][5][4] __attribute__ ((aligned (16))) = {{{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}};
#endif // __SSE2__
diff --git a/rtengine/shmap.h b/rtengine/shmap.h
index 3d5609f48..97a394927 100644
--- a/rtengine/shmap.h
+++ b/rtengine/shmap.h
@@ -36,6 +36,7 @@ public:
~SHMap ();
void update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip);
+ void updateL (float** L, double radius, bool hq, int skip);
void forceStat (float max_, float min_, float avg_);
private:
@@ -43,6 +44,7 @@ private:
bool multiThread;
void fillLuminance( Imagefloat * img, float **luminance, double lumi[3] );
+ void fillLuminanceL( float ** L, float **luminance );
void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale);
};
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 6e1c876cf..9ae940980 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -126,16 +126,18 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if(params.retinex.enabled) { //enabled Retinex
LUTf cdcurve (65536, 0);
+ LUTf mapcurve (65536, 0);
LUTu dummy;
RetinextransmissionCurve dehatransmissionCurve;
bool dehacontlutili = false;
+ bool mapcontlutili = false;
bool useHsl = false;
// multi_array2D conversionBuffer(1, 1);
multi_array2D conversionBuffer(1, 1);
imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy);
- imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, dummy, dummy );
+ imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy );
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
- imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy);
+ imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy);
}
if (pl) {
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 866142a10..062c61ba2 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -50,14 +50,20 @@ void ParamsEdited::set (bool v)
toneCurve.hrenabled = v;
toneCurve.method = v;
retinex.cdcurve = v;
+ retinex.mapcurve = v;
retinex.cdHcurve = v;
retinex.lhcurve = v;
retinex.retinexMethod = v;
+ retinex.mapMethod = v;
+ retinex.viewMethod = v;
retinex.retinexcolorspace = v;
retinex.gammaretinex = v;
retinex.enabled = v;
retinex.str = v;
retinex.scal = v;
+ retinex.iter = v;
+ retinex.grad = v;
+ retinex.grads = v;
retinex.gam = v;
retinex.slope = v;
retinex.neigh = v;
@@ -70,6 +76,12 @@ void ParamsEdited::set (bool v)
// retinex.grbl = v;
retinex.medianmap = v;
retinex.transmissionCurve = v;
+ retinex.highlights = v;
+ retinex.htonalwidth = v;
+ retinex.shadows = v;
+ retinex.stonalwidth = v;
+ retinex.radius = v;
+
retinex.retinex = v;
labCurve.lcurve = v;
labCurve.acurve = v;
@@ -528,14 +540,20 @@ void ParamsEdited::initFrom (const std::vector
toneCurve.hrenabled = toneCurve.hrenabled && p.toneCurve.hrenabled == other.toneCurve.hrenabled;
toneCurve.method = toneCurve.method && p.toneCurve.method == other.toneCurve.method;
retinex.cdcurve = retinex.cdcurve && p.retinex.cdcurve == other.retinex.cdcurve;
+ retinex.mapcurve = retinex.mapcurve && p.retinex.mapcurve == other.retinex.mapcurve;
retinex.cdHcurve = retinex.cdHcurve && p.retinex.cdHcurve == other.retinex.cdHcurve;
retinex.lhcurve = retinex.lhcurve && p.retinex.lhcurve == other.retinex.lhcurve;
retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve;
retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod;
+ retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod;
+ retinex.viewMethod = retinex.viewMethod && p.retinex.viewMethod == other.retinex.viewMethod;
retinex.retinexcolorspace = retinex.retinexcolorspace && p.retinex.retinexcolorspace == other.retinex.retinexcolorspace;
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.grads = retinex.grads && p.retinex.grads == other.retinex.grads;
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;
@@ -547,6 +565,12 @@ void ParamsEdited::initFrom (const std::vector
retinex.baselog = retinex.baselog && p.retinex.baselog == other.retinex.baselog;
// retinex.grbl = retinex.grbl && p.retinex.grbl == other.retinex.grbl;
retinex.medianmap = retinex.medianmap && p.retinex.medianmap == other.retinex.medianmap;
+ retinex.highlights = retinex.highlights && p.retinex.highlights == other.retinex.highlights;
+ retinex.htonalwidth = retinex.htonalwidth && p.retinex.htonalwidth == other.retinex.htonalwidth;
+ retinex.shadows = retinex.shadows && p.retinex.shadows == other.retinex.shadows;
+ retinex.stonalwidth = retinex.stonalwidth && p.retinex.stonalwidth == other.retinex.stonalwidth;
+ retinex.radius = retinex.radius && p.retinex.radius == other.retinex.radius;
+
retinex.enabled = retinex.enabled && p.retinex.enabled == other.retinex.enabled;
labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve;
labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve;
@@ -1048,6 +1072,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.retinex.cdcurve = mods.retinex.cdcurve;
}
+ if (retinex.mapcurve) {
+ toEdit.retinex.mapcurve = mods.retinex.mapcurve;
+ }
+
if (retinex.cdHcurve) {
toEdit.retinex.cdHcurve = mods.retinex.cdHcurve;
}
@@ -1064,6 +1092,14 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.retinex.retinexMethod = mods.retinex.retinexMethod;
}
+ if (retinex.mapMethod) {
+ toEdit.retinex.mapMethod = mods.retinex.mapMethod;
+ }
+
+ if (retinex.viewMethod) {
+ toEdit.retinex.viewMethod = mods.retinex.viewMethod;
+ }
+
if (retinex.retinexcolorspace) {
toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace;
}
@@ -1084,6 +1120,22 @@ 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.grads) {
+ toEdit.retinex.grads = mods.retinex.grads;
+ }
+
// if (retinex.scal) {
// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal;
// }
@@ -1124,6 +1176,28 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart;
}
+ if (retinex.highlights) {
+ toEdit.retinex.highlights = mods.retinex.highlights;
+ }
+
+ if (retinex.htonalwidth) {
+ toEdit.retinex.htonalwidth = mods.retinex.htonalwidth;
+ }
+
+ if (retinex.shadows) {
+ toEdit.retinex.shadows = mods.retinex.shadows;
+
+ }
+
+ if (retinex.stonalwidth) {
+ toEdit.retinex.stonalwidth = mods.retinex.stonalwidth;
+ }
+
+ if (retinex.radius) {
+ toEdit.retinex.radius = mods.retinex.radius;
+ }
+
+
if (labCurve.lcurve) {
toEdit.labCurve.lcurve = mods.labCurve.lcurve;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 1993c7aaa..261da1753 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -61,12 +61,17 @@ public:
bool enabled;
bool str;
bool scal;
+ bool iter;
+ bool grad;
+ bool grads;
bool gam;
bool slope;
bool neigh;
bool gain;
bool offs;
bool retinexMethod;
+ bool mapMethod;
+ bool viewMethod;
bool retinexcolorspace;
bool gammaretinex;
bool vart;
@@ -77,11 +82,18 @@ public:
bool method;
bool transmissionCurve;
bool cdcurve;
+ bool mapcurve;
bool cdHcurve;
bool lhcurve;
bool retinex;
bool medianmap;
bool isUnchanged() const;
+ bool highlights;
+ bool htonalwidth;
+ bool shadows;
+ bool stonalwidth;
+ bool radius;
+
};
diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc
index 43cbe4f28..fb69de3e3 100644
--- a/rtgui/retinex.cc
+++ b/rtgui/retinex.cc
@@ -84,6 +84,17 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
curveEditorGDH->curveListComplete();
+ curveEditormap = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_MAP"));
+ curveEditormap->setCurveListener (this);
+ mapshape = static_cast(curveEditormap->addCurve(CT_Diagonal, M("TP_RETINEX_CURVEEDITOR_MAP")));
+ mapshape->setTooltip(M("TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP"));
+ std::vector milestones222;
+ milestones222.push_back( GradientMilestone(0., 0., 0., 0.) );
+ milestones222.push_back( GradientMilestone(1., 1., 1., 1.) );
+ mapshape->setBottomBarBgGradient(milestones222);
+ mapshape->setLeftBarBgGradient(milestones222);
+
+ curveEditormap->curveListComplete();
// Transmission map curve
transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_TRANSMISSION"));
@@ -145,7 +156,10 @@ 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, 6., 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.));
+ grads = Gtk::manage (new Adjuster (M("TP_RETINEX_GRADS"), -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));
@@ -154,10 +168,48 @@ 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"));
+ grads->set_tooltip_markup (M("TP_RETINEX_GRADS_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"));
+
+ mapbox = Gtk::manage (new Gtk::HBox ());
+ labmap = Gtk::manage (new Gtk::Label (M("TP_RETINEX_MAP") + ":"));
+ mapbox->pack_start (*labmap, Gtk::PACK_SHRINK, 1);
+
+ mapMethod = Gtk::manage (new MyComboBoxText ());
+ mapMethod->append_text (M("TP_RETINEX_MAP_NONE"));
+ mapMethod->append_text (M("TP_RETINEX_MAP_CURV"));
+ mapMethod->append_text (M("TP_RETINEX_MAP_GAUS"));
+ mapMethod->append_text (M("TP_RETINEX_MAP_MAPP"));
+ mapMethod->append_text (M("TP_RETINEX_MAP_MAPT"));
+ mapMethod->set_active(0);
+ mapMethodConn = mapMethod->signal_changed().connect ( sigc::mem_fun(*this, &Retinex::mapMethodChanged) );
+ mapMethod->set_tooltip_markup (M("TP_RETINEX_MAP_METHOD_TOOLTIP"));
+
+ highlights = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0));
+ h_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 80));
+ shadows = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0));
+ s_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80));
+ radius = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 40));
+
+ viewbox = Gtk::manage (new Gtk::HBox ());
+ labview = Gtk::manage (new Gtk::Label (M("TP_RETINEX_VIEW") + ":"));
+ viewbox->pack_start (*labview, Gtk::PACK_SHRINK, 1);
+
+ viewMethod = Gtk::manage (new MyComboBoxText ());
+ viewMethod->append_text (M("TP_RETINEX_VIEW_NONE"));
+ viewMethod->append_text (M("TP_RETINEX_VIEW_MASK"));
+ viewMethod->append_text (M("TP_RETINEX_VIEW_UNSHARP"));
+ viewMethod->append_text (M("TP_RETINEX_VIEW_TRAN"));
+ viewMethod->append_text (M("TP_RETINEX_VIEW_TRAN2"));
+ viewMethod->set_active(0);
+ viewMethodConn = viewMethod->signal_changed().connect ( sigc::mem_fun(*this, &Retinex::viewMethodChanged) );
+ viewMethod->set_tooltip_markup (M("TP_RETINEX_VIEW_METHOD_TOOLTIP"));
+
curveEditorGH = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_LH"));
curveEditorGH->setCurveListener (this);
@@ -212,8 +264,17 @@ 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 (*grads);
+ grads->show ();
settingsVBox->pack_start (*gain);
gain->show ();
@@ -227,6 +288,30 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
settingsVBox->pack_start (*limd);
limd->show ();
+ settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator()));
+
+ mapbox->pack_start(*mapMethod);
+ settingsVBox->pack_start(*mapbox);
+
+ settingsVBox->pack_start (*curveEditormap, Gtk::PACK_SHRINK, 4);
+ curveEditormap->show();
+
+ settingsVBox->pack_start (*highlights);
+ highlights->show();
+ settingsVBox->pack_start (*h_tonalwidth);
+ h_tonalwidth->show();
+ settingsVBox->pack_start (*shadows);
+ shadows->show();
+ settingsVBox->pack_start (*s_tonalwidth);
+ s_tonalwidth->show();
+ settingsVBox->pack_start (*radius);
+ radius->show();
+
+ viewbox->pack_start(*viewMethod);
+ settingsVBox->pack_start(*viewbox);
+
+ //settingsVBox->pack_start (*viewMethod);
+
// settingsVBox->pack_start (*highl);
// highl->show ();
@@ -235,6 +320,7 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
// settingsVBox->pack_start (*grbl);
// grbl->show ();
+ settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator()));
settingsVBox->pack_start( *transmissionCurveEditorG, Gtk::PACK_SHRINK, 2);
transmissionCurveEditorG->show();
@@ -268,6 +354,24 @@ 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;
+ }
+
+ grads->setAdjusterListener (this);
+
+ if (grads->delay < 200) {
+ grads->delay = 200;
+ }
+
gam->setAdjusterListener (this);
if (gam->delay < 500) {
@@ -322,6 +426,32 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"),
baselog->delay = 200;
}
+
+ radius->setAdjusterListener (this);
+ if (radius->delay < 200) {
+ radius->delay = 200;
+ }
+
+ highlights->setAdjusterListener (this);
+ if (highlights->delay < 200) {
+ highlights->delay = 200;
+ }
+
+ h_tonalwidth->setAdjusterListener (this);
+ if (h_tonalwidth->delay < 200) {
+ h_tonalwidth->delay = 200;
+ }
+
+ shadows->setAdjusterListener (this);
+ if (shadows->delay < 200) {
+ shadows->delay = 200;
+ }
+
+ s_tonalwidth->setAdjusterListener (this);
+ if (s_tonalwidth->delay < 200) {
+ s_tonalwidth->delay = 200;
+ }
+
/* grbl->setAdjusterListener (this);
if (grbl->delay < 200) {
@@ -346,6 +476,7 @@ Retinex::~Retinex()
delete curveEditorGDH;
delete transmissionCurveEditorG;
delete curveEditorGH;
+ delete curveEditormap;
}
void Retinex::neutral_pressed ()
@@ -355,16 +486,30 @@ void Retinex::neutral_pressed ()
offs->resetValue(false);
str->resetValue(false);
scal->resetValue(false);
+ iter->resetValue(false);
+ grad->resetValue(false);
+ grads->resetValue(false);
vart->resetValue(false);
limd->resetValue(false);
highl->resetValue(false);
baselog->resetValue(false);
gam->resetValue(false);
slope->resetValue(false);
+ highlights->resetValue(false);
+ h_tonalwidth->resetValue(false);
+ shadows->resetValue(false);
+ s_tonalwidth->resetValue(false);
+ radius->resetValue(false);
+ mapMethod->set_active(0);
+ viewMethod->set_active(0);
+ retinexMethod->set_active(2);
+ retinexcolorspace->set_active(0);
+ gammaretinex->set_active(0);
transmissionShape->reset();
cdshape->reset();
cdshapeH->reset();
lhshape->reset();
+ mapshape->reset();
}
void Retinex::foldAllButMe (GdkEventButton* event, MyExpander *expander)
@@ -474,10 +619,15 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
retinexMethodConn.block(true);
retinexColorSpaceConn.block(true);
gammaretinexConn.block(true);
+ mapMethodConn.block(true);
+ viewMethodConn.block(true);
if (pedited) {
scal->setEditedState (pedited->retinex.scal ? Edited : UnEdited);
+ iter->setEditedState (pedited->retinex.iter ? Edited : UnEdited);
+ grad->setEditedState (pedited->retinex.grad ? Edited : UnEdited);
+ grads->setEditedState (pedited->retinex.grads ? Edited : UnEdited);
neigh->setEditedState (pedited->retinex.neigh ? Edited : UnEdited);
gam->setEditedState (pedited->retinex.gam ? Edited : UnEdited);
slope->setEditedState (pedited->retinex.slope ? Edited : UnEdited);
@@ -490,12 +640,25 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
// grbl->setEditedState (pedited->retinex.grbl ? Edited : UnEdited);
set_inconsistent (multiImage && !pedited->retinex.enabled);
medianmap->set_inconsistent (!pedited->retinex.medianmap);
+ radius->setEditedState (pedited->retinex.radius ? Edited : UnEdited);
+ highlights->setEditedState (pedited->retinex.highlights ? Edited : UnEdited);
+ h_tonalwidth->setEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited);
+ shadows->setEditedState (pedited->retinex.shadows ? Edited : UnEdited);
+ s_tonalwidth->setEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited);
if (!pedited->retinex.retinexMethod) {
retinexMethod->set_active_text(M("GENERAL_UNCHANGED"));
}
+ if (!pedited->retinex.mapMethod) {
+ mapMethod->set_active_text(M("GENERAL_UNCHANGED"));
+ }
+
+ if (!pedited->retinex.viewMethod) {
+ viewMethod->set_active_text(M("GENERAL_UNCHANGED"));
+ }
+
if (!pedited->retinex.retinexcolorspace) {
retinexcolorspace->set_active_text(M("GENERAL_UNCHANGED"));
}
@@ -508,6 +671,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
cdshapeH->setUnChanged (!pedited->retinex.cdHcurve);
transmissionShape->setUnChanged (!pedited->retinex.transmissionCurve);
lhshape->setUnChanged (!pedited->retinex.lhcurve);
+ mapshape->setUnChanged (!pedited->retinex.mapcurve);
}
@@ -516,17 +680,36 @@ 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);
+ grads->setValue (pp->retinex.grads);
vart->setValue (pp->retinex.vart);
limd->setValue (pp->retinex.limd);
gam->setValue (pp->retinex.gam);
slope->setValue (pp->retinex.slope);
highl->setValue (pp->retinex.highl);
baselog->setValue (pp->retinex.baselog);
+
+ radius->setValue (pp->retinex.radius);
+ highlights->setValue (pp->retinex.highlights);
+ h_tonalwidth->setValue (pp->retinex.htonalwidth);
+ shadows->setValue (pp->retinex.shadows);
+ s_tonalwidth->setValue (pp->retinex.stonalwidth);
+
// grbl->setValue (pp->retinex.grbl);
+ if(pp->retinex.iter == 1) {
+ grad->set_sensitive(false);
+ scal->set_sensitive(false);
+ grads->set_sensitive(false);
+ }
+ else {
+ grad->set_sensitive(true);
+ scal->set_sensitive(true);
+ grads->set_sensitive(true);
+ }
setEnabled (pp->retinex.enabled);
- medianmapConn.block (true);
medianmap->set_active (pp->retinex.medianmap);
medianmapConn.block (false);
lastmedianmap = pp->retinex.medianmap;
@@ -543,6 +726,30 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
// retinexMethod->set_active (4);
}
+ if (pp->retinex.mapMethod == "none") {
+ mapMethod->set_active (0);
+ } else if (pp->retinex.mapMethod == "curv") {
+ mapMethod->set_active (1);
+ } else if (pp->retinex.mapMethod == "gaus") {
+ mapMethod->set_active (2);
+ } else if (pp->retinex.mapMethod == "map") {
+ mapMethod->set_active (3);
+ } else if (pp->retinex.mapMethod == "mapT") {
+ mapMethod->set_active (4);
+ }
+
+ if (pp->retinex.viewMethod == "none") {
+ viewMethod->set_active (0);
+ } else if (pp->retinex.viewMethod == "mask") {
+ viewMethod->set_active (1);
+ } else if (pp->retinex.viewMethod == "unsharp") {
+ viewMethod->set_active (2);
+ } else if (pp->retinex.viewMethod == "tran") {
+ viewMethod->set_active (3);
+ } else if (pp->retinex.viewMethod == "tran2") {
+ viewMethod->set_active (4);
+ }
+
if (pp->retinex.retinexcolorspace == "Lab") {
retinexcolorspace->set_active (0);
} else if (pp->retinex.retinexcolorspace == "HSLLOG") {
@@ -566,6 +773,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
retinexMethodChanged ();
retinexColorSpaceChanged();
gammaretinexChanged();
+ mapMethodChanged ();
+ viewMethodChanged ();
medianmapConn.block(true);
medianmapChanged ();
@@ -574,10 +783,13 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
cdshape->setCurve (pp->retinex.cdcurve);
cdshapeH->setCurve (pp->retinex.cdHcurve);
lhshape->setCurve (pp->retinex.lhcurve);
+ mapshape->setCurve (pp->retinex.mapcurve);
retinexMethodConn.block(false);
retinexColorSpaceConn.block(false);
gammaretinexConn.block(false);
+ mapMethodConn.block(false);
+ viewMethodConn.block(false);
transmissionShape->setCurve (pp->retinex.transmissionCurve);
@@ -591,6 +803,9 @@ 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.grads = (int) grads->getValue ();
pp->retinex.gam = gam->getValue ();
pp->retinex.slope = slope->getValue ();
pp->retinex.neigh = neigh->getValue ();
@@ -604,18 +819,30 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
pp->retinex.cdcurve = cdshape->getCurve ();
pp->retinex.lhcurve = lhshape->getCurve ();
pp->retinex.cdHcurve = cdshapeH->getCurve ();
+ pp->retinex.mapcurve = mapshape->getCurve ();
pp->retinex.transmissionCurve = transmissionShape->getCurve ();
pp->retinex.enabled = getEnabled();
pp->retinex.medianmap = medianmap->get_active();
+ pp->retinex.radius = (int)radius->getValue ();
+ pp->retinex.highlights = (int)highlights->getValue ();
+ pp->retinex.htonalwidth = (int)h_tonalwidth->getValue ();
+ pp->retinex.shadows = (int)shadows->getValue ();
+ pp->retinex.stonalwidth = (int)s_tonalwidth->getValue ();
+
if (pedited) {
pedited->retinex.retinexMethod = retinexMethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->retinex.retinexcolorspace = retinexcolorspace->get_active_text() != M("GENERAL_UNCHANGED");
pedited->retinex.gammaretinex = gammaretinex->get_active_text() != M("GENERAL_UNCHANGED");
+ pedited->retinex.mapMethod = mapMethod->get_active_text() != M("GENERAL_UNCHANGED");
+ pedited->retinex.viewMethod = viewMethod->get_active_text() != M("GENERAL_UNCHANGED");
//%%%%%%%%%%%%%%%%%%%%%%
pedited->retinex.str = str->getEditedState ();
pedited->retinex.scal = scal->getEditedState ();
+ pedited->retinex.iter = iter->getEditedState ();
+ pedited->retinex.grad = grad->getEditedState ();
+ pedited->retinex.grads = grads->getEditedState ();
pedited->retinex.gam = gam->getEditedState ();
pedited->retinex.slope = slope->getEditedState ();
pedited->retinex.neigh = neigh->getEditedState ();
@@ -629,10 +856,17 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
pedited->retinex.cdcurve = !cdshape->isUnChanged ();
pedited->retinex.cdHcurve = !cdshapeH->isUnChanged ();
pedited->retinex.transmissionCurve = !transmissionShape->isUnChanged ();
+ pedited->retinex.mapcurve = !mapshape->isUnChanged ();
pedited->retinex.enabled = !get_inconsistent();
pedited->retinex.medianmap = !medianmap->get_inconsistent();
pedited->retinex.lhcurve = !lhshape->isUnChanged ();
+ pedited->retinex.radius = radius->getEditedState ();
+ pedited->retinex.highlights = highlights->getEditedState ();
+ pedited->retinex.htonalwidth = h_tonalwidth->getEditedState ();
+ pedited->retinex.shadows = shadows->getEditedState ();
+ pedited->retinex.stonalwidth = s_tonalwidth->getEditedState ();
+
}
if (retinexMethod->get_active_row_number() == 0) {
@@ -647,6 +881,30 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
// pp->retinex.retinexMethod = "highliplus";
}
+ if (mapMethod->get_active_row_number() == 0) {
+ pp->retinex.mapMethod = "none";
+ } else if (mapMethod->get_active_row_number() == 1) {
+ pp->retinex.mapMethod = "curv";
+ } else if (mapMethod->get_active_row_number() == 2) {
+ pp->retinex.mapMethod = "gaus";
+ } else if (mapMethod->get_active_row_number() == 3) {
+ pp->retinex.mapMethod = "map";
+ } else if (mapMethod->get_active_row_number() == 4) {
+ pp->retinex.mapMethod = "mapT";
+ }
+
+ if (viewMethod->get_active_row_number() == 0) {
+ pp->retinex.viewMethod = "none";
+ } else if (viewMethod->get_active_row_number() == 1) {
+ pp->retinex.viewMethod = "mask";
+ } else if (viewMethod->get_active_row_number() == 2) {
+ pp->retinex.viewMethod = "unsharp";
+ } else if (viewMethod->get_active_row_number() == 3) {
+ pp->retinex.viewMethod = "tran";
+ } else if (viewMethod->get_active_row_number() == 4) {
+ pp->retinex.viewMethod = "tran2";
+ }
+
if (retinexcolorspace->get_active_row_number() == 0) {
pp->retinex.retinexcolorspace = "Lab";
} else if (retinexcolorspace->get_active_row_number() == 1) {
@@ -683,6 +941,83 @@ void Retinex::retinexMethodChanged()
}
}
+
+
+void Retinex::mapMethodChanged()
+{
+
+ if(mapMethod->get_active_row_number() == 1 || mapMethod->get_active_row_number() == 2) {
+ curveEditormap->show();
+ highlights->show();
+ h_tonalwidth->show();
+ shadows->show();
+ s_tonalwidth->show();
+ radius->show();
+ } else if(mapMethod->get_active_row_number() == 3 || mapMethod->get_active_row_number() == 4) {
+ curveEditormap->show();
+ highlights->show();
+ h_tonalwidth->show();
+ shadows->show();
+ s_tonalwidth->show();
+ radius->hide();
+ } else {
+ curveEditormap->hide();
+ highlights->hide();
+ h_tonalwidth->hide();
+ shadows->hide();
+ s_tonalwidth->hide();
+ radius->hide();
+
+ }
+
+ if (listener) {
+ listener->panelChanged (EvmapMethod, mapMethod->get_active_text ());
+ }
+}
+
+void Retinex::viewMethodChanged()
+{
+ if(viewMethod->get_active_row_number() == 1 || viewMethod->get_active_row_number() == 2) {
+ vart->hide();
+ gain->hide();
+ offs->hide();
+ limd->hide();
+ transmissionCurveEditorG->hide();
+ medianmap->hide();
+ iter->hide();
+ scal->hide();
+ grad->hide();
+ grads->hide();
+ curveEditorGH->hide();
+ }
+ else if(viewMethod->get_active_row_number() == 3 || viewMethod->get_active_row_number() == 4) {
+ gain->hide();
+ offs->hide();
+ vart->hide();
+ curveEditorGH->hide();
+ }
+ else {
+ vart->show();
+ neigh->show();
+ gain->show();
+ offs->show();
+ limd->show();
+ transmissionCurveEditorG->show();
+ medianmap->show();
+ iter->show();
+ scal->show();
+ grad->show();
+ grads->show();
+ curveEditorGH->show();
+ }
+
+ if (listener) {
+ listener->panelChanged (EvviewMethod, viewMethod->get_active_text ());
+ }
+}
+
+
+
void Retinex::ColorSpaceUpdateUI ()
{
if (!batchMode) {
@@ -771,6 +1106,9 @@ 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);
+ grads->setDefault (defParams->retinex.grads);
vart->setDefault (defParams->retinex.vart);
limd->setDefault (defParams->retinex.limd);
highl->setDefault (defParams->retinex.highl);
@@ -779,12 +1117,21 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
gam->setDefault (defParams->retinex.gam);
slope->setDefault (defParams->retinex.slope);
+ radius->setDefault (defParams->retinex.radius);
+ highlights->setDefault (defParams->retinex.highlights);
+ h_tonalwidth->setDefault (defParams->retinex.htonalwidth);
+ shadows->setDefault (defParams->retinex.shadows);
+ s_tonalwidth->setDefault (defParams->retinex.stonalwidth);
+
if (pedited) {
neigh->setDefaultEditedState (pedited->retinex.neigh ? Edited : UnEdited);
gain->setDefaultEditedState (pedited->retinex.gain ? Edited : UnEdited);
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);
+ grads->setDefaultEditedState (pedited->retinex.grads ? Edited : UnEdited);
vart->setDefaultEditedState (pedited->retinex.vart ? Edited : UnEdited);
limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited);
highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited);
@@ -793,6 +1140,12 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
gam->setDefaultEditedState (pedited->retinex.gam ? Edited : UnEdited);
slope->setDefaultEditedState (pedited->retinex.slope ? Edited : UnEdited);
+ radius->setDefaultEditedState (pedited->retinex.radius ? Edited : UnEdited);
+ highlights->setDefaultEditedState (pedited->retinex.highlights ? Edited : UnEdited);
+ h_tonalwidth->setDefaultEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited);
+ shadows->setDefaultEditedState (pedited->retinex.shadows ? Edited : UnEdited);
+ s_tonalwidth->setDefaultEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited);
+
} else {
neigh->setDefaultEditedState (Irrelevant);
gain->setDefaultEditedState (Irrelevant);
@@ -804,8 +1157,18 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
// grbl->setDefaultEditedState (Irrelevant);
str->setDefaultEditedState (Irrelevant);
scal->setDefaultEditedState (Irrelevant);
+ iter->setDefaultEditedState (Irrelevant);
+ grad->setDefaultEditedState (Irrelevant);
+ grads->setDefaultEditedState (Irrelevant);
gam->setDefaultEditedState (Irrelevant);
slope->setDefaultEditedState (Irrelevant);
+
+ radius->setDefaultEditedState (Irrelevant);
+ highlights->setDefaultEditedState (Irrelevant);
+ h_tonalwidth->setDefaultEditedState (Irrelevant);
+ shadows->setDefaultEditedState (Irrelevant);
+ s_tonalwidth->setDefaultEditedState (Irrelevant);
+
}
}
@@ -828,6 +1191,17 @@ void Retinex::adjusterChanged (Adjuster* a, double newval)
if (!listener || !getEnabled()) {
return;
}
+ if(iter->getTextValue() > "1") {
+ scal->set_sensitive(true);
+ grad->set_sensitive(true);
+ grads->set_sensitive(true);
+ }
+ else {
+ scal->set_sensitive(false);
+ grad->set_sensitive(false);
+ grads->set_sensitive(false);
+ }
+
if (a == neigh) {
listener->panelChanged (EvLneigh, neigh->getTextValue());
@@ -835,6 +1209,12 @@ 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 == grads) {
+ listener->panelChanged (EvLgrads, grads->getTextValue());
} else if (a == gain) {
listener->panelChanged (EvLgain, gain->getTextValue());
} else if (a == offs) {
@@ -853,8 +1233,20 @@ void Retinex::adjusterChanged (Adjuster* a, double newval)
listener->panelChanged (EvLgam, gam->getTextValue());
} else if (a == slope) {
listener->panelChanged (EvLslope, slope->getTextValue());
+ } else if (a == highlights) {
+ listener->panelChanged (EvLhighlights, highlights->getTextValue());
+ } else if (a == h_tonalwidth) {
+ listener->panelChanged (EvLh_tonalwidth, h_tonalwidth->getTextValue());
+ } else if (a == shadows) {
+ listener->panelChanged (EvLshadows, shadows->getTextValue());
+ } else if (a == s_tonalwidth) {
+ listener->panelChanged (EvLs_tonalwidth, s_tonalwidth->getTextValue());
+ } else if (a == radius) {
+ listener->panelChanged (EvLradius, radius->getTextValue());
+
}
+
}
@@ -865,6 +1257,7 @@ void Retinex::autoOpenCurve ()
cdshapeH->openIfNonlinear();
transmissionShape->openIfNonlinear();
lhshape->openIfNonlinear();
+ mapshape->openIfNonlinear();
}
@@ -880,6 +1273,8 @@ void Retinex::curveChanged (CurveEditor* ce)
listener->panelChanged (EvRetinextransmission, M("HISTORY_CUSTOMCURVE"));
} else if (ce == lhshape) {
listener->panelChanged (EvRetinexlhcurve, M("HISTORY_CUSTOMCURVE"));
+ } else if (ce == mapshape) {
+ listener->panelChanged (EvRetinexmapcurve, M("HISTORY_CUSTOMCURVE"));
}
}
}
@@ -903,6 +1298,9 @@ 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);
+ grads->trimValue(pp->retinex.grads);
neigh->trimValue(pp->retinex.neigh);
gain->trimValue(pp->retinex.gain);
offs->trimValue(pp->retinex.offs);
@@ -913,6 +1311,8 @@ void Retinex::trimValues (rtengine::procparams::ProcParams* pp)
// grbl->trimValue(pp->retinex.grbl);
gam->trimValue(pp->retinex.gam);
slope->trimValue(pp->retinex.slope);
+ highlights->trimValue(pp->retinex.highlights);
+ shadows->trimValue(pp->retinex.shadows);
}
void Retinex::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI)
@@ -976,17 +1376,28 @@ void Retinex::setBatchMode (bool batchMode)
offs->showEditedCB ();
str->showEditedCB ();
scal->showEditedCB ();
+ iter->showEditedCB ();
+ grad->showEditedCB ();
+ grads->showEditedCB ();
gam->showEditedCB ();
slope->showEditedCB ();
vart->showEditedCB ();
limd->showEditedCB ();
highl->showEditedCB ();
baselog->showEditedCB ();
+
+ radius->showEditedCB ();
+ highlights->showEditedCB ();
+ h_tonalwidth->showEditedCB ();
+ shadows->showEditedCB ();
+ s_tonalwidth->showEditedCB ();
+
// grbl->showEditedCB ();
curveEditorGD->setBatchMode (batchMode);
curveEditorGDH->setBatchMode (batchMode);
transmissionCurveEditorG->setBatchMode (batchMode);
curveEditorGH->setBatchMode (batchMode);
+ curveEditormap->setBatchMode (batchMode);
}
diff --git a/rtgui/retinex.h b/rtgui/retinex.h
index 59001ce18..d24254757 100644
--- a/rtgui/retinex.h
+++ b/rtgui/retinex.h
@@ -22,8 +22,12 @@ protected:
CurveEditorGroup* curveEditorGD;
CurveEditorGroup* curveEditorGDH;
CurveEditorGroup* curveEditorGH;
+ CurveEditorGroup* curveEditormap;
Adjuster* str;
Adjuster* scal;
+ Adjuster* grad;
+ Adjuster* grads;
+ Adjuster* iter;
Adjuster* neigh;
Adjuster* gain;
Adjuster* offs;
@@ -34,10 +38,21 @@ protected:
Adjuster* grbl;
Adjuster* gam;
Adjuster* slope;
+ Adjuster* highlights;
+ Adjuster* h_tonalwidth;
+ Adjuster* shadows;
+ Adjuster* s_tonalwidth;
+ Adjuster* radius;
+
MyExpander* expsettings;
Gtk::Label* labmdh;
Gtk::HBox* dhbox;
+ Gtk::HBox* mapbox;
+ Gtk::Label* labmap;
+ Gtk::HBox* viewbox;
+ Gtk::Label* labview;
+
Gtk::Label* labgam;
Gtk::HBox* gambox;
Gtk::Button* neutral;
@@ -46,6 +61,8 @@ protected:
MyComboBoxText* retinexMethod;
MyComboBoxText* retinexcolorspace;
MyComboBoxText* gammaretinex;
+ MyComboBoxText* mapMethod;
+ MyComboBoxText* viewMethod;
Gtk::CheckButton* medianmap;
double nextmin;
double nextmax;
@@ -62,8 +79,9 @@ protected:
DiagonalCurveEditor* cdshape;
DiagonalCurveEditor* cdshapeH;
+ DiagonalCurveEditor* mapshape;
CurveEditorGroup* transmissionCurveEditorG;
- sigc::connection retinexMethodConn, neutralconn;
+ sigc::connection retinexMethodConn, neutralconn, mapMethodConn, viewMethodConn;
sigc::connection retinexColorSpaceConn;
sigc::connection gammaretinexConn;
FlatCurveEditor* transmissionShape;
@@ -92,6 +110,8 @@ public:
void enabledChanged ();
void curveChanged (CurveEditor* ce);
void retinexMethodChanged();
+ void mapMethodChanged();
+ void viewMethodChanged();
void retinexColorSpaceChanged();
void gammaretinexChanged();
void ColorSpaceUpdateUI();