diff --git a/rtdata/languages/default b/rtdata/languages/default
index 68a5f29c9..9db59170f 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -711,8 +711,8 @@ HISTORY_MSG_476;Local - Sh Iterations
HISTORY_MSG_477;Local - Sh Scope
HISTORY_MSG_478;Local - Sh Inverse
HISTORY_MSG_479;Local - Spot size
-HISTORY_MSG_480;Local - Hue theshold
-HISTORY_MSG_481;Local - Hue proximity
+HISTORY_MSG_480;Local - artifacts theshold
+HISTORY_MSG_481;Local - artifacts iterations
HISTORY_MSG_482;Local - Quality
HISTORY_MSG_483;Local - Noise lum f
HISTORY_MSG_484;Local - Noise lum c
@@ -739,7 +739,7 @@ HISTORY_MSG_504;Local - Sharpening
HISTORY_MSG_505;Local - CBDL
HISTORY_MSG_506;Local - Denoise
HISTORY_MSG_507;Local - LH Curve
-HISTORY_MSG_508;Local - Enable curve
+HISTORY_MSG_508;Local - Enable super
HISTORY_MSG_509;Local - CC curve
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
@@ -1676,6 +1676,7 @@ TP_LENSPROFILE_USECA;Chromatic aberration correction
TP_LENSPROFILE_USEDIST;Distortion correction
TP_LENSPROFILE_USEVIGN;Vignetting correction
TP_LOCALLAB_ACTIV;Blur luminance only
+TP_LOCALLAB_ARTIF;Reduce artifacts - Improve algoritm
TP_LOCALLAB_AVOID;Avoid color shift
TP_LOCALLAB_BLUFR;Blur & Noise
TP_LOCALLAB_CENTER_X;Center X
@@ -1686,14 +1687,20 @@ TP_LOCALLAB_CHRRT;Chroma
TP_LOCALLAB_CIRCRADIUS;Spot size
TP_LOCALLAB_COFR;Color & Light
TP_LOCALLAB_CONTRAST;Contrast
-TP_LOCALLAB_CURV;Enable curves
+TP_LOCALLAB_CURV;Lightness - Contrast "Super"
+TP_LOCALLAB_CURVNONE;Disable curves
+TP_LOCALLAB_CURVCURR;Normal
+TP_LOCALLAB_CURVENH;Super
TP_LOCALLAB_DENOIS;Denoise
TP_LOCALLAB_LUM;Curves
TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To be active, you must check button 'Enable curves'
+TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) has the same algorithm than slider lightness.\n'Super' the curve L=f(L) has an new improved algorithm, which can leeds in some cases to artifacts.
TP_LOCALLAB_NOISELUMFINE;Luminance fine
TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse
TP_LOCALLAB_NOISECHROFINE;Chroma fine
TP_LOCALLAB_NOISECHROCOARSE;Chroma coarse
+TP_LOCALLAB_QUAL_METHOD;Global quality
+TP_LOCALLAB_QUALCURV_METHOD;Curves type
TP_LOCALLAB_GAM;Gamma
TP_LOCALLAB_ESTOP;Edge stopping
TP_LOCALLAB_SCALTM;Scale
@@ -1706,15 +1713,15 @@ TP_LOCALLAB_NEUTRAL;Reset
TP_LOCALLAB_NEUTRAL_TIP;Reset Current Control point
TP_LOCALLAB_NBSPOT;Control points
TP_LOCALLAB_NBSPOT_TOOLTIP;Add multiple control points and select
-TP_LOCALLAB_STD;Quality Standard
-TP_LOCALLAB_ENH;Quality Enhanced
-TP_LOCALLAB_ENHDEN;Quality Enhanced + chroma denoise
-TP_LOCALLAB_THRES;Hue threshold
-TP_LOCALLAB_PROXI;Hue proximity radius
+TP_LOCALLAB_STD;Standard
+TP_LOCALLAB_ENH;Enhanced
+TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise
+TP_LOCALLAB_THRES;Threshold chroma
+TP_LOCALLAB_PROXI;Iterations
TP_LOCALLAB_ANBSPOT;Help to Move Control point
TP_LOCALLAB_ANBSPOT_TOOLTIP;Provisory control (I hope somebody can help to manage events!! and suppress this bad function)
TP_LOCALLAB_LIGHTNESS;Lightness
-TP_LOCALLAB_METHOD_TOOLTIP;Default - standard.\nIf you select Enhanced or enhanced chroma denoise - only for Color Light-Sharpening-Retinex-CBDL in normal mode, algorithm will detect the variations of hue in the select area and improve shape detection.\nHue threshold define since what value is exclude (* 100 radians).\nHue proximity radius define the radius around each point to calculate variations.\nEnhanced and Hue threshold significantly increases processing times.
+TP_LOCALLAB_METHOD_TOOLTIP;Default - standard.\nIf you select Enhanced or enhanced chroma denoise - only for Color Light-Sharpening-Retinex-CBDL in normal mode\nEnhanced and chroma denoise significantly increases processing times.
TP_LOCALLAB_RADIUS;Radius
TP_LOCALLAB_RETI;Retinex
TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index 2db44d99f..7cbd443ea 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -957,6 +957,14 @@ void Crop::update (int todo)
params.locallab.curvactiv = true;
}
+ if (parent->qualitycurves[sp] == 0) {
+ params.locallab.qualitycurveMethod = "none" ;
+ } else if (parent->qualitycurves[sp] == 1) {
+ params.locallab.qualitycurveMethod = "std" ;
+ } else if (parent->qualitycurves[sp] == 2) {
+ params.locallab.qualitycurveMethod = "enh" ;
+ }
+
std::vector cretie;
for (int j = 0; j < parent->sizeretics[sp]; j++) {
@@ -1176,6 +1184,17 @@ void Crop::update (int todo)
}
+ if (parent->qualitycurves[sp] == 0) {
+ params.locallab.qualitycurveMethod = "none" ;
+ parent->qualitycurves[sp] = 0;
+ } else if (parent->qualitycurves[sp] == 1) {
+ params.locallab.qualitycurveMethod = "std" ;
+ parent->qualitycurves[sp] = 1;
+ } else if (parent->qualitycurves[sp] == 2) {
+ params.locallab.qualitycurveMethod = "enh" ;
+ parent->qualitycurves[sp] = 2;
+ }
+
std::vector ccret;
for (int j = 0; j < parent->sizeretics[sp]; j++) {
diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc
index dd7211667..e5aced0fc 100644
--- a/rtengine/dirpyr_equalizer.cc
+++ b/rtengine/dirpyr_equalizer.cc
@@ -360,78 +360,6 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp(float ** src, float ** dst,
}
float **tmpHue, **tmpChr;
- /*
- if(skinprot != 0.f) {
- // precalculate hue and chroma, use SSE, if available
- // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel()
- // but we need two additional buffers for this preprocessing
- tmpHue = new float*[srcheight];
-
- for (int i = 0; i < srcheight; i++) {
- tmpHue[i] = new float[srcwidth];
- }
-
- #ifdef __SSE2__
- #pragma omp parallel for
-
- for(int i = 0; i < srcheight; i++) {
- int j;
-
- for(j = 0; j < srcwidth - 3; j += 4) {
- _mm_storeu_ps(&tmpHue[i][j], xatan2f(LVFU(l_b[i][j]), LVFU(l_a[i][j])));
- }
-
- for(; j < srcwidth; j++) {
- tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]);
- }
- }
-
- #else
- #pragma omp parallel for
-
- for(int i = 0; i < srcheight; i++) {
- for(int j = 0; j < srcwidth; j++) {
- tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]);
- }
- }
-
- #endif
- tmpChr = new float*[srcheight];
-
- for (int i = 0; i < srcheight; i++) {
- tmpChr[i] = new float[srcwidth];
- }
-
- #ifdef __SSE2__
- #pragma omp parallel
- {
- __m128 div = _mm_set1_ps(327.68f);
- #pragma omp for
-
- for(int i = 0; i < srcheight; i++) {
- int j;
-
- for(j = 0; j < srcwidth - 3; j += 4) {
- _mm_storeu_ps(&tmpChr[i][j], _mm_sqrt_ps(SQRV(LVFU(l_b[i][j])) + SQRV(LVFU(l_a[i][j]))) / div);
- }
-
- for(; j < srcwidth; j++) {
- tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f;
- }
- }
- }
- #else
- #pragma omp parallel for
-
- for(int i = 0; i < srcheight; i++) {
- for(int j = 0; j < srcwidth; j++) {
- tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f;
- }
- }
-
- #endif
- }
- */
// with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory
float ** buffer = dirpyrlo[lastlevel - 1];
@@ -442,21 +370,6 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp(float ** src, float ** dst,
scale = scalesloc[0];
idirpyr_eq_channel_loc(dirpyrlo[0], dst, loctemp, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice );
- /*
- if(skinprot != 0.f) {
- for (int i = 0; i < srcheight; i++) {
- delete [] tmpChr[i];
- }
-
- delete [] tmpChr;
-
- for (int i = 0; i < srcheight; i++) {
- delete [] tmpHue[i];
- }
-
- delete [] tmpHue;
- }
- */
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#pragma omp parallel for
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 0dfad4555..95c530c2f 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -149,6 +149,7 @@ ImProcCoordinator::ImProcCoordinator ()
sizelhcs (500, -10000),
cccurvs (25000, -10000), //allow 500 values for each control point * 500
sizecccs (500, -10000),
+ qualitycurves (500, -10000),
lumarefs (500, -100000.f),
chromarefs (500, -100000.f),
@@ -821,7 +822,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
{
for (int sp = 1; sp < maxspot; sp++) { // spots default
int t_sp = sp;
- int t_mipversion = 10006;//new value for tone mapping
+ int t_mipversion = 10007;//new value for tone mapping
int t_circrad = 18;
int t_locX = 250;
int t_locY = 250;
@@ -855,8 +856,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int t_sensisha = 19;
int t_inverssha = 0;
int t_qualityMethod = 0;
- int t_thres = 50;
- int t_proxi = 2;
+ int t_thres = 18;
+ int t_proxi = 20;
int t_noiselumf = 0;
int t_noiselumc = 0;
int t_noisechrof = 0;
@@ -869,6 +870,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int t_threshold = 20;
int t_sensicb = 19;
int t_activlum = 0;
+
// end versionmip = 10000
//begin versionmip = 10001 Tone mapping
@@ -894,6 +896,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
//10006
std::string t_curvcc = "3000A0B0C1000D1000E"; //"3000A0B0C499D501E1000F1000G";// "3000A0B0C1000D1000E";//with that it works !
+ //10007
+ int t_qualitycurveMethod = 0;
+
//all variables except locRETgainCurve 'coomon for all)
fic << "Mipversion=" << t_mipversion << '@' << endl;
fic << "Spot=" << t_sp << '@' << endl;
@@ -954,6 +959,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
fic << "Retrab=" << t_retrab << '@' << endl;
fic << "Curvactiv=" << t_curvactiv << '@' << endl;
+ fic << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl;
fic << "curveReti=" << t_curvret << '@' << endl;
fic << "curveLL=" << t_curvll << '@' << endl;
@@ -977,9 +983,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int realspot = params.locallab.nbspot;
std::string inser;
- dataspot = new int*[60];
+ dataspot = new int*[61];
- for (int i = 0; i < 60; i++) {
+ for (int i = 0; i < 61; i++) {
dataspot[i] = new int[maxspot];
}
@@ -1107,6 +1113,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
dataspot[56][0] = curvactivs[0] = 1;
}
+ if (params.locallab.qualitycurveMethod == "none") {
+ dataspot[57][0] = qualitycurves[0] = 0;
+ } else if (params.locallab.qualitycurveMethod == "std") {
+ dataspot[57][0] = qualitycurves[0] = 1;
+ } else if (params.locallab.qualitycurveMethod == "enh") {
+ dataspot[57][0] = qualitycurves[0] = 2;
+ }
+
//curve Reti local
int siz = params.locallab.localTgaincurve.size();
@@ -1234,7 +1248,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
std::string line;
std::string spotline;
int cont = 0;
- int maxind = 57;
+ int maxind = 58;
if (versionmip == 10000) {
maxind = 49;
@@ -1259,6 +1273,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
excurvcc = false;
}
+ if (versionmip == 10006) {
+ maxind = 57;
+ }
+
int sizecu;
int sizell;
int sizelh;
@@ -1436,13 +1454,20 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
+ if (versionmip == 10006) {
+
+ for (int sp = 1; sp < maxspot; sp++) { // spots default
+ dataspot[57][sp] = 0; //qualitycurveMethod
+ }
+ }
+
if (ns < (maxspot - 1)) {
ofstream fic (datal, ios::out | ios::app); // ouverture en écriture avec effacement du fichier ouvert
for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default
int t_sp = sp;
- int t_mipversion = 10006;
+ int t_mipversion = 10007;
int t_circrad = 18;
int t_locX = 250;
int t_locY = 250;
@@ -1476,8 +1501,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int t_sensisha = 19;
int t_inverssha = 0;
int t_qualityMethod = 0;
- int t_thres = 50;
- int t_proxi = 2;
+ int t_thres = 18;
+ int t_proxi = 20;
int t_noiselumf = 0;
int t_noiselumc = 0;
int t_noisechrof = 0;
@@ -1510,6 +1535,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int t_curvactiv = 0;
//10006
std::string t_curvcc = "3000A0B0C1000D1000E";
+ //10007
+ int t_qualitycurveMethod = 0;
fic << "Mipversion=" << t_mipversion << '@' << endl;
fic << "Spot=" << t_sp << '@' << endl;
@@ -1569,6 +1596,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
fic << "Sensitm=" << t_sensitm << '@' << endl;
fic << "Retrab=" << t_retrab << '@' << endl;
fic << "Curvactiv=" << t_curvactiv << '@' << endl;
+ fic << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl;
fic << "curveReti=" << t_curvret << '@' << endl;
fic << "curveLL=" << t_curvll << '@' << endl;
@@ -1589,7 +1617,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
std::string spotline2;
int cont2 = 0;
int ns2;
- int maxin = 57;
+ int maxin = 58;
int sizecu2;
int sizell2;
int sizelh2;
@@ -1861,6 +1889,17 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
params.locallab.curvactiv = true;
}
+ if (dataspot[57][sp] == 0) {
+ qualitycurves[sp] = 0;
+ params.locallab.qualitycurveMethod = "none" ;
+ } else if (dataspot[57][sp] == 1) {
+ qualitycurves[sp] = 1;
+ params.locallab.qualitycurveMethod = "std" ;
+ } else if (dataspot[57][sp] == 2) {
+ qualitycurves[sp] = 2;
+ params.locallab.qualitycurveMethod = "enh" ;
+ }
+
int *s_datc;
s_datc = new int[70];
int siz;
@@ -1952,9 +1991,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::curveCCLocal (localcutili, params.locallab.cccurve, cclocalcurve, sca); //scale == 1 ? 1 : 16);
ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
- dataspot[57][sp] = huerefs[sp] = 100.f * params.locallab.hueref;
- dataspot[58][sp] = chromarefs[sp] = params.locallab.chromaref;
- dataspot[59][sp] = lumarefs[sp] = params.locallab.lumaref;
+ dataspot[58][sp] = huerefs[sp] = 100.f * params.locallab.hueref;
+ dataspot[59][sp] = chromarefs[sp] = params.locallab.chromaref;
+ dataspot[60][sp] = lumarefs[sp] = params.locallab.lumaref;
nextParams.locallab.hueref = params.locallab.hueref;
nextParams.locallab.chromaref = params.locallab.chromaref;
nextParams.locallab.lumaref = params.locallab.lumaref;
@@ -2147,6 +2186,20 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
curvactivs[sp] = 1;
}
+ if (dataspot[57][0] == 0) {
+ params.locallab.qualitycurveMethod = "none" ;
+ qualitycurves[sp] = 0;
+ dataspot[57][sp] = 0;
+ } else if (dataspot[57][0] == 1) {
+ params.locallab.qualitycurveMethod = "std" ;
+ qualitycurves[sp] = 1;
+ dataspot[57][sp] = 1;
+ } else if (dataspot[57][0] == 2) {
+ params.locallab.qualitycurveMethod = "enh" ;
+ qualitycurves[sp] = 2;
+ dataspot[57][sp] = 2;
+ }
+
int *s_datc;
s_datc = new int[70];
int siz;
@@ -2243,9 +2296,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::curveCCLocal (localcutili, params.locallab.cccurve, cclocalcurve, sca); //scale == 1 ? 1 : 16);
ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
- dataspot[57][sp] = huerefs[sp] = 100.f * params.locallab.hueref;
- dataspot[58][sp] = chromarefs[sp] = params.locallab.chromaref;
- dataspot[59][sp] = lumarefs[sp] = params.locallab.lumaref;
+ dataspot[58][sp] = huerefs[sp] = 100.f * params.locallab.hueref;
+ dataspot[59][sp] = chromarefs[sp] = params.locallab.chromaref;
+ dataspot[60][sp] = lumarefs[sp] = params.locallab.lumaref;
lllocalcurve.clear();
cclocalcurve.clear();
@@ -2262,7 +2315,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
for (int spe = 1; spe < maxspot; spe++) {
int t_sp = spe;
- int t_mipversion = 10006;
+ int t_mipversion = 10007;
int t_circrad = dataspot[2][spe];
int t_locX = dataspot[3][spe];
int t_locY = dataspot[4][spe];
@@ -2319,10 +2372,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int t_sensitm = dataspot[54][spe];
int t_retrab = dataspot[55][spe];
int t_curvactiv = dataspot[56][spe];
+ int t_qualitycurveMethod = dataspot[57][spe];
- int t_hueref = dataspot[57][spe];
- int t_chromaref = dataspot[58][spe];
- int t_lumaref = dataspot[59][spe];
+ int t_hueref = dataspot[58][spe];
+ int t_chromaref = dataspot[59][spe];
+ int t_lumaref = dataspot[60][spe];
std::string t_curvret = retistr[spe];
std::string t_curvll = llstr[spe];
@@ -2388,6 +2442,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
fou << "Retrab=" << t_retrab << '@' << endl;
fou << "Curvactiv=" << t_curvactiv << '@' << endl;
+ fou << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl;
fou << "hueref=" << t_hueref << '@' << endl;
fou << "chromaref=" << t_chromaref << '@' << endl;
@@ -2405,7 +2460,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
- for (int i = 0; i < 60; i++) {
+ for (int i = 0; i < 61; i++) {
delete [] dataspot[i];
}
diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h
index 80e72e369..0404ad295 100644
--- a/rtengine/improccoordinator.h
+++ b/rtengine/improccoordinator.h
@@ -279,6 +279,7 @@ protected:
LUTi scaltms;
LUTi reweis;
LUTi sensitms;
+ LUTi qualitycurves;
int versionmip;
LUTi sizeretics;
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index 027715c40..63b280dbe 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -72,6 +72,7 @@ class ImProcFunctions
bool needsLCP ();
// static cmsUInt8Number* Mempro = NULL;
+
inline void interpolateTransformCubic (Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul)
{
const double A = -0.85;
@@ -284,7 +285,7 @@ public:
void InverseBlurNoise_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy);
void Reti_Local (int call, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro);
void InverseReti_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro);
- void Contrast_Local (int call, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra &lco, float lumaref, float av, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
+ void Contrast_Local (int call, LabImage * bufcontorig, float ** buflightc, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra &lco, float lumaref, float av, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
void cbdl_Local (int call, int sp, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
void BlurNoise_Local (int call, int sp, LabImage* tmp1, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
void TM_Local (int call, int sp, LabImage* tmp1, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
@@ -293,7 +294,7 @@ public:
void DeNoise_Local (int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy);
- void ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
+ void ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, float **buflight, float **bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
void InverseColorLight_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy);
void Sharp_Local (int call, int sp, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy);
diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc
index 996b943d5..9abb42507 100644
--- a/rtengine/iplocallab.cc
+++ b/rtengine/iplocallab.cc
@@ -45,6 +45,9 @@
#define CLIPC(a) ((a)>-42000?((a)<42000?(a):42000):-42000) // limit a and b to 130 probably enough ?
#define CLIPL(x) LIM(x,0.f,40000.f) // limit L to about L=120 probably enough ?
#define CLIPLOC(x) LIM(x,0.f,32767.f)
+#define CLIPLIG(x) LIM(x,0.f, 100.f)
+#define CLIPCHRO(x) LIM(x,0.f, 140.f)
+
namespace rtengine
{
using namespace procparams;
@@ -56,6 +59,7 @@ struct local_params {
float lx, ly;
float lxL, lyT;
float dxx, dyy;
+ float iterat;
int cir;
float thr;
int prox;
@@ -74,6 +78,7 @@ struct local_params {
bool actsp;
float str;
int qualmet;
+ int qualcurvemet;
float noiself;
float noiselc;
float noisecf;
@@ -115,10 +120,10 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str
double local_yT = locallab.locYT / 2000.0;
double local_center_x = locallab.centerX / 2000.0 + 0.5;
double local_center_y = locallab.centerY / 2000.0 + 0.5;
-// double local_dxx = locallab.proxi / 8000.0;//for proxi = 2==> # 1 pixel
-// double local_dyy = locallab.proxi / 8000.0;
- float local_dxx = locallab.proxi;
- double local_dyy = locallab.proxi;
+ double local_dxx = locallab.proxi / 8000.0;//for proxi = 2==> # 1 pixel
+ double local_dyy = locallab.proxi / 8000.0;
+ float iterati = (float) locallab.proxi;
+// double local_dyy = locallab.proxi;
if (locallab.qualityMethod == "std") {
lp.qualmet = 0;
@@ -128,6 +133,14 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str
lp.qualmet = 2;
}
+ if (locallab.qualitycurveMethod == "none") {
+ lp.qualcurvemet = 0;
+ } else if (locallab.qualitycurveMethod == "std") {
+ lp.qualcurvemet = 1;
+ } else if (locallab.qualitycurveMethod == "enh") {
+ lp.qualcurvemet = 2;
+ }
+
float local_noiself = locallab.noiselumf;
float local_noiselc = locallab.noiselumc;
float local_noisecf = locallab.noisechrof;
@@ -197,10 +210,12 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str
lp.shamo = local_sharamount;
lp.shdamp = local_shardamping;
lp.shiter = local_shariter;
- lp.dxx = local_dxx;
+ lp.iterat = iterati;
+ lp.dxx = w * local_dxx;
lp.dyy = h * local_dyy;
lp.thr = thre;
lp.noiself = local_noiself;
+ lp.noiself = local_noiself;
lp.noiselc = local_noiselc;
lp.noisecf = local_noisecf;
lp.noisecc = local_noisecc;
@@ -457,7 +472,7 @@ void ImProcFunctions::DeNoise_Local (int call, const struct local_params& lp, La
difa = tmp1->a[loy - begy - 1][lox - begx - 1] - original->a[y][x];
difb = tmp1->b[loy - begy - 1][lox - begx - 1] - original->b[y][x];
}
- } else if (call == 1) { //dcrop
+ } else { //dcrop
difL = tmp1->L[y][x] - original->L[y][x];
difa = tmp1->a[y][x] - original->a[y][x];
difb = tmp1->b[y][x] - original->b[y][x];
@@ -483,7 +498,7 @@ void ImProcFunctions::DeNoise_Local (int call, const struct local_params& lp, La
difa = tmp1->a[loy - begy - 1][lox - begx - 1] - original->a[y][x];
difb = tmp1->b[loy - begy - 1][lox - begx - 1] - original->b[y][x];
}
- } else if (call == 1) { //dcrop
+ } else { //dcrop
difL = tmp1->L[y][x] - original->L[y][x];
difa = tmp1->a[y][x] - original->a[y][x];
difb = tmp1->b[y][x] - original->b[y][x];
@@ -672,7 +687,7 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float
}
if (lp.qualmet == 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -704,13 +719,13 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float
case 1: { // inside transition zone
float factorx = localFactor;
- float difL;
+ float difL = 0.f;
if (call == 2) {
if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) {
difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x];
}
- } else if (call == 1) {
+ } else {
difL = loctemp[y][x] - original->L[y][x];
}
@@ -724,7 +739,7 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float
case 2: { // inside selection => full effect, no transition
// float difL = loctemp[y][x] - original->L[y][x];
- float difL;
+ float difL = 0.f;
if (call == 2) {
@@ -732,13 +747,14 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float
// bufsh[loy - begy - 1][lox - begx - 1]
difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x];
}
- } else if (call == 1) {
+ } else {
difL = loctemp[y][x] - original->L[y][x];
}
transformed->L[y][x] = original->L[y][x] + difL * kch * fach;
}
}
+
}
}
}
@@ -914,7 +930,7 @@ void ImProcFunctions::TM_Local (int call, int sp, LabImage * tmp1, const float h
}
if (lp.qualmet == 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -1176,7 +1192,7 @@ void ImProcFunctions::BlurNoise_Local (int call, int sp, LabImage * tmp1, const
}
if (lp.qualmet == 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -1564,7 +1580,7 @@ void ImProcFunctions::Reti_Local (int call, const float hueplus, const float hue
}
if (lp.qualmet >= 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -1816,7 +1832,7 @@ struct local_contra {
float al, bl;
};
-void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra & lco, float lumaref, float av, const struct local_params & lp, float **deltE, LabImage * original, LabImage * transformed, int cx, int cy)
+void ImProcFunctions::Contrast_Local (int call, LabImage * bufcontorig, float ** buflightc, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra & lco, float lumaref, float av, const struct local_params & lp, float **deltE, LabImage * original, LabImage * transformed, int cx, int cy)
{
// BENCHFUN
// contrast - perhaps for 4 areas if need
@@ -1845,7 +1861,6 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
lco.aDY = realcoy;
-
constexpr float delhu = 0.1f; //between 0.05 and 0.2
const float apl = (-1.f) / delhu;
@@ -1865,8 +1880,10 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
const float vinf = (50.f + localtype / 2.f) / 100.f;
ImProcFunctions::secondeg_begin (reducac, vi, lco.aa, lco.bb);//parabolic
ImProcFunctions::secondeg_end (reducac, vinf, lco.aaa, lco.bbb, lco.ccc);//parabolic
+ float maxco = -10000.f;
+ float minco = +10000.f;
- if (call == 2) {
+ if (call <= 3) {
#ifdef _OPENMP
#pragma omp parallel if (multiThread)
@@ -1918,13 +1935,26 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
int begy = int (lp.yc - lp.lyT);
if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) {
- float localFactor = 1.f;
- calcTransition (lox, loy, ach, lp, zone, localFactor);
+ // float localFactor = 1.f;
+ // calcTransition (lox, loy, ach, lp, zone, localFactor);
//prepare shape detection
float khu = 0.f;
float kch = 1.f;
bool kzon = false;
float fach = 1.f;
+
+ float cli = (buflightc[loy - begy - 1][lox - begx - 1]);
+ //parameters for linear interpolation in function of real hue
+ float apluscligh = (1.f - cli) / delhu;
+ float bpluscligh = 1.f - apluscligh * hueplus;
+ float amoinscligh = (cli - 1.f) / delhu;
+ float bmoinscligh = 1.f - amoinscligh * huemoins;
+
+ float realcligh = 1.f;
+
+
+
+
float deltachro = fabs (rchro - chromaref);
float deltahue = fabs (rhue - hueref);
@@ -1955,10 +1985,16 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
//hue detection
if ((hueref + dhue) < M_PI && rhue < hueplus && rhue > huemoins) { //transition are good
if (rhue >= hueplus - delhu ) {
+ realcligh = apluscligh * rhue + bpluscligh;
+
khu = apl * rhue + bpl;
} else if (rhue < huemoins + delhu) {
+ realcligh = amoinscligh * rhue + bmoinscligh;
+
khu = amo * rhue + bmo;
} else {
+ realcligh = cli;
+
khu = 1.f;
}
@@ -1966,10 +2002,16 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
kzon = true;
} else if ((hueref + dhue) >= M_PI && (rhue > huemoins || rhue < hueplus )) {
if (rhue >= hueplus - delhu && rhue < hueplus) {
+ realcligh = apluscligh * rhue + bpluscligh;
+
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
+ realcligh = amoinscligh * rhue + bmoinscligh;
+
khu = amo * rhue + bmo;
} else {
+ realcligh = cli;
+
khu = 1.f;
}
@@ -1978,20 +2020,31 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
if ((hueref - dhue) > -M_PI && rhue < hueplus && rhue > huemoins ) {
if (rhue >= hueplus - delhu && rhue < hueplus) {
+ realcligh = apluscligh * rhue + bpluscligh;
+
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
+ realcligh = amoinscligh * rhue + bmoinscligh;
khu = amo * rhue + bmo;
} else {
+ realcligh = cli;
+
khu = 1.f;
}
kzon = true;
} else if ((hueref - dhue) <= -M_PI && (rhue > huemoins || rhue < hueplus )) {
if (rhue >= hueplus - delhu && rhue < hueplus) {
+ realcligh = apluscligh * rhue + bpluscligh;
+
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
+ realcligh = amoinscligh * rhue + bmoinscligh;
+
khu = amo * rhue + bmo;
} else {
+ realcligh = cli;
+
khu = 1.f;
}
@@ -2011,7 +2064,7 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
}
if (lp.qualmet >= 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -2032,6 +2085,18 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
*/
}
+ float kcr = 100.f * lp.thr;
+ float falL = 1.f;
+
+ if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm
+ falL *= pow (rchro / kcr, lp.iterat / 10.f);
+ }
+
+ float localFactor = 1.f;
+ calcTransition (lox, loy, ach, lp, zone, localFactor);
+
+ float kdiff = 1.f;
+
if (rL > 0.01f) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9
switch (zone) {
@@ -2043,332 +2108,114 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus,
}
case 1: { // inside transition zone
- if (original->L[y][x] < 32768.f) {
- float factorx = localFactor;
- float prov100 = original->L[y][x] / 32768.f;
- float prov = prov100 * 100.f;
- bool contin = true;
+ if (lp.curvact == false) {
+
+ if (original->L[y][x] < 32768.f) {
+ float factorx = localFactor;
+ float prov100 = original->L[y][x] / 32768.f;
+ float prov = prov100 * 100.f;
+ bool contin = true;
- if (contin) {
+ if (contin) {
- if (prov > localtype) {
- if (prov >= localtype && prov < 50.f + localtype / 2.f) {
- float core = (lco.alsup2 * prov + lco.blsup2) ;
- core *= factorx;
+ if (prov > localtype) {
+ if (prov >= localtype && prov < 50.f + localtype / 2.f) {
+ float core = (lco.alsup2 * prov + lco.blsup2) ;
+ core *= factorx;
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach);
- } else {
- float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
+ transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach * falL);
+ } else {
+ float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach);
- }
- } else { //inferior
- if (2.f * prov > localtype && prov < localtype) {
- float core = (lco.alsup * prov + lco.blsup) ;
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- } else if (2.f * prov <= localtype) {
- float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
+ core *= factorx;
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
+ transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach * falL);
+ }
+ } else { //inferior
+ if (2.f * prov > localtype && prov < localtype) {
+ float core = (lco.alsup * prov + lco.blsup) ;
+ core *= factorx;
+
+ transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL);
+ } else if (2.f * prov <= localtype) {
+ float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
+
+ core *= factorx;
+
+ transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL);
+ }
}
}
+ } else {
+ transformed->L[y][x] = original->L[y][x];
}
- } else {
- transformed->L[y][x] = original->L[y][x];
- }
- break;
+ break;
+ } else {
+ float lumnew = bufcontorig->L[loy - begy - 1][lox - begx - 1];
+
+ float factorx = localFactor;
+ float fli = 1.f;
+ fli = ((100.f + realcligh * falL ) / 100.f);//luma transition
+ float lightcont = lumnew;
+ float diflc = lightcont * fli - original->L[y][x];
+ kdiff *= fach * kch;
+ diflc *= kdiff ;
+ diflc *= factorx; //transition
+
+ transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc));
+
+ }
}
case 2: { // inside selection => full effect, no transition
- if (original->L[y][x] < 32768.f) {
- float prov100 = original->L[y][x] / 32768.f;
- float prov = prov100 * 100.f;
+ if (lp.curvact == false) {
- bool contin = true;
+ if (original->L[y][x] < 32768.f) {
+ float prov100 = original->L[y][x] / 32768.f;
+ float prov = prov100 * 100.f;
- if (contin) {
+ bool contin = true;
+
+ if (contin) {
- if (prov > localtype ) {
- if (prov >= localtype && prov < 50.f + localtype / 2.f) {
- float core = (lco.alsup2 * prov + lco.blsup2) ;
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach);
- } else {
- float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach);
- }
- } else { //inferior
- if (2.f * prov > localtype && prov < localtype) {
- float core = (lco.alsup * prov + lco.blsup) ;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- } else if (2.f * prov <= localtype) {
- float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
+ if (prov > localtype ) {
+ if (prov >= localtype && prov < 50.f + localtype / 2.f) {
+ float core = (lco.alsup2 * prov + lco.blsup2) ;
+ transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach * falL);
+ } else {
+ float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
+ transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach * falL);
+ }
+ } else { //inferior
+ if (2.f * prov > localtype && prov < localtype) {
+ float core = (lco.alsup * prov + lco.blsup) ;
+ transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL);
+ } else if (2.f * prov <= localtype) {
+ float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
+ transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL);
+ }
}
}
- }
- } else {
- transformed->L[y][x] = original->L[y][x];
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
-
-#ifdef _OPENMP
- #pragma omp parallel if (multiThread)
-#endif
- {
-#ifdef __SSE2__
- float atan2Buffer[transformed->W] ALIGNED16;
- float sqrtBuffer[transformed->W] ALIGNED16;
- vfloat c327d68v = F2V (327.68f);
-#endif
-
-#ifdef _OPENMP
- #pragma omp for schedule(dynamic,16)
-#endif
-
- for (int y = 0; y < transformed->H; y++)
- {
-#ifdef __SSE2__
- int i = 0;
-
- for (; i < transformed->W - 3; i += 4) {
- vfloat av = LVFU (original->a[y][i]);
- vfloat bv = LVFU (original->b[y][i]);
- STVF (atan2Buffer[i], xatan2f (bv, av));
- STVF (sqrtBuffer[i], _mm_sqrt_ps (SQRV (bv) + SQRV (av)) / c327d68v);
- }
-
- for (; i < transformed->W; i++) {
- atan2Buffer[i] = xatan2f (original->b[y][i], original->a[y][i]);
- sqrtBuffer[i] = sqrt (SQR (original->b[y][i]) + SQR (original->a[y][i])) / 327.68f;
- }
-
-#endif
-
- int loy = cy + y;
-
- for (int x = 0; x < transformed->W; x++) {
- int lox = cx + x;
-#ifdef __SSE2__
- float rhue = atan2Buffer[x];
- float rchro = sqrtBuffer[x];
-#else
- float rhue = xatan2f (original->b[y][x], original->a[y][x]);
- float rchro = sqrt (SQR (original->b[y][x]) + SQR (original->a[y][x])) / 327.68f;
-#endif
- int zone;
- int begx = int (lp.xc - lp.lxL);
- int begy = int (lp.yc - lp.lyT);
- float localFactor = 1.f;
- calcTransition (lox, loy, ach, lp, zone, localFactor);
- //prepare shape detection
- float khu = 0.f;
- float kch = 1.f;
- bool kzon = false;
- float fach = 1.f;
- float deltachro = fabs (rchro - chromaref);
- float deltahue = fabs (rhue - hueref);
-
- if (deltahue > M_PI) {
- deltahue = - (deltahue - 2.f * M_PI);
- }
-
- float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280
- float rL = original->L[y][x] / 327.68f;
-
- //kch to modulate action with chroma
- if (deltachro < 160.f * SQR (lp.sens / 100.f)) {
- kch = 1.f;
- } else {
- float ck = 160.f * SQR (lp.sens / 100.f);
- float ak = 1.f / (ck - 160.f);
- float bk = -160.f * ak;
- kch = ak * deltachro + bk;
- }
-
- if (lp.sens < 40.f ) {
- kch = pow (kch, pa * lp.sens + pb); //increase under 40
- }
-
-
- // algo with detection of hue ==> artifacts for noisy images ==> denoise before
- if (lp.sens < 20.f) { //to try...
- //hue detection
- if ((hueref + dhue) < M_PI && rhue < hueplus && rhue > huemoins) { //transition are good
- if (rhue >= hueplus - delhu ) {
- khu = apl * rhue + bpl;
- } else if (rhue < huemoins + delhu) {
- khu = amo * rhue + bmo;
- } else {
- khu = 1.f;
- }
-
-
- kzon = true;
- } else if ((hueref + dhue) >= M_PI && (rhue > huemoins || rhue < hueplus )) {
- if (rhue >= hueplus - delhu && rhue < hueplus) {
- khu = apl * rhue + bpl;
- } else if (rhue >= huemoins && rhue < huemoins + delhu) {
- khu = amo * rhue + bmo;
- } else {
- khu = 1.f;
- }
-
- kzon = true;
- }
-
- if ((hueref - dhue) > -M_PI && rhue < hueplus && rhue > huemoins ) {
- if (rhue >= hueplus - delhu && rhue < hueplus) {
- khu = apl * rhue + bpl;
- } else if (rhue >= huemoins && rhue < huemoins + delhu) {
- khu = amo * rhue + bmo;
- } else {
- khu = 1.f;
- }
-
- kzon = true;
- } else if ((hueref - dhue) <= -M_PI && (rhue > huemoins || rhue < hueplus )) {
- if (rhue >= hueplus - delhu && rhue < hueplus) {
- khu = apl * rhue + bpl;
- } else if (rhue >= huemoins && rhue < huemoins + delhu) {
- khu = amo * rhue + bmo;
- } else {
- khu = 1.f;
- }
-
- kzon = true;
- }
-
- if (deltaE < 2.8f * lp.sens) {
- fach = khu;
- } else {
- fach = khu * (ahu * deltaE + bhu);
- }
-
- float kcr = 10.f;
-
- if (rchro < kcr) {
- fach *= (1.f / (kcr * kcr)) * rchro * rchro;
- }
-
- if (lp.qualmet >= 1) {
- if (deltE[y][x] > lp.thr) {
- fach = 1.f;
- }
- } else {
- fach = 1.f;
- }
-
- //fach = khu ;
-
- } else {
- /*
- float kcr = 8.f;
- if(lp.sensh > 30.f){
- if (rchro < kcr) {
- fach *= (1.f / (kcr)) * rchro;
-
- }
- }
- */
- }
-
- if (rL > 0.01f) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9
-
- switch (zone) {
- case 0: { // outside selection and outside transition zone => no effect, keep original values
- transformed->L[y][x] = original->L[y][x];
- transformed->a[y][x] = original->a[y][x];
- transformed->b[y][x] = original->b[y][x];
- break;
- }
-
- case 1: { // inside transition zone
- if (original->L[y][x] < 32768.f) {
- float factorx = localFactor;
- float prov100 = original->L[y][x] / 32768.f;
- float prov = prov100 * 100.f;
- bool contin = true;
-
-
- if (contin) {
-
- if (prov > localtype) {
- if (prov >= localtype && prov < 50.f + localtype / 2.f) {
- float core = (lco.alsup2 * prov + lco.blsup2) ;
- core *= factorx;
-
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach);
- } else {
- float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
-
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach);
- }
- } else { //inferior
- if (2.f * prov > localtype && prov < localtype) {
- float core = (lco.alsup * prov + lco.blsup) ;
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- } else if (2.f * prov <= localtype) {
- float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
-
- core *= factorx;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- }
+ } else {
+ transformed->L[y][x] = original->L[y][x];
}
}
- } else {
- transformed->L[y][x] = original->L[y][x];
- }
- break;
- }
-
- case 2: { // inside selection => full effect, no transition
- if (original->L[y][x] < 32768.f) {
- float prov100 = original->L[y][x] / 32768.f;
- float prov = prov100 * 100.f;
-
- bool contin = true;
-
- if (contin) {
-
-
-
- if (prov > localtype ) {
- if (prov >= localtype && prov < 50.f + localtype / 2.f) {
- float core = (lco.alsup2 * prov + lco.blsup2) ;
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach);
- } else {
- float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
- transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach);
- }
- } else { //inferior
- if (2.f * prov > localtype && prov < localtype) {
- float core = (lco.alsup * prov + lco.blsup) ;
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- } else if (2.f * prov <= localtype) {
- float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
- transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach);
- }
- }
+ else {
+ float lumnew = bufcontorig->L[loy - begy - 1][lox - begx - 1];
+ float fli = 1.f;
+ fli = ((100.f + realcligh * falL ) / 100.f);//luma transition
+ float lightcont = lumnew;
+ float diflc = lightcont * fli - original->L[y][x];
+ kdiff *= fach * kch;
+ diflc *= kdiff ;
+ transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc));
}
- } else {
- transformed->L[y][x] = original->L[y][x];
+
}
}
}
@@ -2656,7 +2503,7 @@ void ImProcFunctions::InverseSharp_Local (int sp, float **loctemp, const float h
}
if (lp.qualmet >= 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -2876,7 +2723,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa
}
if (lp.qualmet == 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -2914,7 +2761,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa
if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) {
difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x];
}
- } else if (call == 1) {
+ } else {
difL = loctemp[y][x] - original->L[y][x];
}
@@ -2936,7 +2783,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa
// bufsh[loy - begy - 1][lox - begx - 1]
difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x];
}
- } else if (call == 1) {
+ } else {
difL = loctemp[y][x] - original->L[y][x];
}
@@ -2950,7 +2797,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa
-void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, const local_params & lp, float ** deltE, LabImage * original, LabImage * transformed, int cx, int cy)
+void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, float ** buflight, float ** bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params & lp, float ** deltE, LabImage * original, LabImage * transformed, int cx, int cy)
{
// BENCHFUN
// chroma and lightness
@@ -2975,18 +2822,14 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
const float multchroskin = lp.sens * achsensskin + bchsensskin;
//transition = difficult to avoid artifact with scope on flat area (sky...)
- constexpr float delhu = 0.1f; //between 0.05 and 0.2
+ constexpr float delhu = 0.1f; //between 0.05 and 0.2 ==> minima for scope
+ //constexpr float delhu2 = 0.03f; //between 0.05 and 0.2
+
const float aplus = (1.f - lp.chro) / delhu;
const float bplus = 1.f - aplus * hueplus;
const float amoins = (lp.chro - 1.f) / delhu;
const float bmoins = 1.f - amoins * huemoins;
- const float apluscurv = (1.f - chprov) / delhu;
- const float bpluscurv = 1.f - apluscurv * hueplus;
- const float amoinscurv = (chprov - 1.f) / delhu;
- const float bmoinscurv = 1.f - amoinscurv * huemoins;
-
-
const float apl = (-1.f) / delhu;
const float bpl = - apl * hueplus;
const float amo = 1.f / delhu;
@@ -3113,14 +2956,38 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
eps = 0.01f;
}
+ //retriev data curve lightness
+ float cli = (buflight[loy - begy - 1][lox - begx - 1]);
+ //parameters for linear interpolation in function of real hue
+ float apluscligh = (1.f - cli) / delhu;
+ float bpluscligh = 1.f - apluscligh * hueplus;
+ float amoinscligh = (cli - 1.f) / delhu;
+ float bmoinscligh = 1.f - amoinscligh * huemoins;
+
+ float cchro = (bufchro[loy - begy - 1][lox - begx - 1]);
+ float apluscurv = (1.f - cchro) / delhu;
+ float bpluscurv = 1.f - apluscurv * hueplus;
+ float amoinscurv = (cchro - 1.f) / delhu;
+ float bmoinscurv = 1.f - amoinscurv * huemoins;
+
+ float clisl = (buflightslid[loy - begy - 1][lox - begx - 1]);
+ //parameters for linear interpolation in function of real hue
+ float aplusclighsl = (1.f - clisl) / delhu;
+ float bplusclighsl = 1.f - aplusclighsl * hueplus;
+ float amoinsclighsl = (clisl - 1.f) / delhu;
+ float bmoinsclighsl = 1.f - amoinsclighsl * huemoins;
float kab = (original->a[y][x] / (original->b[y][x] + eps));
//prepare shape detection
-// printf("z");
- //end buf for square
+ // real... = coefficient to apply at lightness, chroma,...
float realchro = 1.f;
float realcurv = 1.f;
+ float realcligh = 1.f;
+ float realclighsl = 1.f;
+ float realchrosl = 1.f;
+
+ //evaluate delta Hue and delta Chro
float deltachro = fabs (rchro - chromaref);
float deltahue = fabs (rhue - hueref);
@@ -3129,6 +2996,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
deltahue = - (deltahue - 2.f * M_PI);
}
+ //pseudo deltaE
float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280
float deltaL = fabs (lumaref - rL); //between 0 and 100
@@ -3155,22 +3023,29 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
//transition = difficult to avoid artifact with scope on flat area (sky...)
//hue detection
+ //for each quart calculate realchro, realcligh,... in function of Hue pixel
if ((hueref + dhue) < M_PI && rhue < hueplus && rhue > huemoins) { //transition are good
if (rhue >= hueplus - delhu) {
realchro = aplus * rhue + bplus;
realcurv = apluscurv * rhue + bpluscurv;
-
+ realcligh = apluscligh * rhue + bpluscligh;
+ realclighsl = aplusclighsl * rhue + bplusclighsl;
khu = apl * rhue + bpl;
} else if (rhue < huemoins + delhu) {
realchro = amoins * rhue + bmoins;
realcurv = amoinscurv * rhue + bmoinscurv;
+ realcligh = amoinscligh * rhue + bmoinscligh;
+ realclighsl = amoinsclighsl * rhue + bmoinsclighsl;
khu = amo * rhue + bmo;
} else {
realchro = lp.chro;
- realcurv = chprov;
+ realcurv = cchro;
+ realcligh = cli;
+ realclighsl = clisl;
+
khu = 1.f;
}
@@ -3180,18 +3055,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
if (rhue >= hueplus - delhu && rhue < hueplus) {
realchro = aplus * rhue + bplus;
realcurv = apluscurv * rhue + bpluscurv;
+ realcligh = apluscligh * rhue + bpluscligh;
+ realclighsl = aplusclighsl * rhue + bplusclighsl;
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
realchro = amoins * rhue + bmoins;
realcurv = amoinscurv * rhue + bmoinscurv;
+ realcligh = amoinscligh * rhue + bmoinscligh;
+ realclighsl = amoinsclighsl * rhue + bmoinsclighsl;
khu = amo * rhue + bmo;
} else {
realchro = lp.chro;
- realcurv = chprov;
+
+ realcurv = cchro;
+ realcligh = cli;
+ realclighsl = clisl;
khu = 1.f;
@@ -3204,17 +3086,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
if (rhue >= hueplus - delhu && rhue < hueplus) {
realchro = aplus * rhue + bplus;
realcurv = apluscurv * rhue + bpluscurv;
+ realcligh = apluscligh * rhue + bpluscligh;
+ realclighsl = aplusclighsl * rhue + bplusclighsl;
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
realchro = amoins * rhue + bmoins;
realcurv = amoinscurv * rhue + bmoinscurv;
+ realcligh = amoinscligh * rhue + bmoinscligh;
+ realclighsl = amoinsclighsl * rhue + bmoinsclighsl;
+
khu = amo * rhue + bmo;
} else {
realchro = lp.chro;
- realcurv = chprov;
+
+ realcurv = cchro;
+ realcligh = cli;
+ realclighsl = clisl;
khu = 1.f;
@@ -3225,18 +3115,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
if (rhue >= hueplus - delhu && rhue < hueplus) {
realchro = aplus * rhue + bplus;
realcurv = apluscurv * rhue + bpluscurv;
+ realcligh = apluscligh * rhue + bpluscligh;
+ realclighsl = aplusclighsl * rhue + bplusclighsl;
khu = apl * rhue + bpl;
} else if (rhue >= huemoins && rhue < huemoins + delhu) {
realchro = amoins * rhue + bmoins;
realcurv = amoinscurv * rhue + bmoinscurv;
+ realcligh = amoinscligh * rhue + bmoinscligh;
+ realclighsl = amoinsclighsl * rhue + bmoinsclighsl;
khu = amo * rhue + bmo;
} else {
realchro = lp.chro;
- realcurv = chprov;
+
+ realcurv = cchro;
+ realcligh = cli;
+ realclighsl = clisl;
khu = 1.f;
@@ -3264,7 +3161,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
//fach = 1.f;//to avoid artifacts in some cases
//can be probably improved
if (lp.qualmet >= 1) {
- if (deltE[y][x] > lp.thr) {
+ if (deltE[y][x] > 10.f * lp.thr) {
fach = 1.f;
}
} else {
@@ -3287,15 +3184,18 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
if ( (rhue > -2.79f && rhue < -1.11f) && (rchro < 35.f * multchro)) {
realchro *= 0.9f;
realcurv *= 0.9f;
+ // realcligh *= 0.9f;
} else {
realchro = 1.f;
realcurv = 1.f;
+ // realcligh = 1.f;
}
}
} else {
realchro = lp.chro;
- realcurv = chprov;
+ realcurv = cchro;
+ // realcligh = cligh;
}
@@ -3305,16 +3205,19 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
if ( (rhue > -0.09f && rhue < 1.59f) && (rchro < 55.f * multchroskin)) {
realchro *= 0.9f;
realcurv *= 0.9f;
+ // realcligh *= 0.9f;
} else {
realchro = 1.f;
realcurv = 1.f;
+ // realcligh = 1.f;
}
}
} else {
realchro = lp.chro;
- realcurv = chprov;
+ realcurv = cchro;
+ // realcligh = cligh;
}
}
@@ -3373,6 +3276,14 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
}
+ float kcr = 100.f * lp.thr;
+ float falL = 1.f;
+
+ if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm
+ falL *= pow (rchro / kcr, lp.iterat / 10.f);
+ }
+
+
int zone;
float localFactor;
calcTransition (lox, loy, ach, lp, zone, localFactor);
@@ -3393,11 +3304,12 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
float lightcont;
- if (lp.curvact) {
+ if (lp.qualcurvemet == 1) {
+
if (lllocalcurve) {
float lumprov = lllocalcurve[lumnew * 1.9f];
- float lumred = 0.526316f * lumprov;
- lumnew = lumnew + (lumred - lumnew) / 1.5f;//reduce sensibility
+ float lumred = 0.526316f * lumprov; //0.526316f
+ lumnew = lumnew + (lumred - lumnew) / 4.f;//reduce sensibility
}
@@ -3425,7 +3337,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
}
- if (lp.ligh != 0.f) {
+ if (lp.ligh != 0.f && lp.curvact == false) {
// calclight (bufcolorig->L[loy - begy - 1][lox - begx - 1], lp.ligh , lumnew, true);//replace L-curve
calclight (lumnew, lp.ligh , lumnew, true);//replace L-curve
lightcont = lumnew;
@@ -3435,15 +3347,31 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
}
float factorx = localFactor;
+ float fli = 1.f;
+ float flisl = 1.f;
- float fac = ((100.f + realcurv * factorx * falu) / 100.f) * (100.f + factorx * realchro * falu) / 100.f; //chroma factor transition
- float diflc = lightcont - original->L[y][x];
+ if (lp.curvact && lp.ligh != 0.f) {
+ flisl = ((100.f + realclighsl * falL ) / 100.f);//luma transition
+ }
+
+ if (lp.qualcurvemet == 2) {
+ fli = ((100.f + realcligh * falL ) / 100.f);//luma transition
+ }
+
+ float flicur = 1.f;
+
+ if (lp.qualcurvemet != 0) {
+ flicur = ((100.f + realcurv * factorx * falu * falL) / 100.f);
+ }
+
+ float fac = flicur * (100.f + factorx * realchro * falu * falL) / 100.f; //chroma factor transition
+ float diflc = lightcont * fli * flisl - original->L[y][x];
kdiff *= fach * kch;
diflc *= kdiff ;
- diflc *= factorx; //transition lightess
+ diflc *= factorx; //transition lightness
// transformed->L[y][x] = CLIPL(bufcolorig->L[loy - begy - 1][lox - begx - 1] + diflc);
- transformed->L[y][x] = CLIPL (original->L[y][x] + diflc);
+ transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc));
if (fabs (kab) > 1.f) {
@@ -3462,11 +3390,12 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
float lumnew = bufcolorig->L[loy - begy - 1][lox - begx - 1];
float lightcont;
- if (lp.curvact) {
+ if (lp.qualcurvemet == 1) {
+
if (lllocalcurve) {
float lumprov = lllocalcurve[lumnew * 1.9f];
- float lumred = 0.526316f * lumprov;
- lumnew = lumnew + (lumred - lumnew) / 1.5f;//reduce sensibility
+ float lumred = 0.526316 * lumprov; // 0.526316f
+ lumnew = lumnew + (lumred - lumnew) / 4.f;//reduce sensibility
}
if (loclhCurve) {
@@ -3494,7 +3423,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
}
- if (lp.ligh != 0.f) {
+ if (lp.ligh != 0.f && lp.curvact == false) {
calclight (lumnew, lp.ligh , lumnew, true);//replace L-curve
lightcont = lumnew;
@@ -3502,13 +3431,30 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag
lightcont = lumnew;
}
- float fac = ((100.f + realcurv * falu) / 100.f) * (100.f + realchro * falu) / 100.f; //chroma factor transition7
+ float fli = 1.f;
+ float flisl = 1.f;
- float diflc = lightcont - original->L[y][x];
+ if (lp.curvact && lp.ligh != 0.f) {
+ flisl = ((100.f + realclighsl * falL ) / 100.f);//luma transition
+ }
+
+ if (lp.qualcurvemet == 2) {
+ fli = ((100.f + realcligh * falL) / 100.f);//luma transition
+ }
+
+ float flicur = 1.f;
+
+ if (lp.qualcurvemet != 0) {
+ flicur = ((100.f + realcurv * falu * falL) / 100.f);
+ }
+
+ float fac = flicur * (100.f + realchro * falu * falL) / 100.f; //chroma factor transition7
+
+ float diflc = lightcont * fli * flisl - original->L[y][x];
kdiff *= fach * kch;
diflc *= kdiff ;
- transformed->L[y][x] = CLIPL (original->L[y][x] + diflc);
+ transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc));
if (fabs (kab) > 1.f) {
transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ;
@@ -3669,7 +3615,109 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
noiscfactiv = false;
}
+ /* //keep in case of !
+ if(lp.qualmet >= 1) {
+ float maxdh = -10.f;
+ #ifdef _OPENMP
+ // #pragma omp parallel ??
+ #endif
+ {
+ float maxdhu = -10.f;
+ #ifdef _OPENMP
+ // #pragma omp for nowait ??
+ #endif
+
+ for (int y = lp.dyy; y < transformed->H - lp.dyy; y++) //{
+ for (int x = lp.dxx; x < transformed->W - lp.dxx; x++) {
+ int lox = cx + x;
+ int loy = cy + y;
+
+ if(lox >= (lp.xc - (lp.lxL - lp.dxx)) && lox < (lp.xc + (lp.lx - lp.dxx)) && loy >= (lp.yc - (lp.lyT - lp.dyy)) && loy < (lp.yc + (lp.ly - lp.dyy))) {
+ float eps = 0.01f;
+
+ float hur = xatan2f(original->b[y][x], original->a[y][x]);
+ float maxdhur = -10.f;
+
+ for(int j = x - lp.dxx; j < x + lp.dxx; j++) {
+ for(int k = y - lp.dyy; k < y + lp.dyy; k++) {
+
+ float hurjk = xatan2f(original->b[k][j], original->a[k][j]);
+ float dE = fabs(hur - hurjk);
+
+ //evaluate local variation of hue
+ if(dE > M_PI) {
+ dE = -(dE - 2.f * M_PI);
+ }
+
+ maxdhur = dE > maxdhur ? dE : maxdhur;
+ }
+ }
+
+
+ deltE[y][x] = maxdhur;
+
+ }
+ }
+
+ #ifdef _OPENMP
+ // #pragma omp critical
+ #endif
+ {
+ //??
+ }
+
+ }
+
+ float maxw = -10.f;
+ float minw = 10.f;
+ int n1 = 0;
+ int n2 = 0;
+ int n3 = 0;
+ int n4 = 0;
+ int n5 = 0;
+ int n6 = 0;
+ int n7 = 0;
+ int n8 = 0;
+ int n9 = 0;
+ int n10 = 0;
+
+ for (int y = lp.dyy; y < transformed->H - lp.dyy; y++) //{
+ for (int x = lp.dxx; x < transformed->W - lp.dxx; x++) {
+ int lox = cx + x;
+ int loy = cy + y;
+
+ if(lox >= (lp.xc - (lp.lxL - lp.dxx)) && lox < (lp.xc + (lp.lx - lp.dxx)) && loy >= (lp.yc - (lp.lyT - lp.dyy)) && loy < (lp.yc + (lp.ly - lp.dyy))) {
+ if(deltE[y][x] < 0.3f) {
+ n1++;
+ } else if(deltE[y][x] < 0.6f) {
+ n2++;
+ } else if(deltE[y][x] < 1.f) {
+ n3++;
+ } else if(deltE[y][x] < 1.3f) {
+ n4++;
+ } else if(deltE[y][x] < 1.6f) {
+ n5++;
+ } else if(deltE[y][x] < 2.f) {
+ n6++;
+ } else if(deltE[y][x] < 2.4f) {
+ n7++;
+ } else if(deltE[y][x] < 2.7f) {
+ n8++;
+ } else if(deltE[y][x] < 2.95f) {
+ n9++;
+ } else if(deltE[y][x] < 3.16f) {
+ n10++;
+ }
+ }
+ }
+
+ printf("n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", n1, n2, n3, n4, n5, n6, n7, n8, n9, n10);
+
+
+
+ }
+ */
if ((!lp.inv || !lp.invret) && hueref == INFINITY && chromaref == INFINITY && lumaref == INFINITY) {
@@ -3728,6 +3776,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
avB = aveB / 327.68f;
avL = aveL / 327.68f;
+//INFINITY to solve crop problem when Ref is outside preview
if (hueref == INFINITY) {
hueref = xatan2f (avB, avA); //mean hue
}
@@ -3765,7 +3814,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
lco.dy = 1.f - 1.f / multh;
-
+//Blur and noise
if ((radius >= GAUSS_SKIP || lp.stren > 0.1) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image
LabImage *tmp1;
LabImage *bufgb;
@@ -3875,7 +3924,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
levred = 7;
}
- if (call == 1) {
+ if (call != 2) {
LabImage *tmp1 = new LabImage (transformed->W, transformed->H);
int GW = transformed->W;
int GH = transformed->H;
@@ -4219,13 +4268,14 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
}
-
- if (!lp.inv && (lp.chro != 0 || lp.ligh != 0.f || lp.curvact) && lp.colorena) { // || lllocalcurve)) { //interior ellipse renforced lightness and chroma //locallutili
+//local color and light
+ if (!lp.inv && (lp.chro != 0 || lp.ligh != 0.f || lp.qualcurvemet != 0) && lp.colorena) { // || lllocalcurve)) { //interior ellipse renforced lightness and chroma //locallutili
float maxhur = -10.f;
float minhur = 10.f;
float hueplus = hueref + dhue;
float huemoins = hueref - dhue;
+ //printf("hueplus=%f huemoins=%f dhu=%f\n", hueplus, huemoins, dhue);
if (hueplus > M_PI) {
hueplus = hueref + dhue - 2.f * M_PI;
}
@@ -4236,11 +4286,24 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
LabImage *bufcolorig;
float chprov = 1.f;
+ float chpro = 1.f;
+ float chp = 1.f;
+ float cligh = 1.f;
+ float clighL = 1.f;
+ float clighmax ;
+ float clighmin ;
LabImage *bufcoltra;
+ float **buflight;
+ float **bufchro;
+ float **buflightslid;
+
+ int bfh, bfw;
+
float adjustr = 1.0f;
+ float compadjustr = 1.0f;
-
+//adapt chroma to working profile
if (params->icm.working == "ProPhoto") {
adjustr = 1.2f; // 1.2 instead 1.0 because it's very rare to have C>170..
} else if (params->icm.working == "Adobe RGB") {
@@ -4260,13 +4323,32 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
- if (call <= 3) { //simpleprocess
+ if (call <= 3) { //simpleprocess, dcrop, improccoordinator
int GW = transformed->W;
int GH = transformed->H;
- int bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone
- int bfw = int (lp.lx + lp.lxL) + 1;
- bufcolorig = new LabImage (bfw, bfh);
- // bufcoltra = new LabImage(bfw, bfh);
+ bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone
+ bfw = int (lp.lx + lp.lxL) + 1;
+ bufcolorig = new LabImage (bfw, bfh);//buffer for data in zone limit
+ // bufcoltra = new LabImage (bfw, bfh);//not used
+
+ buflight = new float*[bfh];//for lightness curve
+
+ for (int i = 0; i < bfh; i++) {
+ buflight[i] = new float[bfw];
+ }
+
+ bufchro = new float*[bfh];//for chroma curve
+
+ for (int i = 0; i < bfh; i++) {
+ bufchro[i] = new float[bfw];
+ }
+
+ buflightslid = new float*[bfh];//for chroma curve
+
+ for (int i = 0; i < bfh; i++) {
+ buflightslid[i] = new float[bfw];
+ }
+
#ifdef _OPENMP
#pragma omp parallel for
@@ -4283,6 +4365,8 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
#ifdef _OPENMP
// #pragma omp parallel for
#endif
+ clighmax = 0.f;
+ clighmin = 100000.f;
for (int y = 0; y < transformed->H ; y++) //{
for (int x = 0; x < transformed->W; x++) {
@@ -4297,47 +4381,98 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
bufcolorig->b[loy - begy - 1][lox - begx - 1] = original->b[y][x];//fill square buffer with datas
chprov = 0.f;
+ chpro = 0.f;
- if (cclocalcurve && lp.curvact) {
+ //Chroma curve
+ if (cclocalcurve && lp.qualcurvemet != 0) { // C=f(C) curve
float chromat = sqrt (SQR (bufcolorig->a[loy - begy - 1][lox - begx - 1]) + SQR (bufcolorig->b[loy - begy - 1][lox - begx - 1]));
float ch;
- float ampli = 12.f;
- ch = (cclocalcurve[chromat * adjustr]) / ((chromat + 0.00001f) * adjustr); //ch between 0 and 0 50 or more
+ float ampli = 25.f;
+ ch = (cclocalcurve[chromat * adjustr ]) / ((chromat + 0.00001f) * adjustr); //ch between 0 and 0 50 or more
if (ch <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape
- chprov = 100.f * ch - 100.f;
+ chpro = 100.f * ch - 100.f;
} else {
- chprov = ampli * ch - ampli;//ampli = 12.f arbitrary empirical coefficient between 5 and 50
+ chpro = CLIPCHRO (ampli * ch - ampli); //ampli = 25.f arbitrary empirical coefficient between 5 and 50
}
+
+ bufchro[loy - begy - 1][lox - begx - 1] = chpro;
+
}
+ //slider lightness
+ clighL = 0.f;
+
+ if (lp.ligh != 0.f && lp.curvact) {
+ float lL;
+ float lighLnew;
+ float amplil = 140.f;
+ float lighL = bufcolorig->L[loy - begy - 1][lox - begx - 1];
+ calclight (lighL, lp.ligh , lighLnew, true);//replace L-curve
+ lL = lighLnew / lighL;
+
+ if (lL <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape
+ clighL = 100.f * lL - 100.f;
+ } else {
+ clighL = CLIPLIG (amplil * lL - amplil); //ampli = 25.f arbitrary empirical coefficient between 5 and 150
+ }
+
+ buflightslid[loy - begy - 1][lox - begx - 1] = clighL;
+
+ }
+
+ cligh = 0.f;
+
+ //luma curve
+ if (lllocalcurve && lp.qualcurvemet == 2) {// L=f(L) curve enhanced
+ float lh;
+ float amplil = 25.f;
+ float lighn = bufcolorig->L[loy - begy - 1][lox - begx - 1];
+ lh = (lllocalcurve[lighn * 1.9f]) / ((lighn + 0.00001f) * 1.9f) ; // / ((lighn) / 1.9f) / 3.61f; //lh between 0 and 0 50 or more
+
+ if (lh <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape
+ cligh = 0.3f * (100.f * lh - 100.f);//0.3 reduce sensibility
+ } else {
+ cligh = CLIPLIG (amplil * lh - amplil);
+ }
+
+ buflight[loy - begy - 1][lox - begx - 1] = cligh;
+
+ }
+
}
}
-
}
- /*
- if(locallutili) printf("Courbe oui\n");
- if(!locallutili) printf("Courbe NON\n");
- */
- /*
- if (cclocalcurve) {
- printf ("Courbe RE OUI\n");
- }
- if (!cclocalcurve) {
- printf ("CouRE NON\n");
- }
- */
-
- ColorLight_Local (call, bufcolorig, bufcoltra, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, cclocalcurve, chprov, lp, deltE, original, transformed, cx, cy);
+ ColorLight_Local (call, bufcolorig, bufcoltra, buflight, bufchro, buflightslid, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, cclocalcurve, chprov, clighmax, lp, deltE, original, transformed, cx, cy);
if (call <= 3) {
delete bufcolorig;
- // delete bufcoltra;
+
+ // delete bufcoltra;
+
+ for (int i = 0; i < bfh; i++) {
+ delete [] buflight[i];
+ }
+
+ delete [] buflight;
+
+ for (int i = 0; i < bfh; i++) {
+ delete [] bufchro[i];
+ }
+
+ delete [] bufchro;
+
+ for (int i = 0; i < bfh; i++) {
+ delete [] buflightslid[i];
+ }
+
+
+ delete [] buflightslid;
}
}
//inverse
@@ -4360,7 +4495,147 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage *
huemoins = hueref - dhue + 2.f * M_PI;
}
- Contrast_Local (call, moy, hueplus, huemoins, hueref, dhue, chromaref, pm, lco, lumaref, av, lp, deltE, original, transformed, cx, cy);
+ LabImage *bufcontorig;
+ float **buflightc;
+ int bfh, bfw;
+ float clighc = 1.f;
+ const float localtype = lumaref;
+ float reducac;
+
+ if (lp.sens < 30.f) {
+ reducac = 0.2f * (lp.sens / 100.f);
+ } else {
+ float areduc = 0.6285714f; //0.44f/0.7f;
+ float breduc = 0.5f - areduc;
+ reducac = areduc * (lp.sens / 100.f) + breduc;
+ }
+
+ const float realcox = lco.dx, realcoy = lco.dy;
+
+ lco.alsup = (-realcox) / (localtype / 2.f);
+ lco.blsup = -lco.alsup * localtype;
+ lco.alsup2 = (realcoy) / (50.f - localtype / 2.f);
+ lco.blsup2 = -lco.alsup2 * localtype;
+ lco.alsup3 = (realcoy) / (localtype / 2.f - 50.f);
+ lco.blsup3 = -lco.alsup3 * 100.f;
+ lco.aDY = realcoy;
+
+ lco.alinf = realcox / (localtype / 2.f);
+ const float vi = (localtype / 2.f) / 100.f;
+ const float vinf = (50.f + localtype / 2.f) / 100.f;
+ ImProcFunctions::secondeg_begin (reducac, vi, lco.aa, lco.bb);//parabolic
+ ImProcFunctions::secondeg_end (reducac, vinf, lco.aaa, lco.bbb, lco.ccc);//parabolic
+
+
+
+
+ if (call <= 3) { //simpleprocess, dcrop, improccoordinator
+ int GW = transformed->W;
+ int GH = transformed->H;
+ bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone
+ bfw = int (lp.lx + lp.lxL) + 1;
+ bufcontorig = new LabImage (bfw, bfh);//buffer for data in zone limit
+
+ buflightc = new float*[bfh];//for lightness curve
+
+ for (int i = 0; i < bfh; i++) {
+ buflightc[i] = new float[bfw];
+ }
+
+
+
+#ifdef _OPENMP
+ #pragma omp parallel for
+#endif
+
+ for (int ir = 0; ir < bfh; ir++) //fill with 0
+ for (int jr = 0; jr < bfw; jr++) {
+ bufcontorig->L[ir][jr] = 0.f;
+ bufcontorig->a[ir][jr] = 0.f;
+ bufcontorig->b[ir][jr] = 0.f;
+
+ }
+
+#ifdef _OPENMP
+// #pragma omp parallel for
+#endif
+ float maxc = -10000.f;
+ float minc = +10000.f;
+ float core = 0.f;
+
+ for (int y = 0; y < transformed->H ; y++) //{
+ for (int x = 0; x < transformed->W; x++) {
+ int lox = cx + x;
+ int loy = cy + y;
+ int begx = int (lp.xc - lp.lxL);
+ int begy = int (lp.yc - lp.lyT);
+
+ if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) {
+ bufcontorig->L[loy - begy - 1][lox - begx - 1] = original->L[y][x];//fill square buffer with datas
+
+ //slider contrast
+ clighc = 0.f;
+
+ if (lp.cont != 0.f && lp.curvact) {
+ float cL;
+ float amplil = 10.f;
+ float prov100 = bufcontorig->L[loy - begy - 1][lox - begx - 1] / 32768.f;
+ float prov = prov100 * 100.f;
+
+ if (prov > localtype) {
+ if (prov >= localtype && prov < 50.f + localtype / 2.f) {
+ core = (lco.alsup2 * prov + lco.blsup2) ;
+
+ } else {
+ core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc);
+
+ }
+ } else {
+ if (2.f * prov > localtype && prov < localtype) {
+ core = (lco.alsup * prov + lco.blsup) ;
+ } else if (2.f * prov <= localtype) {
+ core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100);
+ }
+ }
+
+ // cL = pm * core;
+ cL = pm * core;
+ core = 0.f;
+
+ if (cL > 0.f) {
+ clighc = 100.f * cL;
+
+ } else {
+ clighc = 100.f * cL ;
+
+ }
+
+ buflightc[loy - begy - 1][lox - begx - 1] = clighc;
+
+ }
+
+
+ }
+ }
+
+ }
+
+
+ Contrast_Local (call, bufcontorig, buflightc, moy, hueplus, huemoins, hueref, dhue, chromaref, pm, lco, lumaref, av, lp, deltE, original, transformed, cx, cy);
+
+ if (call <= 3) {
+
+ delete bufcontorig;
+
+
+ for (int i = 0; i < bfh; i++) {
+ delete [] buflightc[i];
+ }
+
+ delete [] buflightc;
+ }
+
+
} else if (lp.inv && lp.cont != 0 && lp.colorena) {
float multL = (float)lp.cont * (maxl - 1.f) / 100.f + 1.f;
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 099148f5a..2b64900d6 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -536,6 +536,7 @@ enum ProcEvent {
EvlocallabLHshape = 506,
Evlocallabcurvactiv = 507,
Evlocallabccshape = 508,
+ EvlocallabqualitycurveMethod = 509,
NUMOFEVENTS
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 2a26991b9..af5922c9f 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -887,8 +887,9 @@ void LocallabParams::setDefaults()
centerY = 0;
circrad = 18;
qualityMethod = "std";
- proxi = 1;
- thres = 60;
+ qualitycurveMethod = "none";
+ proxi = 20;
+ thres = 18;
lightness = 0;
contrast = 0;
chroma = 0;
@@ -2753,6 +2754,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
keyFile.set_string ("Locallab", "qualityMethod", locallab.qualityMethod);
}
+ if (!pedited || pedited->locallab.qualitycurveMethod) {
+ keyFile.set_string ("Locallab", "qualitycurveMethod", locallab.qualitycurveMethod);
+ }
+
if (!pedited || pedited->locallab.locY) {
keyFile.set_integer ("Locallab", "LocY", locallab.locY);
}
@@ -4351,6 +4356,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Locallab", "qualitycurveMethod")) {
+ locallab.qualitycurveMethod = keyFile.get_string ("Locallab", "qualitycurveMethod");
+
+ if (pedited) {
+ pedited->locallab.qualitycurveMethod = true;
+ }
+ }
+
if (keyFile.has_key ("Locallab", "LocY")) {
locallab.locY = keyFile.get_integer ("Locallab", "LocY");
@@ -8845,6 +8858,7 @@ bool ProcParams::operator== (const ProcParams& other)
&& locallab.Smethod == other.locallab.Smethod
&& locallab.retinexMethod == other.locallab.retinexMethod
&& locallab.qualityMethod == other.locallab.qualityMethod
+ && locallab.qualitycurveMethod == other.locallab.qualitycurveMethod
&& locallab.locY == other.locallab.locY
&& locallab.locX == other.locallab.locX
&& locallab.locYT == other.locallab.locYT
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 47f8b03b7..4e56e0ecb 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -877,6 +877,7 @@ public:
int thres;
int proxi;
Glib::ustring qualityMethod;
+ Glib::ustring qualitycurveMethod;
bool expcolor;
bool expblur;
bool exptonemap;
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 4b267c001..4163a1f6e 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -535,7 +535,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, //Evlocenadenoi
LUMINANCECURVE, //EvlocallabLHshape
LUMINANCECURVE, //Evlocallabcurvactiv
- LUMINANCECURVE //Evlocallabccshape
+ LUMINANCECURVE, //Evlocallabccshape
+ LUMINANCECURVE //EvlocallabqualitycurveMethod
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index ea755b3c2..0e61c8086 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -1018,9 +1018,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
std::string inser;
int **dataspots;
- dataspots = new int*[60];
+ dataspots = new int*[61];
- for (int i = 0; i < 60; i++) {
+ for (int i = 0; i < 61; i++) {
dataspots[i] = new int[maxspot];
}
@@ -1154,9 +1154,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
dataspots[56][0] = 1;
}
- dataspots[57][0] = 100.f * params.locallab.hueref;
- dataspots[58][0] = params.locallab.chromaref;
- dataspots[59][0] = params.locallab.lumaref;
+ if (params.locallab.qualitycurveMethod == "none") {
+ dataspots[57][0] = 0;
+ } else if (params.locallab.qualitycurveMethod == "std") {
+ dataspots[57][0] = 1;
+ } else if (params.locallab.qualitycurveMethod == "enh") {
+ dataspots[57][0] = 2;
+ }
+
+ dataspots[58][0] = 100.f * params.locallab.hueref;
+ dataspots[59][0] = params.locallab.chromaref;
+ dataspots[60][0] = params.locallab.lumaref;
//curve Reti local
int siz = params.locallab.localTgaincurve.size();
@@ -1294,7 +1302,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
dataspots[16][0] = std::stoi (str3.c_str());
}
- if (cont > 16 && cont < 60) {
+ if (cont > 16 && cont < 61) {
dataspots[cont][ns] = std::stoi (str3.c_str());
}
@@ -1498,9 +1506,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.locallab.curvactiv = true;
}
- params.locallab.hueref = ((float) dataspots[57][sp]) / 100.f;
- params.locallab.chromaref = dataspots[58][sp];
- params.locallab.lumaref = dataspots[59][sp];
+ if (dataspots[57][sp] == 0) {
+ params.locallab.qualitycurveMethod = "none" ;
+ } else if (dataspots[57][sp] == 1) {
+ params.locallab.qualitycurveMethod = "std" ;
+ } else if (dataspots[57][sp] == 2) {
+ params.locallab.qualitycurveMethod = "enh" ;
+ }
+
+ params.locallab.hueref = ((float) dataspots[58][sp]) / 100.f;
+ params.locallab.chromaref = dataspots[59][sp];
+ params.locallab.lumaref = dataspots[60][sp];
int *s_datc;
@@ -1587,7 +1603,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
- for (int i = 0; i < 60; i++) {
+ for (int i = 0; i < 61; i++) {
delete [] dataspots[i];
}
diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc
index 5ca28a072..61139b666 100644
--- a/rtgui/locallab.cc
+++ b/rtgui/locallab.cc
@@ -62,8 +62,8 @@ Locallab::Locallab ():
centerX (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_X"), -1000, 1000, 1, 0))),
centerY (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_Y"), -1000, 1000, 1, 0))),
circrad (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CIRCRADIUS"), 4, 100, 1, 18))),
- thres (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_THRES"), 1, 315, 1, 60))),
- proxi (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_PROXI"), 1, 8, 1, 1))),
+ thres (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_THRES"), 1, 35, 1, 18))),
+ proxi (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_PROXI"), 0, 60, 1, 20))),
lightness (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_LIGHTNESS"), -100, 100, 1, 0))),
contrast (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CONTRAST"), -100, 100, 1, 0))),
chroma (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CHROMA"), -100, 150, 1, 0))),
@@ -99,10 +99,33 @@ Locallab::Locallab ():
Smethod (Gtk::manage (new MyComboBoxText ())),
qualityMethod (Gtk::manage (new MyComboBoxText ())),
retinexMethod (Gtk::manage (new MyComboBoxText ())),
+ qualitycurveMethod (Gtk::manage (new MyComboBoxText ())),
+
+ shapeFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_SHFR")))),
+ artifFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_ARTIF")))),
+ superFrame (Gtk::manage (new Gtk::Frame ())),
+
+ artifVBox (Gtk::manage (new Gtk::VBox ())),
+ shapeVBox (Gtk::manage (new Gtk::VBox ())),
+ tmBox (Gtk::manage (new Gtk::VBox())),
+ retiBox (Gtk::manage (new Gtk::VBox())),
+ colorVBox (Gtk::manage ( new Gtk::VBox())),
+ blurrVBox (Gtk::manage ( new Gtk::VBox())),
+ sharpVBox (Gtk::manage ( new Gtk::VBox())),
+ cbdlVBox (Gtk::manage ( new Gtk::VBox())),
+ denoisVBox (Gtk::manage ( new Gtk::VBox())),
+ superVBox (Gtk::manage (new Gtk::VBox ())),
+
labmdh (Gtk::manage (new Gtk::Label (M ("TP_LOCRETI_METHOD") + ":"))),
+ labqual (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUAL_METHOD") + ":"))),
+ labqualcurv (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUALCURV_METHOD") + ":"))),
+ labmS (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_STYPE") + ":"))),
+
ctboxS (Gtk::manage (new Gtk::HBox ())),
dhbox (Gtk::manage (new Gtk::HBox ())),
+ qualbox (Gtk::manage (new Gtk::HBox ())),
+ qualcurvbox (Gtk::manage (new Gtk::HBox ())),
avoid (Gtk::manage (new Gtk::CheckButton (M ("TP_LOCALLAB_AVOID")))),
activlum (Gtk::manage (new Gtk::CheckButton (M ("TP_LOCALLAB_ACTIV")))),
@@ -145,8 +168,6 @@ Locallab::Locallab ():
anbspot->setAdjusterListener (this);
anbspot->set_tooltip_text (M ("TP_LOCALLAB_ANBSPOT_TOOLTIP"));
-
- Gtk::Frame* shapeFrame = Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_SHFR")) );
shapeFrame->set_border_width (0);
shapeFrame->set_label_align (0.025, 0.5);
@@ -171,11 +192,9 @@ Locallab::Locallab ():
expdenoi->signal_button_release_event().connect_notify ( sigc::bind ( sigc::mem_fun (this, &Locallab::foldAllButMe), expdenoi) );
enabledenoiConn = expdenoi->signal_enabled_toggled().connect ( sigc::bind ( sigc::mem_fun (this, &Locallab::enableToggled), expdenoi) );
- Gtk::VBox *shapeVBox = Gtk::manage ( new Gtk::VBox());
shapeVBox->set_spacing (2);
shapeVBox->set_border_width (4);
- Gtk::Label* labmS = Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_STYPE") + ":"));
ctboxS->pack_start (*labmS, Gtk::PACK_SHRINK, 4);
ctboxS->set_tooltip_markup (M ("TP_LOCALLAB_STYPE_TOOLTIP"));
@@ -229,6 +248,15 @@ Locallab::Locallab ():
irg = Gtk::manage (new RTImage ("Chanmixer-RG.png"));
+ qualitycurveMethod->append (M ("TP_LOCALLAB_CURVNONE"));
+ qualitycurveMethod->append (M ("TP_LOCALLAB_CURVCURR"));
+ qualitycurveMethod->append (M ("TP_LOCALLAB_CURVENH"));
+ qualitycurveMethod->set_active (0);
+ qualitycurveMethodConn = qualitycurveMethod->signal_changed().connect ( sigc::mem_fun (*this, &Locallab::qualitycurveMethodChanged) );
+ qualitycurveMethod->set_tooltip_markup (M ("TP_LOCALLAB_CURVEMETHOD_TOOLTIP"));
+
+
+
llCurveEditorG->setCurveListener (this);
rtengine::LocallabParams::getDefaultLLCurve (defaultCurve);
@@ -313,7 +341,6 @@ Locallab::Locallab ():
inversretConn = inversret->signal_toggled().connect ( sigc::mem_fun (*this, &Locallab::inversretChanged) );
//tone mapping local
- Gtk::VBox * tmBox = Gtk::manage (new Gtk::VBox());
tmBox->set_border_width (4);
tmBox->set_spacing (2);
@@ -334,7 +361,6 @@ Locallab::Locallab ():
//retinex local
- Gtk::VBox * retiBox = Gtk::manage (new Gtk::VBox());
retiBox->set_border_width (4);
retiBox->set_spacing (2);
@@ -403,26 +429,24 @@ Locallab::Locallab ():
shapeVBox->pack_start (*centerY);
shapeVBox->pack_start (*circrad);
//shapeVBox->pack_start (*activlum);
- shapeVBox->pack_start (*qualityMethod);
- // shapeVBox->pack_start (*thres);
- // shapeVBox->pack_start (*proxi);
+ qualbox->pack_start (*labqual, Gtk::PACK_SHRINK, 4);
+ qualbox->pack_start (*qualityMethod);
+ shapeVBox->pack_start (*qualbox);
+// shapeVBox->pack_start (*thres);
+// shapeVBox->pack_start (*proxi);
shapeFrame->add (*shapeVBox);
pack_start (*shapeFrame);
- Gtk::VBox *colorVBox = Gtk::manage ( new Gtk::VBox());
colorVBox->set_spacing (2);
colorVBox->set_border_width (4);
- Gtk::VBox *blurrVBox = Gtk::manage ( new Gtk::VBox());
blurrVBox->set_spacing (2);
blurrVBox->set_border_width (4);
- Gtk::VBox *sharpVBox = Gtk::manage ( new Gtk::VBox());
sharpVBox->set_spacing (2);
sharpVBox->set_border_width (4);
- Gtk::VBox *cbdlVBox = Gtk::manage ( new Gtk::VBox());
cbdlVBox->set_spacing (2);
cbdlVBox->set_border_width (4);
@@ -490,7 +514,6 @@ Locallab::Locallab ():
sharpVBox->pack_start (*sensisha);
sharpVBox->pack_start (*inverssha);
- Gtk::VBox *denoisVBox = Gtk::manage ( new Gtk::VBox());
denoisVBox->set_spacing (2);
denoisVBox->set_border_width (4);
@@ -519,16 +542,39 @@ Locallab::Locallab ():
neutrHBox1->pack_start (*neutral1);
pack_start (*neutrHBox1);
+ superFrame->set_label_align (0.025, 0.5);
+ Gtk::VBox *superVBox = Gtk::manage ( new Gtk::VBox());
+ superVBox->set_spacing (2);
+ superFrame->set_label_widget (*curvactiv);
- colorVBox->pack_start (*lightness);
- colorVBox->pack_start (*contrast);
+ superVBox->pack_start (*lightness);
+// colorVBox->pack_start (*curvactiv);
+ superVBox->pack_start (*contrast);
+ superFrame->add (*superVBox);
+ colorVBox->pack_start (*superFrame);
+
colorVBox->pack_start (*chroma);
colorVBox->pack_start (*sensi);
- colorVBox->pack_start (*curvactiv);
+
+ qualcurvbox->pack_start (*labqualcurv, Gtk::PACK_SHRINK, 4);
+ qualcurvbox->pack_start (*qualitycurveMethod);
+
+ colorVBox->pack_start (*qualcurvbox);
+
colorVBox->pack_start (*llCurveEditorG, Gtk::PACK_SHRINK, 2);
+ artifFrame->set_border_width (0);
+ artifFrame->set_label_align (0.025, 0.5);
+ artifVBox->set_spacing (2);
+ artifVBox->set_border_width (4);
+
+ artifVBox->pack_start (*thres);
+ artifVBox->pack_start (*proxi);
+ artifFrame->add (*artifVBox);
+
+ colorVBox->pack_start (*artifFrame);
colorVBox->pack_start (*invers);
expcolor->add (*colorVBox);
@@ -759,6 +805,7 @@ void Locallab::neutral_pressed ()
centerY->resetValue (false);
circrad->resetValue (false);
qualityMethod->set_active (0);
+ qualitycurveMethod->set_active (0);
thres->resetValue (false);
proxi->resetValue (false);
lightness->resetValue (false);
@@ -1150,6 +1197,14 @@ bool Locallab::localComputed_ ()
curvactiv->set_active (true);
}
+ if (nextdatasp[57] == 0) {
+ qualitycurveMethod->set_active (0);
+ } else if (nextdatasp[57] == 1) {
+ qualitycurveMethod->set_active (1);
+ } else if (nextdatasp[57] == 2) {
+ qualitycurveMethod->set_active (2);
+ }
+
int *s_datc;
s_datc = new int[70];
int siz;
@@ -1291,7 +1346,10 @@ bool Locallab::localComputed_ ()
if (listener) {//for quality method
listener->panelChanged (EvlocallabqualityMethod, qualityMethod->get_active_text ());
+ }
+ if (listener) {//for quality method
+ listener->panelChanged (EvlocallabqualitycurveMethod, qualitycurveMethod->get_active_text ());
}
if (listener) {//for inverse retinex
@@ -1331,7 +1389,7 @@ bool Locallab::localComputed_ ()
void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat)
{
- for (int i = 2; i < 60; i++) { //58
+ for (int i = 2; i < 61; i++) {
nextdatasp[i] = datasp[i][sp];
}
@@ -1452,6 +1510,10 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited)
qualityMethod->set_active_text (M ("GENERAL_UNCHANGED"));
}
+ if (!pedited->locallab.qualitycurveMethod) {
+ qualitycurveMethod->set_active_text (M ("GENERAL_UNCHANGED"));
+ }
+
}
setEnabled (pp->locallab.enabled);
@@ -1459,6 +1521,7 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited)
Smethodconn.block (true);
retinexMethodConn.block (true);
qualityMethodConn.block (true);
+ qualitycurveMethodConn.block (true);
avoidConn.block (true);
avoid->set_active (pp->locallab.avoid);
@@ -1595,6 +1658,16 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited)
qualityMethodChanged ();
qualityMethodConn.block (false);
+ if (pp->locallab.qualitycurveMethod == "none") {
+ qualitycurveMethod->set_active (0);
+ } else if (pp->locallab.qualitycurveMethod == "std") {
+ qualitycurveMethod->set_active (1);
+ } else if (pp->locallab.qualitycurveMethod == "enh") {
+ qualitycurveMethod->set_active (2);
+ }
+
+ qualitycurveMethodChanged ();
+ qualitycurveMethodConn.block (false);
anbspot->hide();
@@ -1788,6 +1861,7 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited)
pedited->locallab.Smethod = Smethod->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->locallab.retinexMethod = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->locallab.qualityMethod = qualityMethod->get_active_text() != M ("GENERAL_UNCHANGED");
+ pedited->locallab.qualitycurveMethod = qualitycurveMethod->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->locallab.locY = locY->getEditedState ();
pedited->locallab.locX = locX->getEditedState ();
pedited->locallab.locYT = locYT->getEditedState ();
@@ -1874,6 +1948,14 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited)
pp->locallab.qualityMethod = "enhden";
}
+ if (qualitycurveMethod->get_active_row_number() == 0) {
+ pp->locallab.qualitycurveMethod = "none";
+ } else if (qualitycurveMethod->get_active_row_number() == 1) {
+ pp->locallab.qualitycurveMethod = "std";
+ } else if (qualitycurveMethod->get_active_row_number() == 2) {
+ pp->locallab.qualitycurveMethod = "enh";
+ }
+
if (Smethod->get_active_row_number() == 0) {
pp->locallab.Smethod = "IND";
@@ -1980,6 +2062,7 @@ void Locallab::retinexMethodChanged()
void Locallab::qualityMethodChanged()
{
if (!batchMode) {
+ /*
if (qualityMethod->get_active_row_number() == 0) { //STD
proxi->hide();
thres->hide();
@@ -1987,6 +2070,7 @@ void Locallab::qualityMethodChanged()
proxi->show();
thres->show();
}
+ */
}
if (listener) {
@@ -1994,6 +2078,25 @@ void Locallab::qualityMethodChanged()
}
}
+void Locallab::qualitycurveMethodChanged()
+{
+ if (!batchMode) {
+ /*
+ if (qualitycurveMethod->get_active_row_number() == 0 || qualitycurveMethod->get_active_row_number() == 1) { //None or STD
+ artifFrame->hide();
+ } else if (qualitycurveMethod->get_active_row_number() == 0 && qualityMethod->get_active_row_number() >= 1) {
+ artifFrame->show();
+ } else if (qualitycurveMethod->get_active_row_number() == 2){
+ artifFrame->show();
+ }
+ */
+ }
+
+ if (listener) {
+ listener->panelChanged (EvlocallabqualitycurveMethod, qualitycurveMethod->get_active_text ());
+ }
+}
+
void Locallab::SmethodChanged ()
{
if (!batchMode) {
@@ -2078,10 +2181,18 @@ void Locallab::inversChanged ()
sensi->hide();
llCurveEditorG->hide();
curvactiv->hide();
+ qualitycurveMethod->hide();
+ artifFrame->hide();
+ labqualcurv->hide();
+
} else {
sensi->show();
llCurveEditorG->show();
curvactiv->show();
+ qualitycurveMethod->show();
+ artifFrame->show();
+ labqualcurv->show();
+
}
if (listener) {
diff --git a/rtgui/locallab.h b/rtgui/locallab.h
index 0ff384325..9b56f9ccc 100644
--- a/rtgui/locallab.h
+++ b/rtgui/locallab.h
@@ -100,6 +100,23 @@ private:
sigc::connection editConn, avoidConn, inversConn, curvactivConn, activlumConn, inversradConn, inversretConn, inversshaConn, neutralconn, neutralconn1;
Gtk::HBox* const ctboxS;
+ Gtk::HBox* const qualbox;
+ Gtk::HBox* const qualcurvbox;
+
+ Gtk::Frame* const artifFrame;
+ Gtk::Frame* const shapeFrame;
+ Gtk::Frame* const superFrame;
+
+ Gtk::VBox* const artifVBox;
+ Gtk::VBox* const shapeVBox;
+ Gtk::VBox* const tmBox;
+ Gtk::VBox* const retiBox;
+ Gtk::VBox* const colorVBox;
+ Gtk::VBox* const blurrVBox;
+ Gtk::VBox* const sharpVBox;
+ Gtk::VBox* const cbdlVBox;
+ Gtk::VBox* const denoisVBox;
+ Gtk::VBox* const superVBox;
Gtk::CheckButton* const avoid;
Gtk::CheckButton* const invers;
@@ -120,9 +137,15 @@ private:
sigc::connection retinexMethodConn;
MyComboBoxText* const qualityMethod;
sigc::connection qualityMethodConn;
+ MyComboBoxText* const qualitycurveMethod;
+ sigc::connection qualitycurveMethodConn;
Gtk::Label* const labmdh;
+ Gtk::Label* const labqual;
+ Gtk::Label* const labqualcurv;
+ Gtk::Label* const labmS;
+
Gtk::HBox* const dhbox;
CurveEditorGroup* const LocalcurveEditorgainT;
@@ -137,7 +160,7 @@ private:
- int nextdatasp[60];
+ int nextdatasp[61];
int nextlength;
std::string nextstr;
std::string nextstr2;
@@ -197,6 +220,7 @@ public:
void setEditProvider (EditDataProvider* provider);
void retinexMethodChanged();
void qualityMethodChanged();
+ void qualitycurveMethodChanged();
void lumaneutralPressed ();
void lumacontrastPlusPressed ();
void lumacontrastMinusPressed ();
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 53590db4a..41d70bcb2 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -310,6 +310,7 @@ void ParamsEdited::set (bool v)
locallab.thres = v;
locallab.proxi = v;
locallab.qualityMethod = v;
+ locallab.qualitycurveMethod = v;
locallab.lightness = v;
locallab.contrast = v;
locallab.chroma = v;
@@ -881,6 +882,7 @@ void ParamsEdited::initFrom (const std::vector
locallab.thres = locallab.thres && p.locallab.thres == other.locallab.thres;
locallab.proxi = locallab.proxi && p.locallab.proxi == other.locallab.proxi;
locallab.qualityMethod = locallab.qualityMethod && p.locallab.qualityMethod == other.locallab.qualityMethod;
+ locallab.qualitycurveMethod = locallab.qualitycurveMethod && p.locallab.qualitycurveMethod == other.locallab.qualitycurveMethod;
locallab.lightness = locallab.lightness && p.locallab.lightness == other.locallab.lightness;
locallab.contrast = locallab.contrast && p.locallab.contrast == other.locallab.contrast;
locallab.chroma = locallab.chroma && p.locallab.chroma == other.locallab.chroma;
@@ -2229,6 +2231,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.locallab.qualityMethod = mods.locallab.qualityMethod;
}
+ if (locallab.qualitycurveMethod) {
+ toEdit.locallab.qualitycurveMethod = mods.locallab.qualitycurveMethod;
+ }
+
if (locallab.centerX) {
toEdit.locallab.centerX = mods.locallab.centerX;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index f7d5956ac..8544261a9 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -429,6 +429,7 @@ public:
bool thres;
bool proxi;
bool qualityMethod;
+ bool qualitycurveMethod;
bool lightness;
bool contrast;
bool chroma;