diff --git a/rtdata/languages/default b/rtdata/languages/default index 6fa3d1b6e..77f46be18 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1917,6 +1917,9 @@ TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance "Super" TP_LOCALLAB_CURVNONE;Disable curves TP_LOCALLAB_CURVCURR;Normal TP_LOCALLAB_CURVENH;Super +TP_LOCALLAB_CURVENHSU;Combined HueChroma (experimental) +TP_LOCALLAB_CURVENCONTRAST;Super+Contrast threshold (experimental) +TP_LOCALLAB_CURVENSOB2;Combined HueChroma + Contrast threshold (experimental) TP_LOCALLAB_DENOIS;Denoise TP_LOCALLAB_LUM;Curves TP_LOCALLAB_CHROMACBDL;Chroma diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 0ce82c379..850638495 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -305,7 +305,7 @@ public: void vibrancelocal(int sp, int bfw, int bfh, LabImage* lab, LabImage* dest, bool & localskutili, LUTf & sklocalcurve); void Expo_vibr_Local(int senstype, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk); void exlabLocal(const local_params& lp, int bfh, int bfw, LabImage* bufexporig, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve); - void Exclude_Local(int sen, float **deltaso, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, int cx, int cy, int sk); + void Exclude_Local(int sen, float **deltaso, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, LabImage * reserv, int cx, int cy, int sk); // void vibrance_Local(float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk); // void ColorLight_Local(int call, LabImage * bufcolorig, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 8ded508b4..f1e61dc58 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -62,7 +62,7 @@ #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, 99.5f) +#define CLIPLIG(x) LIM(x,-99.5f, 99.5f) #define CLIPCHRO(x) LIM(x,0.f, 140.f) #define CLIPRET(x) LIM(x,-99.5f, 99.5f) #define CLIP1(x) LIM(x, 0.f, 1.f) @@ -371,6 +371,12 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.qualcurvemet = 1; } else if (locallab.qualitycurveMethod.at(sp) == "enh") { lp.qualcurvemet = 2; + } else if (locallab.qualitycurveMethod.at(sp) == "enhsup") { + lp.qualcurvemet = 3; + } else if (locallab.qualitycurveMethod.at(sp) == "contr") { + lp.qualcurvemet = 4; + } else if (locallab.qualitycurveMethod.at(sp) == "sob2") { + lp.qualcurvemet = 5; } if (locallab.blurMethod.at(sp) == "norm") { @@ -2522,6 +2528,10 @@ void ImProcFunctions::cbdl_Local(float ** buflight, float ** bufchrom, float **l const float pb = 4.f; const float pa = (1.f - pb) / 40.f; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; const float ahu = 1.f / (2.8f * lp.senscb - 280.f); const float bhu = 1.f - ahu * 2.8f * lp.senscb; @@ -2614,6 +2624,7 @@ void ImProcFunctions::cbdl_Local(float ** buflight, float ** bufchrom, float **l #endif // int zone; float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); //retrieve data float cli = 1.f; @@ -2651,6 +2662,7 @@ void ImProcFunctions::cbdl_Local(float ** buflight, float ** bufchrom, float **l //prepare shape detection float khu = 0.f; float kch = 1.f; + float kchchro = 1.f; float fach = 1.f; float falu = 1.f; float deltachro = fabs(rchro - chromaref); @@ -2663,18 +2675,61 @@ void ImProcFunctions::cbdl_Local(float ** buflight, float ** bufchrom, float **l float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 float deltaL = fabs(lumaref - rL); //between 0 and 100 - //kch to modulate action with chroma + /* + //kch to modulate action with chroma + if (deltachro < 160.f * SQR(lp.senscb / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR(lp.senscb / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (lp.senscb < 40.f) { + kch = pow(kch, pa * lp.senscb + pb); //increase under 40 + } + */ if (deltachro < 160.f * SQR(lp.senscb / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(lp.senscb / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + // kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; + } + float kkch = 1.f; + kkch = pa * lp.senscb + pb; + float kch0 = kch; + if (lp.senscb < 40.f) { - kch = pow(kch, pa * lp.senscb + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * lp.senscb; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } + } + + float dEsensall = lp.senscb; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } } @@ -2759,6 +2814,9 @@ void ImProcFunctions::cbdl_Local(float ** buflight, float ** bufchrom, float **l } + realcligh *= kD;; + realcchro *= kD; + if (lp.senscb <= 20.f) { if (deltaE < 2.8f * lp.senscb) { @@ -2900,6 +2958,11 @@ void ImProcFunctions::TM_Local(LabImage * tmp1, float **buflight, const float hu const float pb = 4.f; const float pa = (1.f - pb) / 40.f; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; + const float ahu = 1.f / (2.8f * lp.senstm - 280.f); const float bhu = 1.f - ahu * 2.8f * lp.senstm; @@ -2997,6 +3060,7 @@ void ImProcFunctions::TM_Local(LabImage * tmp1, float **buflight, const float hu #endif // int zone; float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); //retrieve data float cli = 1.f; @@ -3018,6 +3082,7 @@ void ImProcFunctions::TM_Local(LabImage * tmp1, float **buflight, const float hu //prepare shape detection float khu = 0.f; float kch = 1.f; + float kchchro = 1.f; float fach = 1.f; float falu = 1.f; float deltachro = fabs(rchro - chromaref); @@ -3030,20 +3095,62 @@ void ImProcFunctions::TM_Local(LabImage * tmp1, float **buflight, const float hu float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 float deltaL = fabs(lumaref - rL); //between 0 and 100 - //kch to modulate action with chroma + /* + //kch to modulate action with chroma + if (deltachro < 160.f * SQR(lp.senstm / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR(lp.senstm / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (lp.senstm < 40.f) { + kch = pow(kch, pa * lp.senstm + pb); //increase under 40 + } + */ if (deltachro < 160.f * SQR(lp.senstm / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(lp.senstm / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + // kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; + } + float kkch = 1.f; + kkch = pa * lp.senstm + pb; + float kch0 = kch; + if (lp.senstm < 40.f) { - kch = pow(kch, pa * lp.senstm + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * lp.senstm; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } } + float dEsensall = lp.senstm; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } + } // algo with detection of hue ==> artifacts for noisy images ==> denoise before if (lp.senstm < 100.f) { //to try... @@ -3113,6 +3220,8 @@ void ImProcFunctions::TM_Local(LabImage * tmp1, float **buflight, const float hu } + realcligh *= kD; + if (lp.senstm <= 20.f) { if (deltaE < 2.8f * lp.senstm) { @@ -3226,11 +3335,15 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 const float ahu = 1.f / (2.8f * lp.sensbn - 280.f); const float bhu = 1.f - ahu * 2.8f * lp.sensbn; + const float moddE = 2.f; const float alum = 1.f / (lp.sensbn - 100.f); const float blum = 1.f - alum * lp.sensbn; + int GW = transformed->W; int GH = transformed->H; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); LabImage *origblur = nullptr; @@ -3361,6 +3474,7 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 #endif float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); float cli = 1.f; float clc = 1.f; @@ -3379,6 +3493,7 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 float bmoinsch = 1.f - amoinsch * huemoins; //prepare shape detection + float kchchro = 1.f; float kch = 1.f; float fach = 1.f; float falu = 1.f; @@ -3395,18 +3510,68 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 float deltaL = fabs(lumaref - rL); //between 0 and 100 - //kch to modulate action with chroma + /* + //kch to modulate action with chroma + if (deltachro < 160.f * SQR(lp.sensbn / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR(lp.sensbn / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (lp.sensbn < 40.f) { + kch = pow(kch, pa * lp.sensbn + pb); //increase under 90 + } + + */ + //kch and kgcchro acts on luma and chroma if (deltachro < 160.f * SQR(lp.sensbn / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(lp.sensbn / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; } + float kkch = 1.f; + kkch = pa * lp.sensbn + pb; + float kch0 = kch; + if (lp.sensbn < 40.f) { - kch = pow(kch, pa * lp.sensbn + pb); //increase under 90 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * lp.sensbn; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } + + /* + if (deltahue < 0.3f && dE > (2.5f * lp.sensbn) && settings->detectshape == true) { + float epsi = 0.000001f; + kchchro = kch = pow(kch0, (1.f + 5.f * (3.f - 10.f * deltahue)) * kkch);//increase more and more if deltahue very small and chrom diffrent + } + */ + } + + float dEsensall = lp.sensbn; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } } // algo with detection of hue ==> artifacts for noisy images ==> denoise before @@ -3472,7 +3637,11 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } } - if (lp.sensbn <= 35.f) { //to try... + realstr *= kD; + realstrch *= kD; + + + if (lp.sensbn <= 20.f) { //to try... if (deltaE < 2.8f * lp.sensbn) { fach = khu; @@ -3520,7 +3689,7 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } - difL *= factorx * (100.f + realstr) / 100.f; + difL *= factorx * (100.f + realstr * kchchro) / 100.f; difL *= kch * fach; if (lp.blurmet == 0) { @@ -3532,8 +3701,8 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } if (!lp.actsp) { - difa *= factorx * (100.f + realstrch * falu) / 100.f; - difb *= factorx * (100.f + realstrch * falu) / 100.f; + difa *= factorx * (100.f + realstrch * falu * kchchro) / 100.f; + difb *= factorx * (100.f + realstrch * falu * kchchro) / 100.f; difa *= kch * fach; difb *= kch * fach; @@ -3565,7 +3734,7 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } - difL *= (100.f + realstr) / 100.f; + difL *= (100.f + realstr * kchchro) / 100.f; difL *= kch * fach; if (lp.blurmet == 0) { @@ -3577,8 +3746,8 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } if (!lp.actsp) { - difa *= (100.f + realstrch * falu) / 100.f; - difb *= (100.f + realstrch * falu) / 100.f; + difa *= (100.f + realstrch * falu * kchchro) / 100.f; + difb *= (100.f + realstrch * falu * kchchro) / 100.f; difa *= kch * fach; difb *= kch * fach; @@ -3714,6 +3883,11 @@ void ImProcFunctions::Reti_Local(float **buflight, float **bufchro, const float const float pb = 4.f; const float pa = (1.f - pb) / 40.f; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; + const float ahu = 1.f / (2.8f * lp.sensh - 280.f); const float bhu = 1.f - ahu * 2.8f * lp.sensh; @@ -3811,6 +3985,7 @@ void ImProcFunctions::Reti_Local(float **buflight, float **bufchro, const float float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); float cli = 1.f; float clc = 1.f; @@ -3842,21 +4017,65 @@ void ImProcFunctions::Reti_Local(float **buflight, float **bufchro, const float float deltaL = fabs(lumaref - rL); //between 0 and 100 float kch = 1.f; + float kchchro = 1.f; float khu = 0.f; float fach = 1.f; float falu = 1.f; + /* + if (deltachro < 160.f * SQR(lp.sensh / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR(lp.sensh / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (lp.sensh < 40.f) { + kch = pow(kch, pa * lp.sensh + pb); //increase under 40 + } + */ if (deltachro < 160.f * SQR(lp.sensh / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(lp.sensh / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + // kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; + } + float kkch = 1.f; + kkch = pa * lp.sensh + pb; + float kch0 = kch; + if (lp.sensh < 40.f) { - kch = pow(kch, pa * lp.sensh + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * lp.sensh; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } + } + + float dEsensall = lp.sensh; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } } bool kzon = false; @@ -3943,6 +4162,9 @@ void ImProcFunctions::Reti_Local(float **buflight, float **bufchro, const float kzon = true; } + realstr *= kD; + realstrch *= kD; + //shape detection for hue chroma and luma if (lp.sensh <= 20.f) { //to try... @@ -4220,6 +4442,10 @@ void ImProcFunctions::Contrast_Local(int call, float ** buflightc, const float h const float pb = 4.f; const float pa = (1.f - pb) / 40.f; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + //const float moddE = 2.f; const float ahu = 1.f / (2.8f * lp.sens - 280.f); const float bhu = 1.f - ahu * 2.8f * lp.sens; @@ -4321,6 +4547,10 @@ void ImProcFunctions::Contrast_Local(int call, float ** buflightc, const float h float rhue = xatan2f(origblur->b[y][x], origblur->a[y][x]); float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif + rL = origblur->L[y][x] / 327.68f; + + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); + //prepare shape detection float khu = 0.f; float kch = 1.f; @@ -4369,6 +4599,17 @@ void ImProcFunctions::Contrast_Local(int call, float ** buflightc, const float h } } + float dEsensall = lp.sens; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } + } + // algo with detection of hue ==> artifacts for noisy images ==> denoise before if (lp.sens < 100.f && lp.qualmet >= 1) { //to try... //hue detection @@ -4436,6 +4677,8 @@ void ImProcFunctions::Contrast_Local(int call, float ** buflightc, const float h } + realcligh *= kD; + if (deltaE < 2.8f * lp.sens) { fach = khu; } else { @@ -5359,7 +5602,7 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, const float hueplus -void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, int cx, int cy, int sk) +void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, LabImage * reserv, int cx, int cy, int sk) { //perhaps we can group with expo_vib_Local ?? but I prefer keep as that for now @@ -5389,6 +5632,10 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, //transition = difficult to avoid artifact with scope on flat area (sky...) constexpr float delhu = 0.05f; //between 0.05 and 0.2 + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; const float apl = (-1.f) / delhu; const float bpl = - apl * hueplus; @@ -5418,9 +5665,9 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, #pragma omp parallel #endif { - gaussianBlur(original->L, origblur->L, GW, GH, radius); - gaussianBlur(original->a, origblur->a, GW, GH, radius); - gaussianBlur(original->b, origblur->b, GW, GH, radius); + gaussianBlur(reserv->L, origblur->L, GW, GH, radius); + gaussianBlur(reserv->a, origblur->a, GW, GH, radius); + gaussianBlur(reserv->b, origblur->b, GW, GH, radius); } @@ -5497,13 +5744,15 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); float cli = 1.f; float clc = 1.f; + float cli2 = 1.f; + float clc2 = 1.f; cli = (buflight[loy - begy][lox - begx]); clc = (bufchro[loy - begy][lox - begx]); - float aplus = (1.f - cli) / delhu; float bplus = 1.f - aplus * hueplus; float amoins = (cli - 1.f) / delhu; @@ -5528,21 +5777,65 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, float deltaL = fabs(lumaref - rL); //between 0 and 100 float kch = 1.f; + float kchchro = 1.f; float khu = 0.f; float fach = 1.f; float falu = 1.f; + /* + if (deltachro < 160.f * SQR(varsens / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR(varsens / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (varsens < 40.f) { + kch = pow(kch, pa * varsens + pb); //increase under 40 + } + */ + //kch and kgcchro acts on luma and chroma if (deltachro < 160.f * SQR(varsens / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(varsens / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; } + float kkch = 1.f; + kkch = pa * varsens + pb; + float kch0 = kch; + if (varsens < 40.f) { - kch = pow(kch, pa * varsens + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * varsens; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } + } + + //take into account deltaE but only for mode >= super + float dEsensall = varsens; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f);// 5 empirical + } } bool kzon = false; @@ -5629,6 +5922,11 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, kzon = true; } + realstr *= kD; + realstrch *= kD; + + // printf("real=%f ", realstr); + /* //printf("re=%f", realstrch); if (realstrch > maxc) { @@ -5699,6 +5997,7 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, } +//printf("rea=%f ", realstr); float kcr = 100.f * lp.thr; float falL = 1.f; @@ -5706,7 +6005,6 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, falL *= pow(rchro / kcr, lp.iterat / 10.f); } - if (rL > 0.1f) { //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 @@ -5790,6 +6088,7 @@ void ImProcFunctions::Exclude_Local(int sen, float **deltaso, float **buflight, } } + } } @@ -5842,6 +6141,10 @@ void ImProcFunctions::Expo_vibr_Local(int senstype, float **buflight, float **bu const float pb = 4.f; const float pa = (1.f - pb) / 40.f; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; const float ahu = 1.f / (2.8f * varsens - 280.f); const float bhu = 1.f - ahu * 2.8f * varsens; @@ -5941,6 +6244,7 @@ void ImProcFunctions::Expo_vibr_Local(int senstype, float **buflight, float **bu float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); float cli = 1.f; float clc = 1.f; @@ -5973,23 +6277,58 @@ void ImProcFunctions::Expo_vibr_Local(int senstype, float **buflight, float **bu float deltaL = fabs(lumaref - rL); //between 0 and 100 float kch = 1.f; + float kchchro = 1.f; float khu = 0.f; float fach = 1.f; float falu = 1.f; if (deltachro < 160.f * SQR(varsens / 100.f)) { - kch = 1.f; + kch = kchchro = 1.f; } else { float ck = 160.f * SQR(varsens / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; - kch = ak * deltachro + bk; + // kch = ak * deltachro + bk; + kch = kchchro = ak * deltachro + bk; + } + float kkch = 1.f; + kkch = pa * varsens + pb; + float kch0 = kch; + if (varsens < 40.f) { - kch = pow(kch, pa * varsens + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * varsens; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && settings->detectshape == true) { + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } } + float dEsensall = varsens; + float kD = 1.f; + + if (settings->detectshape == true) { + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f); + } + } + + /* + if (varsens < 40.f) { + kch = pow(kch, pa * varsens + pb); //increase under 40 + } + */ bool kzon = false; //transition = difficult to avoid artifact with scope on flat area (sky...) @@ -6074,6 +6413,9 @@ void ImProcFunctions::Expo_vibr_Local(int senstype, float **buflight, float **bu kzon = true; } + realstr *= kD; + realstrch *= kD; + //shape detection for hue chroma and luma if (varsens <= 20.f) { //to try... @@ -6299,6 +6641,10 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** //luma constexpr float lumdelta = 11.f; //11 float modlum = lumdelta * multlum; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); + + const float moddE = 2.f; // constant and variables to prepare shape detection if (lumaref + modlum >= 100.f) { @@ -6427,6 +6773,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** origblur->b[y][x] = 0.01f; } + float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); //retriev data curve lightness float cli = (buflight[loy - begy][lox - begx]); //parameters for linear interpolation in function of real hue @@ -6486,23 +6833,65 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 float deltaL = fabs(lumaref - rL); //between 0 and 100 + float kchchro = 1.f; float kch = 1.f; float khu = 0.f; float fach = 1.f; float falu = 1.f; - //kch acts on luma + /* + //kch acts on luma + 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 + } + */ + //kch and kgcchro acts on luma and chroma if (deltachro < 160.f * SQR(lp.sens / 100.f)) { - kch = 1.f; + kch = kchchro = 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; + kch = kchchro = ak * deltachro + bk; } + float kkch = 1.f; + kkch = pa * lp.sens + pb; + float kch0 = kch; + if (lp.sens < 40.f) { - kch = pow(kch, pa * lp.sens + pb); //increase under 40 + kch = kchchro = pow(kch0, kkch); //increase under 40 + float dEsens = moddE * lp.sens; + float kdE = 1.f; + + if (dE > dEsens) { + kdE = 1.f; + } else { + kdE = SQR(SQR(dE / dEsens)); + } + + if (deltahue < 0.3f && (lp.qualcurvemet == 3 || lp.qualcurvemet == 5)) {//for very low differences with smal values of scope + kchchro = kch = pow(kch0, (1.f + kdE * moddE * (3.f - 10.f * deltahue)) * kkch); + } + } + + //take into account deltaE but only for mode >= super + float dEsensall = lp.sens; + float kD = 1.f; + + if (dE < dEsensall) { + kD = 1.f; + } else { + kD = pow(dEsensall / dE, 5.f);// 5 empirical } bool kzon = false; @@ -6646,6 +7035,11 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** kzon = true; } + realcligh *= kD; + realchro *= kD; + realchroslid *= kD; + realcurv *= kD; + realclighsl *= kD; //detection of deltaE and deltaL if (lp.sens <= 20.f) { //to try... @@ -6861,14 +7255,14 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** //realchro = 1.f; } - if (lp.qualcurvemet == 2) { + 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); + flicur = ((100.f + realcurv * factorx * falu * falL * kchchro) / 100.f); } float fac = flicur * (100.f + factorx * realchro * falu * falL) / 100.f; //chroma factor transition @@ -6895,7 +7289,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** // float dh = (0.02f*addh - 1.f) * rtengine::RT_PI; } - if (lp.qualcurvemet == 2) { + if (lp.qualcurvemet >= 2) { addh = 0.01f * realhh * factorx; } @@ -6978,14 +7372,14 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** //realchro = 1.f; } - if (lp.qualcurvemet == 2) { + 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); + flicur = ((100.f + realcurv * falu * falL * kchchro) / 100.f); } float fac = flicur * (100.f + realchro * falu * falL) / 100.f; //chroma factor transition7 @@ -7011,7 +7405,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** addh = ddhue; } - if (lp.qualcurvemet == 2) { + if (lp.qualcurvemet >= 2) { addh = 0.01f * realhh; } @@ -8109,7 +8503,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L av = ave / 327.68f; } - //printf ("call= %i sp=%i hueref=%f chromaref=%f lumaref=%f\n", call, sp, hueref, chromaref, lumaref); + printf("call= %i sp=%i hueref=%f chromaref=%f lumaref=%f\n", call, sp, hueref, chromaref, lumaref); struct local_contra lco; // we must here detect : general case, skin, sky,...foliages ??? @@ -8964,8 +9358,9 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float rL; - rL = CLIPRET((bufreserv->L[ir][jr] - bufexclu->L[ir][jr]) / 328.f); - buflight[ir][jr] = rL; + rL = (bufreserv->L[ir][jr] - bufexclu->L[ir][jr]) / 327.68f; + buflight[ir][jr] = rL ; + } @@ -8986,11 +9381,52 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float rch; - rch = CLIPRET((sqrt((SQR(bufreserv->a[ir][jr]) + SQR(bufreserv->b[ir][jr]))) - orig[ir][jr]) / 328.f); - bufchro[ir][jr] = rch; + rch = CLIPRET((sqrt((SQR(bufreserv->a[ir][jr]) + SQR(bufreserv->b[ir][jr]))) - orig[ir][jr])) / 327.68f; + bufchro[ir][jr] = rch ; } - Exclude_Local(1, deltasobelL->L, buflight, bufchro, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, bufreserv, cx, cy, sk); + /* + if (lp.sensexclu < 15.f) { + JaggedArray blend(bfw, bfh); + float contrastf = lp.sensexclu / 100.f; + + buildBlendMask(bufreserv->L, blend, bfw, bfh, contrastf, 1.f, true); + + #ifdef _OPENMP + #pragma omp parallel for + #endif + + for (int i = 0; i < bfh; ++i) { + for (int j = 0; j < bfw; ++j) { + if (blend[i][j] > 0.05f) { + blend[i][j] = 1.22361f * sqrt(blend[i][j]) - 0.22361f; + } + + bufreserv->L[i][j] = intp(blend[i][j], bufexclu->L[i][j], bufreserv->L[i][j]); + bufreserv->a[i][j] = intp(blend[i][j], bufexclu->a[i][j], bufreserv->a[i][j]); + bufreserv->b[i][j] = intp(blend[i][j], bufexclu->b[i][j], bufreserv->b[i][j]); + + } + } + } + + #ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) + #endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + original->L[y][x] = bufreserv->L[loy - begy][lox - begx]; + original->a[y][x] = bufreserv->a[loy - begy][lox - begx]; + original->b[y][x] = bufreserv->b[loy - begy][lox - begx]; + } + } + */ + Exclude_Local(1, deltasobelL->L, buflight, bufchro, hueplus, huemoins, hueref, dhueexclu, chromaref, lumaref, lp, original, transformed, bufreserv, reserved, cx, cy, sk); delete deltasobelL; @@ -10504,11 +10940,11 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L 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 - chpro = 99.f * ch - 99.f; - } else { - chpro = CLIPCHRO(ampli * ch - ampli); //ampli = 25.f arbitrary empirical coefficient between 5 and 50 - } + // if (ch <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape + // chpro = 99.f * ch - 99.f; + // } else { + chpro = CLIPCHRO(ampli * ch - ampli); //ampli = 25.f arbitrary empirical coefficient between 5 and 50 + // } bufchro[loy - begy][lox - begx] = chpro; @@ -10534,7 +10970,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } - if (lochhCurve && lp.qualcurvemet == 2 && HHutili) { + if (lochhCurve && lp.qualcurvemet >= 2 && HHutili) { float hhforcurv = xatan2f(bufcolorig->b[loy - begy][lox - begx], bufcolorig->a[loy - begy][lox - begx]); float valparam = float ((lochhCurve[500.f * Color::huelab_to_huehsv2(hhforcurv)] - 0.5f)); //get H=f(H) 1.7 optimisation ! @@ -10561,30 +10997,60 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } buflightslid[loy - begy][lox - begx] = clighL; + // printf("cl=%f ", clighL); } cligh = 0.f; //luma curve - if (lllocalcurve && lp.qualcurvemet == 2) {// L=f(L) curve enhanced + if (lllocalcurve && lp.qualcurvemet >= 2) {// L=f(L) curve enhanced float lh; float amplil = 25.f; float lighn = bufcolorig->L[loy - begy][lox - begx]; 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); - } + // printf("lh=%f ", lh); + // 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); + cligh = CLIPLIG(amplil * lh - amplil); + // } buflight[loy - begy][lox - begx] = cligh; + // printf("cli=%f ", cligh); } } } + + if (lp.qualcurvemet >= 4) { + JaggedArray blend(bfw, bfh); + float contrastf = lp.sensexclu / 100.f; + + buildBlendMask(bufcolorig->L, blend, bfw, bfh, contrastf, 1.f, true); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < bfh; ++i) { + for (int j = 0; j < bfw; ++j) { + if (blend[i][j] > 0.05f) { + blend[i][j] = 1.22361f * sqrt(blend[i][j]) - 0.22361f; + } + + buflight[i][j] = intp(blend[i][j], buflight[i][j], 0.f); + bufchro[i][j] = intp(blend[i][j], bufchro[i][j], 0.f); + } + } + } + + } + // printf("callCOLOR= %i sp=%i hueref=%f chromaref=%f lumaref=%f\n", call, sp, hueref, chromaref, lumaref); + ColorLight_Local(call, bufcolorig, buflight, bufchro, bufchroslid, bufhh, buflightslid, LHutili, HHutili, hueplus, huemoins, hueref, dhue, chromaref, lumaref, lllocalcurve, loclhCurve, lochhCurve, lightCurveloc, lp, original, transformed, cx, cy, sk); if (call <= 3) { diff --git a/rtengine/settings.h b/rtengine/settings.h index 05aca89cf..f40fb23b4 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -65,7 +65,7 @@ public: bool gamutICC; // no longer used bool gamutLch; bool HistogramWorking; // true: histogram is display the value of the image computed in the Working profile - // false: histogram is display the value of the image computed in the Output profile + // false: histogram is display the value of the image computed in the Output profile int amchroma; int protectred; double protectredh; @@ -85,6 +85,7 @@ public: int cropsleep; double reduchigh; double reduclow; + bool detectshape; Glib::ustring lensfunDbDirectory; ///< The directory containing the lensfun database. If empty, the system defaults will be used (as described in http://lensfun.sourceforge.net/manual/dbsearch.html) diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 8551e00da..f97dc4917 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -43,7 +43,7 @@ ControlSpotPanel::ControlSpotPanel(): shapeMethod_(Gtk::manage(new MyComboBoxText())), qualityMethod_(Gtk::manage(new MyComboBoxText())), - sensiexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 19))), + sensiexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 12))), struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUC"), 0, 5, 1, 0))), locX_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH"), 0, 2250, 1, 250))), locXL_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH_L"), 0, 2250, 1, 250))), @@ -200,7 +200,7 @@ ControlSpotPanel::ControlSpotPanel(): qualityMethod_->append(M("TP_LOCALLAB_STD")); qualityMethod_->append(M("TP_LOCALLAB_ENH")); qualityMethod_->append(M("TP_LOCALLAB_ENHDEN")); - qualityMethod_->set_active(0); + qualityMethod_->set_active(1); qualityMethodconn_ = qualityMethod_->signal_changed().connect( sigc::mem_fun( *this, &ControlSpotPanel::qualityMethodChanged)); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 3489d0c53..ce79823b5 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -186,6 +186,10 @@ Locallab::Locallab(): qualitycurveMethod->append(M("TP_LOCALLAB_CURVNONE")); qualitycurveMethod->append(M("TP_LOCALLAB_CURVCURR")); qualitycurveMethod->append(M("TP_LOCALLAB_CURVENH")); + qualitycurveMethod->append(M("TP_LOCALLAB_CURVENHSU")); + qualitycurveMethod->append(M("TP_LOCALLAB_CURVENCONTRAST")); + qualitycurveMethod->append(M("TP_LOCALLAB_CURVENSOB2")); + qualitycurveMethod->set_active(0); qualitycurveMethod->set_tooltip_markup(M("TP_LOCALLAB_CURVEMETHOD_TOOLTIP")); qualitycurveMethodConn = qualitycurveMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::qualitycurveMethodChanged)); @@ -965,7 +969,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) std::vector* const list = expsettings->getSpotIdList(); bool ispresent; - for (int i = 0; i < (int)list->size(); i++) { + for (int i = 0; i < (int)list->size() - 1; i++) { ispresent = false; for (int j = 0; j < pp->locallab.nbspot; j++) { @@ -1012,7 +1016,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) r->isvisible = true; r->shape = 0; r->spotMethod = 0; - r->sensiexclu = 19; + r->sensiexclu = 12; r->struc = 0; r->shapeMethod = 2; r->locX = 250; @@ -1022,7 +1026,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) r->centerX = 0; r->centerY = 0; r->circrad = 18; - r->qualityMethod = 0; + r->qualityMethod = 1; r->transit = 60; r->thresh = 18; r->iter = 0; @@ -1374,6 +1378,12 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.qualitycurveMethod.at(pp->locallab.selspot) = "std"; } else if (qualitycurveMethod->get_active_row_number() == 2) { pp->locallab.qualitycurveMethod.at(pp->locallab.selspot) = "enh"; + } else if (qualitycurveMethod->get_active_row_number() == 3) { + pp->locallab.qualitycurveMethod.at(pp->locallab.selspot) = "enhsup"; + } else if (qualitycurveMethod->get_active_row_number() == 4) { + pp->locallab.qualitycurveMethod.at(pp->locallab.selspot) = "contr"; + } else if (qualitycurveMethod->get_active_row_number() == 5) { + pp->locallab.qualitycurveMethod.at(pp->locallab.selspot) = "sob2"; } pp->locallab.llcurve.at(pp->locallab.selspot) = llshape->getCurve(); @@ -1441,7 +1451,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.vart.at(pp->locallab.selspot) = vart->getIntValue(); pp->locallab.sensih.at(pp->locallab.selspot) = sensih->getIntValue(); pp->locallab.localTgaincurve.at(pp->locallab.selspot) = cTgainshape->getCurve(); - pp->locallab.inversret.at(pp->locallab.selspot) = (int)inversret->get_active(); + pp->locallab.inversret.at(pp->locallab.selspot) = inversret->get_active(); // Sharpening pp->locallab.expsharp.at(pp->locallab.selspot) = (int)expsharp->getEnabled(); pp->locallab.sharradius.at(pp->locallab.selspot) = sharradius->getIntValue(); @@ -1974,7 +1984,7 @@ void Locallab::inversretChanged() sensih->show(); } - if (getEnabled() && expsharp->getEnabled()) { + if (getEnabled() && expreti->getEnabled()) { if (listener) { if (inversret->get_active()) { listener->panelChanged(Evlocallabinversret, M("GENERAL_ENABLED")); @@ -2951,8 +2961,14 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, int qualitycurveMethod->set_active(0); } else if (pp->locallab.qualitycurveMethod.at(index) == "std") { qualitycurveMethod->set_active(1); - } else { + } else if (pp->locallab.qualitycurveMethod.at(index) == "enh") { qualitycurveMethod->set_active(2); + } else if (pp->locallab.qualitycurveMethod.at(index) == "enhsup") { + qualitycurveMethod->set_active(3); + } else if (pp->locallab.qualitycurveMethod.at(index) == "contr") { + qualitycurveMethod->set_active(4); + } else if (pp->locallab.qualitycurveMethod.at(index) == "sob2") { + qualitycurveMethod->set_active(5); } llshape->setCurve(pp->locallab.llcurve.at(index)); diff --git a/rtgui/options.cc b/rtgui/options.cc index 1444fffc0..797f50193 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -170,7 +170,7 @@ void Options::updatePaths() lastWaveletCurvesDir = preferredPath; } - if (lastlocalCurvesDir.empty() || !Glib::file_test (lastlocalCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastlocalCurvesDir, Glib::FILE_TEST_IS_DIR)) { + if (lastlocalCurvesDir.empty() || !Glib::file_test(lastlocalCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastlocalCurvesDir, Glib::FILE_TEST_IS_DIR)) { lastlocalCurvesDir = preferredPath; } @@ -576,6 +576,7 @@ void Options::setDefaults() rtSettings.cropsleep = 50;//generate a pause of 50 µs for dcrop (100%)to avoid crash when moving window, between 0 to ?? rtSettings.reduchigh = 0.85;//transition for luminance in scope rtSettings.reduclow = 0.85;//transition for luminance out scope + rtSettings.detectshape = true;//experimental new detection shape // end locallab @@ -736,16 +737,20 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.verbose = keyFile.get_boolean("General", "Verbose"); } - if (keyFile.has_key ("General", "Cropsleep")) { - rtSettings.cropsleep = keyFile.get_integer ("General", "Cropsleep"); + if (keyFile.has_key("General", "Detectshape")) { + rtSettings.detectshape = keyFile.get_boolean("General", "Detectshape"); } - if (keyFile.has_key ("General", "Reduchigh")) { - rtSettings.reduchigh = keyFile.get_double ("General", "Reduchigh"); + if (keyFile.has_key("General", "Cropsleep")) { + rtSettings.cropsleep = keyFile.get_integer("General", "Cropsleep"); } - if (keyFile.has_key ("General", "Reduclow")) { - rtSettings.reduclow = keyFile.get_double ("General", "Reduclow"); + if (keyFile.has_key("General", "Reduchigh")) { + rtSettings.reduchigh = keyFile.get_double("General", "Reduchigh"); + } + + if (keyFile.has_key("General", "Reduclow")) { + rtSettings.reduclow = keyFile.get_double("General", "Reduclow"); } } @@ -788,8 +793,8 @@ void Options::readFromFile(Glib::ustring fname) saveFormat.tiffBits = keyFile.get_integer("Output", "TiffBps"); } - if (keyFile.has_key ("Output", "TiffFloat")) { - saveFormat.tiffFloat = keyFile.get_boolean ("Output", "TiffFloat"); + if (keyFile.has_key("Output", "TiffFloat")) { + saveFormat.tiffFloat = keyFile.get_boolean("Output", "TiffFloat"); } if (keyFile.has_key("Output", "TiffUncompressed")) { @@ -821,8 +826,8 @@ void Options::readFromFile(Glib::ustring fname) saveFormatBatch.tiffBits = keyFile.get_integer("Output", "TiffBpsBatch"); } - if (keyFile.has_key ("Output", "TiffFloatBatch")) { - saveFormatBatch.tiffFloat = keyFile.get_boolean ("Output", "TiffFloatBatch"); + if (keyFile.has_key("Output", "TiffFloatBatch")) { + saveFormatBatch.tiffFloat = keyFile.get_boolean("Output", "TiffFloatBatch"); } if (keyFile.has_key("Output", "TiffUncompressedBatch")) { @@ -1301,27 +1306,27 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("GUI", "HistogramPosition")) { histogramPosition = keyFile.get_integer("GUI", "HistogramPosition"); } - + if (keyFile.has_key("GUI", "HistogramRed")) { histogramRed = keyFile.get_boolean("GUI", "HistogramRed"); } - + if (keyFile.has_key("GUI", "HistogramGreen")) { histogramGreen = keyFile.get_boolean("GUI", "HistogramGreen"); } - + if (keyFile.has_key("GUI", "HistogramBlue")) { histogramBlue = keyFile.get_boolean("GUI", "HistogramBlue"); } - + if (keyFile.has_key("GUI", "HistogramLuma")) { histogramLuma = keyFile.get_boolean("GUI", "HistogramLuma"); } - + if (keyFile.has_key("GUI", "HistogramChroma")) { histogramChroma = keyFile.get_boolean("GUI", "HistogramChroma"); } - + if (keyFile.has_key("GUI", "HistogramRAW")) { histogramRAW = keyFile.get_boolean("GUI", "HistogramRAW"); } @@ -1329,13 +1334,13 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("GUI", "HistogramBar")) { histogramBar = keyFile.get_boolean("GUI", "HistogramBar"); } - - if (keyFile.has_key ("GUI", "HistogramHeight")) { - histogramHeight = keyFile.get_integer ("GUI", "HistogramHeight"); + + if (keyFile.has_key("GUI", "HistogramHeight")) { + histogramHeight = keyFile.get_integer("GUI", "HistogramHeight"); } - - if (keyFile.has_key ("GUI", "HistogramDrawMode")) { - histogramDrawMode = keyFile.get_integer ("GUI", "HistogramDrawMode"); + + if (keyFile.has_key("GUI", "HistogramDrawMode")) { + histogramDrawMode = keyFile.get_integer("GUI", "HistogramDrawMode"); } if (keyFile.has_key("GUI", "NavigatorRGBUnit")) { @@ -1350,8 +1355,8 @@ void Options::readFromFile(Glib::ustring fname) showFilmStripToolBar = keyFile.get_boolean("GUI", "ShowFilmStripToolBar"); } - if (keyFile.has_key ("GUI", "FileBrowserToolbarSingleRow")) { - FileBrowserToolbarSingleRow = keyFile.get_boolean ("GUI", "FileBrowserToolbarSingleRow"); + if (keyFile.has_key("GUI", "FileBrowserToolbarSingleRow")) { + FileBrowserToolbarSingleRow = keyFile.get_boolean("GUI", "FileBrowserToolbarSingleRow"); } if (keyFile.has_key("GUI", "HideTPVScrollbar")) { @@ -1466,6 +1471,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "AdobeRGB")) { rtSettings.adobe = keyFile.get_string("Color Management", "AdobeRGB"); + if (rtSettings.adobe == "RT_Medium_gsRGB") { rtSettings.adobe = "RTv4_Medium"; } @@ -1473,6 +1479,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "ProPhoto")) { rtSettings.prophoto = keyFile.get_string("Color Management", "ProPhoto"); + if (rtSettings.prophoto == "RT_Large_gBT709") { rtSettings.prophoto = "RTv4_Large"; } @@ -1480,6 +1487,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "WideGamut")) { rtSettings.widegamut = keyFile.get_string("Color Management", "WideGamut"); + if (rtSettings.widegamut == "WideGamutRGB") { rtSettings.widegamut = "RTv4_Wide"; } @@ -1487,6 +1495,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "sRGB")) { rtSettings.srgb = keyFile.get_string("Color Management", "sRGB"); + if (rtSettings.srgb == "RT_sRGB") { rtSettings.srgb = "RTv4_sRGB"; } @@ -1494,6 +1503,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "Beta")) { rtSettings.beta = keyFile.get_string("Color Management", "Beta"); + if (rtSettings.beta == "BetaRGB") { rtSettings.beta = "RTv4_Beta"; } @@ -1501,6 +1511,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "Best")) { rtSettings.best = keyFile.get_string("Color Management", "Best"); + if (rtSettings.best == "BestRGB") { rtSettings.best = "RTv4_Best"; } @@ -1508,6 +1519,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "Rec2020")) { rtSettings.rec2020 = keyFile.get_string("Color Management", "Rec2020"); + if (rtSettings.rec2020 == "Rec2020") { rtSettings.rec2020 = "RTv4_Rec2020"; } @@ -1515,6 +1527,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("Color Management", "Bruce")) { rtSettings.bruce = keyFile.get_string("Color Management", "Bruce"); + if (rtSettings.bruce == "Bruce") { rtSettings.bruce = "RTv4_Bruce"; } @@ -1556,45 +1569,59 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("ICC Profile Creator", "PimariesPreset")) { ICCPC_primariesPreset = keyFile.get_string("ICC Profile Creator", "PimariesPreset"); } + if (keyFile.has_key("ICC Profile Creator", "RedPrimaryX")) { ICCPC_redPrimaryX = keyFile.get_double("ICC Profile Creator", "RedPrimaryX"); } + if (keyFile.has_key("ICC Profile Creator", "RedPrimaryY")) { ICCPC_redPrimaryY = keyFile.get_double("ICC Profile Creator", "RedPrimaryY"); } + if (keyFile.has_key("ICC Profile Creator", "GreenPrimaryX")) { ICCPC_greenPrimaryX = keyFile.get_double("ICC Profile Creator", "GreenPrimaryX"); } + if (keyFile.has_key("ICC Profile Creator", "GreenPrimaryY")) { ICCPC_greenPrimaryY = keyFile.get_double("ICC Profile Creator", "GreenPrimaryY"); } + if (keyFile.has_key("ICC Profile Creator", "BluePrimaryX")) { ICCPC_bluePrimaryX = keyFile.get_double("ICC Profile Creator", "BluePrimaryX"); } + if (keyFile.has_key("ICC Profile Creator", "BluePrimaryY")) { ICCPC_bluePrimaryY = keyFile.get_double("ICC Profile Creator", "BluePrimaryY"); } + if (keyFile.has_key("ICC Profile Creator", "GammaPreset")) { ICCPC_gammaPreset = keyFile.get_string("ICC Profile Creator", "GammaPreset"); } + if (keyFile.has_key("ICC Profile Creator", "Gamma")) { ICCPC_gamma = keyFile.get_double("ICC Profile Creator", "Gamma"); } + if (keyFile.has_key("ICC Profile Creator", "Slope")) { ICCPC_slope = keyFile.get_double("ICC Profile Creator", "Slope"); } + if (keyFile.has_key("ICC Profile Creator", "ProfileVersion")) { ICCPC_profileVersion = keyFile.get_string("ICC Profile Creator", "ProfileVersion"); } + if (keyFile.has_key("ICC Profile Creator", "Illuminant")) { ICCPC_illuminant = keyFile.get_string("ICC Profile Creator", "Illuminant"); } + if (keyFile.has_key("ICC Profile Creator", "Description")) { ICCPC_description = keyFile.get_string("ICC Profile Creator", "Description"); } + if (keyFile.has_key("ICC Profile Creator", "Copyright")) { ICCPC_copyright = keyFile.get_string("ICC Profile Creator", "Copyright"); } + if (keyFile.has_key("ICC Profile Creator", "AppendParamsToDesc")) { ICCPC_appendParamsToDesc = keyFile.get_boolean("ICC Profile Creator", "AppendParamsToDesc"); } @@ -1786,7 +1813,7 @@ void Options::readFromFile(Glib::ustring fname) safeDirGet(keyFile, "Dialogs", "LastRetinexDir", lastRetinexDir); safeDirGet(keyFile, "Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); safeDirGet(keyFile, "Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); - safeDirGet (keyFile, "Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); safeDirGet(keyFile, "Dialogs", "LastPFCurvesDir", lastPFCurvesDir); safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); @@ -1872,21 +1899,22 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("General", "StartupDirectory", "last"); } - keyFile.set_string ("General", "StartupPath", startupPath); - keyFile.set_string ("General", "DateFormat", dateFormat); - keyFile.set_integer ("General", "AdjusterMinDelay", adjusterMinDelay); - keyFile.set_integer ("General", "AdjusterMaxDelay", adjusterMaxDelay); - keyFile.set_boolean ("General", "MultiUser", multiUser); - keyFile.set_string ("General", "Language", language); - keyFile.set_boolean ("General", "LanguageAutoDetect", languageAutoDetect); - keyFile.set_string ("General", "Theme", theme); - keyFile.set_string ("General", "Version", RTVERSION); - keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); - keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); - keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); - keyFile.set_integer ("General", "Cropsleep", rtSettings.cropsleep); - keyFile.set_double ("General", "Reduchigh", rtSettings.reduchigh); - keyFile.set_double ("General", "Reduclow", rtSettings.reduclow); + keyFile.set_string("General", "StartupPath", startupPath); + keyFile.set_string("General", "DateFormat", dateFormat); + keyFile.set_integer("General", "AdjusterMinDelay", adjusterMinDelay); + keyFile.set_integer("General", "AdjusterMaxDelay", adjusterMaxDelay); + keyFile.set_boolean("General", "MultiUser", multiUser); + keyFile.set_string("General", "Language", language); + keyFile.set_boolean("General", "LanguageAutoDetect", languageAutoDetect); + keyFile.set_string("General", "Theme", theme); + keyFile.set_string("General", "Version", RTVERSION); + keyFile.set_string("General", "DarkFramesPath", rtSettings.darkFramesPath); + keyFile.set_string("General", "FlatFieldsPath", rtSettings.flatFieldsPath); + keyFile.set_boolean("General", "Verbose", rtSettings.verbose); + keyFile.set_integer("General", "Cropsleep", rtSettings.cropsleep); + keyFile.set_double("General", "Reduchigh", rtSettings.reduchigh); + keyFile.set_double("General", "Reduclow", rtSettings.reduclow); + keyFile.set_boolean("General", "Detectshape", rtSettings.detectshape); keyFile.set_integer("External Editor", "EditorKind", editorToSendTo); keyFile.set_string("External Editor", "GimpDir", gimpDir); @@ -2037,28 +2065,28 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("GUI", "FrameColor", bgcolor); keyFile.set_boolean("GUI", "ProcessingQueueEnbled", procQueueEnabled); Glib::ArrayHandle tpopen = tpOpen; - keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); - keyFile.set_boolean ("GUI", "ToolPanelsExpandedAutoSave", autoSaveTpOpen); - keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); - keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); - keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); - keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); - keyFile.set_boolean ("GUI", "HistogramRed", histogramRed); - keyFile.set_boolean ("GUI", "HistogramGreen", histogramGreen); - keyFile.set_boolean ("GUI", "HistogramBlue", histogramBlue); - keyFile.set_boolean ("GUI", "HistogramLuma", histogramLuma); - keyFile.set_boolean ("GUI", "HistogramChroma", histogramChroma); - keyFile.set_boolean ("GUI", "HistogramRAW", histogramRAW); - keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); - keyFile.set_integer ("GUI", "HistogramHeight", histogramHeight); - keyFile.set_integer ("GUI", "HistogramDrawMode", histogramDrawMode); - keyFile.set_integer ("GUI", "NavigatorRGBUnit", (int)navRGBUnit); - keyFile.set_integer ("GUI", "NavigatorHSVUnit", (int)navHSVUnit); - keyFile.set_boolean ("GUI", "ShowFilmStripToolBar", showFilmStripToolBar); - keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); - keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); - keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking); - keyFile.set_integer ("GUI", "CurveBBoxPosition", curvebboxpos); + keyFile.set_integer_list("GUI", "ToolPanelsExpanded", tpopen); + keyFile.set_boolean("GUI", "ToolPanelsExpandedAutoSave", autoSaveTpOpen); + keyFile.set_integer("GUI", "MultiDisplayMode", multiDisplayMode); + keyFile.set_double_list("GUI", "CutOverlayBrush", cutOverlayBrush); + keyFile.set_double_list("GUI", "NavGuideBrush", navGuideBrush); + keyFile.set_integer("GUI", "HistogramPosition", histogramPosition); + keyFile.set_boolean("GUI", "HistogramRed", histogramRed); + keyFile.set_boolean("GUI", "HistogramGreen", histogramGreen); + keyFile.set_boolean("GUI", "HistogramBlue", histogramBlue); + keyFile.set_boolean("GUI", "HistogramLuma", histogramLuma); + keyFile.set_boolean("GUI", "HistogramChroma", histogramChroma); + keyFile.set_boolean("GUI", "HistogramRAW", histogramRAW); + keyFile.set_boolean("GUI", "HistogramBar", histogramBar); + keyFile.set_integer("GUI", "HistogramHeight", histogramHeight); + keyFile.set_integer("GUI", "HistogramDrawMode", histogramDrawMode); + keyFile.set_integer("GUI", "NavigatorRGBUnit", (int)navRGBUnit); + keyFile.set_integer("GUI", "NavigatorHSVUnit", (int)navHSVUnit); + keyFile.set_boolean("GUI", "ShowFilmStripToolBar", showFilmStripToolBar); + keyFile.set_boolean("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); + keyFile.set_boolean("GUI", "HideTPVScrollbar", hideTPVScrollbar); + keyFile.set_boolean("GUI", "HistogramWorking", rtSettings.HistogramWorking); + keyFile.set_integer("GUI", "CurveBBoxPosition", curvebboxpos); //Glib::ArrayHandle crvopen = crvOpen; //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); @@ -2176,7 +2204,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Dialogs", "LastRetinexDir", lastRetinexDir); keyFile.set_string("Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); keyFile.set_string("Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); - keyFile.set_string ("Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); + keyFile.set_string("Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); keyFile.set_string("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); keyFile.set_string("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); keyFile.set_string("Dialogs", "LastBWCurvesDir", lastBWCurvesDir);