diff --git a/rtdata/languages/default b/rtdata/languages/default index 055b38b51..60ae42dbb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1286,6 +1286,7 @@ HISTORY_MSG_1038;Local - Nlmeans - gamma HISTORY_MSG_1039;Local - Grain - gamma HISTORY_MSG_1040;Local - Spot - soft radius HISTORY_MSG_1041;Local - Spot - Munsell +HISTORY_MSG_1042;Local - Log encoding - threshold HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_BLURWAV;Blur luminance @@ -2792,8 +2793,10 @@ TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. TP_LOCALLAB_LOGCONQL;Contrast (Q) TP_LOCALLAB_LOGCONTL;Contrast (J) +TP_LOCALLAB_LOGCONTHRES;Contrast threshold (J & Q) TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. +TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process : 1) Dynamic Range calculation 2) Manual adjustment TP_LOCALLAB_LOGEXP;All tools diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index dff12aa02..da452c89b 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -48,7 +48,7 @@ void Ciecam02::curvecolorfloat (float satind, float satval, float &sres, float p } } -void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf & outCurve) +void Ciecam02::curveJfloat (float br, float contr, float thr, const LUTu & histogram, LUTf & outCurve) { // check if brightness curve is needed @@ -97,7 +97,6 @@ void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf outCurve.makeIdentity (32767.f); } - if (contr > 0.00001f || contr < -0.00001f) { // compute mean luminance of the image with the curve applied @@ -110,6 +109,9 @@ void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf } avg /= sum; + float thrmin = (thr - contr / 250.0f); + float thrmax = (thr + contr / 250.0f); + std::vector contrastcurvePoints (9); contrastcurvePoints[0] = double (DCT_NURBS); @@ -117,11 +119,11 @@ void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf contrastcurvePoints[1] = 0.f; // black point. Value in [0 ; 1] range contrastcurvePoints[2] = 0.f; // black point. Value in [0 ; 1] range - contrastcurvePoints[3] = avg - avg * (0.6f - contr / 250.0f); // toe point - contrastcurvePoints[4] = avg - avg * (0.6f + contr / 250.0f); // value at toe point + contrastcurvePoints[3] = avg - avg * thrmin; // toe point + contrastcurvePoints[4] = avg - avg * thrmax;// value at toe point - contrastcurvePoints[5] = avg + (1 - avg) * (0.6f - contr / 250.0f); // shoulder point - contrastcurvePoints[6] = avg + (1 - avg) * (0.6f + contr / 250.0f); // value at shoulder point + contrastcurvePoints[5] = avg + (1.f - avg) * thrmin; // shoulder point + contrastcurvePoints[6] = avg + (1.f - avg) * thrmax; // value at shoulder point contrastcurvePoints[7] = 1.f; // white point contrastcurvePoints[8] = 1.f; // value at white point diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h index ca967af1c..cd140a702 100644 --- a/rtengine/ciecam02.h +++ b/rtengine/ciecam02.h @@ -65,7 +65,7 @@ private: public: Ciecam02 () {} static void curvecolorfloat (float satind, float satval, float &sres, float parsat); - static void curveJfloat (float br, float contr, const LUTu & histogram, LUTf & outCurve ) ; + static void curveJfloat (float br, float contr, float thr, const LUTu & histogram, LUTf & outCurve ) ; /** * Inverse transform from CIECAM02 JCh to XYZ. diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 261724384..fc1133986 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -991,7 +991,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb } if (CAMBrightCurveJ.dirty) { - Ciecam02::curveJfloat(params->colorappearance.jlight, params->colorappearance.contrast, hist16J, CAMBrightCurveJ); //lightness and contrast J + Ciecam02::curveJfloat(params->colorappearance.jlight, params->colorappearance.contrast, 0.6f, hist16J, CAMBrightCurveJ); //lightness and contrast J CAMBrightCurveJ /= 327.68f; CAMBrightCurveJ.dirty = false; } @@ -1003,7 +1003,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb } if (CAMBrightCurveQ.dirty) { - Ciecam02::curveJfloat(params->colorappearance.qbright, params->colorappearance.qcontrast, hist16Q, CAMBrightCurveQ); //brightness and contrast Q + Ciecam02::curveJfloat(params->colorappearance.qbright, params->colorappearance.qcontrast, 0.6f, hist16Q, CAMBrightCurveQ); //brightness and contrast Q // CAMBrightCurveQ /= coefQ; CAMBrightCurveQ.dirty = false; } diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 6abd9ec4f..5ff43c472 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2404,8 +2404,8 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab, int call) LUTu hist16J(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); LUTu hist16Q(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); //for J light and contrast - LUTf CAMBrightCurveJ(32768, LUT_CLIP_ABOVE); - LUTf CAMBrightCurveQ(32768, LUT_CLIP_ABOVE); + LUTf CAMBrightCurveJ(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); + LUTf CAMBrightCurveQ(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); #ifdef _OPENMP const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); @@ -2482,11 +2482,24 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab, int call) const float lightL = 0.4 * params->locallab.spots.at(sp).lightl; //0.4 less effect, no need 1. const float contQ = 0.5 * params->locallab.spots.at(sp).contq; //0.5 less effect, no need 1. const float lightQ = 0.4 * params->locallab.spots.at(sp).lightq; //0.4 less effect, no need 1. - - Ciecam02::curveJfloat(lightL, contL, hist16J, CAMBrightCurveJ); //lightness J and contrast J + + float contthresL = params->locallab.spots.at(sp).contthres; + float contthresQ = contthresL; + if(contL < 0.f) { + contthresL *= -1; + } + float thL = 0.6f; + thL = 0.3f * contthresL + 0.6f; + + if(contQ < 0.f) { + contthresQ *= -1; + } + float thQ = 0.6f; + thQ = 0.3f * contthresQ + 0.6f; + Ciecam02::curveJfloat(lightL, contL, thL, hist16J, CAMBrightCurveJ); //lightness J and contrast J CAMBrightCurveJ /= 327.68f; - Ciecam02::curveJfloat(lightQ, contQ, hist16Q, CAMBrightCurveQ); //brightness Q and contrast Q + Ciecam02::curveJfloat(lightQ, contQ, thQ, hist16Q, CAMBrightCurveQ); //brightness Q and contrast Q } int tempo = 5000; if(params->locallab.spots.at(sp).expvibrance && call == 2) { diff --git a/rtengine/procevents.h b/rtengine/procevents.h index d1d0c1126..e65a4e12e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -1064,6 +1064,7 @@ enum ProcEventCode { Evlocallabdivgr = 1038, EvLocallabSpotavoidrad = 1039, EvLocallabSpotavoidmun = 1040, + Evlocallabcontthres = 1041, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 91d141696..3d6dae89d 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3981,6 +3981,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : lightl(0.), lightq(0.), contl(0.), + contthres(0.), contq(0.), colorfl(0.), LcurveL{ @@ -4695,6 +4696,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && lightl == other.lightl && lightq == other.lightq && contl == other.contl + && contthres == other.contthres && contq == other.contq && colorfl == other.colorfl && LcurveL == other.LcurveL @@ -6341,6 +6343,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->lightl, "Locallab", "Lightl_" + index_str, spot.lightl, keyFile); saveToKeyfile(!pedited || spot_edited->lightq, "Locallab", "Brightq_" + index_str, spot.lightq, keyFile); saveToKeyfile(!pedited || spot_edited->contl, "Locallab", "Contl_" + index_str, spot.contl, keyFile); + saveToKeyfile(!pedited || spot_edited->contthres, "Locallab", "Contthres_" + index_str, spot.contthres, keyFile); saveToKeyfile(!pedited || spot_edited->contq, "Locallab", "Contq_" + index_str, spot.contq, keyFile); saveToKeyfile(!pedited || spot_edited->colorfl, "Locallab", "Colorfl_" + index_str, spot.colorfl, keyFile); saveToKeyfile(!pedited || spot_edited->Autogray, "Locallab", "Autogray_" + index_str, spot.Autogray, keyFile); @@ -8237,6 +8240,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Lightl_" + index_str, pedited, spot.lightl, spotEdited.lightl); assignFromKeyfile(keyFile, "Locallab", "Brightq_" + index_str, pedited, spot.lightq, spotEdited.lightq); assignFromKeyfile(keyFile, "Locallab", "Contl_" + index_str, pedited, spot.contl, spotEdited.contl); + assignFromKeyfile(keyFile, "Locallab", "Contthres_" + index_str, pedited, spot.contthres, spotEdited.contthres); assignFromKeyfile(keyFile, "Locallab", "Contq_" + index_str, pedited, spot.contq, spotEdited.contq); assignFromKeyfile(keyFile, "Locallab", "Colorfl_" + index_str, pedited, spot.colorfl, spotEdited.colorfl); assignFromKeyfile(keyFile, "Locallab", "LCurveL_" + index_str, pedited, spot.LcurveL, spotEdited.LcurveL); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index fd8b6aebb..c75d8139b 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1492,6 +1492,7 @@ struct LocallabParams { double lightl; double lightq; double contl; + double contthres; double contq; double colorfl; std::vector LcurveL; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 1f071e37a..29af1190d 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -1067,7 +1067,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { AUTOEXP, // Evlocallabnlgam AUTOEXP, // Evlocallabdivgr AUTOEXP, // EvLocallabSpotavoidrad - AUTOEXP // EvLocallabSpotavoidmun + AUTOEXP, // EvLocallabSpotavoidmun + AUTOEXP // Evlocallabcontthres }; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1e3a1c6fa..4fda00f08 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -1317,6 +1317,7 @@ private: Adjuster* const lightq; Adjuster* const contl; Adjuster* const contq; + Adjuster* const contthres; Adjuster* const colorfl; Adjuster* const saturl; MyExpander* const expL; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 228b7da0a..fc3eba39e 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -5125,6 +5125,7 @@ LocallabLog::LocallabLog(): lightq(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTQ"), -100., 100., 0.5, 0.))), contl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTL"), -100., 100., 0.5, 0.))), contq(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONQL"), -100., 100., 0.5, 0.))), + contthres(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTHRES"), -1., 1., 0.01, 0.))), colorfl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCOLORFL"), -100., 100., 0.5, 0.))), saturl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), expL(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_LOGEXP")))), @@ -5199,6 +5200,7 @@ LocallabLog::LocallabLog(): lightq->setAdjusterListener(this); contl->setAdjusterListener(this); + contthres->setAdjusterListener(this); contq->setAdjusterListener(this); colorfl->setAdjusterListener(this); @@ -5323,6 +5325,7 @@ LocallabLog::LocallabLog(): ToolParamBlock* const logP1Box = Gtk::manage(new ToolParamBlock()); logP1Box->pack_start(*detail); logP1Box->pack_start(*contl); + logP1Box->pack_start(*contthres); logP1Box->pack_start(*saturl); ToolParamBlock* const logP11Box = Gtk::manage(new ToolParamBlock()); logP11Box->pack_start(*lightl); @@ -5420,6 +5423,7 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) anglog->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); contl->set_tooltip_text(M("TP_LOCALLAB_LOGCONTL_TOOLTIP")); contq->set_tooltip_text(M("TP_LOCALLAB_LOGCONTQ_TOOLTIP")); + contthres->set_tooltip_text(M("TP_LOCALLAB_LOGCONTTHRES_TOOLTIP")); colorfl->set_tooltip_text(M("TP_LOCALLAB_LOGCOLORF_TOOLTIP")); lightl->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTL_TOOLTIP")); lightq->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTQ_TOOLTIP")); @@ -5470,6 +5474,7 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) lightl->set_tooltip_text(""); lightq->set_tooltip_text(""); contq->set_tooltip_text(""); + contthres->set_tooltip_text(""); colorfl->set_tooltip_text(""); saturl->set_tooltip_text(""); catad->set_tooltip_text(""); @@ -5594,6 +5599,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE lightl->setValue(spot.lightl); lightq->setValue(spot.lightq); contl->setValue(spot.contl); + contthres->setValue(spot.contthres); contq->setValue(spot.contq); colorfl->setValue(spot.colorfl); LshapeL->setCurve(spot.LcurveL); @@ -5656,6 +5662,7 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.lightl = lightl->getValue(); spot.lightq = lightq->getValue(); spot.contl = contl->getValue(); + spot.contthres = contthres->getValue(); spot.contq = contq->getValue(); spot.colorfl = colorfl->getValue(); spot.LcurveL = LshapeL->getCurve(); @@ -5737,6 +5744,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) targabs->hide(); saturl->hide(); contl->hide(); + contthres->hide(); lightl->hide(); lightq->hide(); contq->hide(); @@ -5765,6 +5773,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) lightl->show(); lightq->show(); contl->show(); + contthres->show(); contq->show(); colorfl->show(); surrHBox->show(); @@ -5797,6 +5806,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) lightl->show(); lightq->show(); contl->show(); + contthres->show(); contq->show(); colorfl->show(); surrHBox->show(); @@ -5829,6 +5839,7 @@ void LocallabLog::convertParamToSimple() disableListener(); ciecam->set_active(false); contq->setValue(defSpot.contq); + contthres->setValue(defSpot.contthres); colorfl->setValue(defSpot.colorfl); lightl->setValue(defSpot.lightl); lightq->setValue(defSpot.lightq); @@ -5941,6 +5952,7 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, lightl->setDefault(defSpot.lightl); lightq->setDefault(defSpot.lightq); contl->setDefault(defSpot.contl); + contthres->setDefault(defSpot.contthres); contq->setDefault(defSpot.contq); colorfl->setDefault(defSpot.colorfl); detail->setDefault(defSpot.detail); @@ -6050,6 +6062,13 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == contthres) { + if (listener) { + listener->panelChanged(Evlocallabcontthres, + contthres->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == contq) { if (listener) { listener->panelChanged(Evlocallabcontq, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 452daa16d..4f3726334 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1569,6 +1569,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).lightl = locallab.spots.at(j).lightl && pSpot.lightl == otherSpot.lightl; locallab.spots.at(j).lightq = locallab.spots.at(j).lightq && pSpot.lightq == otherSpot.lightq; locallab.spots.at(j).contl = locallab.spots.at(j).contl && pSpot.contl == otherSpot.contl; + locallab.spots.at(j).contthres = locallab.spots.at(j).contthres && pSpot.contthres == otherSpot.contthres; locallab.spots.at(j).contq = locallab.spots.at(j).contq && pSpot.contq == otherSpot.contq; locallab.spots.at(j).colorfl = locallab.spots.at(j).colorfl && pSpot.colorfl == otherSpot.colorfl; locallab.spots.at(j).LcurveL = locallab.spots.at(j).LcurveL && pSpot.LcurveL == otherSpot.LcurveL; @@ -5217,6 +5218,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).contl = mods.locallab.spots.at(i).contl; } + if (locallab.spots.at(i).contthres) { + toEdit.locallab.spots.at(i).contthres = mods.locallab.spots.at(i).contthres; + } + if (locallab.spots.at(i).contq) { toEdit.locallab.spots.at(i).contq = mods.locallab.spots.at(i).contq; } @@ -7152,6 +7157,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : lightl(v), lightq(v), contl(v), + contthres(v), contq(v), colorfl(v), LcurveL(v), @@ -7729,6 +7735,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) lightl = v; lightq = v; contl = v; + contthres = v; contq = v; colorfl = v; LcurveL = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 486d1ee6d..d9087d729 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -900,6 +900,7 @@ public: bool lightl; bool lightq; bool contl; + bool contthres; bool contq; bool colorfl; bool LcurveL;