1 /*
2  *  This file is part of RawTherapee.
3  */
4 #include "retinex.h"
5 
6 #include "curveeditor.h"
7 #include "curveeditorgroup.h"
8 #include "mycurve.h"
9 #include "rtimage.h"
10 #include "options.h"
11 #include "../rtengine/color.h"
12 
13 using namespace rtengine;
14 using namespace rtengine::procparams;
15 
Retinex()16 Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL"), false, true), lastmedianmap (false)
17 {
18     CurveListener::setMulti (true);
19     std::vector<GradientMilestone> milestones;
20     nextmin = 0.;
21     nextmax = 0.;
22     nextminiT = 0.;
23     nextmaxiT = 0.;
24     nextmeanT = 0.;
25     nextsigma = 0.;
26     nextminT = 0.;
27     nextmaxT = 0.;
28 
29 
30 
31 
32     // MAIN Expander ==================================================================
33 
34 
35 
36 
37     Gtk::Grid *retinexGrid = Gtk::manage ( new Gtk::Grid());
38     setExpandAlignProperties (retinexGrid, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
39 
40     dhgrid = Gtk::manage (new Gtk::Grid ());
41     setExpandAlignProperties (dhgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
42 
43     labmdh = Gtk::manage (new Gtk::Label (M ("TP_RETINEX_METHOD") + ":"));
44     setExpandAlignProperties (labmdh, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE);
45     dhgrid->attach (*labmdh, 0, 0, 1, 1);
46 
47     retinexMethod = Gtk::manage (new MyComboBoxText ());
48     setExpandAlignProperties (retinexMethod, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
49     retinexMethod->append (M ("TP_RETINEX_LOW"));
50     retinexMethod->append (M ("TP_RETINEX_UNIFORM"));
51     retinexMethod->append (M ("TP_RETINEX_HIGH"));
52     retinexMethod->append (M ("TP_RETINEX_HIGHLIG"));
53 //  retinexMethod->append (M("TP_RETINEX_HIGHLIGPLUS"));
54     retinexMethod->set_active (0);
55     retinexMethodConn = retinexMethod->signal_changed().connect ( sigc::mem_fun (*this, &Retinex::retinexMethodChanged) );
56     retinexMethod->set_tooltip_markup (M ("TP_RETINEX_METHOD_TOOLTIP"));
57     dhgrid->attach (*retinexMethod, 1, 0, 1, 1);
58 
59     retinexcolorspace = Gtk::manage (new MyComboBoxText ());
60     setExpandAlignProperties (retinexcolorspace, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
61     retinexcolorspace->append (M ("TP_RETINEX_LABSPACE"));
62     retinexcolorspace->append (M ("TP_RETINEX_HSLSPACE_LOG"));
63     retinexcolorspace->append (M ("TP_RETINEX_HSLSPACE_LIN"));
64     retinexcolorspace->set_active (0);
65     retinexColorSpaceConn = retinexcolorspace->signal_changed().connect ( sigc::mem_fun (*this, &Retinex::retinexColorSpaceChanged) );
66     dhgrid->attach (*retinexcolorspace, 2, 0, 1, 1);
67     retinexGrid->attach (*dhgrid, 0, 0, 1, 1);
68 
69     str = Gtk::manage (new Adjuster (M ("TP_RETINEX_STRENGTH"), 0, 100., 1., 20.));
70     setExpandAlignProperties (str, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
71     retinexGrid->attach (*str, 0, 1, 1, 1);
72     str->show ();
73 
74     neigh = Gtk::manage (new Adjuster (M ("TP_RETINEX_NEIGHBOR"), 6, 100., 1., 80.));
75     setExpandAlignProperties (neigh, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
76     retinexGrid->attach (*neigh, 0, 2, 1, 1);
77     neigh->show ();
78 
79     vart   = Gtk::manage (new Adjuster (M ("TP_RETINEX_VARIANCE"), 50, 500, 1, 200));
80     setExpandAlignProperties (vart, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
81     vart->set_tooltip_markup (M ("TP_RETINEX_VARIANCE_TOOLTIP"));
82     retinexGrid->attach (*vart, 0, 3, 1, 1);
83     vart->show ();
84 
85     highl   = Gtk::manage (new Adjuster (M ("TP_RETINEX_HIGHLIGHT"), 1, 20, 1, 4));
86     setExpandAlignProperties (highl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
87     highl->set_tooltip_markup (M ("TP_RETINEX_HIGHLIGHT_TOOLTIP"));
88     retinexGrid->attach (*highl, 0, 4, 1, 1);
89     highl->show ();
90 
91     viewgrid = Gtk::manage (new Gtk::Grid ());
92     setExpandAlignProperties (viewgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
93 
94     labview = Gtk::manage (new Gtk::Label (M ("TP_RETINEX_VIEW") + ":"));
95     setExpandAlignProperties (labview, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE);
96     viewgrid->attach (*labview, 0, 0, 1, 1);
97 
98     viewMethod = Gtk::manage (new MyComboBoxText ());
99     setExpandAlignProperties (viewMethod, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
100     viewMethod->append (M ("TP_RETINEX_VIEW_NONE"));
101     viewMethod->append (M ("TP_RETINEX_VIEW_UNSHARP"));
102     viewMethod->append (M ("TP_RETINEX_VIEW_MASK"));
103     viewMethod->append (M ("TP_RETINEX_VIEW_TRAN"));
104     viewMethod->append (M ("TP_RETINEX_VIEW_TRAN2"));
105     viewMethod->set_active (0);
106     viewMethodConn = viewMethod->signal_changed().connect ( sigc::mem_fun (*this, &Retinex::viewMethodChanged) );
107     viewMethod->set_tooltip_markup (M ("TP_RETINEX_VIEW_METHOD_TOOLTIP"));
108     viewgrid->attach (*viewMethod, 1, 0, 1, 1);
109     retinexGrid->attach (*viewgrid, 0, 5, 1, 1);
110 
111     //-------------
112 
113     pack_start (*retinexGrid);
114 
115 
116     // MAP (MASK) Frame ---------------------------------------------------------------
117 
118 
119     Gtk::Frame *maskFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_LABEL_MASK")) );
120     setExpandAlignProperties (maskFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
121 
122     Gtk::Grid *maskGrid = Gtk::manage ( new Gtk::Grid());
123     setExpandAlignProperties (maskGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
124 
125     // Map Method
126     mapgrid = Gtk::manage (new Gtk::Grid ());
127     setExpandAlignProperties (mapgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
128 
129     labmap = Gtk::manage (new Gtk::Label (M ("TP_RETINEX_MAP") + ":"));
130     setExpandAlignProperties (labmap, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE);
131     mapgrid->attach (*labmap, 0, 0, 1, 1);
132 
133     mapMethod = Gtk::manage (new MyComboBoxText ());
134     setExpandAlignProperties (mapMethod, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
135     mapMethod->append (M ("TP_RETINEX_MAP_NONE"));
136     mapMethod->append (M ("TP_RETINEX_MAP_GAUS"));
137     mapMethod->append (M ("TP_RETINEX_MAP_MAPP"));
138     mapMethod->append (M ("TP_RETINEX_MAP_MAPT"));
139     mapMethod->set_active (0);
140     mapMethodConn = mapMethod->signal_changed().connect ( sigc::mem_fun (*this, &Retinex::mapMethodChanged) );
141     mapMethod->set_tooltip_markup (M ("TP_RETINEX_MAP_METHOD_TOOLTIP"));
142     mapgrid->attach (*mapMethod, 1, 0, 1, 1);
143 
144     maskGrid->attach (*mapgrid, 0, 0, 1, 1);
145     mapgrid->show();
146 
147     // Map Equalizer
148     curveEditormap = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_CONTEDIT_MAP"));
149     setExpandAlignProperties (curveEditormap, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
150     curveEditormap->setCurveListener (this);
151     std::vector<GradientMilestone> milestones222;
152     milestones222.push_back ( GradientMilestone (0., 0., 0., 0.) );
153     milestones222.push_back ( GradientMilestone (1., 1., 1., 1.) );
154     mapshape = static_cast<DiagonalCurveEditor*> (curveEditormap->addCurve (CT_Diagonal, M ("TP_RETINEX_CURVEEDITOR_MAP")));
155     mapshape->setTooltip (M ("TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP"));
156     mapshape->setBottomBarBgGradient (milestones222);
157     mapshape->setLeftBarBgGradient (milestones222);
158     curveEditormap->curveListComplete();
159     maskGrid->attach (*curveEditormap, 0, 1, 1, 1);
160     curveEditormap->show();
161 
162     // Adjusters
163     highlights = Gtk::manage (new Adjuster (M ("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0));
164     setExpandAlignProperties (highlights, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
165     maskGrid->attach (*highlights, 0, 2, 1, 1);
166     highlights->show();
167 
168     h_tonalwidth = Gtk::manage (new Adjuster (M ("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 80));
169     setExpandAlignProperties (h_tonalwidth, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
170     maskGrid->attach (*h_tonalwidth, 0, 3, 1, 1);
171     h_tonalwidth->show();
172 
173     shadows = Gtk::manage (new Adjuster (M ("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0));
174     setExpandAlignProperties (shadows, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
175     maskGrid->attach (*shadows, 0, 4, 1, 1);
176     shadows->show();
177 
178     s_tonalwidth = Gtk::manage (new Adjuster (M ("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80));
179     setExpandAlignProperties (s_tonalwidth, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
180     maskGrid->attach (*s_tonalwidth, 0, 5, 1, 1);
181     s_tonalwidth->show();
182 
183     radius = Gtk::manage (new Adjuster (M ("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 40));
184     setExpandAlignProperties (radius, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
185     maskGrid->attach (*radius, 0, 6, 1, 1);
186     radius->show();
187 
188     //-------------
189 
190     maskFrame->add (*maskGrid);
191     pack_start (*maskFrame, Gtk::PACK_EXPAND_WIDGET, 4);
192 
193 
194 
195 
196     // SETTINGS Expander ==============================================================
197 
198 
199 
200 
201     expsettings = Gtk::manage(new MyExpander(false, M ("TP_RETINEX_SETTINGS")));
202     setExpandAlignProperties (expsettings, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
203     expsettings->signal_button_release_event().connect_notify ( sigc::bind ( sigc::mem_fun (this, &Retinex::foldAllButMe), expsettings) );
204 
205     Gtk::Grid *settingsGrid = Gtk::manage ( new Gtk::Grid());
206     setExpandAlignProperties (settingsGrid, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
207 
208     mMLabels = Gtk::manage (new Gtk::Label ("---"));
209     setExpandAlignProperties (mMLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START);
210     mMLabels->set_tooltip_markup (M ("TP_RETINEX_MLABEL_TOOLTIP"));
211     settingsGrid->attach (*mMLabels, 0, 0, 1, 1);
212     mMLabels->show ();
213 
214     transLabels = Gtk::manage (new Gtk::Label ("---"));
215     setExpandAlignProperties (transLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START);
216     transLabels->set_tooltip_markup (M ("TP_RETINEX_TLABEL_TOOLTIP"));
217     settingsGrid->attach (*transLabels, 0, 1, 1, 1);
218     transLabels->show ();
219 
220     transLabels2 = Gtk::manage (new Gtk::Label ("---"));
221     setExpandAlignProperties (transLabels2, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START);
222     settingsGrid->attach (*transLabels2, 0, 2, 1, 1);
223     transLabels2->show ();
224 
225 
226     // EQUALIZER Frame ----------------------------------------------------------------
227 
228 
229     equalFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_EQUAL")));
230     setExpandAlignProperties (equalFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
231 //GTK318
232 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
233     equalFrame->set_border_width (5);
234 #endif
235 //GTK318
236 
237     Gtk::Grid *equalGrid = Gtk::manage (new Gtk::Grid());
238     setExpandAlignProperties (equalGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
239 
240     // Histogram equalizer Lab curve
241     curveEditorGD = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_CONTEDIT_LAB"));
242     setExpandAlignProperties (curveEditorGD, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
243     curveEditorGD->setCurveListener (this);
244     std::vector<GradientMilestone> milestones22;
245     milestones22.push_back ( GradientMilestone (0., 0., 0., 0.) );
246     milestones22.push_back ( GradientMilestone (1., 1., 1., 1.) );
247     cdshape = static_cast<DiagonalCurveEditor*> (curveEditorGD->addCurve (CT_Diagonal, M ("TP_RETINEX_CURVEEDITOR_CD")));
248     cdshape->setTooltip (M ("TP_RETINEX_CURVEEDITOR_CD_TOOLTIP"));
249     cdshape->setBottomBarBgGradient (milestones22);
250     cdshape->setLeftBarBgGradient (milestones22);
251     curveEditorGD->curveListComplete();
252     equalGrid->attach (*curveEditorGD, 0, 0, 1, 1);
253     curveEditorGD->show();
254 
255     // Histogram equalizer HSL curve
256     curveEditorGDH = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_CONTEDIT_HSL"));
257     setExpandAlignProperties (curveEditorGDH, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
258     curveEditorGDH->setCurveListener (this);
259     std::vector<GradientMilestone> milestones22H;
260     milestones22H.push_back ( GradientMilestone (0., 0., 0., 0.) );
261     milestones22H.push_back ( GradientMilestone (1., 1., 1., 1.) );
262     cdshapeH = static_cast<DiagonalCurveEditor*> (curveEditorGDH->addCurve (CT_Diagonal, M ("TP_RETINEX_CURVEEDITOR_CD")));
263     cdshapeH->setTooltip (M ("TP_RETINEX_CURVEEDITOR_CD_TOOLTIP"));
264     cdshapeH->setBottomBarBgGradient (milestones22H);
265     cdshapeH->setLeftBarBgGradient (milestones22H);
266     curveEditorGDH->curveListComplete();
267     equalGrid->attach (*curveEditorGDH, 0, 1, 1, 1);
268     curveEditorGDH->show();
269 
270     // Hue equalizer
271     curveEditorGH = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_CONTEDIT_LH"));
272     setExpandAlignProperties (curveEditorGH, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
273     curveEditorGH->setCurveListener (this);
274     lhshape = static_cast<FlatCurveEditor*> (curveEditorGH->addCurve (CT_Flat, M ("TP_RETINEX_CURVEEDITOR_LH")));
275     lhshape->setTooltip (M ("TP_RETINEX_CURVEEDITOR_LH_TOOLTIP"));
276     lhshape->setCurveColorProvider (this, 4);
277     milestones.clear();
278 
279     for (int i = 0; i < 7; i++) {
280         float R, G, B;
281         float x = float (i) * (1.0f / 6.0);
282         Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B);
283         milestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) );
284     }
285 
286     lhshape->setBottomBarBgGradient (milestones);
287     curveEditorGH->curveListComplete();
288     equalGrid->attach (*curveEditorGH, 0, 2, 1, 1);
289     curveEditorGH->show();
290 
291     // Gamma settings
292     gamgrid = Gtk::manage (new Gtk::Grid ());
293     setExpandAlignProperties (gamgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
294 
295     labgam = Gtk::manage (new Gtk::Label (M ("TP_RETINEX_GAMMA") + ":"));
296     setExpandAlignProperties (labgam, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE);
297     gamgrid->attach (*labgam, 0, 0, 1, 1);
298 
299     gammaretinex = Gtk::manage (new MyComboBoxText ());
300     setExpandAlignProperties (gammaretinex, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE);
301     gammaretinex->append (M ("TP_RETINEX_GAMMA_NONE"));
302     gammaretinex->append (M ("TP_RETINEX_GAMMA_LOW"));
303     gammaretinex->append (M ("TP_RETINEX_GAMMA_MID"));
304     gammaretinex->append (M ("TP_RETINEX_GAMMA_HIGH"));
305     gammaretinex->append (M ("TP_RETINEX_GAMMA_FREE"));
306     gammaretinex->set_active (0);
307     gammaretinexConn = gammaretinex->signal_changed().connect ( sigc::mem_fun (*this, &Retinex::gammaretinexChanged) );
308     gammaretinex->set_tooltip_markup (M ("TP_RETINEX_GAMMA_TOOLTIP"));
309     gamgrid->attach (*gammaretinex, 1, 0, 1, 1);
310     equalGrid->attach (*gamgrid, 0, 3, 1, 1);
311     gammaretinex->show();
312 
313     gam = Gtk::manage (new Adjuster (M ("TP_RETINEX_FREEGAMMA"), 0.6, 3.0, 0.01, 1.30));
314     setExpandAlignProperties (gam, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
315     equalGrid->attach (*gam, 0, 4, 1, 1);
316     gam->show ();
317 
318     slope = Gtk::manage (new Adjuster (M ("TP_RETINEX_SLOPE"), 1., 20., 0.1, 3.));
319     setExpandAlignProperties (slope, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
320     equalGrid->attach (*slope, 0, 5, 1, 1);
321     slope->show ();
322 
323     //-------------
324 
325     equalFrame->add (*equalGrid);
326     settingsGrid->attach (*equalFrame, 0, 3, 1, 1);
327 
328 
329     // TONE MAPPING Frame -------------------------------------------------------------
330 
331 
332     iterFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_ITERF")));
333     setExpandAlignProperties (iterFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
334 //GTK318
335 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
336     iterFrame->set_border_width (5);
337 #endif
338 //GTK318
339 
340     Gtk::Grid *iterGrid = Gtk::manage (new Gtk::Grid());
341     setExpandAlignProperties (iterGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
342 
343     iter   = Gtk::manage (new Adjuster (M ("TP_RETINEX_ITER"), 1, 5., 1., 1.));
344     setExpandAlignProperties (iter, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
345     iter->set_tooltip_markup (M ("TP_RETINEX_ITER_TOOLTIP"));
346     iterGrid->attach (*iter, 0, 0, 1, 1);
347     iter->show ();
348 
349     scal   = Gtk::manage (new Adjuster (M ("TP_RETINEX_SCALES"), -1, 6., 1., 3.));
350     setExpandAlignProperties (scal, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
351     scal->set_tooltip_markup (M ("TP_RETINEX_SCALES_TOOLTIP"));
352     iterGrid->attach (*scal, 0, 1, 1, 1);
353     scal->show ();
354 
355     grad   = Gtk::manage (new Adjuster (M ("TP_RETINEX_GRAD"), -2., 2., 1., 1.));
356     setExpandAlignProperties (grad, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
357     grad->set_tooltip_markup (M ("TP_RETINEX_GRAD_TOOLTIP"));
358     iterGrid->attach (*grad, 0, 2, 1, 1);
359     grad->show ();
360 
361     grads   = Gtk::manage (new Adjuster (M ("TP_RETINEX_GRADS"), -2., 2., 1., 1.));
362     setExpandAlignProperties (grads, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
363     grads->set_tooltip_markup (M ("TP_RETINEX_GRADS_TOOLTIP"));
364     iterGrid->attach (*grads, 0, 3, 1, 1);
365     grads->show ();
366 
367     //-------------
368 
369     iterFrame->add (*iterGrid);
370     settingsGrid->attach (*iterFrame, 0, 4, 1, 1);
371 
372 
373     // TRANSMISSION Frame -------------------------------------------------------------
374 
375 
376     tranFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_TRANF")));
377     setExpandAlignProperties (tranFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
378 //GTK318
379 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
380     tranFrame->set_border_width (5);
381 #endif
382 //GTK318
383 
384     Gtk::Grid *tranGrid = Gtk::manage (new Gtk::Grid());
385     setExpandAlignProperties (tranGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
386 
387     const RetinexParams default_params;
388 
389     // Transmission map curve
390     transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_TRANSMISSION"));
391     setExpandAlignProperties (transmissionCurveEditorG, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
392     transmissionCurveEditorG->setCurveListener (this);
393     transmissionShape = static_cast<FlatCurveEditor*> (transmissionCurveEditorG->addCurve (CT_Flat, "", nullptr, false, false));
394     transmissionShape->setIdentityValue (0.);
395     transmissionShape->setResetCurve (FlatCurveType (default_params.transmissionCurve.at (0)), default_params.transmissionCurve);
396     // transmissionShape->setBottomBarBgGradient(milestones);
397     transmissionCurveEditorG->curveListComplete();
398     transmissionCurveEditorG->set_tooltip_markup (M ("TP_RETINEX_TRANSMISSION_TOOLTIP"));
399     tranGrid->attach ( *transmissionCurveEditorG, 0, 0, 1, 1);
400     transmissionCurveEditorG->show();
401 
402     // Scale
403     skal = Gtk::manage (new Adjuster (M ("TP_RETINEX_SKAL"), 1, 8, 1, 3));
404     setExpandAlignProperties (skal, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
405     tranGrid->attach (*skal, 0, 1, 1, 1);
406     skal->show ();
407 
408     // Threshold
409     limd = Gtk::manage (new Adjuster (M ("TP_RETINEX_THRESHOLD"), 2, 100, 1, 8));
410     setExpandAlignProperties (limd, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
411     limd->set_tooltip_markup (M ("TP_RETINEX_THRESHOLD_TOOLTIP"));
412     tranGrid->attach (*limd, 0, 2, 1, 1);
413     limd->show ();
414 
415     // Transmission median filter
416     medianmap = Gtk::manage (new Gtk::CheckButton (M ("TP_RETINEX_MEDIAN")));
417     setExpandAlignProperties (medianmap, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
418     medianmap->set_active (true);
419     medianmapConn  = medianmap->signal_toggled().connect ( sigc::mem_fun (*this, &Retinex::medianmapChanged) );
420     tranGrid->attach (*medianmap, 0, 3, 1, 1);
421     medianmap->show ();
422 
423     //-------------
424 
425     tranFrame->add (*tranGrid);
426     settingsGrid->attach (*tranFrame, 0, 5, 1, 1);
427 
428 
429     // GAIN AND OFFSET Frame ----------------------------------------------------------
430 
431 
432     gainFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_GAINOFFS")));
433     setExpandAlignProperties (gainFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
434 //GTK318
435 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
436     gainFrame->set_border_width (5);
437 #endif
438 //GTK318
439 
440     Gtk::Grid *gainGrid = Gtk::manage (new Gtk::Grid());
441     setExpandAlignProperties (gainGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
442 
443     // Gain Transmission map curve
444     gaintransmissionCurve = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_GAINTRANSMISSION"));
445     setExpandAlignProperties (gaintransmissionCurve, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
446     gaintransmissionCurve->setCurveListener (this);
447     gaintransmissionShape = static_cast<FlatCurveEditor*> (gaintransmissionCurve->addCurve (CT_Flat, "", nullptr, false, false));
448     gaintransmissionShape->setIdentityValue (0.);
449     gaintransmissionShape->setResetCurve (FlatCurveType (default_params.gaintransmissionCurve.at (0)), default_params.gaintransmissionCurve);
450     //gaintransmissionShape->setBottomBarBgGradient(milestones);
451     gaintransmissionCurve->set_tooltip_markup (M ("TP_RETINEX_GAINTRANSMISSION_TOOLTIP"));
452     gaintransmissionCurve->curveListComplete();
453 
454     gainGrid->attach ( *gaintransmissionCurve, 0, 0, 1, 1);
455     gaintransmissionCurve->show();
456 
457     offs   = Gtk::manage (new Adjuster (M ("TP_RETINEX_OFFSET"), -1000, 5000, 1, 0));
458     setExpandAlignProperties (offs, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
459     gainGrid->attach (*offs, 0, 1, 1, 1);
460     offs->show ();
461 
462     gainFrame->add (*gainGrid);
463     settingsGrid->attach (*gainFrame, 0, 6, 1, 1);
464 
465     expsettings->add (*settingsGrid, false);
466     expsettings->setLevel (2);
467     pack_start (*expsettings);
468 
469     // End of SETTINGS Expander =======================================================
470 
471     // Reset button
472 
473     neutral = Gtk::manage (new Gtk::Button (M ("TP_RETINEX_NEUTRAL")));
474     setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
475     RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png"));
476     setExpandAlignProperties (resetImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
477     neutral->set_image (*resetImg);
478     neutral->set_tooltip_text (M ("TP_RETINEX_NEUTRAL_TIP"));
479     neutralconn = neutral->signal_pressed().connect ( sigc::mem_fun (*this, &Retinex::neutral_pressed) );
480     neutral->show();
481 
482     //-------------
483 
484     pack_start (*neutral);
485 
486 
487     // Setting Adjusters'delay
488 
489 
490     str->setAdjusterListener (this);
491 
492     if (str->delay < 200) {
493         str->delay = 200;
494     }
495 
496     scal->setAdjusterListener (this);
497 
498     if (scal->delay < 200) {
499         scal->delay = 200;
500     }
501 
502     iter->setAdjusterListener (this);
503 
504     if (iter->delay < 200) {
505         iter->delay = 200;
506     }
507 
508     grad->setAdjusterListener (this);
509 
510     if (grad->delay < 200) {
511         grad->delay = 200;
512     }
513 
514     grads->setAdjusterListener (this);
515 
516     if (grads->delay < 200) {
517         grads->delay = 200;
518     }
519 
520     gam->setAdjusterListener (this);
521 
522     if (gam->delay < 500) {
523         gam->delay = 500;
524     }
525 
526     slope->setAdjusterListener (this);
527 
528     if (slope->delay < 500) {
529         slope->delay = 500;
530     }
531 
532     neigh->setAdjusterListener (this);
533 
534     if (neigh->delay < 200) {
535         neigh->delay = 200;
536     }
537 
538     offs->setAdjusterListener (this);
539 
540     if (offs->delay < 200) {
541         offs->delay = 200;
542     }
543 
544     vart->setAdjusterListener (this);
545 
546     if (vart->delay < 200) {
547         vart->delay = 200;
548     }
549 
550     limd->setAdjusterListener (this);
551 
552     if (limd->delay < 200) {
553         limd->delay = 200;
554     }
555 
556     highl->setAdjusterListener (this);
557 
558     if (highl->delay < 200) {
559         highl->delay = 200;
560     }
561 
562     radius->setAdjusterListener (this);
563 
564     if (radius->delay < 200) {
565         radius->delay = 200;
566     }
567 
568     highlights->setAdjusterListener (this);
569 
570     if (highlights->delay < 200) {
571         highlights->delay = 200;
572     }
573 
574     h_tonalwidth->setAdjusterListener (this);
575 
576     if (h_tonalwidth->delay < 200) {
577         h_tonalwidth->delay = 200;
578     }
579 
580     shadows->setAdjusterListener (this);
581 
582     if (shadows->delay < 200) {
583         shadows->delay = 200;
584     }
585 
586     s_tonalwidth->setAdjusterListener (this);
587 
588     if (s_tonalwidth->delay < 200) {
589         s_tonalwidth->delay = 200;
590     }
591 
592     skal->setAdjusterListener (this);
593 
594     if (skal->delay < 200) {
595         skal->delay = 200;
596     }
597 
598     disableListener();
599     retinexColorSpaceChanged();
600     gammaretinexChanged();
601     medianmapChanged();
602     enableListener();
603 
604 }
605 
~Retinex()606 Retinex::~Retinex()
607 {
608     idle_register.destroy();
609 
610     delete curveEditorGD;
611     delete curveEditorGDH;
612     delete transmissionCurveEditorG;
613     delete gaintransmissionCurve;
614     delete curveEditorGH;
615     delete curveEditormap;
616 
617 }
neutral_pressed()618 void Retinex::neutral_pressed ()
619 {
620     neigh->resetValue (false);
621     offs->resetValue (false);
622     str->resetValue (false);
623     scal->resetValue (false);
624     iter->resetValue (false);
625     grad->resetValue (false);
626     grads->resetValue (false);
627     vart->resetValue (false);
628     limd->resetValue (false);
629     highl->resetValue (false);
630     gam->resetValue (false);
631     slope->resetValue (false);
632     highlights->resetValue (false);
633     h_tonalwidth->resetValue (false);
634     shadows->resetValue (false);
635     s_tonalwidth->resetValue (false);
636     radius->resetValue (false);
637     mapMethod->set_active (0);
638     viewMethod->set_active (0);
639     retinexMethod->set_active (2);
640     retinexcolorspace->set_active (0);
641     gammaretinex->set_active (0);
642     transmissionShape->reset();
643     gaintransmissionShape->reset();
644     cdshape->reset();
645     cdshapeH->reset();
646     lhshape->reset();
647     mapshape->reset();
648 }
649 
foldAllButMe(GdkEventButton * event,MyExpander * expander)650 void Retinex::foldAllButMe (GdkEventButton* event, MyExpander *expander)
651 {
652     if (event->button == 3) {
653         expsettings->set_expanded (expsettings == expander);
654     }
655 }
656 
writeOptions(std::vector<int> & tpOpen)657 void Retinex::writeOptions (std::vector<int> &tpOpen)
658 {
659     tpOpen.push_back (expsettings->get_expanded ());
660 }
661 
updateToolState(std::vector<int> & tpOpen)662 void Retinex::updateToolState (std::vector<int> &tpOpen)
663 {
664     if (tpOpen.size() >= 10) {
665         expsettings->set_expanded (tpOpen.at (9));
666     }
667 }
668 
minmaxChanged(double cdma,double cdmin,double mini,double maxi,double Tmean,double Tsigma,double Tmin,double Tmax)669 void Retinex::minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax)
670 {
671     nextmin = cdmin;
672     nextmax = cdma;
673     nextminiT = mini;
674     nextmaxiT = maxi;
675     nextmeanT = Tmean;
676     nextsigma = Tsigma;
677     nextminT = Tmin;
678     nextmaxT = Tmax;
679 
680     idle_register.add(
681         [this]() -> bool
682         {
683             GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
684             // FIXME: The above can't be true?!
685             disableListener();
686             enableListener();
687             updateLabel();
688             updateTrans();
689             return false;
690         }
691     );
692 }
693 
updateLabel()694 void Retinex::updateLabel ()
695 {
696     if (!batchMode) {
697         float nX, nY;
698         nX = nextmin;
699         nY = nextmax;
700         {
701             mMLabels->set_text (
702                 Glib::ustring::compose (M ("TP_RETINEX_MLABEL"),
703                                         Glib::ustring::format (std::fixed, std::setprecision (0), nX),
704                                         Glib::ustring::format (std::fixed, std::setprecision (0), nY))
705             );
706         }
707     }
708 }
709 
updateTrans()710 void Retinex::updateTrans ()
711 {
712     if (!batchMode) {
713         float nm, nM, nZ, nA, nB, nS;
714         nm = nextminiT;
715         nM = nextmaxiT;
716         nZ = nextmeanT;
717         nA = nextminT;
718         nB = nextmaxT;
719         nS = nextsigma;
720         {
721             transLabels->set_text (
722                 Glib::ustring::compose (M ("TP_RETINEX_TLABEL"),
723                                         Glib::ustring::format (std::fixed, std::setprecision (1), nm),
724                                         Glib::ustring::format (std::fixed, std::setprecision (1), nM),
725                                         Glib::ustring::format (std::fixed, std::setprecision (1), nZ),
726                                         Glib::ustring::format (std::fixed, std::setprecision (1), nS))
727             );
728             transLabels2->set_text (
729                 Glib::ustring::compose (M ("TP_RETINEX_TLABEL2"),
730                                         Glib::ustring::format (std::fixed, std::setprecision (1), nA),
731                                         Glib::ustring::format (std::fixed, std::setprecision (1), nB))
732             );
733 
734 
735         }
736     }
737 }
738 
739 
740 
read(const ProcParams * pp,const ParamsEdited * pedited)741 void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
742 {
743     disableListener ();
744     retinexMethodConn.block (true);
745     retinexColorSpaceConn.block (true);
746     gammaretinexConn.block (true);
747     mapMethodConn.block (true);
748     viewMethodConn.block (true);
749 
750 
751     if (pedited) {
752         scal->setEditedState (pedited->retinex.scal ? Edited : UnEdited);
753         iter->setEditedState (pedited->retinex.iter ? Edited : UnEdited);
754         grad->setEditedState (pedited->retinex.grad ? Edited : UnEdited);
755         grads->setEditedState (pedited->retinex.grads ? Edited : UnEdited);
756         neigh->setEditedState (pedited->retinex.neigh ? Edited : UnEdited);
757         gam->setEditedState (pedited->retinex.gam ? Edited : UnEdited);
758         slope->setEditedState (pedited->retinex.slope ? Edited : UnEdited);
759         offs->setEditedState (pedited->retinex.offs ? Edited : UnEdited);
760         vart->setEditedState (pedited->retinex.vart ? Edited : UnEdited);
761         limd->setEditedState (pedited->retinex.limd ? Edited : UnEdited);
762         highl->setEditedState (pedited->retinex.highl ? Edited : UnEdited);
763         skal->setEditedState (pedited->retinex.skal ? Edited : UnEdited);
764         set_inconsistent (multiImage && !pedited->retinex.enabled);
765         medianmap->set_inconsistent (!pedited->retinex.medianmap);
766         radius->setEditedState       (pedited->retinex.radius ? Edited : UnEdited);
767         highlights->setEditedState   (pedited->retinex.highlights ? Edited : UnEdited);
768         h_tonalwidth->setEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited);
769         shadows->setEditedState      (pedited->retinex.shadows ? Edited : UnEdited);
770         s_tonalwidth->setEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited);
771 
772 
773         if (!pedited->retinex.retinexMethod) {
774             retinexMethod->set_active_text (M ("GENERAL_UNCHANGED"));
775         }
776 
777         if (!pedited->retinex.mapMethod) {
778             mapMethod->set_active_text (M ("GENERAL_UNCHANGED"));
779         }
780 
781         if (!pedited->retinex.viewMethod) {
782             viewMethod->set_active_text (M ("GENERAL_UNCHANGED"));
783         }
784 
785         if (!pedited->retinex.retinexcolorspace) {
786             retinexcolorspace->set_active_text (M ("GENERAL_UNCHANGED"));
787         }
788 
789         if (!pedited->retinex.gammaretinex) {
790             gammaretinex->set_active_text (M ("GENERAL_UNCHANGED"));
791         }
792 
793         cdshape->setUnChanged  (!pedited->retinex.cdcurve);
794         cdshapeH->setUnChanged  (!pedited->retinex.cdHcurve);
795         transmissionShape->setUnChanged (!pedited->retinex.transmissionCurve);
796         gaintransmissionShape->setUnChanged (!pedited->retinex.gaintransmissionCurve);
797         lhshape->setUnChanged  (!pedited->retinex.lhcurve);
798         mapshape->setUnChanged  (!pedited->retinex.mapcurve);
799 
800     }
801 
802     neigh->setValue    (pp->retinex.neigh);
803     offs->setValue  (pp->retinex.offs);
804     str->setValue    (pp->retinex.str);
805     scal->setValue      (pp->retinex.scal);
806     iter->setValue      (pp->retinex.iter);
807     grad->setValue      (pp->retinex.grad);
808     grads->setValue      (pp->retinex.grads);
809     vart->setValue  (pp->retinex.vart);
810     limd->setValue  (pp->retinex.limd);
811     gam->setValue      (pp->retinex.gam);
812     slope->setValue      (pp->retinex.slope);
813     highl->setValue  (pp->retinex.highl);
814 
815     radius->setValue        (pp->retinex.radius);
816     highlights->setValue    (pp->retinex.highlights);
817     h_tonalwidth->setValue  (pp->retinex.htonalwidth);
818     shadows->setValue       (pp->retinex.shadows);
819     s_tonalwidth->setValue  (pp->retinex.stonalwidth);
820 
821     skal->setValue  (pp->retinex.skal);
822 
823     if (!batchMode) {
824         if (pp->retinex.iter == 1)   {
825             grad->set_sensitive (false);
826             scal->set_sensitive (false);
827             grads->set_sensitive (false);
828         } else {
829             grad->set_sensitive (true);
830             scal->set_sensitive (true);
831             grads->set_sensitive (true);
832         }
833     }
834 
835     setEnabled (pp->retinex.enabled);
836 
837     medianmap->set_active (pp->retinex.medianmap);
838     medianmapConn.block (false);
839     lastmedianmap = pp->retinex.medianmap;
840 
841     if (pp->retinex.retinexMethod == "low") {
842         retinexMethod->set_active (0);
843     } else if (pp->retinex.retinexMethod == "uni") {
844         retinexMethod->set_active (1);
845     } else if (pp->retinex.retinexMethod == "high") {
846         retinexMethod->set_active (2);
847     } else if (pp->retinex.retinexMethod == "highli") {
848         retinexMethod->set_active (3);
849 //    } else if (pp->retinex.retinexMethod == "highliplus") {
850 //        retinexMethod->set_active (4);
851     }
852 
853     if (pp->retinex.mapMethod == "none") {
854         mapMethod->set_active (0);
855 //    } else if (pp->retinex.mapMethod == "curv") {
856 //        mapMethod->set_active (1);
857     } else if (pp->retinex.mapMethod == "gaus") {
858         mapMethod->set_active (1);
859     } else if (pp->retinex.mapMethod == "map") {
860         mapMethod->set_active (2);
861     } else if (pp->retinex.mapMethod == "mapT") {
862         mapMethod->set_active (3);
863     }
864 
865     if (pp->retinex.viewMethod == "none") {
866         viewMethod->set_active (0);
867     } else if (pp->retinex.viewMethod == "unsharp") {
868         viewMethod->set_active (1);
869     } else if (pp->retinex.viewMethod == "mask") {
870         viewMethod->set_active (2);
871     } else if (pp->retinex.viewMethod == "tran") {
872         viewMethod->set_active (3);
873     } else if (pp->retinex.viewMethod == "tran2") {
874         viewMethod->set_active (4);
875     }
876 
877     if (pp->retinex.retinexcolorspace == "Lab") {
878         retinexcolorspace->set_active (0);
879     } else if (pp->retinex.retinexcolorspace == "HSLLOG") {
880         retinexcolorspace->set_active (1);
881     } else if (pp->retinex.retinexcolorspace == "HSLLIN") {
882         retinexcolorspace->set_active (2);
883     }
884 
885     if (pp->retinex.gammaretinex == "none") {
886         gammaretinex->set_active (0);
887     } else if (pp->retinex.gammaretinex == "low") {
888         gammaretinex->set_active (1);
889     } else if (pp->retinex.gammaretinex == "mid") {
890         gammaretinex->set_active (2);
891     } else if (pp->retinex.gammaretinex == "hig") {
892         gammaretinex->set_active (3);
893     } else if (pp->retinex.gammaretinex == "fre") {
894         gammaretinex->set_active (4);
895     }
896 
897     retinexMethodChanged ();
898     retinexColorSpaceChanged();
899     gammaretinexChanged();
900     mapMethodChanged ();
901     viewMethodChanged ();
902 
903     medianmapConn.block (true);
904     medianmapChanged ();
905     medianmapConn.block (false);
906 
907     cdshape->setCurve  (pp->retinex.cdcurve);
908     cdshapeH->setCurve  (pp->retinex.cdHcurve);
909     lhshape->setCurve  (pp->retinex.lhcurve);
910     mapshape->setCurve  (pp->retinex.mapcurve);
911 
912     retinexMethodConn.block (false);
913     retinexColorSpaceConn.block (false);
914     gammaretinexConn.block (false);
915     mapMethodConn.block (false);
916     viewMethodConn.block (false);
917     transmissionShape->setCurve (pp->retinex.transmissionCurve);
918     gaintransmissionShape->setCurve (pp->retinex.gaintransmissionCurve);
919 
920 
921     enableListener ();
922 }
923 
924 
925 
write(ProcParams * pp,ParamsEdited * pedited)926 void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
927 {
928 
929     pp->retinex.str    = str->getValue ();
930     pp->retinex.scal      = (int)scal->getValue ();
931     pp->retinex.iter      = (int) iter->getValue ();
932     pp->retinex.grad      = (int) grad->getValue ();
933     pp->retinex.grads      = (int) grads->getValue ();
934     pp->retinex.gam      = gam->getValue ();
935     pp->retinex.slope      = slope->getValue ();
936     pp->retinex.neigh    = neigh->getValue ();
937     pp->retinex.offs  = (int)offs->getValue ();
938     pp->retinex.vart  = (int)vart->getValue ();
939     pp->retinex.limd  = (int)limd->getValue ();
940     pp->retinex.highl  = (int)highl->getValue ();
941     pp->retinex.skal  = (int)skal->getValue ();
942     pp->retinex.cdcurve = cdshape->getCurve ();
943     pp->retinex.lhcurve = lhshape->getCurve ();
944     pp->retinex.cdHcurve = cdshapeH->getCurve ();
945     pp->retinex.mapcurve = mapshape->getCurve ();
946     pp->retinex.transmissionCurve = transmissionShape->getCurve ();
947     pp->retinex.gaintransmissionCurve = gaintransmissionShape->getCurve ();
948     pp->retinex.enabled      = getEnabled();
949     pp->retinex.medianmap                = medianmap->get_active();
950 
951     pp->retinex.radius        = (int)radius->getValue ();
952     pp->retinex.highlights    = (int)highlights->getValue ();
953     pp->retinex.htonalwidth   = (int)h_tonalwidth->getValue ();
954     pp->retinex.shadows       = (int)shadows->getValue ();
955     pp->retinex.stonalwidth   = (int)s_tonalwidth->getValue ();
956 
957     if (pedited) {
958         pedited->retinex.retinexMethod    = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED");
959         pedited->retinex.retinexcolorspace    = retinexcolorspace->get_active_text() != M ("GENERAL_UNCHANGED");
960         pedited->retinex.gammaretinex    = gammaretinex->get_active_text() != M ("GENERAL_UNCHANGED");
961         pedited->retinex.mapMethod    = mapMethod->get_active_text() != M ("GENERAL_UNCHANGED");
962         pedited->retinex.viewMethod    = viewMethod->get_active_text() != M ("GENERAL_UNCHANGED");
963 
964         //%%%%%%%%%%%%%%%%%%%%%%
965         pedited->retinex.str   = str->getEditedState ();
966         pedited->retinex.scal     = scal->getEditedState ();
967         pedited->retinex.iter     = iter->getEditedState ();
968         pedited->retinex.grad     = grad->getEditedState ();
969         pedited->retinex.grads     = grads->getEditedState ();
970         pedited->retinex.gam     = gam->getEditedState ();
971         pedited->retinex.slope     = slope->getEditedState ();
972         pedited->retinex.neigh   = neigh->getEditedState ();
973         pedited->retinex.offs = offs->getEditedState ();
974         pedited->retinex.vart = vart->getEditedState ();
975         pedited->retinex.limd = limd->getEditedState ();
976         pedited->retinex.highl = highl->getEditedState ();
977         pedited->retinex.skal = skal->getEditedState ();
978         pedited->retinex.cdcurve   = !cdshape->isUnChanged ();
979         pedited->retinex.cdHcurve   = !cdshapeH->isUnChanged ();
980         pedited->retinex.transmissionCurve  = !transmissionShape->isUnChanged ();
981         pedited->retinex.gaintransmissionCurve  = !gaintransmissionShape->isUnChanged ();
982         pedited->retinex.mapcurve   = !mapshape->isUnChanged ();
983         pedited->retinex.enabled       = !get_inconsistent();
984         pedited->retinex.medianmap       = !medianmap->get_inconsistent();
985         pedited->retinex.lhcurve   = !lhshape->isUnChanged ();
986 
987         pedited->retinex.radius          = radius->getEditedState ();
988         pedited->retinex.highlights      = highlights->getEditedState ();
989         pedited->retinex.htonalwidth     = h_tonalwidth->getEditedState ();
990         pedited->retinex.shadows         = shadows->getEditedState ();
991         pedited->retinex.stonalwidth     = s_tonalwidth->getEditedState ();
992 
993     }
994 
995     if (retinexMethod->get_active_row_number() == 0) {
996         pp->retinex.retinexMethod = "low";
997     } else if (retinexMethod->get_active_row_number() == 1) {
998         pp->retinex.retinexMethod = "uni";
999     } else if (retinexMethod->get_active_row_number() == 2) {
1000         pp->retinex.retinexMethod = "high";
1001     } else if (retinexMethod->get_active_row_number() == 3) {
1002         pp->retinex.retinexMethod = "highli";
1003 //    } else if (retinexMethod->get_active_row_number() == 4) {
1004 //        pp->retinex.retinexMethod = "highliplus";
1005     }
1006 
1007     if (mapMethod->get_active_row_number() == 0) {
1008         pp->retinex.mapMethod = "none";
1009 //   } else if (mapMethod->get_active_row_number() == 1) {
1010 //       pp->retinex.mapMethod = "curv";
1011     } else if (mapMethod->get_active_row_number() == 1) {
1012         pp->retinex.mapMethod = "gaus";
1013     } else if (mapMethod->get_active_row_number() == 2) {
1014         pp->retinex.mapMethod = "map";
1015     } else if (mapMethod->get_active_row_number() == 3) {
1016         pp->retinex.mapMethod = "mapT";
1017     }
1018 
1019     if (viewMethod->get_active_row_number() == 0) {
1020         pp->retinex.viewMethod = "none";
1021     } else if (viewMethod->get_active_row_number() == 1) {
1022         pp->retinex.viewMethod = "unsharp";
1023     } else if (viewMethod->get_active_row_number() == 2) {
1024         pp->retinex.viewMethod = "mask";
1025     } else if (viewMethod->get_active_row_number() == 3) {
1026         pp->retinex.viewMethod = "tran";
1027     } else if (viewMethod->get_active_row_number() == 4) {
1028         pp->retinex.viewMethod = "tran2";
1029     }
1030 
1031     if (retinexcolorspace->get_active_row_number() == 0) {
1032         pp->retinex.retinexcolorspace = "Lab";
1033     } else if (retinexcolorspace->get_active_row_number() == 1) {
1034         pp->retinex.retinexcolorspace = "HSLLOG";
1035     } else if (retinexcolorspace->get_active_row_number() == 2) {
1036         pp->retinex.retinexcolorspace = "HSLLIN";
1037     }
1038 
1039     if (gammaretinex->get_active_row_number() == 0) {
1040         pp->retinex.gammaretinex = "none";
1041     } else if (gammaretinex->get_active_row_number() == 1) {
1042         pp->retinex.gammaretinex = "low";
1043     } else if (gammaretinex->get_active_row_number() == 2) {
1044         pp->retinex.gammaretinex = "mid";
1045     } else if (gammaretinex->get_active_row_number() == 3) {
1046         pp->retinex.gammaretinex = "hig";
1047     } else if (gammaretinex->get_active_row_number() == 4) {
1048         pp->retinex.gammaretinex = "fre";
1049     }
1050 
1051 }
1052 
retinexMethodChanged()1053 void Retinex::retinexMethodChanged()
1054 {
1055 
1056     if (!batchMode) {
1057         if (retinexMethod->get_active_row_number() == 3) {
1058             highl->show();
1059         } else {
1060             highl->hide();
1061         }
1062     }
1063 
1064     if (listener) {
1065         listener->panelChanged (EvretinexMethod, retinexMethod->get_active_text ());
1066     }
1067 }
1068 
1069 
1070 
mapMethodChanged()1071 void Retinex::mapMethodChanged()
1072 {
1073 
1074     if (!batchMode) {
1075         if (mapMethod->get_active_row_number() == 1  /*|| mapMethod->get_active_row_number() == 2*/) {
1076             curveEditormap->show();
1077             highlights->show();
1078             h_tonalwidth->show();
1079             shadows->show();
1080             s_tonalwidth->show();
1081             radius->show();
1082         } else if (mapMethod->get_active_row_number() == 2  || mapMethod->get_active_row_number() == 3) {
1083             curveEditormap->show();
1084             highlights->show();
1085             h_tonalwidth->show();
1086             shadows->show();
1087             s_tonalwidth->show();
1088             radius->hide();
1089         } else {
1090             curveEditormap->hide();
1091             highlights->hide();
1092             h_tonalwidth->hide();
1093             shadows->hide();
1094             s_tonalwidth->hide();
1095             radius->hide();
1096         }
1097     }
1098 
1099     if (listener) {
1100         listener->panelChanged (EvmapMethod, mapMethod->get_active_text ());
1101     }
1102 }
1103 
viewMethodChanged()1104 void Retinex::viewMethodChanged()
1105 {
1106     if (!batchMode) {
1107         if (viewMethod->get_active_row_number() == 1 || viewMethod->get_active_row_number() == 2) {
1108             //vart->hide();
1109             offs->hide();
1110             limd->hide();
1111             transmissionCurveEditorG->hide();
1112             medianmap->hide();
1113 
1114             iterFrame->hide();
1115             /*
1116             iter->hide();
1117             scal->hide();
1118             grad->hide();
1119             grads->hide();
1120             */
1121 
1122             curveEditorGH->hide();
1123         } else if (viewMethod->get_active_row_number() == 3 || viewMethod->get_active_row_number() == 4) {
1124             offs->hide();
1125             transmissionCurveEditorG->show();
1126             //vart->hide();
1127             curveEditorGH->hide();
1128         } else {
1129             vart->show();
1130             neigh->show();
1131             offs->show();
1132             limd->show();
1133             transmissionCurveEditorG->show();
1134             medianmap->show();
1135 
1136             iterFrame->show();
1137             /*
1138             iter->show();
1139             scal->show();
1140             grad->show();
1141             grads->show();
1142             */
1143 
1144             curveEditorGH->show();
1145         }
1146     }
1147 
1148     if (listener) {
1149         listener->panelChanged (EvviewMethod, viewMethod->get_active_text ());
1150     }
1151 }
1152 
1153 
1154 
ColorSpaceUpdateUI()1155 void Retinex::ColorSpaceUpdateUI ()
1156 {
1157     if (!batchMode) {
1158         curveEditorGH->show();
1159 
1160         if (retinexcolorspace->get_active_row_number() == 0) {
1161             curveEditorGD->show();
1162             curveEditorGDH->hide();
1163         } else if (retinexcolorspace->get_active_row_number() == 1) {
1164             curveEditorGD->hide();
1165             curveEditorGDH->show();
1166         } else if (retinexcolorspace->get_active_row_number() == 2) {
1167             curveEditorGD->hide();
1168             curveEditorGDH->show();
1169         }
1170     }
1171 }
1172 
1173 
retinexColorSpaceChanged()1174 void Retinex::retinexColorSpaceChanged()
1175 {
1176     ColorSpaceUpdateUI();
1177 
1178     if (listener) {
1179         listener->panelChanged (EvretinexColorSpace, retinexcolorspace->get_active_text ());
1180     }
1181 }
1182 
gammaretinexChanged()1183 void Retinex::gammaretinexChanged()
1184 {
1185     if (!batchMode) {
1186         if (gammaretinex->get_active_row_number() == 4) {
1187             gam->show();
1188             slope->show();
1189         } else { /*if(gammaretinex->get_active_row_number() != 4)*/
1190             gam->hide();
1191             slope->hide();
1192         }
1193     }
1194 
1195     ColorSpaceUpdateUI();
1196 
1197     if (listener) {
1198         listener->panelChanged (Evretinexgamma, gammaretinex->get_active_text ());
1199     }
1200 }
1201 
medianmapChanged()1202 void Retinex::medianmapChanged ()
1203 {
1204     if (batchMode) {
1205         if (medianmap->get_inconsistent()) {
1206             medianmap->set_inconsistent (false);
1207             medianmapConn.block (true);
1208             medianmap->set_active (false);
1209             medianmapConn.block (false);
1210         } else if (lastmedianmap) {
1211             medianmap->set_inconsistent (true);
1212         }
1213 
1214         lastmedianmap = medianmap->get_active ();
1215     }
1216 
1217     if (listener) {
1218         if (medianmap->get_active()) {
1219             if (getEnabled()) {
1220                 listener->panelChanged (EvRetinexmedianmap, M ("GENERAL_ENABLED"));
1221             }
1222         } else {
1223             if (getEnabled()) {
1224                 listener->panelChanged (EvRetinexmedianmap, M ("GENERAL_DISABLED"));
1225             }
1226         }
1227 
1228     }
1229 }
1230 
1231 
setDefaults(const ProcParams * defParams,const ParamsEdited * pedited)1232 void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
1233 {
1234 
1235     neigh->setDefault (defParams->retinex.neigh);
1236     offs->setDefault (defParams->retinex.offs);
1237     str->setDefault (defParams->retinex.str);
1238     scal->setDefault (defParams->retinex.scal);
1239     iter->setDefault (defParams->retinex.iter);
1240     grad->setDefault (defParams->retinex.grad);
1241     grads->setDefault (defParams->retinex.grads);
1242     vart->setDefault (defParams->retinex.vart);
1243     limd->setDefault (defParams->retinex.limd);
1244     highl->setDefault (defParams->retinex.highl);
1245     skal->setDefault (defParams->retinex.skal);
1246     gam->setDefault (defParams->retinex.gam);
1247     slope->setDefault (defParams->retinex.slope);
1248 
1249     radius->setDefault (defParams->retinex.radius);
1250     highlights->setDefault (defParams->retinex.highlights);
1251     h_tonalwidth->setDefault (defParams->retinex.htonalwidth);
1252     shadows->setDefault (defParams->retinex.shadows);
1253     s_tonalwidth->setDefault (defParams->retinex.stonalwidth);
1254 
1255     if (pedited) {
1256         neigh->setDefaultEditedState (pedited->retinex.neigh ? Edited : UnEdited);
1257         offs->setDefaultEditedState (pedited->retinex.offs ? Edited : UnEdited);
1258         str->setDefaultEditedState (pedited->retinex.str ? Edited : UnEdited);
1259         scal->setDefaultEditedState (pedited->retinex.scal ? Edited : UnEdited);
1260         iter->setDefaultEditedState (pedited->retinex.iter ? Edited : UnEdited);
1261         grad->setDefaultEditedState (pedited->retinex.grad ? Edited : UnEdited);
1262         grads->setDefaultEditedState (pedited->retinex.grads ? Edited : UnEdited);
1263         vart->setDefaultEditedState (pedited->retinex.vart ? Edited : UnEdited);
1264         limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited);
1265         highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited);
1266         skal->setDefaultEditedState (pedited->retinex.skal ? Edited : UnEdited);
1267         gam->setDefaultEditedState (pedited->retinex.gam ? Edited : UnEdited);
1268         slope->setDefaultEditedState (pedited->retinex.slope ? Edited : UnEdited);
1269 
1270         radius->setDefaultEditedState       (pedited->retinex.radius ? Edited : UnEdited);
1271         highlights->setDefaultEditedState   (pedited->retinex.highlights ? Edited : UnEdited);
1272         h_tonalwidth->setDefaultEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited);
1273         shadows->setDefaultEditedState      (pedited->retinex.shadows ? Edited : UnEdited);
1274         s_tonalwidth->setDefaultEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited);
1275 
1276     } else {
1277         neigh->setDefaultEditedState (Irrelevant);
1278         offs->setDefaultEditedState (Irrelevant);
1279         vart->setDefaultEditedState (Irrelevant);
1280         limd->setDefaultEditedState (Irrelevant);
1281         highl->setDefaultEditedState (Irrelevant);
1282         skal->setDefaultEditedState (Irrelevant);
1283         str->setDefaultEditedState (Irrelevant);
1284         scal->setDefaultEditedState (Irrelevant);
1285         iter->setDefaultEditedState (Irrelevant);
1286         grad->setDefaultEditedState (Irrelevant);
1287         grads->setDefaultEditedState (Irrelevant);
1288         gam->setDefaultEditedState (Irrelevant);
1289         slope->setDefaultEditedState (Irrelevant);
1290 
1291         radius->setDefaultEditedState       (Irrelevant);
1292         highlights->setDefaultEditedState   (Irrelevant);
1293         h_tonalwidth->setDefaultEditedState (Irrelevant);
1294         shadows->setDefaultEditedState      (Irrelevant);
1295         s_tonalwidth->setDefaultEditedState (Irrelevant);
1296 
1297     }
1298 }
1299 
setAdjusterBehavior(bool strAdd,bool neighAdd,bool limdAdd,bool offsAdd,bool vartAdd,bool gamAdd,bool slopeAdd)1300 void Retinex::setAdjusterBehavior (bool strAdd, bool neighAdd, bool limdAdd, bool offsAdd, bool vartAdd, bool gamAdd, bool slopeAdd)
1301 {
1302     str->setAddMode (strAdd);
1303     neigh->setAddMode (neighAdd);
1304     limd->setAddMode (limdAdd);
1305     offs->setAddMode (offsAdd);
1306     vart->setAddMode (vartAdd);
1307     gam->setAddMode (gamAdd);
1308     slope->setAddMode (slopeAdd);
1309 }
1310 
1311 
adjusterChanged(Adjuster * a,double newval)1312 void Retinex::adjusterChanged(Adjuster* a, double newval)
1313 {
1314     if (a == iter && !batchMode) {
1315         if (iter->getIntValue() > 1) {
1316             scal->set_sensitive (true);
1317             grad->set_sensitive (true);
1318             grads->set_sensitive (true);
1319         } else {
1320             scal->set_sensitive (false);
1321             grad->set_sensitive (false);
1322             grads->set_sensitive (false);
1323         }
1324     }
1325 
1326     if (!listener || !getEnabled()) {
1327         return;
1328     }
1329 
1330     if (a == neigh) {
1331         listener->panelChanged (EvLneigh, neigh->getTextValue());
1332     } else if (a == str) {
1333         listener->panelChanged (EvLstr, str->getTextValue());
1334     } else if (a == scal) {
1335         listener->panelChanged (EvLscal, scal->getTextValue());
1336     } else if (a == iter) {
1337         listener->panelChanged (EvLiter, iter->getTextValue());
1338     } else if (a == grad) {
1339         listener->panelChanged (EvLgrad, grad->getTextValue());
1340     } else if (a == grads) {
1341         listener->panelChanged (EvLgrads, grads->getTextValue());
1342     } else if (a == offs) {
1343         listener->panelChanged (EvLoffs, offs->getTextValue());
1344     } else if (a == vart) {
1345         listener->panelChanged (EvLvart, vart->getTextValue());
1346     } else if (a == limd) {
1347         listener->panelChanged (EvLlimd, limd->getTextValue());
1348     } else if (a == highl) {
1349         listener->panelChanged (EvLhighl, highl->getTextValue());
1350     } else if (a == skal) {
1351         listener->panelChanged (EvLskal, skal->getTextValue());
1352     } else if (a == gam) {
1353         listener->panelChanged (EvLgam, gam->getTextValue());
1354     } else if (a == slope) {
1355         listener->panelChanged (EvLslope, slope->getTextValue());
1356     } else if (a == highlights) {
1357         listener->panelChanged (EvLhighlights, highlights->getTextValue());
1358     } else if (a == h_tonalwidth) {
1359         listener->panelChanged (EvLh_tonalwidth, h_tonalwidth->getTextValue());
1360     } else if (a == shadows) {
1361         listener->panelChanged (EvLshadows, shadows->getTextValue());
1362     } else if (a ==  s_tonalwidth) {
1363         listener->panelChanged (EvLs_tonalwidth,  s_tonalwidth->getTextValue());
1364     } else if (a ==  radius) {
1365         listener->panelChanged (EvLradius,  radius->getTextValue());
1366 
1367     }
1368 }
1369 
autoOpenCurve()1370 void Retinex::autoOpenCurve  ()
1371 {
1372     cdshape->openIfNonlinear();
1373     cdshapeH->openIfNonlinear();
1374     transmissionShape->openIfNonlinear();
1375     gaintransmissionShape->openIfNonlinear();
1376     lhshape->openIfNonlinear();
1377     mapshape->openIfNonlinear();
1378 
1379 }
1380 
1381 
curveChanged(CurveEditor * ce)1382 void Retinex::curveChanged (CurveEditor* ce)
1383 {
1384     if (listener && getEnabled()) {
1385         if (ce == cdshape) {
1386             listener->panelChanged (EvLCDCurve, M ("HISTORY_CUSTOMCURVE"));
1387         } else if (ce == cdshapeH) {
1388             listener->panelChanged (EvLCDHCurve, M ("HISTORY_CUSTOMCURVE"));
1389         } else if (ce == transmissionShape) {
1390             listener->panelChanged (EvRetinextransmission, M ("HISTORY_CUSTOMCURVE"));
1391         } else if (ce == gaintransmissionShape) {
1392             listener->panelChanged (EvRetinexgaintransmission, M ("HISTORY_CUSTOMCURVE"));
1393         } else if (ce == lhshape) {
1394             listener->panelChanged (EvRetinexlhcurve, M ("HISTORY_CUSTOMCURVE"));
1395         } else if (ce == mapshape) {
1396             listener->panelChanged (EvRetinexmapcurve, M ("HISTORY_CUSTOMCURVE"));
1397         }
1398     }
1399 }
1400 
enabledChanged()1401 void Retinex::enabledChanged ()
1402 {
1403 
1404     if (listener) {
1405         if (get_inconsistent()) {
1406             listener->panelChanged (EvRetinexEnabled, M ("GENERAL_UNCHANGED"));
1407         } else if (getEnabled()) {
1408             listener->panelChanged (EvRetinexEnabled, M ("GENERAL_ENABLED"));
1409         } else {
1410             listener->panelChanged (EvRetinexEnabled, M ("GENERAL_DISABLED"));
1411         }
1412     }
1413 }
1414 
1415 
trimValues(rtengine::procparams::ProcParams * pp)1416 void Retinex::trimValues (rtengine::procparams::ProcParams* pp)
1417 {
1418     str->trimValue (pp->retinex.str);
1419     scal->trimValue (pp->retinex.scal);
1420     iter->trimValue (pp->retinex.iter);
1421     grad->trimValue (pp->retinex.grad);
1422     grads->trimValue (pp->retinex.grads);
1423     neigh->trimValue (pp->retinex.neigh);
1424     offs->trimValue (pp->retinex.offs);
1425     vart->trimValue (pp->retinex.vart);
1426     limd->trimValue (pp->retinex.limd);
1427     highl->trimValue (pp->retinex.highl);
1428     gam->trimValue (pp->retinex.gam);
1429     slope->trimValue (pp->retinex.slope);
1430     highlights->trimValue (pp->retinex.highlights);
1431     shadows->trimValue (pp->retinex.shadows);
1432 
1433 
1434 }
1435 
updateCurveBackgroundHistogram(const LUTu & histToneCurve,const LUTu & histLCurve,const LUTu & histCCurve,const LUTu & histLCAM,const LUTu & histCCAM,const LUTu & histRed,const LUTu & histGreen,const LUTu & histBlue,const LUTu & histLuma,const LUTu & histLRETI)1436 void Retinex::updateCurveBackgroundHistogram(
1437     const LUTu& histToneCurve,
1438     const LUTu& histLCurve,
1439     const LUTu& histCCurve,
1440     const LUTu& histLCAM,
1441     const LUTu& histCCAM,
1442     const LUTu& histRed,
1443     const LUTu& histGreen,
1444     const LUTu& histBlue,
1445     const LUTu& histLuma,
1446     const LUTu& histLRETI
1447 )
1448 {
1449     cdshape->updateBackgroundHistogram(histLRETI);
1450     cdshapeH->updateBackgroundHistogram(histLRETI);
1451 }
1452 
colorForValue(double valX,double valY,enum ColorCaller::ElemType elemType,int callerId,ColorCaller * caller)1453 void Retinex::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller)
1454 {
1455 
1456     float R = 0.f, G = 0.f, B = 0.f;
1457 
1458     if (elemType == ColorCaller::CCET_VERTICAL_BAR) {
1459         valY = 0.5;
1460     }
1461 
1462     if (callerId == 1) {         // ch - main curve
1463 
1464         Color::hsv2rgb01 (float (valX), float (valY), 0.5f, R, G, B);
1465     } else if (callerId == 2) {  // cc - bottom bar
1466 
1467         float value = (1.f - 0.7f) * float (valX) + 0.7f;
1468         // whole hue range
1469         // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before)
1470         Color::hsv2rgb01 (float (valY), float (valX), value, R, G, B);
1471     } else if (callerId == 3) {  // lc - bottom bar
1472 
1473         float value = (1.f - 0.7f) * float (valX) + 0.7f;
1474 
1475         // whole hue range
1476         // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before)
1477         Color::hsv2rgb01 (float (valY), float (valX), value, R, G, B);
1478     } else if (callerId == 4) {  // LH - bottom bar
1479         Color::hsv2rgb01 (float (valX), 0.5f, float (valY), R, G, B);
1480     } else if (callerId == 5) {  // HH - bottom bar
1481         float h = float ((valY - 0.5) * 0.3 + valX);
1482 
1483         if (h > 1.0f) {
1484             h -= 1.0f;
1485         } else if (h < 0.0f) {
1486             h += 1.0f;
1487         }
1488 
1489         Color::hsv2rgb01 (h, 0.5f, 0.5f, R, G, B);
1490     }
1491 
1492     caller->ccRed = double (R);
1493     caller->ccGreen = double (G);
1494     caller->ccBlue = double (B);
1495 }
1496 
1497 
1498 
setBatchMode(bool batchMode)1499 void Retinex::setBatchMode (bool batchMode)
1500 {
1501     ToolPanel::setBatchMode (batchMode);
1502     neigh->showEditedCB ();
1503     offs->showEditedCB ();
1504     str->showEditedCB ();
1505     scal->showEditedCB ();
1506     iter->showEditedCB ();
1507     grad->showEditedCB ();
1508     grads->showEditedCB ();
1509     gam->showEditedCB ();
1510     slope->showEditedCB ();
1511     vart->showEditedCB ();
1512     limd->showEditedCB ();
1513     highl->showEditedCB ();
1514     radius->showEditedCB ();
1515     highlights->showEditedCB ();
1516     h_tonalwidth->showEditedCB ();
1517     shadows->showEditedCB ();
1518     s_tonalwidth->showEditedCB ();
1519 
1520     skal->showEditedCB ();
1521     curveEditorGD->setBatchMode (batchMode);
1522     curveEditorGDH->setBatchMode (batchMode);
1523     transmissionCurveEditorG->setBatchMode (batchMode);
1524     gaintransmissionCurve->setBatchMode (batchMode);
1525     curveEditorGH->setBatchMode (batchMode);
1526     curveEditormap->setBatchMode (batchMode);
1527 
1528 
1529 }
1530