Clean rtengine::procparams::Threshold

This commit is contained in:
Flössie 2017-11-13 22:00:27 +01:00
parent c702e5d847
commit aa414fca41
7 changed files with 257 additions and 301 deletions

View File

@ -1268,10 +1268,10 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
//if(params->dirpyrequalizer.enabled) if(execsharp) {
if (params->dirpyrequalizer.enabled) {
if (params->dirpyrequalizer.gamutlab /*&& execsharp*/) {
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[2]) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[3]) / 100.0f;
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomRight()) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f;
float artifact = (float) settings->artifact_cbdl;
@ -1312,10 +1312,10 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
// if (params->dirpyrequalizer.algo=="FI") choice=0;
// else if(params->dirpyrequalizer.algo=="LA") choice=1;
if (rtt == 1) {
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[2]) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[3]) / 100.0f;
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomRight()) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f;
int choice = 0; //not disabled in case of ! always 0
dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM
}
@ -2707,10 +2707,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
//if(params->dirpyrequalizer.enabled) if(execsharp) {
if (params->dirpyrequalizer.enabled) {
if (params->dirpyrequalizer.gamutlab /*&& execsharp*/) { //remove artifacts by gaussian blur - skin control
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[2]) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[3]) / 100.0f;
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomRight()) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f;
float artifact = (float) settings->artifact_cbdl;
if (artifact > 6.f) {
@ -2761,10 +2761,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
// else if(params->dirpyrequalizer.algo=="LA") choice=1;
if (rtt == 1) {
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[2]) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[3]) / 100.0f;
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomRight()) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f;
int choice = 0; // I have not suppress this statement in case of !! always to 0
lab->deleteLab();
dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM
@ -3337,8 +3337,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float RedHigh = (100.f + float (params->colorToning.redhigh)) / 100.f; //printf("RedH=%f\n",RedHigh);
float GreenHigh = (100.f + float (params->colorToning.greenhigh)) / 100.f;
float BlueHigh = (100.f + float (params->colorToning.bluehigh)) / 100.f;
float SatLow = float (params->colorToning.shadowsColSat.value[0]) / 100.f;
float SatHigh = float (params->colorToning.hlColSat.value[0]) / 100.f;
float SatLow = float (params->colorToning.shadowsColSat.getBottom()) / 100.f;
float SatHigh = float (params->colorToning.hlColSat.getBottom()) / 100.f;
float Balan = float (params->colorToning.balance);
@ -6512,10 +6512,10 @@ void ImProcFunctions::badpixlab (LabImage* lab, double rad, int thr, int mode, f
void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale)
{
if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) {
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[2]) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.value[3]) / 100.0f;
float b_l = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f;
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
float b_r = static_cast<float> (params->dirpyrequalizer.hueskin.getBottomRight()) / 100.0f;
float t_r = static_cast<float> (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f;
int choice = 0; //I have not disabled this statement in case of ! always 0
// if (params->dirpyrequalizer.algo=="FI") choice=0;
// else if(params->dirpyrequalizer.algo=="LA") choice=1;

View File

@ -126,7 +126,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
const float chromaPastel = float (params->vibrance.pastels) / 100.0f;
const float chromaSatur = float (params->vibrance.saturated) / 100.0f;
const float p00 = 0.07f;
const float limitpastelsatur = (static_cast<float> (params->vibrance.psthreshold.value[ThresholdSelector::TS_TOPLEFT]) / 100.0f) * (1.0f - p00) + p00;
const float limitpastelsatur = (static_cast<float>(params->vibrance.psthreshold.getTopLeft()) / 100.0f) * (1.0f - p00) + p00;
const float maxdp = (limitpastelsatur - p00) / 4.0f;
const float maxds = (1.0 - limitpastelsatur) / 4.0f;
const float p0 = p00 + maxdp;
@ -135,7 +135,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
const float s0 = limitpastelsatur + maxds;
const float s1 = limitpastelsatur + 2.0f * maxds;
const float s2 = limitpastelsatur + 3.0f * maxds;
const float transitionweighting = static_cast<float> (params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f;
const float transitionweighting = static_cast<float>(params->vibrance.psthreshold.getBottomLeft()) / 100.0f;
float chromamean = 0.0f;
if (chromaPastel != chromaSatur) {

View File

@ -432,56 +432,56 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
cp.thH = float(waparams.thrH);
cp.sky = waparams.sky;
//skin
cp.b_l = static_cast<float>(params->wavelet.hueskin.value[0]) / 100.0f;
cp.t_l = static_cast<float>(params->wavelet.hueskin.value[1]) / 100.0f;
cp.b_r = static_cast<float>(params->wavelet.hueskin.value[2]) / 100.0f;
cp.t_r = static_cast<float>(params->wavelet.hueskin.value[3]) / 100.0f;
cp.b_l = static_cast<float>(params->wavelet.hueskin.getBottomLeft()) / 100.0f;
cp.t_l = static_cast<float>(params->wavelet.hueskin.getTopLeft()) / 100.0f;
cp.b_r = static_cast<float>(params->wavelet.hueskin.getBottomRight()) / 100.0f;
cp.t_r = static_cast<float>(params->wavelet.hueskin.getTopRight()) / 100.0f;
cp.b_ly = static_cast<float>(params->wavelet.hueskin2.value[0]) / 100.0f;
cp.t_ly = static_cast<float>(params->wavelet.hueskin2.value[1]) / 100.0f;
cp.b_ry = static_cast<float>(params->wavelet.hueskin2.value[2]) / 100.0f;
cp.t_ry = static_cast<float>(params->wavelet.hueskin2.value[3]) / 100.0f;
cp.b_ly = static_cast<float>(params->wavelet.hueskin2.getBottomLeft()) / 100.0f;
cp.t_ly = static_cast<float>(params->wavelet.hueskin2.getTopLeft()) / 100.0f;
cp.b_ry = static_cast<float>(params->wavelet.hueskin2.getBottomRight()) / 100.0f;
cp.t_ry = static_cast<float>(params->wavelet.hueskin2.getTopRight()) / 100.0f;
cp.numlevH = params->wavelet.threshold;
//shadows
cp.b_lsl = static_cast<float>(params->wavelet.bllev.value[0]);
cp.t_lsl = static_cast<float>(params->wavelet.bllev.value[1]);
cp.b_rsl = static_cast<float>(params->wavelet.bllev.value[2]);
cp.t_rsl = static_cast<float>(params->wavelet.bllev.value[3]);
cp.b_lsl = static_cast<float>(params->wavelet.bllev.getBottomLeft());
cp.t_lsl = static_cast<float>(params->wavelet.bllev.getTopLeft());
cp.b_rsl = static_cast<float>(params->wavelet.bllev.getBottomRight());
cp.t_rsl = static_cast<float>(params->wavelet.bllev.getTopRight());
cp.numlevS = params->wavelet.threshold2;
int maxlevS = 9 - cp.numlevH;
cp.numlevS = MIN(cp.numlevS, maxlevS);
//printf("levHigh=%d levShad=%d\n",cp.numlevH,cp.numlevS);
//highlight
cp.b_lhl = static_cast<float>(params->wavelet.hllev.value[0]);
cp.t_lhl = static_cast<float>(params->wavelet.hllev.value[1]);
cp.b_rhl = static_cast<float>(params->wavelet.hllev.value[2]);
cp.t_rhl = static_cast<float>(params->wavelet.hllev.value[3]);
cp.b_lhl = static_cast<float>(params->wavelet.hllev.getBottomLeft());
cp.t_lhl = static_cast<float>(params->wavelet.hllev.getTopLeft());
cp.b_rhl = static_cast<float>(params->wavelet.hllev.getBottomRight());
cp.t_rhl = static_cast<float>(params->wavelet.hllev.getTopRight());
//printf("BL=%f TL=%f BR=%f TR=%f\n",cp.b_lhl,cp.t_lhl,cp.b_rhl,cp.t_rhl);
//pastel
cp.b_lpast = static_cast<float>(params->wavelet.pastlev.value[0]);
cp.t_lpast = static_cast<float>(params->wavelet.pastlev.value[1]);
cp.b_rpast = static_cast<float>(params->wavelet.pastlev.value[2]);
cp.t_rpast = static_cast<float>(params->wavelet.pastlev.value[3]);
cp.b_lpast = static_cast<float>(params->wavelet.pastlev.getBottomLeft());
cp.t_lpast = static_cast<float>(params->wavelet.pastlev.getTopLeft());
cp.b_rpast = static_cast<float>(params->wavelet.pastlev.getBottomRight());
cp.t_rpast = static_cast<float>(params->wavelet.pastlev.getTopRight());
//saturated
cp.b_lsat = static_cast<float>(params->wavelet.satlev.value[0]);
cp.t_lsat = static_cast<float>(params->wavelet.satlev.value[1]);
cp.b_rsat = static_cast<float>(params->wavelet.satlev.value[2]);
cp.t_rsat = static_cast<float>(params->wavelet.satlev.value[3]);
cp.b_lsat = static_cast<float>(params->wavelet.satlev.getBottomLeft());
cp.t_lsat = static_cast<float>(params->wavelet.satlev.getTopLeft());
cp.b_rsat = static_cast<float>(params->wavelet.satlev.getBottomRight());
cp.t_rsat = static_cast<float>(params->wavelet.satlev.getTopRight());
//edge local contrast
cp.edg_low = static_cast<float>(params->wavelet.edgcont.value[0]);
cp.edg_mean = static_cast<float>(params->wavelet.edgcont.value[1]);
cp.edg_max = static_cast<float>(params->wavelet.edgcont.value[2]);
cp.edg_sd = static_cast<float>(params->wavelet.edgcont.value[3]);
cp.edg_low = static_cast<float>(params->wavelet.edgcont.getBottomLeft());
cp.edg_mean = static_cast<float>(params->wavelet.edgcont.getTopLeft());
cp.edg_max = static_cast<float>(params->wavelet.edgcont.getBottomRight());
cp.edg_sd = static_cast<float>(params->wavelet.edgcont.getTopRight());
//level noise
cp.lev0s = static_cast<float>(params->wavelet.level0noise.value[0]);
cp.lev0n = static_cast<float>(params->wavelet.level0noise.value[1]);
cp.lev1s = static_cast<float>(params->wavelet.level1noise.value[0]);
cp.lev1n = static_cast<float>(params->wavelet.level1noise.value[1]);
cp.lev2s = static_cast<float>(params->wavelet.level2noise.value[0]);
cp.lev2n = static_cast<float>(params->wavelet.level2noise.value[1]);
cp.lev3s = static_cast<float>(params->wavelet.level3noise.value[0]);
cp.lev3n = static_cast<float>(params->wavelet.level3noise.value[1]);
cp.lev0s = static_cast<float>(params->wavelet.level0noise.getBottom());
cp.lev0n = static_cast<float>(params->wavelet.level0noise.getTop());
cp.lev1s = static_cast<float>(params->wavelet.level1noise.getBottom());
cp.lev1n = static_cast<float>(params->wavelet.level1noise.getTop());
cp.lev2s = static_cast<float>(params->wavelet.level2noise.getBottom());
cp.lev2n = static_cast<float>(params->wavelet.level2noise.getTop());
cp.lev3s = static_cast<float>(params->wavelet.level3noise.getBottom());
cp.lev3n = static_cast<float>(params->wavelet.level3noise.getTop());
cp.detectedge = params->wavelet.medianlev;
//printf("low=%f mean=%f sd=%f max=%f\n",cp.edg_low,cp.edg_mean,cp.edg_sd,cp.edg_max);

View File

@ -192,6 +192,17 @@ void putToKeyfile(
keyfile.set_string(group_name, key, value);
}
void putToKeyfile(
const Glib::ustring& group_name,
const Glib::ustring& key,
const std::vector<int>& value,
Glib::KeyFile& keyfile
)
{
const Glib::ArrayHandle<int> list = value;
keyfile.set_integer_list(group_name, key, list);
}
void putToKeyfile(
const Glib::ustring& group_name,
const Glib::ustring& key,
@ -729,7 +740,7 @@ void ColorToningParams::mixerToCurve (std::vector<double> &colorCurve, std::vect
void ColorToningParams::slidersToCurve (std::vector<double> &colorCurve, std::vector<double> &opacityCurve) const
{
if (hlColSat.value[0] == 0 && shadowsColSat.value[0] == 0) { // if both opacity are null, set both curves to Linear
if (hlColSat.getBottom() == 0 && shadowsColSat.getBottom() == 0) { // if both opacity are null, set both curves to Linear
colorCurve.resize (1);
colorCurve.at (0) = FCT_Linear;
opacityCurve.resize (1);
@ -740,22 +751,22 @@ void ColorToningParams::slidersToCurve (std::vector<double> &colorCurve, std::ve
colorCurve.resize (9);
colorCurve.at (0) = FCT_MinMaxCPoints;
colorCurve.at (1) = 0.26 + 0.12 * double (balance) / 100.;
colorCurve.at (2) = double (shadowsColSat.value[1]) / 360.;
colorCurve.at (2) = double (shadowsColSat.getTop()) / 360.;
colorCurve.at (3) = 0.35;
colorCurve.at (4) = 0.35;
colorCurve.at (5) = 0.64 + 0.12 * double (balance) / 100.;
colorCurve.at (6) = double (hlColSat.value[1]) / 360.;
colorCurve.at (6) = double (hlColSat.getTop()) / 360.;
colorCurve.at (7) = 0.35;
colorCurve.at (8) = 0.35;
opacityCurve.resize (9);
opacityCurve.at (0) = FCT_MinMaxCPoints;
opacityCurve.at (1) = colorCurve.at (1);
opacityCurve.at (2) = double (shadowsColSat.value[0]) / 100.;
opacityCurve.at (2) = double (shadowsColSat.getBottom()) / 100.;
opacityCurve.at (3) = 0.35;
opacityCurve.at (4) = 0.35;
opacityCurve.at (5) = colorCurve.at (5);
opacityCurve.at (6) = double (hlColSat.value[0]) / 100.;
opacityCurve.at (6) = double (hlColSat.getBottom()) / 100.;
opacityCurve.at (7) = 0.35;
opacityCurve.at (8) = 0.35;
}
@ -1803,11 +1814,7 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->sharpening.method, "Sharpening", "Method", sharpening.method, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.radius, "Sharpening", "Radius", sharpening.radius, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.amount, "Sharpening", "Amount", sharpening.amount, keyFile);
if (!pedited || pedited->sharpening.threshold) {
Glib::ArrayHandle<int> thresh (sharpening.threshold.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Sharpening", "Threshold", thresh);
}
saveToKeyfile(!pedited || pedited->sharpening.threshold, "Sharpening", "Threshold", sharpening.threshold.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->sharpening.edgesonly, "Sharpening", "OnlyEdges", sharpening.edgesonly, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.edges_radius, "Sharpening", "EdgedetectionRadius", sharpening.edges_radius, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.edges_tolerance, "Sharpening", "EdgeTolerance", sharpening.edges_tolerance, keyFile);
@ -1822,11 +1829,7 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->vibrance.enabled, "Vibrance", "Enabled", vibrance.enabled, keyFile);
saveToKeyfile(!pedited || pedited->vibrance.pastels, "Vibrance", "Pastels", vibrance.pastels, keyFile);
saveToKeyfile(!pedited || pedited->vibrance.saturated, "Vibrance", "Saturated", vibrance.saturated, keyFile);
if (!pedited || pedited->vibrance.psthreshold) {
Glib::ArrayHandle<int> thresh (vibrance.psthreshold.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Vibrance", "PSThreshold", thresh);
}
saveToKeyfile(!pedited || pedited->vibrance.psthreshold, "Vibrance", "PSThreshold", vibrance.psthreshold.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->vibrance.protectskins, "Vibrance", "ProtectSkins", vibrance.protectskins, keyFile);
saveToKeyfile(!pedited || pedited->vibrance.avoidcolorshift, "Vibrance", "AvoidColorShift", vibrance.avoidcolorshift, keyFile);
saveToKeyfile(!pedited || pedited->vibrance.pastsattog, "Vibrance", "PastSatTog", vibrance.pastsattog, keyFile);
@ -2081,10 +2084,7 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->prsharpening.method, "PostResizeSharpening", "Method", prsharpening.method, keyFile);
saveToKeyfile(!pedited || pedited->prsharpening.radius, "PostResizeSharpening", "Radius", prsharpening.radius, keyFile);
saveToKeyfile(!pedited || pedited->prsharpening.amount, "PostResizeSharpening", "Amount", prsharpening.amount, keyFile);
if (!pedited || pedited->prsharpening.threshold) {
Glib::ArrayHandle<int> thresh (prsharpening.threshold.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("PostResizeSharpening", "Threshold", thresh);
}
saveToKeyfile(!pedited || pedited->prsharpening.threshold, "PostResizeSharpening", "Threshold", prsharpening.threshold.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->prsharpening.edgesonly, "PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly, keyFile);
saveToKeyfile(!pedited || pedited->prsharpening.edges_radius, "PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius, keyFile);
saveToKeyfile(!pedited || pedited->prsharpening.edges_tolerance, "PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance, keyFile);
@ -2163,34 +2163,13 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->wavelet.sup, "Wavelet", "ContExtra", wavelet.sup, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.HSmethod, "Wavelet", "HSMethod", wavelet.HSmethod, keyFile);
if (!pedited || pedited->wavelet.hllev) {
Glib::ArrayHandle<int> thresh (wavelet.hllev.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "HLRange", thresh);
}
if (!pedited || pedited->wavelet.bllev) {
Glib::ArrayHandle<int> thresh (wavelet.bllev.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "SHRange", thresh);
}
if (!pedited || pedited->wavelet.edgcont) {
Glib::ArrayHandle<int> thresh (wavelet.edgcont.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "Edgcont", thresh);
}
if (!pedited || pedited->wavelet.level0noise) {
Glib::ArrayHandle<double> thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("Wavelet", "Level0noise", thresh);
}
if (!pedited || pedited->wavelet.level1noise) {
Glib::ArrayHandle<double> thresh (wavelet.level1noise.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("Wavelet", "Level1noise", thresh);
}
if (!pedited || pedited->wavelet.level2noise) {
Glib::ArrayHandle<double> thresh (wavelet.level2noise.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("Wavelet", "Level2noise", thresh);
}
if (!pedited || pedited->wavelet.level3noise) {
Glib::ArrayHandle<double> thresh (wavelet.level3noise.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("Wavelet", "Level3noise", thresh);
}
saveToKeyfile(!pedited || pedited->wavelet.hllev, "Wavelet", "HLRange", wavelet.hllev.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.bllev, "Wavelet", "SHRange", wavelet.bllev.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgcont, "Wavelet", "Edgcont", wavelet.edgcont.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.level0noise, "Wavelet", "Level0noise", wavelet.level0noise.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.level1noise, "Wavelet", "Level1noise", wavelet.level1noise.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.level2noise, "Wavelet", "Level2noise", wavelet.level2noise.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.level3noise, "Wavelet", "Level3noise", wavelet.level3noise.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.threshold, "Wavelet", "ThresholdHighlight", wavelet.threshold, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.threshold2, "Wavelet", "ThresholdShadow", wavelet.threshold2, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgedetect, "Wavelet", "Edgedetect", wavelet.edgedetect, keyFile);
@ -2208,15 +2187,8 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->wavelet.TMmethod, "Wavelet", "TMMethod", wavelet.TMmethod, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.chro, "Wavelet", "ChromaLink", wavelet.chro, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.ccwcurve, "Wavelet", "ContrastCurve", wavelet.ccwcurve, keyFile);
if (!pedited || pedited->wavelet.pastlev) {
Glib::ArrayHandle<int> thresh (wavelet.pastlev.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "Pastlev", thresh);
}
if (!pedited || pedited->wavelet.satlev) {
Glib::ArrayHandle<int> thresh (wavelet.satlev.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "Satlev", thresh);
}
saveToKeyfile(!pedited || pedited->wavelet.pastlev, "Wavelet", "Pastlev", wavelet.pastlev.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.satlev, "Wavelet", "Satlev", wavelet.satlev.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveBY, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveW, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, keyFile);
@ -2231,10 +2203,7 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->wavelet.lipst, "Wavelet", "Lipst", wavelet.lipst, keyFile);
// if (!pedited || pedited->wavelet.edgreinf) keyFile.set_boolean ("Wavelet", "Edgreinf", wavelet.edgreinf);
saveToKeyfile(!pedited || pedited->wavelet.skinprotect, "Wavelet", "Skinprotect", wavelet.skinprotect, keyFile);
if (!pedited || pedited->wavelet.hueskin) {
Glib::ArrayHandle<int> thresh (wavelet.hueskin.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "Hueskin", thresh);
}
saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgthresh, "Wavelet", "ThrEdg", wavelet.edgthresh, keyFile);
@ -2250,10 +2219,7 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->wavelet.tmrs, "Wavelet", "ResidualTM", wavelet.tmrs, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.gamma, "Wavelet", "Residualgamma", wavelet.gamma, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.sky, "Wavelet", "HueRangeResidual", wavelet.sky, keyFile);
if (!pedited || pedited->wavelet.hueskin2) {
Glib::ArrayHandle<int> thresh (wavelet.hueskin2.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Wavelet", "HueRange", thresh);
}
saveToKeyfile(!pedited || pedited->wavelet.hueskin2, "Wavelet", "HueRange", wavelet.hueskin2.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->wavelet.contrast, "Wavelet", "Contrast", wavelet.contrast, keyFile);
// Directional pyramid equalizer
@ -2264,15 +2230,12 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
std::stringstream ss;
ss << "Mult" << i;
saveToKeyfile(!pedited || pedited->dirpyrequalizer.mult[i], "Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i], keyFile); }
saveToKeyfile(!pedited || pedited->dirpyrequalizer.mult[i], "Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i], keyFile);
}
saveToKeyfile(!pedited || pedited->dirpyrequalizer.threshold, "Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrequalizer.skinprotect, "Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect, keyFile);
// if (!pedited || pedited->dirpyrequalizer.algo) keyFile.set_string ("Directional Pyramid Equalizer", "Algorithm", dirpyrequalizer.algo);
if (!pedited || pedited->dirpyrequalizer.hueskin) {
Glib::ArrayHandle<int> thresh (dirpyrequalizer.hueskin.value, 4, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("Directional Pyramid Equalizer", "Hueskin", thresh);
}
saveToKeyfile(!pedited || pedited->dirpyrequalizer.hueskin, "Directional Pyramid Equalizer", "Hueskin", dirpyrequalizer.hueskin.toVector(), keyFile);
// HSV Equalizer
saveToKeyfile(!pedited || pedited->hsvequalizer.hcurve, "HSV Equalizer", "HCurve", hsvequalizer.hcurve, keyFile);
@ -2312,15 +2275,8 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
saveToKeyfile(!pedited || pedited->colorToning.satprotectionthreshold, "ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold, keyFile);
saveToKeyfile(!pedited || pedited->colorToning.saturatedopacity, "ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity, keyFile);
saveToKeyfile(!pedited || pedited->colorToning.strength, "ColorToning", "Strength", colorToning.strength, keyFile);
if (!pedited || pedited->colorToning.hlColSat) {
Glib::ArrayHandle<int> thresh (colorToning.hlColSat.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("ColorToning", "HighlightsColorSaturation", thresh);
}
if (!pedited || pedited->colorToning.shadowsColSat) {
Glib::ArrayHandle<int> thresh (colorToning.shadowsColSat.value, 2, Glib::OWNERSHIP_NONE);
keyFile.set_integer_list ("ColorToning", "ShadowsColorSaturation", thresh);
}
saveToKeyfile(!pedited || pedited->colorToning.hlColSat, "ColorToning", "HighlightsColorSaturation", colorToning.hlColSat.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->colorToning.shadowsColSat, "ColorToning", "ShadowsColorSaturation", colorToning.shadowsColSat.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->colorToning.clcurve, "ColorToning", "ClCurve", colorToning.clcurve, keyFile);
saveToKeyfile(!pedited || pedited->colorToning.cl2curve, "ColorToning", "Cl2Curve", colorToning.cl2curve, keyFile);

View File

@ -16,19 +16,18 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PROCPARAMS_H_
#define _PROCPARAMS_H_
#pragma once
#include <vector>
#include <cstdio>
#include <cmath>
#include <cstdio>
#include <type_traits>
#include <vector>
#include <glibmm.h>
#include <lcms2.h>
#include "LUT.h"
#include "coord.h"
#include "LUT.h"
class ParamsEdited;
@ -36,15 +35,15 @@ namespace rtengine
{
class ColorGradientCurve;
class OpacityCurve;
class NoiseCurve;
class OpacityCurve;
class RetinexgaintransmissionCurve;
class RetinextransmissionCurve;
class WavCurve;
class WavOpacityCurveRG;
class WavOpacityCurveBY;
class WavOpacityCurveRG;
class WavOpacityCurveW;
class WavOpacityCurveWL;
class RetinextransmissionCurve;
class RetinexgaintransmissionCurve;
enum RenderingIntent {
RI_PERCEPTUAL = INTENT_PERCEPTUAL,
@ -58,195 +57,197 @@ namespace procparams
{
template<typename T>
class Threshold
class Threshold final
{
public:
T value[4];
protected:
bool initEq1;
bool _isDouble;
public:
Threshold (T bottom, T top, bool startAtOne)
Threshold(T _bottom, T _top, bool _start_at_one) :
Threshold(_bottom, _top, 0, 0, _start_at_one, false)
{
initEq1 = startAtOne;
value[0] = bottom;
value[1] = top;
value[2] = T (0);
value[3] = T (0);
_isDouble = false;
}
Threshold (T bottomLeft, T topLeft, T bottomRight, T topRight, bool startAtOne)
Threshold(T _bottom_left, T _top_left, T _bottom_right, T _top_right, bool _start_at_one) :
Threshold(_bottom_left, _top_left, _bottom_right, _top_right, _start_at_one, true)
{
initEq1 = startAtOne;
value[0] = bottomLeft;
value[1] = topLeft;
value[2] = bottomRight;
value[3] = topRight;
_isDouble = true;
}
// for convenience, since 'values' is public
void setValues (T bottom, T top)
{
value[0] = bottom;
value[1] = top;
}
// for convenience, since 'values' is public
void setValues (T bottomLeft, T topLeft, T bottomRight, T topRight)
{
value[0] = bottomLeft;
value[1] = topLeft;
value[2] = bottomRight;
value[3] = topRight;
}
bool isDouble() const
{
return _isDouble;
}
// RT: Type of the returned value
// RV: Type of the value on the X axis
// RV2: Type of the maximum value on the Y axis
template <typename RT, typename RV, typename RV2>
RT multiply (RV x, RV2 yMax) const
{
double val = double (x);
if (initEq1) {
if (_isDouble) {
if (val == double (value[2]) && double (value[2]) == double (value[3]))
// this handle the special case where the 2 right values are the same, then bottom one is sent back,
// useful if one wants to keep the bottom value even beyond the x max bound
{
return RT (0.);
}
if (val >= double (value[3])) {
return RT (yMax);
}
if (val > double (value[2])) {
return RT (double (yMax) * (val - double (value[2])) / (double (value[3]) - double (value[2])));
}
}
if (val >= double (value[0])) {
return RT (0);
}
if (val > double (value[1])) {
return RT (double (yMax) * (1. - (val - double (value[0])) / (double (value[1]) - double (value[0]))));
}
return RT (yMax);
} else {
if (_isDouble) {
if (val == double (value[2]) && double (value[2]) == double (value[3]))
// this handle the special case where the 2 right values are the same, then top one is sent back,
// useful if one wants to keep the top value even beyond the x max bound
{
return RT (yMax);
}
if (val >= double (value[2])) {
return RT (0);
}
if (val > double (value[3])) {
return RT (double (yMax) * (1. - (val - double (value[3])) / (double (value[2]) - double (value[3]))));
}
}
if (val >= double (value[1])) {
return RT (yMax);
}
if (val > double (value[0])) {
return RT (double (yMax) * (val - double (value[0])) / (double (value[1]) - double (value[0])));
}
return RT (0);
}
}
// RT: Type of the returned value
// RV: Type of the value on the X axis
/*template <typename RT, typename RV>
RT getRatio(RV val) const {
double val = double(val);
if (initEq1) {
if (_isDouble) { // assuming that simple thresholds will be more frequent
if (val >= double(value[3]))
return RT(1);
if (val > double(value[2]))
return (val-double(value[2]))/(double(value[3])-double(value[2]));
}
if (val >= double(value[1]))
return RT(0);
if (val > double(value[0]))
return 1.-(val-double(value[0]))/(double(value[1])-double(value[0]));
return RT(1);
}
else {
if (_isDouble) { // assuming that simple thresholds will be more frequent
if (val >= double(value[3]))
return RT(0);
if (val > double(value[2]))
return 1.-(val-double(value[2]))/(double(value[3])-double(value[2]));
}
if (val >= double(value[1]))
return RT(1);
if (val > double(value[0]))
return (val-double(value[0]))/(double(value[1])-double(value[0]));
return RT(0);
}
}*/
Threshold<T>& operator = (const Threshold<T> &rhs)
{
value[0] = rhs.value[0];
value[1] = rhs.value[1];
value[2] = rhs.value[2];
value[3] = rhs.value[3];
initEq1 = rhs.initEq1;
_isDouble = rhs._isDouble;
return *this;
}
template<typename U = T>
typename std::enable_if<std::is_floating_point<U>::value, bool>::type operator ==(const Threshold<U>& rhs) const
{
if (_isDouble) {
return std::fabs (value[0] - rhs.value[0]) < 1e-10
&& std::fabs (value[1] - rhs.value[1]) < 1e-10
&& std::fabs (value[2] - rhs.value[2]) < 1e-10
&& std::fabs (value[3] - rhs.value[3]) < 1e-10;
if (is_double) {
return
std::fabs (bottom_left - rhs.bottom_left) < 1e-10
&& std::fabs (top_left - rhs.top_left) < 1e-10
&& std::fabs (bottom_right - rhs.bottom_right) < 1e-10
&& std::fabs (top_right - rhs.top_right) < 1e-10;
} else {
return std::fabs (value[0] - rhs.value[0]) < 1e-10
&& std::fabs (value[1] - rhs.value[1]) < 1e-10;
return
std::fabs (bottom_left - rhs.bottom_left) < 1e-10
&& std::fabs (top_left - rhs.top_left) < 1e-10;
}
}
template<typename U = T>
typename std::enable_if<std::is_integral<U>::value, bool>::type operator ==(const Threshold<U>& rhs) const
{
if (_isDouble) {
if (is_double) {
return
value[0] == rhs.value[0]
&& value[1] == rhs.value[1]
&& value[2] == rhs.value[2]
&& value[3] == rhs.value[3];
bottom_left == rhs.bottom_left
&& top_left == rhs.top_left
&& bottom_right == rhs.bottom_right
&& top_right == rhs.top_right;
} else {
return
value[0] == rhs.value[0]
&& value[1] == rhs.value[1];
bottom_left == rhs.bottom_left
&& top_left == rhs.top_left;
}
}
T getBottom() const
{
return bottom_left;
}
T getTop() const
{
return top_left;
}
T getBottomLeft() const
{
return bottom_left;
}
T getTopLeft() const
{
return top_left;
}
T getBottomRight() const
{
return bottom_right;
}
T getTopRight() const
{
return top_right;
}
void setValues(T bottom, T top)
{
bottom_left = bottom;
top_left = top;
}
void setValues(T bottom_left, T top_left, T bottom_right, T top_right)
{
this->bottom_left = bottom_left;
this->top_left = top_left;
this->bottom_right = bottom_right;
this->top_right = top_right;
}
bool isDouble() const
{
return is_double;
}
std::vector<T> toVector() const
{
if (is_double) {
return {
bottom_left,
top_left,
bottom_right,
top_right
};
} else {
return {
bottom_left,
top_left
};
}
}
// RT: Type of the returned value
// RV: Type of the value on the X axis
// RV2: Type of the maximum value on the Y axis
template <typename RT, typename RV, typename RV2>
RT multiply (RV x, RV2 y_max) const
{
const double val = x;
if (init_eql) {
if (is_double) {
if (val == static_cast<double>(bottom_right) && static_cast<double>(bottom_right) == static_cast<double>(top_right)) {
// This handles the special case where the 2 right values are the same, then bottom one is sent back,
// useful if one wants to keep the bottom value even beyond the x max bound
return 0;
}
if (val >= static_cast<double>(top_right)) {
return y_max;
}
if (val > static_cast<double>(bottom_right)) {
return static_cast<double>(y_max * (val - static_cast<double>(bottom_right)) / (static_cast<double>(top_right) - static_cast<double>(bottom_right)));
}
}
if (val >= static_cast<double>(bottom_left)) {
return 0;
}
if (val > static_cast<double>(top_left)) {
return static_cast<double>(y_max * (1. - (val - static_cast<double>(bottom_left)) / (static_cast<double>(top_left) - static_cast<double>(bottom_left))));
}
return y_max;
} else {
if (is_double) {
if (val == static_cast<double>(bottom_right) && static_cast<double>(bottom_right) == static_cast<double>(top_right)) {
// This handles the special case where the 2 right values are the same, then top one is sent back,
// useful if one wants to keep the top value even beyond the x max bound
return y_max;
}
if (val >= static_cast<double>(bottom_right)) {
return 0;
}
if (val > static_cast<double>(top_right)) {
return static_cast<double>(y_max * (1.0 - (val - static_cast<double>(top_right)) / (static_cast<double>(bottom_right) - static_cast<double>(top_right))));
}
}
if (val >= static_cast<double>(top_left)) {
return y_max;
}
if (val > static_cast<double>(bottom_left)) {
return static_cast<double>(y_max * (val - static_cast<double>(bottom_left)) / (static_cast<double>(top_left) - static_cast<double>(bottom_left)));
}
return 0;
}
}
private:
Threshold(T _bottom_left, T _top_left, T _bottom_right, T _top_right, bool _start_at_one, bool _is_double) :
bottom_left(_bottom_left),
top_left(_top_left),
bottom_right(_bottom_right),
top_right(_top_right),
init_eql(_start_at_one),
is_double(_is_double)
{
}
T bottom_left;
T top_left;
T bottom_right;
T top_right;
bool init_eql;
bool is_double;
};
/**
@ -1535,4 +1536,3 @@ public:
}
}
#endif

View File

@ -341,20 +341,20 @@ void ThresholdAdjuster::sendToListener ()
rtengine::procparams::Threshold<double> t = tSelector.getPositions<double>();
if (tSelector.isDouble()) {
adjusterListener->adjusterChanged (this, t.value[0], t.value[1], t.value[2], t.value[3]);
adjusterListener->adjusterChanged2 (this, t.value[0], t.value[1], t.value[2], t.value[3]);
adjusterListener->adjusterChanged (this, t.getBottomLeft(), t.getTopLeft(), t.getBottomRight(), t.getTopRight());
adjusterListener->adjusterChanged2 (this, t.getBottomLeft(), t.getTopLeft(), t.getBottomRight(), t.getTopRight());
} else {
adjusterListener->adjusterChanged (this, t.value[0], t.value[1]);
adjusterListener->adjusterChanged (this, t.getBottomLeft(), t.getTopLeft());
}
} else {
// if precision is equal to 0, then we assume that the listener is waiting for integers
rtengine::procparams::Threshold<int> t = tSelector.getPositions<int>();
if (tSelector.isDouble()) {
adjusterListener->adjusterChanged (this, t.value[0], t.value[1], t.value[2], t.value[3]);
adjusterListener->adjusterChanged2 (this, t.value[0], t.value[1], t.value[2], t.value[3]);
adjusterListener->adjusterChanged (this, t.getBottomLeft(), t.getTopLeft(), t.getBottomRight(), t.getTopRight());
adjusterListener->adjusterChanged2 (this, t.getBottomLeft(), t.getTopLeft(), t.getBottomRight(), t.getTopRight());
} else {
adjusterListener->adjusterChanged (this, t.value[0], t.value[1]);
adjusterListener->adjusterChanged (this, t.getBottomLeft(), t.getTopLeft());
}
}
}

View File

@ -138,12 +138,12 @@ public:
template <typename T>
void setDefaults (const rtengine::procparams::Threshold<T> &t)
{
defPos[TS_BOTTOMLEFT] = double(t.value[0]); // should we use shapeValue() ?
defPos[TS_TOPLEFT] = double(t.value[1]);
defPos[TS_BOTTOMLEFT] = double(t.getBottomLeft()); // should we use shapeValue() ?
defPos[TS_TOPLEFT] = double(t.getTopLeft());
if (doubleThresh) {
defPos[TS_BOTTOMRIGHT] = double(t.value[2]);
defPos[TS_TOPRIGHT] = double(t.value[3]);
defPos[TS_BOTTOMRIGHT] = double(t.getBottomRight());
defPos[TS_TOPRIGHT] = double(t.getTopRight());
}
}
void setDefaults (double bottom, double top);
@ -151,12 +151,12 @@ public:
template <typename T>
void setPositions (const rtengine::procparams::Threshold<T> &tValues)
{
positions[TS_BOTTOMLEFT] = static_cast<double>(tValues.value[TS_BOTTOMLEFT]);
positions[TS_TOPLEFT] = static_cast<double>(tValues.value[TS_TOPLEFT]);
positions[TS_BOTTOMLEFT] = static_cast<double>(tValues.getBottomLeft());
positions[TS_TOPLEFT] = static_cast<double>(tValues.getTopLeft());
if (tValues.isDouble()) {
positions[TS_BOTTOMRIGHT] = static_cast<double>(tValues.value[TS_BOTTOMRIGHT]);
positions[TS_TOPRIGHT] = static_cast<double>(tValues.value[TS_TOPRIGHT]);
positions[TS_BOTTOMRIGHT] = static_cast<double>(tValues.getBottomRight());
positions[TS_TOPRIGHT] = static_cast<double>(tValues.getTopRight());
}
updateTooltip();