diff --git a/rtengine/ipdehaz.cc b/rtengine/ipdehaz.cc index 5f85f883a..a829abe9a 100644 --- a/rtengine/ipdehaz.cc +++ b/rtengine/ipdehaz.cc @@ -206,7 +206,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width // float mini, delta, maxi; float delta; float eps = 2.f; + bool useHsl = deh.dehazcolorspace == "HSL"; float gain2 = (float) deh.gain / 100.f; //def =1 not use + gain2 = useHsl ? gain2 * 0.5f : gain2; float offse = (float) deh.offs; //def = 0 not use int scal = deh.scal; //def=3 int nei = (int) 2.8f * deh.neigh; //def = 220 @@ -214,8 +216,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width float strength = (float) deh.str / 100.f; // Blend with original L channel data float limD = (float) deh.limd; limD = pow(limD, 1.7f);//about 2500 enough + limD *= useHsl ? 10.f : 1.f; float ilimD = 1.f / limD; - int modedehaz = 0; // default to 0 ( deh.dehazmet == "uni" ) bool execcur = false; @@ -281,15 +283,24 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width for (int i = 0; i < H_L; i++) { int j = 0; #ifdef __SSE2__ - - for (; j < W_L - 3; j += 4) { - _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); + if(useHsl) { + for (; j < W_L - 3; j += 4) { + _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); + } + } else { + for (; j < W_L - 3; j += 4) { + _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); + } } - #endif - - for (; j < W_L; j++) { - luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimD, limD)); + if(useHsl) { + for (; j < W_L; j++) { + luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimD, limD)); + } + } else { + for (; j < W_L; j++) { + luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimD, limD)); + } } } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index c61782da5..98972fd89 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -445,7 +445,7 @@ enum ProcEvent { EvDehazretinex = 416, EvDehazmedianmap = 417, EvLlimd = 418, - + EvdehazColorSpace = 419, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 3b40dd949..92d4bf714 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -172,6 +172,7 @@ void DehazParams::setDefaults() getDefaulttransmissionCurve(transmissionCurve); getDefaultCDCurve(cdcurve); dehazmet = "uni"; + dehazcolorspace = "Lab"; retinex = false; medianmap = true; @@ -1493,6 +1494,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Dehaz", "Dehazmet", dehaz.dehazmet); } + if (!pedited || pedited->dehaz.dehazcolorspace) { + keyFile.set_string ("Dehaz", "Dehazcolorspace", dehaz.dehazcolorspace); + } + if (!pedited || pedited->dehaz.cdcurve) { Glib::ArrayHandle cdcurve = dehaz.cdcurve; keyFile.set_double_list("Dehaz", "CDCurve", cdcurve); @@ -3788,6 +3793,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Dehaz", "Dehazcolorspace")) { + dehaz.dehazcolorspace = keyFile.get_string ("Dehaz", "Dehazcolorspace"); + + if (pedited) { + pedited->dehaz.dehazcolorspace = true; + } + } + if (keyFile.has_key ("Dehaz", "Enabled")) { dehaz.enabled = keyFile.get_boolean ("Dehaz", "Enabled"); @@ -7238,6 +7251,7 @@ bool ProcParams::operator== (const ProcParams& other) && dehaz.limd == other.dehaz.limd && dehaz.offs == other.dehaz.offs && dehaz.dehazmet == other.dehaz.dehazmet + && dehaz.dehazcolorspace == other.dehaz.dehazcolorspace && dehaz.vart == other.dehaz.vart && dehaz.medianmap == other.dehaz.medianmap && dehaz.enabled == other.dehaz.enabled diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 1645289a8..d0451d50f 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -277,6 +277,7 @@ public: int gain; int offs; Glib::ustring dehazmet; + Glib::ustring dehazcolorspace; int vart; int limd; bool medianmap; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 4f7d88fd7..114fb537d 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -40,6 +40,7 @@ #include #endif #include "opthelper.h" +#include "Stopwatch.h" namespace rtengine { @@ -1839,6 +1840,26 @@ void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams labTmp[i] = &labTmpBuffer[i * WNew]; } + bool useHsl = deh.dehazcolorspace == "HSL"; + if(useHsl) { + for (int i = border; i < H - border; i++ ) + for (int j = border; j < W - border; j++) { + float H,S,L; + //rgb=>lab + Color::rgb2hsl(red[i][j], green[i][j], blue[i][j],H,S,L); + L *= 65535.f; + labTmp[i - border][j - border] = L; + + if(dehacontlutili) { + L = cdcurve[L]; //apply curve to equalize histogram + } + + labdeha->L[i - border][j - border] = L; + labdeha->a[i - border][j - border] = H; + labdeha->b[i - border][j - border] = S; + } + } else { + // Conversion rgb -> lab is hard to vectorize because it uses a lut (that's not the main problem) // and it uses a condition inside XYZ2Lab which is almost impossible to vectorize without making it slower... #ifdef _OPENMP @@ -1862,11 +1883,25 @@ void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams labdeha->a[i - border][j - border] = aa; labdeha->b[i - border][j - border] = bb; } + } MSR(labdeha->L, labTmp, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); delete [] labTmpBuffer; + if(useHsl) { + for (int i = border; i < H - border; i++ ) { + int j = border; + for (; j < W - border; j++) { + float R, G, B; + Color::hsl2rgb(labdeha->a[i - border][j - border],labdeha->b[i - border][j - border],labdeha->L[i - border][j - border]/65535.f,R,G,B); + red[i][j] = R; + green[i][j] = G; + blue[i][j] = B; + } + } + + } else { #ifdef __SSE2__ vfloat wipv[3][3]; @@ -1912,6 +1947,7 @@ void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams blue[i][j] = B; } } + } delete labdeha; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index f368b42d4..2bf2e261e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -440,7 +440,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DEMOSAIC, // EvDehazEnabled DEMOSAIC, // EvDehazretinex DEMOSAIC, // EvDehazmedianmap - DEMOSAIC // EvLlimd + DEMOSAIC, // EvLlimd + DEMOSAIC // Evdehazcolorspace }; diff --git a/rtgui/dehaz.cc b/rtgui/dehaz.cc index 8c9f7bbfb..509477eed 100644 --- a/rtgui/dehaz.cc +++ b/rtgui/dehaz.cc @@ -44,7 +44,18 @@ Dehaz::Dehaz () : FoldableToolPanel(this, "dehaz", M("TP_DEHAZ_LABEL"), false, t dehazmet->set_active(0); dehazmetConn = dehazmet->signal_changed().connect ( sigc::mem_fun(*this, &Dehaz::dehazmetChanged) ); dehazmet->set_tooltip_markup (M("TP_DEHAZ_MET_TOOLTIP")); + + dehazcolorspace = Gtk::manage (new MyComboBoxText ()); + dehazcolorspace->append_text (M("TP_DEHAZ_LABSAPCE")); + dehazcolorspace->append_text (M("TP_DEHAZ_HSLSPACE")); + dehazcolorspace->set_active(0); + dehazmetConn = dehazcolorspace->signal_changed().connect ( sigc::mem_fun(*this, &Dehaz::dehazColorSpaceChanged) ); + dehazcolorspace->set_tooltip_markup (M("TP_DEHAZ_COLORSPACE_TOOLTIP")); + + + dhbox->pack_start(*dehazmet); + dhbox->pack_start(*dehazcolorspace); dehazVBox->pack_start(*dhbox); std::vector defaultCurve; @@ -266,6 +277,10 @@ void Dehaz::read (const ProcParams* pp, const ParamsEdited* pedited) dehazmet->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->dehaz.dehazcolorspace) { + dehazcolorspace->set_active_text(M("GENERAL_UNCHANGED")); + } + cdshape->setUnChanged (!pedited->dehaz.cdcurve); transmissionShape->setUnChanged (!pedited->dehaz.transmissionCurve); @@ -301,6 +316,14 @@ void Dehaz::read (const ProcParams* pp, const ParamsEdited* pedited) } dehazmetChanged (); + + if (pp->dehaz.dehazcolorspace == "Lab") { + dehazcolorspace->set_active (0); + } else if (pp->dehaz.dehazcolorspace == "HSL") { + dehazcolorspace->set_active (1); + } + dehazColorSpaceChanged(); + retinexConn.block(false); retinexChanged (); retinexConn.block(false); @@ -311,6 +334,7 @@ void Dehaz::read (const ProcParams* pp, const ParamsEdited* pedited) cdshape->setCurve (pp->dehaz.cdcurve); dehazmetConn.block(false); + dehazColorSpaceConn.block(false); transmissionShape->setCurve (pp->dehaz.transmissionCurve); @@ -367,6 +391,7 @@ void Dehaz::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->dehaz.dehazmet = dehazmet->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->dehaz.dehazcolorspace = dehazcolorspace->get_active_text() != M("GENERAL_UNCHANGED"); //%%%%%%%%%%%%%%%%%%%%%% pedited->dehaz.str = str->getEditedState (); @@ -391,6 +416,12 @@ void Dehaz::write (ProcParams* pp, ParamsEdited* pedited) } else if (dehazmet->get_active_row_number() == 2) { pp->dehaz.dehazmet = "high"; } + + if (dehazcolorspace->get_active_row_number() == 0) { + pp->dehaz.dehazcolorspace = "Lab"; + } else if (dehazcolorspace->get_active_row_number() == 1) { + pp->dehaz.dehazcolorspace = "HSL"; + } } void Dehaz::dehazmetChanged() @@ -400,6 +431,13 @@ void Dehaz::dehazmetChanged() } } +void Dehaz::dehazColorSpaceChanged() +{ + if (listener) { + listener->panelChanged (EvdehazColorSpace, dehazcolorspace->get_active_text ()); + } +} + void Dehaz::retinexChanged () { if (batchMode) { diff --git a/rtgui/dehaz.h b/rtgui/dehaz.h index 48007bea8..aed67ba6f 100644 --- a/rtgui/dehaz.h +++ b/rtgui/dehaz.h @@ -31,6 +31,7 @@ protected: Gtk::Label* labmdh; Gtk::HBox* dhbox; MyComboBoxText* dehazmet; + MyComboBoxText* dehazcolorspace; Gtk::CheckButton* retinex; Gtk::Frame* dehazFrame; Gtk::CheckButton* medianmap; @@ -49,6 +50,7 @@ protected: DiagonalCurveEditor* cdshape; CurveEditorGroup* transmissionCurveEditorG; sigc::connection dehazmetConn; + sigc::connection dehazColorSpaceConn; FlatCurveEditor* transmissionShape; bool lastretinex, lastmedianmap; sigc::connection retinexConn, medianmapConn; @@ -75,6 +77,7 @@ public: void enabledChanged (); void curveChanged (CurveEditor* ce); void dehazmetChanged(); + void dehazColorSpaceChanged(); void retinexUpdateUI(); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index edf449dcc..23439c8e0 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -51,6 +51,7 @@ void ParamsEdited::set (bool v) toneCurve.method = v; dehaz.cdcurve = v; dehaz.dehazmet = v; + dehaz.dehazcolorspace = v; dehaz.enabled = v; dehaz.str = v; dehaz.scal = v; @@ -520,6 +521,7 @@ void ParamsEdited::initFrom (const std::vector dehaz.cdcurve = dehaz.cdcurve && p.dehaz.cdcurve == other.dehaz.cdcurve; dehaz.transmissionCurve = dehaz.transmissionCurve && p.dehaz.transmissionCurve == other.dehaz.transmissionCurve; dehaz.dehazmet = dehaz.dehazmet && p.dehaz.dehazmet == other.dehaz.dehazmet; + dehaz.dehazcolorspace = dehaz.dehazcolorspace && p.dehaz.dehazcolorspace == other.dehaz.dehazcolorspace; dehaz.str = dehaz.str && p.dehaz.str == other.dehaz.str; dehaz.scal = dehaz.scal && p.dehaz.scal == other.dehaz.scal; dehaz.neigh = dehaz.neigh && p.dehaz.neigh == other.dehaz.neigh; @@ -1037,6 +1039,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.dehaz.dehazmet = mods.dehaz.dehazmet; } + if (dehaz.dehazcolorspace) { + toEdit.dehaz.dehazcolorspace = mods.dehaz.dehazcolorspace; + } + if (dehaz.str) { toEdit.dehaz.str = mods.dehaz.str; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index b2a7056d1..25f5750c3 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -65,6 +65,7 @@ public: bool gain; bool offs; bool dehazmet; + bool dehazcolorspace; bool vart; bool limd; bool method;