diff --git a/rtdata/languages/default b/rtdata/languages/default index 13460b070..00197e33c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1004,7 +1004,7 @@ HISTORY_MSG_747;Local Spot created HISTORY_MSG_748;Local - Exp Denoise HISTORY_MSG_749;Local - Reti Depth HISTORY_MSG_750;Local - Reti Mode log - lin -HISTORY_MSG_751;Local - Reti Dehaze luminance +HISTORY_MSG_751;Local - Reti Dehaze saturation HISTORY_MSG_752;Local - Reti Offset HISTORY_MSG_753;Local - Reti Transmission map HISTORY_MSG_754;Local - Reti Clip @@ -1251,7 +1251,7 @@ HISTORY_MSG_COMPLEX;Wavelet complexity HISTORY_MSG_COMPLEXRETI;Retinex complexity HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth HISTORY_MSG_DEHAZE_ENABLED;Haze Removal -HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only +HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -2142,7 +2142,7 @@ TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Threshold TP_DEHAZE_DEPTH;Depth TP_DEHAZE_LABEL;Haze Removal -TP_DEHAZE_LUMINANCE;Luminance only +TP_DEHAZE_SATURATION;Saturation TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map TP_DEHAZE_STRENGTH;Strength TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 6526d0d1e..6ae8be27b 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -313,10 +313,6 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams) const int H = img->getHeight(); const float strength = LIM01(float(dehazeParams.strength) / 100.f * 0.9f); - if (settings->verbose) { - std::cout << "dehaze: strength = " << strength << std::endl; - } - array2D dark(W, H); int patchsize = max(int(5 / scale), 2); @@ -384,14 +380,15 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams) const float depth = -float(dehazeParams.depth) / 100.f; const float t0 = max(1e-3f, std::exp(depth * maxDistance)); - const float teps = 1e-3f; + constexpr float teps = 1.f + 1e-3f; - const bool luminance = dehazeParams.luminance; + const float satBlend = dehazeParams.saturation / 100.f; const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); #ifdef __SSE2__ const vfloat wsv[3] = {F2V(ws[1][0]), F2V(ws[1][1]),F2V(ws[1][2])}; #endif const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws); + #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif @@ -407,30 +404,27 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams) const vfloat t0v = F2V(t0); const vfloat tepsv = F2V(teps); const vfloat cmaxChannelv = F2V(maxChannel); + const vfloat satBlendv = F2V(satBlend); for (; x < W - 3; x += 4) { // ensure that the transmission is such that to avoid clipping... const vfloat r = LVFU(img->r(y, x)); const vfloat g = LVFU(img->g(y, x)); const vfloat b = LVFU(img->b(y, x)); // ... t >= tl to avoid negative values - const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); - const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv + tepsv, t0v)); + const vfloat tlv = tepsv - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); + const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv, t0v)); if (dehazeParams.showDepthMap) { const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * cmaxChannelv; STVFU(img->r(y, x), valv); STVFU(img->g(y, x), valv); STVFU(img->b(y, x), valv); - } else if (luminance) { + } else { const vfloat Yv = Color::rgbLuminance(r, g, b, wsv); const vfloat YYv = (Yv - ambientYv) / mtv + ambientYv; const vfloat fv = vself(vmaskf_gt(Yv, epsYv), cmaxChannelv * YYv / Yv, cmaxChannelv); - STVFU(img->r(y, x), r * fv); - STVFU(img->g(y, x), g * fv); - STVFU(img->b(y, x), b * fv); - } else { - STVFU(img->r(y, x), ((r - ambient0v) / mtv + ambient0v) * cmaxChannelv); - STVFU(img->g(y, x), ((g - ambient1v) / mtv + ambient1v) * cmaxChannelv); - STVFU(img->b(y, x), ((b - ambient2v) / mtv + ambient2v) * cmaxChannelv); + STVFU(img->r(y, x), vintpf(satBlendv, ((r - ambient0v) / mtv + ambient0v) * cmaxChannelv, r * fv)); + STVFU(img->g(y, x), vintpf(satBlendv, ((g - ambient1v) / mtv + ambient1v) * cmaxChannelv, g * fv)); + STVFU(img->b(y, x), vintpf(satBlendv, ((b - ambient2v) / mtv + ambient2v) * cmaxChannelv, b * fv)); } } #endif @@ -440,39 +434,31 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams) const float g = img->g(y, x); const float b = img->b(y, x); // ... t >= tl to avoid negative values - const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]); - const float mt = max(dark[y][x], t0, tl + teps); + const float tl = teps - min(r / ambient[0], g / ambient[1], b / ambient[2]); + const float mt = max(dark[y][x], t0, tl); if (dehazeParams.showDepthMap) { img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel; - } else if (luminance) { + } else { const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); const float YY = (Y - ambientY) / mt + ambientY; const float f = Y > 1e-5f ? maxChannel * YY / Y : maxChannel; - img->r(y, x) *= f; - img->g(y, x) *= f; - img->b(y, x) *= f; - } else { - img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * maxChannel; - img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * maxChannel; - img->b(y, x) = ((b - ambient[2]) / mt + ambient[2]) * maxChannel; + img->r(y, x) = intp(satBlend, ((r - ambient[0]) / mt + ambient[0]) * maxChannel, r * f); + img->g(y, x) = intp(satBlend, ((g - ambient[1]) / mt + ambient[1]) * maxChannel, g * f); + img->b(y, x) = intp(satBlend, ((b - ambient[2]) / mt + ambient[2]) * maxChannel, b * f); } } } } - - void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParams) { //J.Desmis 12 2019 - this version derived from ART, is slower than the main from maximum 10% - probably use of SSE //Probably Ingo could solved this problem in some times - BENCHFUN + if (!dehazeParams.enabled || dehazeParams.strength == 0.0) { return; } - - const float maxChannel = normalize(img, multiThread); const int W = img->getWidth(); @@ -480,10 +466,6 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam const float strength = LIM01(float(std::abs(dehazeParams.strength)) / 100.f * 0.9f); const bool add_haze = dehazeParams.strength < 0; - if (settings->verbose) { - std::cout << "dehaze: strength = " << strength << std::endl; - } - array2D dark(W, H); int patchsize = max(int(5 / scale), 2); @@ -553,10 +535,11 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam } const float depth = -float(dehazeParams.depth) / 100.f; - const float teps = 1e-6f; + constexpr float teps = 1e-6f; const float t0 = max(teps, std::exp(depth * maxDistance)); - const bool luminance = dehazeParams.luminance; + const float satBlend = dehazeParams.saturation / 100.f; + const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws); @@ -565,56 +548,43 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam #endif for (int y = 0; y < H; ++y) { - int x = 0; - for (; x < W; ++x) { + for (int x = 0; x < W; ++x) { // ensure that the transmission is such that to avoid clipping... - float rgb[3] = { img->r(y, x), img->g(y, x), img->b(y, x) }; + const float rIn = img->r(y, x); + const float gIn = img->g(y, x); + const float bIn = img->b(y, x); // ... t >= tl to avoid negative values - float tl = 1.f - min(rgb[0] / ambient[0], rgb[1] / ambient[1], rgb[2] / ambient[2]); - // // ... t >= tu to avoid values > 1 - // float tu = t0 - teps; - // for (int c = 0; c < 3; ++c) { - // if (ambient[c] < 1) { - // tu = max(tu, (rgb[c] - ambient[c])/(1.f - ambient[c])); - // } - // } - float &ir = img->r(y, x); - float &ig = img->g(y, x); - float &ib = img->b(y, x); - const float mt = max(dark[y][x], t0, tl + teps); + const float tl = 1.f + teps - min(rIn / ambient[0], gIn / ambient[1], bIn / ambient[2]); + const float mt = max(dark[y][x], t0, tl); if (dehazeParams.showDepthMap) { img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel; - } else if (luminance) { - float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); - float YY = (Y - ambientY) / mt + ambientY; - + } else { + float f = 1.f; + const float Y = Color::rgbLuminance(rIn, gIn, bIn, ws); if (Y > 1e-5f) { + float YY = (Y - ambientY) / mt + ambientY; if (add_haze) { YY = Y + Y - YY; } - - float f = YY / Y; - ir = rgb[0] * f; - ig = rgb[1] * f; - ib = rgb[2] * f; - + f = YY / Y; } - } else { - float r = ((rgb[0] - ambient[0]) / mt + ambient[0]); - float g = ((rgb[1] - ambient[1]) / mt + ambient[1]); - float b = ((rgb[2] - ambient[2]) / mt + ambient[2]); + const float r1 = rIn * f; + const float g1 = gIn * f; + const float b1 = bIn * f; + + float r2 = ((rIn - ambient[0]) / mt + ambient[0]); + float g2 = ((gIn - ambient[1]) / mt + ambient[1]); + float b2 = ((bIn - ambient[2]) / mt + ambient[2]); if (add_haze) { - ir += (ir - r); - ig += (ig - g); - ib += (ib - b); - } else { - ir = r; - ig = g; - ib = b; + r2 = rIn + rIn - r2; + g2 = gIn + gIn - g2; + b2 = bIn + bIn - b2; } - + img->r(y, x) = intp(satBlend, r2, r1); + img->g(y, x) = intp(satBlend, g2, g1); + img->b(y, x) = intp(satBlend, b2, b1); } } } diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index e2b51bfdb..31278584b 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -500,6 +500,7 @@ struct local_params { float trans; float feath; int dehaze; + int dehazeSaturation; int depth; bool inv; bool invex; @@ -754,8 +755,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.showmaskblmet = llblMask; lp.showmasklogmet = lllogMask; lp.showmask_met = ll_Mask; - printf("mask=%i \n", lp.showmasklogmet); - + lp.enaColorMask = locallab.spots.at(sp).enaColorMask && llsoftMask == 0 && llColorMask == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaColorMaskinv = locallab.spots.at(sp).enaColorMask && llColorMaskinv == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaExpMask = locallab.spots.at(sp).enaExpMask && llExpMask == 0 && llColorMask == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0;// Exposure mask is deactivated if Color & Light mask is visible @@ -1007,6 +1007,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall int local_sensih = locallab.spots.at(sp).sensih; int local_dehaze = locallab.spots.at(sp).dehaz; int local_depth = locallab.spots.at(sp).depth; + int local_dehazeSaturation = locallab.spots.at(sp).dehazeSaturation; int local_sensicb = locallab.spots.at(sp).sensicb; float local_clarityml = (float) locallab.spots.at(sp).clarityml; float local_contresid = (float) locallab.spots.at(sp).contresid; @@ -1262,6 +1263,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.sens = local_sensi; lp.sensh = local_sensih; lp.dehaze = local_dehaze; + lp.dehazeSaturation = local_dehazeSaturation; lp.depth = local_depth; lp.senscb = local_sensicb; lp.clarityml = local_clarityml; @@ -12358,8 +12360,8 @@ void ImProcFunctions::Lab_Local( dehazeParams.enabled = true; dehazeParams.strength = lp.dehaze; dehazeParams.showDepthMap = false; + dehazeParams.saturation = lp.dehazeSaturation; dehazeParams.depth = lp.depth; - dehazeParams.luminance = params->locallab.spots.at(sp).lumonly; lab2rgb(*bufexpfin, *tmpImage.get(), params->icm.workingProfile); dehazeloc(tmpImage.get(), dehazeParams); rgb2lab(*tmpImage.get(), *bufexpfin, params->icm.workingProfile); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index ceea08f42..9f4e3e77c 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -773,7 +773,7 @@ enum ProcEventCode { EvlocallabexnoiseMethod = 747, Evlocallabdepth = 748, Evlocallabloglin = 749, - Evlocallablumonly = 750, + EvlocallabdehazeSaturation = 750, Evlocallaboffs = 751, EvlocallabCTtransCurve = 752, Evlocallabcliptm = 753, diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index fa3fa7f51..48a5e70b2 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3485,7 +3485,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : inversret(false), equilret(true), loglin(false), - lumonly(false), + dehazeSaturation(50.0), softradiusret(40.0), CCmaskreticurve{ static_cast(FCT_MinMaxCPoints), @@ -4350,7 +4350,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && inversret == other.inversret && equilret == other.equilret && loglin == other.loglin - && lumonly == other.lumonly + && dehazeSaturation == other.dehazeSaturation && softradiusret == other.softradiusret && CCmaskreticurve == other.CCmaskreticurve && LLmaskreticurve == other.LLmaskreticurve @@ -4698,9 +4698,9 @@ bool SoftLightParams::operator !=(const SoftLightParams& other) const DehazeParams::DehazeParams() : enabled(false), strength(50), + saturation(50), showDepthMap(false), - depth(25), - luminance(false) + depth(25) { } @@ -4711,7 +4711,7 @@ bool DehazeParams::operator ==(const DehazeParams& other) const && strength == other.strength && showDepthMap == other.showDepthMap && depth == other.depth - && luminance == other.luminance; + && saturation == other.saturation; } bool DehazeParams::operator !=(const DehazeParams& other) const @@ -5454,7 +5454,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Luminance", dehaze.luminance, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Saturation", dehaze.saturation, keyFile); // Directional pyramid denoising saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile); @@ -5908,7 +5908,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->inversret, "Locallab", "Inversret_" + index_str, spot.inversret, keyFile); saveToKeyfile(!pedited || spot_edited->equilret, "Locallab", "Equilret_" + index_str, spot.equilret, keyFile); saveToKeyfile(!pedited || spot_edited->loglin, "Locallab", "Loglin_" + index_str, spot.loglin, keyFile); - saveToKeyfile(!pedited || spot_edited->lumonly, "Locallab", "Lumonly_" + index_str, spot.lumonly, keyFile); + saveToKeyfile(!pedited || spot_edited->dehazeSaturation, "Locallab", "dehazeSaturation_" + index_str, spot.dehazeSaturation, keyFile); saveToKeyfile(!pedited || spot_edited->softradiusret, "Locallab", "Softradiusret_" + index_str, spot.softradiusret, keyFile); saveToKeyfile(!pedited || spot_edited->CCmaskreticurve, "Locallab", "CCmaskretiCurve_" + index_str, spot.CCmaskreticurve, keyFile); saveToKeyfile(!pedited || spot_edited->LLmaskreticurve, "Locallab", "LLmaskretiCurve_" + index_str, spot.LLmaskreticurve, keyFile); @@ -7685,7 +7685,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Inversret_" + index_str, pedited, spot.inversret, spotEdited.inversret); assignFromKeyfile(keyFile, "Locallab", "Equilret_" + index_str, pedited, spot.equilret, spotEdited.equilret); assignFromKeyfile(keyFile, "Locallab", "Loglin_" + index_str, pedited, spot.loglin, spotEdited.loglin); - assignFromKeyfile(keyFile, "Locallab", "Lumonly_" + index_str, pedited, spot.lumonly, spotEdited.lumonly); + assignFromKeyfile(keyFile, "Locallab", "dehazeSaturation" + index_str, pedited, spot.dehazeSaturation, spotEdited.dehazeSaturation); assignFromKeyfile(keyFile, "Locallab", "Softradiusret_" + index_str, pedited, spot.softradiusret, spotEdited.softradiusret); assignFromKeyfile(keyFile, "Locallab", "CCmaskretiCurve_" + index_str, pedited, spot.CCmaskreticurve, spotEdited.CCmaskreticurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskretiCurve_" + index_str, pedited, spot.LLmaskreticurve, spotEdited.LLmaskreticurve); @@ -8472,7 +8472,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Dehaze", "Strength", pedited, dehaze.strength, pedited->dehaze.strength); assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap); assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth); - assignFromKeyfile(keyFile, "Dehaze", "Luminance", pedited, dehaze.luminance, pedited->dehaze.luminance); + if (ppVersion < 349 && dehaze.enabled && keyFile.has_key("Dehaze", "Luminance")) { + const bool luminance = keyFile.get_boolean("Dehaze", "Luminance"); + dehaze.saturation = luminance ? 0 : 100; + if (pedited) { + pedited->dehaze.saturation = true; + } + } else { + assignFromKeyfile(keyFile, "Dehaze", "Saturation", pedited, dehaze.saturation, pedited->dehaze.saturation); + } } if (keyFile.has_group("Film Simulation")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 907f30f6d..39992d88b 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1292,7 +1292,7 @@ struct LocallabParams { bool inversret; bool equilret; bool loglin; - bool lumonly; + double dehazeSaturation; double softradiusret; std::vector CCmaskreticurve; std::vector LLmaskreticurve; @@ -1979,9 +1979,9 @@ struct SoftLightParams { struct DehazeParams { bool enabled; int strength; + int saturation; bool showDepthMap; int depth; - bool luminance; DehazeParams(); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 0a2cae7fa..e424ef14d 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -777,7 +777,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvlocallabexnoiseMethod LUMINANCECURVE, // Evlocallabdepth LUMINANCECURVE, // Evlocallabloglin - LUMINANCECURVE, // Evlocallablumonly + LUMINANCECURVE, // EvlocallabdehazeSaturation LUMINANCECURVE, // Evlocallaboffs LUMINANCECURVE, // EvlocallabCTtransCurve LUMINANCECURVE, // Evlocallabcliptm diff --git a/rtgui/dehaze.cc b/rtgui/dehaze.cc index 6b7fcd64f..76d309afc 100644 --- a/rtgui/dehaze.cc +++ b/rtgui/dehaze.cc @@ -36,7 +36,7 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, EvDehazeStrength = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_STRENGTH"); EvDehazeShowDepthMap = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP"); EvDehazeDepth = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_DEPTH"); - EvDehazeLuminance = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_LUMINANCE"); + EvDehazeSaturation = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_SATURATION"); strength = Gtk::manage(new Adjuster(M("TP_DEHAZE_STRENGTH"), 0., 100., 1., 50.)); strength->setAdjusterListener(this); @@ -46,9 +46,9 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, depth->setAdjusterListener(this); depth->show(); - luminance = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_LUMINANCE"))); - luminance->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::luminanceChanged)); - luminance->show(); + saturation = Gtk::manage(new Adjuster(M("TP_DEHAZE_SATURATION"), 0., 100., 1., 50.)); + saturation->setAdjusterListener(this); + saturation->show(); showDepthMap = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_SHOW_DEPTH_MAP"))); showDepthMap->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::showDepthMapChanged)); @@ -56,65 +56,65 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, pack_start(*strength); pack_start(*depth); - pack_start(*luminance); + pack_start(*saturation); pack_start(*showDepthMap); } - void Dehaze::read(const ProcParams *pp, const ParamsEdited *pedited) { disableListener(); if (pedited) { strength->setEditedState(pedited->dehaze.strength ? Edited : UnEdited); + saturation->setEditedState(pedited->dehaze.saturation ? Edited : UnEdited); depth->setEditedState(pedited->dehaze.depth ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->dehaze.enabled); showDepthMap->set_inconsistent(!pedited->dehaze.showDepthMap); - luminance->set_inconsistent(!pedited->dehaze.luminance); } setEnabled(pp->dehaze.enabled); strength->setValue(pp->dehaze.strength); + saturation->setValue(pp->dehaze.saturation); depth->setValue(pp->dehaze.depth); showDepthMap->set_active(pp->dehaze.showDepthMap); - luminance->set_active(pp->dehaze.luminance); enableListener(); } - void Dehaze::write(ProcParams *pp, ParamsEdited *pedited) { pp->dehaze.strength = strength->getValue(); + pp->dehaze.saturation = saturation->getValue(); pp->dehaze.depth = depth->getValue(); pp->dehaze.enabled = getEnabled(); pp->dehaze.showDepthMap = showDepthMap->get_active(); - pp->dehaze.luminance = luminance->get_active(); if (pedited) { pedited->dehaze.strength = strength->getEditedState(); + pedited->dehaze.saturation = saturation->getEditedState(); pedited->dehaze.depth = depth->getEditedState(); pedited->dehaze.enabled = !get_inconsistent(); pedited->dehaze.showDepthMap = !showDepthMap->get_inconsistent(); - pedited->dehaze.luminance = !luminance->get_inconsistent(); } } void Dehaze::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited) { strength->setDefault(defParams->dehaze.strength); + saturation->setDefault(defParams->dehaze.saturation); depth->setDefault(defParams->dehaze.depth); if (pedited) { + saturation->setDefaultEditedState(pedited->dehaze.saturation ? Edited : UnEdited); strength->setDefaultEditedState(pedited->dehaze.strength ? Edited : UnEdited); depth->setDefaultEditedState(pedited->dehaze.depth ? Edited : UnEdited); } else { + saturation->setDefaultEditedState(Irrelevant); strength->setDefaultEditedState(Irrelevant); depth->setDefaultEditedState(Irrelevant); } } - void Dehaze::adjusterChanged(Adjuster* a, double newval) { if (listener && getEnabled()) { @@ -122,11 +122,12 @@ void Dehaze::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvDehazeStrength, a->getTextValue()); } else if (a == depth) { listener->panelChanged(EvDehazeDepth, a->getTextValue()); + } else if (a == saturation) { + listener->panelChanged(EvDehazeSaturation, a->getTextValue()); } } } - void Dehaze::enabledChanged () { if (listener) { @@ -140,7 +141,6 @@ void Dehaze::enabledChanged () } } - void Dehaze::showDepthMapChanged() { if (listener) { @@ -148,13 +148,6 @@ void Dehaze::showDepthMapChanged() } } -void Dehaze::luminanceChanged() -{ - if (listener) { - listener->panelChanged(EvDehazeLuminance, luminance->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); - } -} - void Dehaze::setBatchMode(bool batchMode) { ToolPanel::setBatchMode(batchMode); @@ -163,9 +156,7 @@ void Dehaze::setBatchMode(bool batchMode) depth->showEditedCB(); } - void Dehaze::setAdjusterBehavior(bool strengthAdd) { strength->setAddMode(strengthAdd); } - diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 79d2e015c..155efa522 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -28,14 +28,15 @@ class Dehaze final : public ToolParamBlock, public AdjusterListener, public Fold private: Adjuster *strength; Adjuster *depth; + Adjuster *saturation; Gtk::CheckButton *showDepthMap; - Gtk::CheckButton *luminance; +// Gtk::CheckButton *luminance; rtengine::ProcEvent EvDehazeEnabled; rtengine::ProcEvent EvDehazeStrength; rtengine::ProcEvent EvDehazeDepth; rtengine::ProcEvent EvDehazeShowDepthMap; - rtengine::ProcEvent EvDehazeLuminance; + rtengine::ProcEvent EvDehazeSaturation; public: @@ -49,7 +50,7 @@ public: void adjusterChanged(Adjuster *a, double newval) override; void enabledChanged() override; void showDepthMapChanged(); - void luminanceChanged(); +// void luminanceChanged(); void setAdjusterBehavior(bool strengthAdd); }; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1e4b1ad30..c221983c1 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -827,7 +827,7 @@ private: Gtk::Frame* const dehaFrame; Adjuster* const dehaz; Adjuster* const depth; - Gtk::CheckButton* const lumonly; + Adjuster* const dehazeSaturation; Gtk::Frame* const retiFrame; Adjuster* const str; Gtk::CheckButton* const loglin; @@ -872,7 +872,7 @@ private: DiagonalCurveEditor* const Lmaskretishape; Gtk::CheckButton* const inversret; - sigc::connection lumonlyConn, loglinConn, retinexMethodConn, fftwretiConn, equilretConn, showmaskretiMethodConn, enaretiMaskConn, enaretiMasktmapConn, inversretConn; + sigc::connection loglinConn, retinexMethodConn, fftwretiConn, equilretConn, showmaskretiMethodConn, enaretiMaskConn, enaretiMasktmapConn, inversretConn; public: LocallabRetinex(); @@ -903,7 +903,6 @@ private: void updateMaskBackground(const double normChromar, const double normLumar, const double normHuer) override; - void lumonlyChanged(); void loglinChanged(); void retinexMethodChanged(); void fftwretiChanged(); diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 972a4257d..52d5d9ad3 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -686,7 +686,7 @@ LocallabRetinex::LocallabRetinex(): dehaFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_DEHAFRA")))), dehaz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEHAZ"), -100, 100, 1, 0))), depth(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEPTH"), 0, 100, 1, 25))), - lumonly(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LUMONLY")))), + dehazeSaturation(Gtk::manage(new Adjuster(M("TP_DEHAZE_SATURATION"), 0, 100, 1, 50))), retiFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_RETIFRA")))), str(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STR"), 0., 100., 0.2, 0.))), loglin(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LOGLIN")))), @@ -736,10 +736,9 @@ LocallabRetinex::LocallabRetinex(): // Parameter Retinex specific widgets dehaz->setAdjusterListener(this); + dehazeSaturation->setAdjusterListener(this); depth->setAdjusterListener(this); - lumonlyConn = lumonly->signal_toggled().connect(sigc::mem_fun(*this, &LocallabRetinex::lumonlyChanged)); - retiFrame->set_label_align(0.025, 0.5); str->setAdjusterListener(this); @@ -865,7 +864,7 @@ LocallabRetinex::LocallabRetinex(): ToolParamBlock* const dehaBox = Gtk::manage(new ToolParamBlock()); dehaBox->pack_start(*dehaz); dehaBox->pack_start(*depth); - dehaBox->pack_start(*lumonly); + dehaBox->pack_start(*dehazeSaturation); dehaFrame->add(*dehaBox); auxBox->add(*dehaFrame); ToolParamBlock* const deharetiBox = Gtk::manage(new ToolParamBlock()); @@ -1060,7 +1059,6 @@ void LocallabRetinex::disableListener() { LocallabTool::disableListener(); - lumonlyConn.block(true); loglinConn.block(true); retinexMethodConn.block(true); fftwretiConn.block(true); @@ -1075,7 +1073,6 @@ void LocallabRetinex::enableListener() { LocallabTool::enableListener(); - lumonlyConn.block(false); loglinConn.block(false); retinexMethodConn.block(false); fftwretiConn.block(false); @@ -1105,7 +1102,7 @@ void LocallabRetinex::read(const rtengine::procparams::ProcParams* pp, const Par dehaz->setValue((double)spot.dehaz); depth->setValue((double)spot.depth); - lumonly->set_active(spot.lumonly); + dehazeSaturation->setValue((double)spot.dehazeSaturation); str->setValue(spot.str); loglin->set_active(spot.loglin); sensih->setValue((double)spot.sensih); @@ -1178,7 +1175,7 @@ void LocallabRetinex::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.dehaz = dehaz->getIntValue(); spot.depth = depth->getIntValue(); - spot.lumonly = lumonly->get_active(); + spot.dehazeSaturation = dehazeSaturation->getIntValue(); spot.str = str->getValue(); spot.loglin = loglin->get_active(); spot.sensih = sensih->getIntValue(); @@ -1232,6 +1229,7 @@ void LocallabRetinex::setDefaults(const rtengine::procparams::ProcParams* defPar // Set default values for adjuster widgets dehaz->setDefault((double)defSpot.dehaz); + dehazeSaturation->setDefault((double)defSpot.dehazeSaturation); depth->setDefault((double)defSpot.depth); str->setDefault(defSpot.str); sensih->setDefault((double)defSpot.sensih); @@ -1276,6 +1274,13 @@ void LocallabRetinex::adjusterChanged(Adjuster* a, double newval) } } + if (a == dehazeSaturation) { + if (listener) { + listener->panelChanged(EvlocallabdehazeSaturation, + dehazeSaturation->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == depth) { if (listener) { listener->panelChanged(Evlocallabdepth, @@ -1535,16 +1540,6 @@ void LocallabRetinex::convertParamToNormal() void LocallabRetinex::convertParamToSimple() { - const LocallabParams::LocallabSpot defSpot; - - // Disable all listeners - disableListener(); - - // Set hidden specific GUI widgets in Simple mode to default spot values - lumonly->set_active(defSpot.lumonly); - - // Enable all listeners - enableListener(); } void LocallabRetinex::updateGUIToMode(const modeType new_type) @@ -1552,10 +1547,8 @@ void LocallabRetinex::updateGUIToMode(const modeType new_type) switch (new_type) { case Simple: // Expert and Normal mode widgets are hidden in Simple mode - lumonly->hide(); retiFrame->hide(); retitoolFrame->hide(); - break; case Normal: @@ -1563,13 +1556,10 @@ void LocallabRetinex::updateGUIToMode(const modeType new_type) retiFrame->hide(); retitoolFrame->hide(); // Specific Simple mode widgets are shown in Normal mode - lumonly->show(); - break; case Expert: // Show widgets hidden in Normal and Simple mode - lumonly->show(); retiFrame->show(); retitoolFrame->show(); } @@ -1592,21 +1582,6 @@ void LocallabRetinex::updateMaskBackground(const double normChromar, const doubl ); } -void LocallabRetinex::lumonlyChanged() -{ - if (isLocActivated && exp->getEnabled()) { - if (listener) { - if (lumonly->get_active()) { - listener->panelChanged(Evlocallablumonly, - M("GENERAL_ENABLED") + " (" + escapeHtmlChars(spotName) + ")"); - } else { - listener->panelChanged(Evlocallablumonly, - M("GENERAL_DISABLED") + " (" + escapeHtmlChars(spotName) + ")"); - } - } - } -} - void LocallabRetinex::loglinChanged() { if (isLocActivated && exp->getEnabled()) { diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index d0f30e332..2543a25f7 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -670,7 +670,7 @@ void ParamsEdited::set(bool v) dehaze.strength = v; dehaze.showDepthMap = v; dehaze.depth = v; - dehaze.luminance = v; + dehaze.saturation = v; metadata.mode = v; filmNegative.enabled = v; filmNegative.redRatio = v; @@ -1360,7 +1360,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).inversret = locallab.spots.at(j).inversret && pSpot.inversret == otherSpot.inversret; locallab.spots.at(j).equilret = locallab.spots.at(j).equilret && pSpot.equilret == otherSpot.equilret; locallab.spots.at(j).loglin = locallab.spots.at(j).loglin && pSpot.loglin == otherSpot.loglin; - locallab.spots.at(j).lumonly = locallab.spots.at(j).lumonly && pSpot.lumonly == otherSpot.lumonly; + locallab.spots.at(j).dehazeSaturation = locallab.spots.at(j).dehazeSaturation && pSpot.dehazeSaturation == otherSpot.dehazeSaturation; locallab.spots.at(j).softradiusret = locallab.spots.at(j).softradiusret && pSpot.softradiusret == otherSpot.softradiusret; locallab.spots.at(j).CCmaskreticurve = locallab.spots.at(j).CCmaskreticurve && pSpot.CCmaskreticurve == otherSpot.CCmaskreticurve; locallab.spots.at(j).LLmaskreticurve = locallab.spots.at(j).LLmaskreticurve && pSpot.LLmaskreticurve == otherSpot.LLmaskreticurve; @@ -1859,7 +1859,7 @@ void ParamsEdited::initFrom(const std::vector& dehaze.strength = dehaze.strength && p.dehaze.strength == other.dehaze.strength; dehaze.showDepthMap = dehaze.showDepthMap && p.dehaze.showDepthMap == other.dehaze.showDepthMap; dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; - dehaze.luminance = dehaze.luminance && p.dehaze.luminance == other.dehaze.luminance; + dehaze.saturation = dehaze.saturation && p.dehaze.saturation == other.dehaze.saturation; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; @@ -4357,8 +4357,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).loglin = mods.locallab.spots.at(i).loglin; } - if (locallab.spots.at(i).lumonly) { - toEdit.locallab.spots.at(i).lumonly = mods.locallab.spots.at(i).lumonly; + if (locallab.spots.at(i).dehazeSaturation) { + toEdit.locallab.spots.at(i).dehazeSaturation = mods.locallab.spots.at(i).dehazeSaturation; } if (locallab.spots.at(i).softradiusret) { @@ -6230,8 +6230,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; } - if (dehaze.luminance) { - toEdit.dehaze.luminance = mods.dehaze.luminance; + if (dehaze.saturation) { + toEdit.dehaze.saturation = mods.dehaze.saturation; } if (metadata.mode) { @@ -6625,7 +6625,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : inversret(v), equilret(v), loglin(v), - lumonly(v), + dehazeSaturation(v), softradiusret(v), CCmaskreticurve(v), LLmaskreticurve(v), @@ -7139,7 +7139,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) inversret = v; equilret = v; loglin = v; - lumonly = v; + dehazeSaturation = v; softradiusret = v; CCmaskreticurve = v; LLmaskreticurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0e303f83a..523999e67 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -700,7 +700,7 @@ public: bool inversret; bool equilret; bool loglin; - bool lumonly; + bool dehazeSaturation; bool softradiusret; bool CCmaskreticurve; bool LLmaskreticurve; @@ -1206,7 +1206,7 @@ struct DehazeParamsEdited { bool strength; bool showDepthMap; bool depth; - bool luminance; + bool saturation; }; struct RAWParamsEdited { diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index 5aef01806..162e63f9e 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,11 +1,13 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 348 +#define PPVERSION 349 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 349 2020-10-29 + replaced Haze removal Luminance checkbox with an adjuster to blend between luminance and normal mode 348 2018-09-25 Added Locallab tool parameters 347 2019-11-17