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