diff --git a/rtdata/languages/default b/rtdata/languages/default index 6a84b78a5..b96bf1c38 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1974,6 +1974,7 @@ TP_LOCALLAB_EXNORM;Normal spot TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXPOSE;Exposure TP_LOCALLAB_LOC_CONTRAST;Local contrast +TP_LOCALLAB_REFLABEL;Reference (0..1) Luma=%1 Chroma=%2 TP_LOCALLAB_NOISELUMFINE;Luminance fine (Wav) TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luminance detail (DCT) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 1e782c7f2..73473a16f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -93,7 +93,7 @@ ImProcCoordinator::ImProcCoordinator() fw(0), fh(0), tr(0), fullw(1), fullh(1), pW(-1), pH(-1), - plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), flatFieldAutoClipListener(nullptr), bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr), + plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), flatFieldAutoClipListener(nullptr), bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), locallListener(nullptr), hListener(nullptr), resultValid(false), lastOutputProfile("BADFOOD"), lastOutputIntent(RI__COUNT), lastOutputBPC(false), thread(nullptr), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), wavcontlutili(false), colourToningSatLimit(0.f), colourToningSatLimitOpacity(0.f), highQualityComputed(false), customTransformIn(nullptr), customTransformOut(nullptr), //locallab @@ -818,6 +818,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lumar = lumarefs[sp] = lumare ; sobeler = sobelrefs[sp] = sobelre; + if (locallListener) { + locallListener->refChanged(huer, lumar, chromar); + } + //printf("sp=%i huerblu=%f, huer=%f, chromar=%f, lumar=%f, sobeler=%f\n", sp, huerblu, huer, chromar, lumar, sobeler); // Locallab tools computation diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index aebde02f0..e8d186dc4 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -167,6 +167,7 @@ protected: AutoChromaListener* adnListener; WaveletListener* awavListener; RetinexListener* dehaListener; + LocallabListener* locallListener; HistogramListener* hListener; @@ -381,6 +382,10 @@ public: { dehaListener = adh; } + void setLocallabListener (LocallabListener* lla) override + { + locallListener = lla; + } void setWaveletListener (WaveletListener* awa) override { awavListener = awa; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a0873c767..e4b199f1c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2369,7 +2369,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : LHcurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.166, 0.50, 0.35, 0.35, 0.333, 0.50, 0.35, 0.35, 0.50, 0.50, 0.35, 0.35, 0.666, 0.50, 0.35, 0.35, 0.833, 0.50, 0.35, 0.35}, HHcurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.166, 0.50, 0.35, 0.35, 0.333, 0.50, 0.35, 0.35, 0.50, 0.50, 0.35, 0.35, 0.666, 0.50, 0.35, 0.35, 0.833, 0.50, 0.35, 0.35}, CCmaskcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, - LLmaskcurve{(double)FCT_MinMaxCPoints, 0.166, 1., 0.35, 0.35, 0.82, 1., 0.35, 0.35}, + LLmaskcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, invers(false), // Exposure expexpose(false), diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index cb81f0eb0..fa6b3d7f6 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -344,6 +344,13 @@ public: virtual void minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) = 0; }; +class LocallabListener +{ +public: + virtual ~LocallabListener() = default; + virtual void refChanged (double huer, double lumar, double chromar) = 0; +}; + class AutoColorTonListener { public: @@ -507,6 +514,7 @@ public: virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; virtual void setImageTypeListener (ImageTypeListener* l) = 0; + virtual void setLocallabListener (LocallabListener* l) = 0; virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0; virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 2e62712a6..fb5efd21e 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -180,7 +180,11 @@ Locallab::Locallab(): // Others defparams(nullptr), defpedited(nullptr), - pe(nullptr) + pe(nullptr), + nexthuer(0.), + nextlumar(0.), + nextchromar(0.) + { ToolVBox* const panel = Gtk::manage(new ToolVBox()); @@ -289,6 +293,7 @@ Locallab::Locallab(): maskCurveEditorG->setCurveListener(this); inversConn = invers->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::inversChanged)); + transLabels = Gtk::manage (new Gtk::Label ("---")); CCmaskshape = static_cast(maskCurveEditorG->addCurve(CT_Flat, "C(C)", nullptr, false, false)); CCmaskshape->setIdentityValue(0.); @@ -325,6 +330,7 @@ Locallab::Locallab(): maskcolFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW"))); maskcolFrame->set_label_align(0.025, 0.5); ToolParamBlock* const maskcolBox = Gtk::manage(new ToolParamBlock()); + maskcolBox->pack_start(*transLabels, Gtk::PACK_SHRINK, 4); maskcolBox->pack_start(*showmaskcolMethod, Gtk::PACK_SHRINK, 0); maskcolBox->pack_start(*maskCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor @@ -369,7 +375,7 @@ Locallab::Locallab(): curveEditorG->curveListComplete(); maskexpCurveEditorG->setCurveListener(this); - + transLabels2 = Gtk::manage (new Gtk::Label ("---")); showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMNONE")); showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); @@ -399,6 +405,7 @@ Locallab::Locallab(): maskexpFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW"))); maskexpFrame->set_label_align(0.025, 0.5); ToolParamBlock* const maskexpBox = Gtk::manage(new ToolParamBlock()); + maskexpBox->pack_start(*transLabels2, Gtk::PACK_SHRINK, 4); maskexpBox->pack_start(*showmaskexpMethod, Gtk::PACK_SHRINK, 0); maskexpBox->pack_start(*maskexpCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor @@ -895,6 +902,53 @@ void Locallab::writeOptions(std::vector &tpOpen) } +void Locallab::refChanged (double huer, double lumar, double chromar) +{ + nexthuer = huer; + nextlumar = lumar / 100.f; + nextchromar = chromar / 152.f; + //printf("nh=%f nl=%f nc=%f\n", nexthuer, nextlumar, nextchromar); + const auto func = [] (gpointer data) -> gboolean { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + static_cast (data)->refComputed_(); + + return FALSE; + }; + + idle_register.add (func, this); +} + +bool Locallab::refComputed_ () +{ + + disableListener (); + enableListener (); + updateLabel (); + return false; +} + +void Locallab::updateLabel () +{ + if (!batchMode) { + float nX, nY; + + nX = nextlumar; + nY = nextchromar; + { + transLabels->set_text ( + Glib::ustring::compose (M ("TP_LOCALLAB_REFLABEL"), + Glib::ustring::format (std::fixed, std::setprecision (3), nX), + Glib::ustring::format (std::fixed, std::setprecision (3), nY)) + ); + transLabels2->set_text ( + Glib::ustring::compose (M ("TP_LOCALLAB_REFLABEL"), + Glib::ustring::format (std::fixed, std::setprecision (3), nX), + Glib::ustring::format (std::fixed, std::setprecision (3), nY)) + ); + } + } +} + void Locallab::updateToolState(std::vector &tpOpen) { if (tpOpen.size() >= 13) { diff --git a/rtgui/locallab.h b/rtgui/locallab.h index dca7909bc..0159f4af3 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -38,10 +38,13 @@ class Locallab : public CurveListener, public ColorProvider, public ThresholdCurveProvider, + public rtengine::LocallabListener, public ThresholdAdjusterListener { private: + IdleRegister idle_register; + // Expander widgets ControlSpotPanel* const expsettings; MyExpander* const expcolor; @@ -202,6 +205,8 @@ private: Gtk::Button* const lumaneutralButton; Gtk::Button* const lumacontrastPlusButton; sigc::connection lumacontrastMinusPressedConn, lumaneutralPressedConn, lumacontrastPlusPressedConn; + Gtk::Label* transLabels; + Gtk::Label* transLabels2; //Frame Gtk::Frame* maskcolFrame; @@ -266,6 +271,9 @@ private: void updateLocallabGUI(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited, int index); void updateSpecificGUIState(); void setParamEditable(bool cond); + double nexthuer; + double nextlumar; + double nextchromar; /* void onLabRegionSelectionChanged(); @@ -321,6 +329,9 @@ public: void disableListener(); void writeOptions(std::vector &tpOpen); void updateToolState(std::vector &tpOpen); + void refChanged (double huer, double lumar, double chromar); + bool refComputed_ (); + void updateLabel (); // EditProvider management function void setEditProvider(EditDataProvider* provider); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index e3e444f78..93847846a 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -634,6 +634,7 @@ void ToolPanelCoordinator::initImage(rtengine::StagedImageProcessor* ipc_, bool ipc->setRetinexListener(retinex); ipc->setSizeListener(crop); ipc->setSizeListener(resize); + ipc->setLocallabListener(locallab); ipc->setImageTypeListener(this); flatfield->setShortcutPath(Glib::path_get_dirname(ipc->getInitialImage()->getFileName()));