diff --git a/rtdata/languages/default b/rtdata/languages/default
index 90af69bdb..fb653eff1 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -3086,7 +3086,7 @@ TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtr
TP_LOCALLAB_WAMASKCOL;Ψ Mask Wavelet level
TP_LOCALLAB_WARM;Warm/Cool & Color artifacts
TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases.
-TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve corresponds to the first 3 levels 0,1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3 and beyond).
+TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve including the 'separation point' corresponds to the first 3 levels 0, 1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3, 4, 5, 6).
TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balances the action within each level.
TP_LOCALLAB_WAT_BLURLC_TOOLTIP;The default blur setting affects all 3 L*a* b* components (luminance and colour).\nWhen checked, only luminance is blurred.
TP_LOCALLAB_WAT_CLARIC_TOOLTIP;“Merge chroma” is used to select the intensity of the desired effect on chrominance.
@@ -3661,6 +3661,7 @@ TP_WAVELET_PASTEL;Pastel chroma
TP_WAVELET_PROC;Process
TP_WAVELET_PROTAB;Protection
TP_WAVELET_QUAAGRES;Agressive
+TP_WAVELET_QUANONE;None
TP_WAVELET_QUACONSER;Conservative
TP_WAVELET_RADIUS;Radius shadows - highlight
TP_WAVELET_RANGEAB;Range a and b %
diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc
index 5d00d5bd8..3241e93e9 100644
--- a/rtengine/iplocallab.cc
+++ b/rtengine/iplocallab.cc
@@ -607,6 +607,9 @@ struct local_params {
float noisechrodetail;
float bilat;
float noiselc;
+ float noiselc4;
+ float noiselc5;
+ float noiselc6;
float noisecf;
float noisecc;
float mulloc[6];
@@ -629,6 +632,7 @@ struct local_params {
bool sfena;
bool cbdlena;
bool denoiena;
+ bool wavcurvedenoi;
bool expvib;
bool exposena;
bool hsena;
@@ -859,6 +863,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
lp.quamet = 0;
} else if (locallab.spots.at(sp).quamethod == "agre") {
lp.quamet = 1;
+ } else if (locallab.spots.at(sp).quamethod == "none") {
+ lp.quamet = 2;
}
if (locallab.spots.at(sp).shMethod == "std") {
@@ -1026,6 +1032,9 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
float local_noiself0 = 0.f;
float local_noiself2 = 0.f;
float local_noiselc = 0.f;
+ float lnoiselc4 = 0.f;
+ float lnoiselc5 = 0.f;
+ float lnoiselc6 = 0.f;
if (locwavCurveden && locwavdenutili) {
if (lp.denoiena) {
@@ -1040,12 +1049,15 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
if (wavcurveden) {
if (lp.denoiena) {
local_noiself0 = 250.f * locwavCurveden[0];
- local_noiself = 250.f * locwavCurveden[166];
- local_noiself2 = 250.f * locwavCurveden[333];
- local_noiselc = 200.f * locwavCurveden[500];
- }
+ local_noiself = 250.f * locwavCurveden[83];
+ local_noiself2 = 250.f * locwavCurveden[166];
+ local_noiselc = 200.f * locwavCurveden[250];
+ lnoiselc4 = 250.f * locwavCurveden[333];
+ lnoiselc5 = 250.f * locwavCurveden[416];
+ lnoiselc6 = 250.f * locwavCurveden[500];
+ }
}
-
+ lp.wavcurvedenoi = wavcurveden;
float local_noiseldetail = (float)locallab.spots.at(sp).noiselumdetail;
int local_noiselequal = locallab.spots.at(sp).noiselequal;
float local_noisechrodetail = (float)locallab.spots.at(sp).noisechrodetail;
@@ -1453,6 +1465,10 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
lp.noiselequal = local_noiselequal;
lp.noisechrodetail = local_noisechrodetail;
lp.noiselc = local_noiselc;
+ lp.noiselc4 = lnoiselc4;
+ lp.noiselc5 = lnoiselc5;
+ lp.noiselc6 = lnoiselc6;
+
lp.noisecf = local_noisecf;
lp.noisecc = local_noisecc;
lp.sensden = local_sensiden;
@@ -6273,11 +6289,11 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform
deltasobelL = new LabImage(spotSi, spotSi);
bool isdenoise = false;
- if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) {
+ if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) {
isdenoise = true;
}
- if (isdenoise) {
+ if (isdenoise) {
origblur = new LabImage(spotSi, spotSi);
blurorig = new LabImage(spotSi, spotSi);
@@ -8850,9 +8866,9 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
bool execdenoi = noiscfactiv && ((lp.colorena && execcolor) || (lp.tonemapena && lp.strengt != 0.f) || (lp.cbdlena && execbdl) || (lp.sfena && lp.strng > 0.f) || (lp.lcena && lp.lcamount > 0.f) || (lp.sharpena && lp.shrad > 0.42) || (lp.retiena && lp.str > 0.f) || (lp.exposena && lp.expcomp != 0.f) || (lp.expvib && lp.past != 0.f));
bool execmaskden = (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) && lp.smasktyp != 0;
- if (((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f
+ if (((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f
// || lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4 || aut == 1 || aut == 2) && lp.denoiena) || execdenoi) { // sk == 1 ??
- || execmaskden || aut == 1 || aut == 2) && lp.denoiena) || execdenoi) { // sk == 1 ??
+ || execmaskden || aut == 1 || aut == 2) && lp.denoiena && lp.quamet != 2) || execdenoi) { // sk == 1 ??
StopWatch Stop1("locallab Denoise called");
@@ -8948,9 +8964,9 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
vari[2] = 0.8f * SQR((lp.noiself2 / 125.0) * (1.0 + lp.noiself2 / 25.0));
vari[3] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[4] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[5] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[6] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
+ vari[4] = 0.8f * SQR((lp.noiselc4 / 125.0) * (1.0 + lp.noiselc4 / 25.0));
+ vari[5] = 0.8f * SQR((lp.noiselc5 / 125.0) * (1.0 + lp.noiselc5 / 25.0));
+ vari[6] = 0.8f * SQR((lp.noiselc6 / 125.0) * (1.0 + lp.noiselc6 / 25.0));
} else if (levred == 4) {
edge = 3;
vari[0] = 0.8f * SQR((lp.noiself0 / 125.0) * (1.0 + lp.noiself0 / 25.0));
@@ -9009,6 +9025,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
vari[3] = rtengine::max(0.000001f, kr3 * vari[3]);
if (levred == 7) {
+ kr3 = kr4 = kr5 = 1.f;
vari[4] = rtengine::max(0.000001f, kr4 * vari[4]);
vari[5] = rtengine::max(0.000001f, kr5 * vari[5]);
vari[6] = rtengine::max(0.000001f, kr5 * vari[6]);
@@ -9418,7 +9435,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
}
if (!Ldecomp.memory_allocation_failed() && aut == 0) {
- if ((lp.noiself >= 0.01f || lp.noiself0 >= 0.01f || lp.noiself2 >= 0.01f || lp.noiselc >= 0.01f) && levred == 7 && lp.noiseldetail != 100.f) {
+ if ((lp.noiself >= 0.01f || lp.noiself0 >= 0.01f || lp.noiself2 >= 0.01f || lp.wavcurvedenoi || lp.noiselc >= 0.01f) && levred == 7 && lp.noiseldetail != 100.f && lp.quamet != 2) {
fftw_denoise(sk, GW, GH, max_numblox_W, min_numblox_W, tmp1.L, Lin, numThreads, lp, 0);
}
}
@@ -9629,9 +9646,9 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
vari[2] = 0.8f * SQR((lp.noiself2 / 125.0) * (1.0 + lp.noiself2 / 25.0));
vari[3] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[4] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[5] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
- vari[6] = 0.8f * SQR((lp.noiselc / 125.0) * (1.0 + lp.noiselc / 25.0));
+ vari[4] = 0.8f * SQR((lp.noiselc4 / 125.0) * (1.0 + lp.noiselc4 / 25.0));
+ vari[5] = 0.8f * SQR((lp.noiselc5 / 125.0) * (1.0 + lp.noiselc5 / 25.0));
+ vari[6] = 0.8f * SQR((lp.noiselc6 / 125.0) * (1.0 + lp.noiselc6 / 25.0));
} else if (levred == 4) {
edge = 3;
vari[0] = 0.8f * SQR((lp.noiself0 / 125.0) * (1.0 + lp.noiself0 / 25.0));
@@ -9691,6 +9708,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
vari[3] = rtengine::max(0.000001f, kr3 * vari[3]);
if (levred == 7) {
+ kr3 = kr4 = kr5 = 1.f;
vari[4] = rtengine::max(0.000001f, kr4 * vari[4]);
vari[5] = rtengine::max(0.000001f, kr5 * vari[5]);
vari[6] = rtengine::max(0.000001f, kr5 * vari[6]);
@@ -10100,7 +10118,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl
if (!Ldecomp.memory_allocation_failed() && aut == 0) {
- if ((lp.noiself >= 0.01f || lp.noiself0 >= 0.01f || lp.noiself2 >= 0.01f || lp.noiselc >= 0.01f) && levred == 7 && lp.noiseldetail != 100.f) {
+ if ((lp.noiself >= 0.01f || lp.noiself0 >= 0.01f || lp.noiself2 >= 0.01f || lp.wavcurvedenoi || lp.noiselc >= 0.01f) && levred == 7 && lp.noiseldetail != 100.f && lp.quamet != 2) {
fftw_denoise(sk, bfw, bfh, max_numblox_W, min_numblox_W, bufwv.L, Lin, numThreads, lp, 0);
}
}
@@ -10956,7 +10974,7 @@ void ImProcFunctions::Lab_Local(
//Prepare mask for Blur and noise and Denoise
bool denoiz = false;
- if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f || lp.bilat > 0.f) && lp.denoiena) {
+ if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.wavcurvedenoi || lp.noisecf > 0.f || lp.noisecc > 0.f || lp.bilat > 0.f) && lp.denoiena) {
denoiz = true;
}
@@ -11755,7 +11773,7 @@ void ImProcFunctions::Lab_Local(
}
//local denoise
- if (lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used
+ if (lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used
float slidL[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
float slida[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
float slidb[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 96587733f..63eefc334 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -3324,7 +3324,7 @@ LocallabParams::LocallabSpot::LocallabSpot() :
epsbl(0),
blMethod("blur"),
chroMethod("lum"),
- quamethod("cons"),
+ quamethod("none"),
blurMethod("norm"),
medMethod("33"),
usemask(false),
@@ -3350,15 +3350,15 @@ LocallabParams::LocallabSpot::LocallabSpot() :
locwavcurveden{
static_cast(FCT_MinMaxCPoints),
0.0,
- 0.0,
- 0.0,
+ 0.09,
0.35,
- 0.66,
0.,
- 0.35,
+ 0.33,
+ 0.17,
+ 0.33,
0.35,
1.0,
- 0.0,
+ 0.03,
0.35,
0.35
},
diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc
index 45eab0939..d7bf6bec3 100644
--- a/rtgui/locallabtools.cc
+++ b/rtgui/locallabtools.cc
@@ -6252,6 +6252,7 @@ LocallabBlur::LocallabBlur():
quamethod->append(M("TP_WAVELET_QUACONSER"));
quamethod->append(M("TP_WAVELET_QUAAGRES"));
+ quamethod->append(M("TP_WAVELET_QUANONE"));
quamethodconn = quamethod->signal_changed().connect(sigc::mem_fun(*this, &LocallabBlur::quamethodChanged));
Gtk::Label* const quaLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENQUA") + ":"));
quaHBox->pack_start(*quaLabel, Gtk::PACK_SHRINK, 4);
@@ -6678,7 +6679,7 @@ void LocallabBlur::neutral_pressed ()
adjblur->setValue(defSpot.adjblur);
bilateral->setValue(defSpot.bilateral);
sensiden->setValue(defSpot.sensiden);
- quamethod->set_active (0);
+ quamethod->set_active (2);
wavshapeden->setCurve(defSpot.locwavcurveden);
wavhue->setCurve(defSpot.locwavcurvehue);
usemask->set_active(defSpot.usemask);
@@ -6828,6 +6829,8 @@ void LocallabBlur::read(const rtengine::procparams::ProcParams* pp, const Params
quamethod->set_active(0);
} else if (spot.quamethod == "agre") {
quamethod->set_active(1);
+ } else if (spot.quamethod == "none") {
+ quamethod->set_active(2);
}
activlum->set_active(spot.activlum);
@@ -6963,6 +6966,8 @@ void LocallabBlur::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped
spot.quamethod = "cons";
} else if (quamethod->get_active_row_number() == 1) {
spot.quamethod = "agre";
+ } else if (quamethod->get_active_row_number() == 2) {
+ spot.quamethod = "none";
}
spot.activlum = activlum->get_active();