1 /*
2 * This file is part of RawTherapee.
3 *
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
5 *
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <map>
21
22 #include <locale.h>
23
24 #include <glib/gstdio.h>
25 #include <glibmm/fileutils.h>
26 #include <glibmm/miscutils.h>
27 #include <glibmm/keyfile.h>
28
29 #include "color.h"
30 #include "curves.h"
31 #include "procparams.h"
32 #include "utils.h"
33
34 #include "../rtgui/multilangmgr.h"
35 #include "../rtgui/options.h"
36 #include "../rtgui/paramsedited.h"
37 #include "../rtgui/ppversion.h"
38 #include "../rtgui/version.h"
39
40 using namespace std;
41
42 namespace
43 {
44
expandRelativePath(const Glib::ustring & procparams_fname,const Glib::ustring & prefix,Glib::ustring embedded_fname)45 Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Glib::ustring &prefix, Glib::ustring embedded_fname)
46 {
47 if (embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) {
48 return embedded_fname;
49 }
50
51 if (!prefix.empty()) {
52 if (embedded_fname.length() < prefix.length() || embedded_fname.substr(0, prefix.length()) != prefix) {
53 return embedded_fname;
54 }
55
56 embedded_fname = embedded_fname.substr(prefix.length());
57 }
58
59 if (Glib::path_is_absolute(embedded_fname)) {
60 return prefix + embedded_fname;
61 }
62
63 Glib::ustring absPath = prefix + Glib::path_get_dirname(procparams_fname) + G_DIR_SEPARATOR_S + embedded_fname;
64 return absPath;
65 }
66
relativePathIfInside(const Glib::ustring & procparams_fname,bool fnameAbsolute,Glib::ustring embedded_fname)67 Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname)
68 {
69 if (fnameAbsolute || embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) {
70 return embedded_fname;
71 }
72
73 Glib::ustring prefix;
74
75 if (embedded_fname.length() > 5 && embedded_fname.substr(0, 5) == "file:") {
76 embedded_fname = embedded_fname.substr(5);
77 prefix = "file:";
78 }
79
80 if (!Glib::path_is_absolute(embedded_fname)) {
81 return prefix + embedded_fname;
82 }
83
84 Glib::ustring dir1 = Glib::path_get_dirname(procparams_fname) + G_DIR_SEPARATOR_S;
85 Glib::ustring dir2 = Glib::path_get_dirname(embedded_fname) + G_DIR_SEPARATOR_S;
86
87 if (dir2.substr(0, dir1.length()) != dir1) {
88 // it's in a different directory, ie not inside
89 return prefix + embedded_fname;
90 }
91
92 return prefix + embedded_fname.substr(dir1.length());
93 }
94
getFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,int & value)95 void getFromKeyfile(
96 const Glib::KeyFile& keyfile,
97 const Glib::ustring& group_name,
98 const Glib::ustring& key,
99 int& value
100 )
101 {
102 value = keyfile.get_integer(group_name, key);
103 }
104
getFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,double & value)105 void getFromKeyfile(
106 const Glib::KeyFile& keyfile,
107 const Glib::ustring& group_name,
108 const Glib::ustring& key,
109 double& value
110 )
111 {
112 value = keyfile.get_double(group_name, key);
113 }
114
getFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,bool & value)115 void getFromKeyfile(
116 const Glib::KeyFile& keyfile,
117 const Glib::ustring& group_name,
118 const Glib::ustring& key,
119 bool& value
120 )
121 {
122 value = keyfile.get_boolean(group_name, key);
123 }
124
getFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,Glib::ustring & value)125 void getFromKeyfile(
126 const Glib::KeyFile& keyfile,
127 const Glib::ustring& group_name,
128 const Glib::ustring& key,
129 Glib::ustring& value
130 )
131 {
132 value = keyfile.get_string(group_name, key);
133 }
134
getFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,std::vector<double> & value)135 void getFromKeyfile(
136 const Glib::KeyFile& keyfile,
137 const Glib::ustring& group_name,
138 const Glib::ustring& key,
139 std::vector<double>& value
140 )
141 {
142 value = keyfile.get_double_list(group_name, key);
143 rtengine::sanitizeCurve(value);
144 }
145
146 template<typename T>
assignFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,bool has_params_edited,T & value,bool & params_edited_value)147 bool assignFromKeyfile(
148 const Glib::KeyFile& keyfile,
149 const Glib::ustring& group_name,
150 const Glib::ustring& key,
151 bool has_params_edited,
152 T& value,
153 bool& params_edited_value
154 )
155 {
156 if (keyfile.has_key(group_name, key)) {
157 getFromKeyfile(keyfile, group_name, key, value);
158
159 if (has_params_edited) {
160 params_edited_value = true;
161 }
162
163 return true;
164 }
165
166 return false;
167 }
168
169 template<typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
assignFromKeyfile(const Glib::KeyFile & keyfile,const Glib::ustring & group_name,const Glib::ustring & key,bool has_params_edited,const std::map<std::string,T> & mapping,T & value,bool & params_edited_value)170 bool assignFromKeyfile(
171 const Glib::KeyFile& keyfile,
172 const Glib::ustring& group_name,
173 const Glib::ustring& key,
174 bool has_params_edited,
175 const std::map<std::string, T>& mapping,
176 T& value,
177 bool& params_edited_value
178 )
179 {
180 if (keyfile.has_key(group_name, key)) {
181 Glib::ustring v;
182 getFromKeyfile(keyfile, group_name, key, v);
183
184 const typename std::map<std::string, T>::const_iterator m = mapping.find(v);
185
186 if (m != mapping.end()) {
187 value = m->second;
188 } else {
189 return false;
190 }
191
192 if (has_params_edited) {
193 params_edited_value = true;
194 }
195
196 return true;
197 }
198
199 return false;
200 }
201
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,int value,Glib::KeyFile & keyfile)202 void putToKeyfile(
203 const Glib::ustring& group_name,
204 const Glib::ustring& key,
205 int value,
206 Glib::KeyFile& keyfile
207 )
208 {
209 keyfile.set_integer(group_name, key, value);
210 }
211
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,double value,Glib::KeyFile & keyfile)212 void putToKeyfile(
213 const Glib::ustring& group_name,
214 const Glib::ustring& key,
215 double value,
216 Glib::KeyFile& keyfile
217 )
218 {
219 keyfile.set_double(group_name, key, value);
220 }
221
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,bool value,Glib::KeyFile & keyfile)222 void putToKeyfile(
223 const Glib::ustring& group_name,
224 const Glib::ustring& key,
225 bool value,
226 Glib::KeyFile& keyfile
227 )
228 {
229 keyfile.set_boolean(group_name, key, value);
230 }
231
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,const Glib::ustring & value,Glib::KeyFile & keyfile)232 void putToKeyfile(
233 const Glib::ustring& group_name,
234 const Glib::ustring& key,
235 const Glib::ustring& value,
236 Glib::KeyFile& keyfile
237 )
238 {
239 keyfile.set_string(group_name, key, value);
240 }
241
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,const std::vector<int> & value,Glib::KeyFile & keyfile)242 void putToKeyfile(
243 const Glib::ustring& group_name,
244 const Glib::ustring& key,
245 const std::vector<int>& value,
246 Glib::KeyFile& keyfile
247 )
248 {
249 const Glib::ArrayHandle<int> list = value;
250 keyfile.set_integer_list(group_name, key, list);
251 }
252
putToKeyfile(const Glib::ustring & group_name,const Glib::ustring & key,const std::vector<double> & value,Glib::KeyFile & keyfile)253 void putToKeyfile(
254 const Glib::ustring& group_name,
255 const Glib::ustring& key,
256 const std::vector<double>& value,
257 Glib::KeyFile& keyfile
258 )
259 {
260 const Glib::ArrayHandle<double> list = value;
261 keyfile.set_double_list(group_name, key, list);
262 }
263
264 template<typename T>
saveToKeyfile(bool save,const Glib::ustring & group_name,const Glib::ustring & key,const T & value,Glib::KeyFile & keyfile)265 bool saveToKeyfile(
266 bool save,
267 const Glib::ustring& group_name,
268 const Glib::ustring& key,
269 const T& value,
270 Glib::KeyFile& keyfile
271 )
272 {
273 if (save) {
274 putToKeyfile(group_name, key, value, keyfile);
275 return true;
276 }
277
278 return false;
279 }
280
281 template<typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
saveToKeyfile(bool save,const Glib::ustring & group_name,const Glib::ustring & key,const std::map<T,const char * > & mapping,const T & value,Glib::KeyFile & keyfile)282 bool saveToKeyfile(
283 bool save,
284 const Glib::ustring& group_name,
285 const Glib::ustring& key,
286 const std::map<T, const char*>& mapping,
287 const T& value,
288 Glib::KeyFile& keyfile
289 )
290 {
291 if (save) {
292 const typename std::map<T, const char*>::const_iterator m = mapping.find(value);
293
294 if (m != mapping.end()) {
295 keyfile.set_string(group_name, key, m->second);
296 return true;
297 }
298 }
299
300 return false;
301 }
302
303 }
304
305 namespace rtengine
306 {
307
308 namespace procparams
309 {
310
ToneCurveParams()311 ToneCurveParams::ToneCurveParams() :
312 autoexp(false),
313 clip(0.02),
314 hrenabled(false),
315 method("Blend"),
316 expcomp(0),
317 curve{
318 DCT_Linear
319 },
320 curve2{
321 DCT_Linear
322 },
323 curveMode(ToneCurveMode::STD),
324 curveMode2(ToneCurveMode::STD),
325 brightness(0),
326 black(0),
327 contrast(0),
328 saturation(0),
329 shcompr(50),
330 hlcompr(0),
331 hlcomprthresh(0),
332 histmatching(false),
333 fromHistMatching(false),
334 clampOOG(true)
335 {
336 }
337
isPanningRelatedChange(const ToneCurveParams & other) const338 bool ToneCurveParams::isPanningRelatedChange(const ToneCurveParams& other) const
339 {
340 return !
341 (autoexp == other.autoexp
342 && clip == other.clip
343 && hrenabled == other.hrenabled
344 && method == other.method
345 && expcomp == other.expcomp
346 && curve == other.curve
347 && curve2 == other.curve2
348 && curveMode == other.curveMode
349 && curveMode2 == other.curveMode2
350 && brightness == other.brightness
351 && black == other.black
352 && contrast == other.contrast
353 && saturation == other.saturation
354 && shcompr == other.shcompr
355 && hlcompr == other.hlcompr
356 && hlcomprthresh == other.hlcomprthresh
357 && histmatching == other.histmatching
358 && clampOOG == other.clampOOG);
359 }
360
operator ==(const ToneCurveParams & other) const361 bool ToneCurveParams::operator ==(const ToneCurveParams& other) const
362 {
363 return
364 autoexp == other.autoexp
365 && clip == other.clip
366 && hrenabled == other.hrenabled
367 && method == other.method
368 && expcomp == other.expcomp
369 && curve == other.curve
370 && curve2 == other.curve2
371 && curveMode == other.curveMode
372 && curveMode2 == other.curveMode2
373 && brightness == other.brightness
374 && black == other.black
375 && contrast == other.contrast
376 && saturation == other.saturation
377 && shcompr == other.shcompr
378 && hlcompr == other.hlcompr
379 && hlcomprthresh == other.hlcomprthresh
380 && histmatching == other.histmatching
381 && fromHistMatching == other.fromHistMatching
382 && clampOOG == other.clampOOG;
383 }
384
operator !=(const ToneCurveParams & other) const385 bool ToneCurveParams::operator !=(const ToneCurveParams& other) const
386 {
387 return !(*this == other);
388 }
389
RetinexParams()390 RetinexParams::RetinexParams() :
391 enabled(false),
392 cdcurve{
393 DCT_Linear
394 },
395 cdHcurve{
396 DCT_Linear
397 },
398 lhcurve{
399 DCT_Linear
400 },
401 transmissionCurve{
402 FCT_MinMaxCPoints,
403 0.00,
404 0.50,
405 0.35,
406 0.35,
407 0.60,
408 0.75,
409 0.35,
410 0.35,
411 1.00,
412 0.50,
413 0.35,
414 0.35
415 },
416 gaintransmissionCurve{
417 FCT_MinMaxCPoints,
418 0.00,
419 0.1,
420 0.35,
421 0.00,
422 0.25,
423 0.25,
424 0.35,
425 0.35,
426 0.70,
427 0.25,
428 0.35,
429 0.35,
430 1.00,
431 0.1,
432 0.00,
433 0.00
434 },
435 mapcurve{
436 DCT_Linear
437 },
438 str(20),
439 scal(3),
440 iter(1),
441 grad(1),
442 grads(1),
443 gam(1.30),
444 slope(3.),
445 neigh(80),
446 offs(0),
447 highlights(0),
448 htonalwidth(80),
449 shadows(0),
450 stonalwidth(80),
451 radius(40),
452 retinexMethod("high"),
453 retinexcolorspace("Lab"),
454 gammaretinex("none"),
455 mapMethod("none"),
456 viewMethod("none"),
457 vart(200),
458 limd(8),
459 highl(4),
460 skal(3),
461 medianmap(false)
462 {
463 }
464
operator ==(const RetinexParams & other) const465 bool RetinexParams::operator ==(const RetinexParams& other) const
466 {
467 return
468 enabled == other.enabled
469 && cdcurve == other.cdcurve
470 && cdHcurve == other.cdHcurve
471 && lhcurve == other.lhcurve
472 && transmissionCurve == other.transmissionCurve
473 && gaintransmissionCurve == other.gaintransmissionCurve
474 && mapcurve == other.mapcurve
475 && str == other.str
476 && scal == other.scal
477 && iter == other.iter
478 && grad == other.grad
479 && grads == other.grads
480 && gam == other.gam
481 && slope == other.slope
482 && neigh == other.neigh
483 && offs == other.offs
484 && highlights == other.highlights
485 && htonalwidth == other.htonalwidth
486 && shadows == other.shadows
487 && stonalwidth == other.stonalwidth
488 && radius == other.radius
489 && retinexMethod == other.retinexMethod
490 && retinexcolorspace == other.retinexcolorspace
491 && gammaretinex == other.gammaretinex
492 && mapMethod == other.mapMethod
493 && viewMethod == other.viewMethod
494 && vart == other.vart
495 && limd == other.limd
496 && highl == other.highl
497 && skal == other.skal
498 && medianmap == other.medianmap;
499 }
500
operator !=(const RetinexParams & other) const501 bool RetinexParams::operator !=(const RetinexParams& other) const
502 {
503 return !(*this == other);
504 }
505
getCurves(RetinextransmissionCurve & transmissionCurveLUT,RetinexgaintransmissionCurve & gaintransmissionCurveLUT) const506 void RetinexParams::getCurves(RetinextransmissionCurve &transmissionCurveLUT, RetinexgaintransmissionCurve &gaintransmissionCurveLUT) const
507 {
508 transmissionCurveLUT.Set(this->transmissionCurve);
509 gaintransmissionCurveLUT.Set(this->gaintransmissionCurve);
510
511 }
512
LCurveParams()513 LCurveParams::LCurveParams() :
514 enabled(false),
515 lcurve{
516 DCT_Linear
517 },
518 acurve{
519 DCT_Linear
520 },
521 bcurve{
522 DCT_Linear
523 },
524 cccurve{
525 DCT_Linear
526 },
527 chcurve{
528 FCT_Linear
529 },
530 lhcurve{
531 FCT_Linear
532 },
533 hhcurve{
534 FCT_Linear
535 },
536 lccurve{
537 DCT_Linear
538 },
539 clcurve{
540 DCT_Linear
541 },
542 brightness(0),
543 contrast(0),
544 chromaticity(0),
545 avoidcolorshift(false),
546 rstprotection(0),
547 lcredsk(true)
548 {
549 }
550
operator ==(const LCurveParams & other) const551 bool LCurveParams::operator ==(const LCurveParams& other) const
552 {
553 return
554 enabled == other.enabled
555 && lcurve == other.lcurve
556 && acurve == other.acurve
557 && bcurve == other.bcurve
558 && cccurve == other.cccurve
559 && chcurve == other.chcurve
560 && lhcurve == other.lhcurve
561 && hhcurve == other.hhcurve
562 && lccurve == other.lccurve
563 && clcurve == other.clcurve
564 && brightness == other.brightness
565 && contrast == other.contrast
566 && chromaticity == other.chromaticity
567 && avoidcolorshift == other.avoidcolorshift
568 && rstprotection == other.rstprotection
569 && lcredsk == other.lcredsk;
570 }
571
operator !=(const LCurveParams & other) const572 bool LCurveParams::operator !=(const LCurveParams& other) const
573 {
574 return !(*this == other);
575 }
576
RGBCurvesParams()577 RGBCurvesParams::RGBCurvesParams() :
578 enabled(false),
579 lumamode(false),
580 rcurve{
581 DCT_Linear
582 },
583 gcurve{
584 DCT_Linear
585 },
586 bcurve{
587 DCT_Linear
588 }
589 {
590 }
591
operator ==(const RGBCurvesParams & other) const592 bool RGBCurvesParams::operator ==(const RGBCurvesParams& other) const
593 {
594 return
595 enabled == other.enabled
596 && lumamode == other.lumamode
597 && rcurve == other.rcurve
598 && gcurve == other.gcurve
599 && bcurve == other.bcurve;
600 }
601
operator !=(const RGBCurvesParams & other) const602 bool RGBCurvesParams::operator !=(const RGBCurvesParams& other) const
603 {
604 return !(*this == other);
605 }
606
607
LocalContrastParams()608 LocalContrastParams::LocalContrastParams():
609 enabled(false),
610 radius(80),
611 amount(0.2),
612 darkness(1.0),
613 lightness(1.0)
614 {
615 }
616
617
operator ==(const LocalContrastParams & other) const618 bool LocalContrastParams::operator==(const LocalContrastParams &other) const
619 {
620 return
621 enabled == other.enabled
622 && radius == other.radius
623 && amount == other.amount
624 && darkness == other.darkness
625 && lightness == other.lightness;
626 }
627
628
operator !=(const LocalContrastParams & other) const629 bool LocalContrastParams::operator!=(const LocalContrastParams &other) const
630 {
631 return !(*this == other);
632 }
633
634
635 const double ColorToningParams::LABGRID_CORR_MAX = 12000.f;
636 const double ColorToningParams::LABGRID_CORR_SCALE = 3.f;
637
LabCorrectionRegion()638 ColorToningParams::LabCorrectionRegion::LabCorrectionRegion():
639 a(0),
640 b(0),
641 saturation(0),
642 slope(1),
643 offset(0),
644 power(1),
645 hueMask{
646 FCT_MinMaxCPoints,
647 0.166666667,
648 1.,
649 0.35,
650 0.35,
651 0.8287775246,
652 1.,
653 0.35,
654 0.35
655 },
656 chromaticityMask{
657 FCT_MinMaxCPoints,
658 0.,
659 1.,
660 0.35,
661 0.35,
662 1.,
663 1.,
664 0.35,
665 0.35
666 },
667 lightnessMask{
668 FCT_MinMaxCPoints,
669 0.,
670 1.,
671 0.35,
672 0.35,
673 1.,
674 1.,
675 0.35,
676 0.35
677 },
678 maskBlur(0),
679 channel(ColorToningParams::LabCorrectionRegion::CHAN_ALL)
680 {
681 }
682
683
operator ==(const LabCorrectionRegion & other) const684 bool ColorToningParams::LabCorrectionRegion::operator==(const LabCorrectionRegion &other) const
685 {
686 return a == other.a
687 && b == other.b
688 && saturation == other.saturation
689 && slope == other.slope
690 && offset == other.offset
691 && power == other.power
692 && hueMask == other.hueMask
693 && chromaticityMask == other.chromaticityMask
694 && lightnessMask == other.lightnessMask
695 && maskBlur == other.maskBlur
696 && channel == other.channel;
697 }
698
699
operator !=(const LabCorrectionRegion & other) const700 bool ColorToningParams::LabCorrectionRegion::operator!=(const LabCorrectionRegion &other) const
701 {
702 return !(*this == other);
703 }
704
705
ColorToningParams()706 ColorToningParams::ColorToningParams() :
707 enabled(false),
708 autosat(true),
709 opacityCurve{
710 FCT_MinMaxCPoints,
711 0.00,
712 0.3,
713 0.35,
714 0.00,
715 0.25,
716 0.8,
717 0.35,
718 0.35,
719 0.70,
720 0.8,
721 0.35,
722 0.35,
723 1.00,
724 0.3,
725 0.00,
726 0.00
727 },
728 colorCurve{
729 FCT_MinMaxCPoints,
730 0.050,
731 0.62,
732 0.25,
733 0.25,
734 0.585,
735 0.11,
736 0.25,
737 0.25
738 },
739 satProtectionThreshold(30),
740 saturatedOpacity(80),
741 strength(50),
742 balance(0),
743 hlColSat(60, 80, false),
744 shadowsColSat (80, 208, false),
745 clcurve{
746 DCT_NURBS,
747 0.00,
748 0.00,
749 0.35,
750 0.65,
751 1.00,
752 1.00
753 },
754 cl2curve{
755 DCT_NURBS,
756 0.00,
757 0.00,
758 0.35,
759 0.65,
760 1.00,
761 1.00
762 },
763 method("LabRegions"),
764 twocolor("Std"),
765 redlow(0.0),
766 greenlow(0.0),
767 bluelow(0.0),
768 redmed(0.0),
769 greenmed(0.0),
770 bluemed(0.0),
771 redhigh(0.0),
772 greenhigh(0.0),
773 bluehigh(0.0),
774 satlow(0.0),
775 sathigh(0.0),
776 lumamode(true),
777 labgridALow(0.0),
778 labgridBLow(0.0),
779 labgridAHigh(0.0),
780 labgridBHigh(0.0),
781 labregions{LabCorrectionRegion()},
782 labregionsShowMask(-1)
783 {
784 }
785
operator ==(const ColorToningParams & other) const786 bool ColorToningParams::operator ==(const ColorToningParams& other) const
787 {
788 return
789 enabled == other.enabled
790 && autosat == other.autosat
791 && opacityCurve == other.opacityCurve
792 && colorCurve == other.colorCurve
793 && satProtectionThreshold == other.satProtectionThreshold
794 && saturatedOpacity == other.saturatedOpacity
795 && strength == other.strength
796 && balance == other.balance
797 && hlColSat == other.hlColSat
798 && shadowsColSat == other.shadowsColSat
799 && clcurve == other.clcurve
800 && cl2curve == other.cl2curve
801 && method == other.method
802 && twocolor == other.twocolor
803 && redlow == other.redlow
804 && greenlow == other.greenlow
805 && bluelow == other.bluelow
806 && redmed == other.redmed
807 && greenmed == other.greenmed
808 && bluemed == other.bluemed
809 && redhigh == other.redhigh
810 && greenhigh == other.greenhigh
811 && bluehigh == other.bluehigh
812 && satlow == other.satlow
813 && sathigh == other.sathigh
814 && lumamode == other.lumamode
815 && labgridALow == other.labgridALow
816 && labgridBLow == other.labgridBLow
817 && labgridAHigh == other.labgridAHigh
818 && labgridBHigh == other.labgridBHigh
819 && labregions == other.labregions
820 && labregionsShowMask == other.labregionsShowMask;
821 }
822
operator !=(const ColorToningParams & other) const823 bool ColorToningParams::operator !=(const ColorToningParams& other) const
824 {
825 return !(*this == other);
826 }
827
mixerToCurve(std::vector<double> & colorCurve,std::vector<double> & opacityCurve) const828 void ColorToningParams::mixerToCurve(std::vector<double>& colorCurve, std::vector<double>& opacityCurve) const
829 {
830 // check if non null first
831 if (!redlow && !greenlow && !bluelow && !redmed && !greenmed && !bluemed && !redhigh && !greenhigh && !bluehigh) {
832 colorCurve.resize(1);
833 colorCurve.at(0) = FCT_Linear;
834 opacityCurve.resize(1);
835 opacityCurve.at(0) = FCT_Linear;
836 return;
837 }
838
839 float low[3]; // RGB color for shadows
840 float med[3]; // RGB color for mid-tones
841 float high[3]; // RGB color for highlights
842 float lowSat = 0.f;
843 float medSat = 0.f;
844 float highSat = 0.f;
845 float minTmp, maxTmp;
846
847 // Fill the shadow mixer values of the Color TOning tool
848 low[0] = float (redlow) / 100.f; // [-1. ; +1.]
849 low[1] = float (greenlow) / 100.f; // [-1. ; +1.]
850 low[2] = float (bluelow) / 100.f; // [-1. ; +1.]
851 minTmp = min<float> (low[0], low[1], low[2]);
852 maxTmp = max<float> (low[0], low[1], low[2]);
853
854 if (maxTmp - minTmp > 0.005f) {
855 float v[3];
856 lowSat = (maxTmp - minTmp) / 2.f;
857
858 if (low[0] == minTmp) {
859 v[0] = 0.f;
860 } else if (low[1] == minTmp) {
861 v[1] = 0.f;
862 } else if (low[2] == minTmp) {
863 v[2] = 0.f;
864 }
865
866 if (low[0] == maxTmp) {
867 v[0] = 1.f;
868 } else if (low[1] == maxTmp) {
869 v[1] = 1.f;
870 } else if (low[2] == maxTmp) {
871 v[2] = 1.f;
872 }
873
874 if (low[0] != minTmp && low[0] != maxTmp) {
875 v[0] = (low[0] - minTmp) / (maxTmp - minTmp);
876 } else if (low[1] != minTmp && low[1] != maxTmp) {
877 v[1] = (low[1] - minTmp) / (maxTmp - minTmp);
878 } else if (low[2] != minTmp && low[2] != maxTmp) {
879 v[2] = (low[2] - minTmp) / (maxTmp - minTmp);
880 }
881
882 low[0] = v[0];
883 low[1] = v[1];
884 low[2] = v[2];
885 } else {
886 low[0] = low[1] = low[2] = 1.f;
887 }
888
889 // Fill the mid-tones mixer values of the Color TOning tool
890 med[0] = float (redmed) / 100.f; // [-1. ; +1.]
891 med[1] = float (greenmed) / 100.f; // [-1. ; +1.]
892 med[2] = float (bluemed) / 100.f; // [-1. ; +1.]
893 minTmp = min<float> (med[0], med[1], med[2]);
894 maxTmp = max<float> (med[0], med[1], med[2]);
895
896 if (maxTmp - minTmp > 0.005f) {
897 float v[3];
898 medSat = (maxTmp - minTmp) / 2.f;
899
900 if (med[0] == minTmp) {
901 v[0] = 0.f;
902 } else if (med[1] == minTmp) {
903 v[1] = 0.f;
904 } else if (med[2] == minTmp) {
905 v[2] = 0.f;
906 }
907
908 if (med[0] == maxTmp) {
909 v[0] = 1.f;
910 } else if (med[1] == maxTmp) {
911 v[1] = 1.f;
912 } else if (med[2] == maxTmp) {
913 v[2] = 1.f;
914 }
915
916 if (med[0] != minTmp && med[0] != maxTmp) {
917 v[0] = (med[0] - minTmp) / (maxTmp - minTmp);
918 } else if (med[1] != minTmp && med[1] != maxTmp) {
919 v[1] = (med[1] - minTmp) / (maxTmp - minTmp);
920 } else if (med[2] != minTmp && med[2] != maxTmp) {
921 v[2] = (med[2] - minTmp) / (maxTmp - minTmp);
922 }
923
924 med[0] = v[0];
925 med[1] = v[1];
926 med[2] = v[2];
927 } else {
928 med[0] = med[1] = med[2] = 1.f;
929 }
930
931 // Fill the highlight mixer values of the Color TOning tool
932 high[0] = float (redhigh) / 100.f; // [-1. ; +1.]
933 high[1] = float (greenhigh) / 100.f; // [-1. ; +1.]
934 high[2] = float (bluehigh) / 100.f; // [-1. ; +1.]
935 minTmp = min<float> (high[0], high[1], high[2]);
936 maxTmp = max<float> (high[0], high[1], high[2]);
937
938 if (maxTmp - minTmp > 0.005f) {
939 float v[3];
940 highSat = (maxTmp - minTmp) / 2.f;
941
942 if (high[0] == minTmp) {
943 v[0] = 0.f;
944 } else if (high[1] == minTmp) {
945 v[1] = 0.f;
946 } else if (high[2] == minTmp) {
947 v[2] = 0.f;
948 }
949
950 if (high[0] == maxTmp) {
951 v[0] = 1.f;
952 } else if (high[1] == maxTmp) {
953 v[1] = 1.f;
954 } else if (high[2] == maxTmp) {
955 v[2] = 1.f;
956 }
957
958 if (high[0] != minTmp && high[0] != maxTmp) {
959 v[0] = (high[0] - minTmp) / (maxTmp - minTmp);
960 } else if (high[1] != minTmp && high[1] != maxTmp) {
961 v[1] = (high[1] - minTmp) / (maxTmp - minTmp);
962 } else if (high[2] != minTmp && high[2] != maxTmp) {
963 v[2] = (high[2] - minTmp) / (maxTmp - minTmp);
964 }
965
966 high[0] = v[0];
967 high[1] = v[1];
968 high[2] = v[2];
969 } else {
970 high[0] = high[1] = high[2] = 1.f;
971 }
972
973 const double xPosLow = 0.1;
974 const double xPosMed = 0.4;
975 const double xPosHigh = 0.7;
976
977 colorCurve.resize(medSat != 0.f ? 13 : 9);
978 colorCurve.at(0) = FCT_MinMaxCPoints;
979 opacityCurve.resize(13);
980 opacityCurve.at(0) = FCT_MinMaxCPoints;
981
982 float h, s, l;
983 int idx = 1;
984
985 if (lowSat == 0.f) {
986 if (medSat != 0.f) {
987 Color::rgb2hsl(med[0], med[1], med[2], h, s, l);
988 } else { // highSat can't be null if the 2 other ones are!
989 Color::rgb2hsl(high[0], high[1], high[2], h, s, l);
990 }
991 } else {
992 Color::rgb2hsl(low[0], low[1], low[2], h, s, l);
993 }
994
995 colorCurve.at(idx++) = xPosLow;
996 colorCurve.at(idx++) = h;
997 colorCurve.at(idx++) = 0.35;
998 colorCurve.at(idx++) = 0.35;
999
1000 if (medSat != 0.f) {
1001 Color::rgb2hsl(med[0], med[1], med[2], h, s, l);
1002 colorCurve.at(idx++) = xPosMed;
1003 colorCurve.at(idx++) = h;
1004 colorCurve.at(idx++) = 0.35;
1005 colorCurve.at(idx++) = 0.35;
1006 }
1007
1008 if (highSat == 0.f) {
1009 if (medSat != 0.f) {
1010 Color::rgb2hsl(med[0], med[1], med[2], h, s, l);
1011 } else { // lowSat can't be null if the 2 other ones are!
1012 Color::rgb2hsl(low[0], low[1], low[2], h, s, l);
1013 }
1014 } else {
1015 Color::rgb2hsl(high[0], high[1], high[2], h, s, l);
1016 }
1017
1018 colorCurve.at(idx++) = xPosHigh;
1019 colorCurve.at(idx++) = h;
1020 colorCurve.at(idx++) = 0.35;
1021 colorCurve.at(idx) = 0.35;
1022
1023 opacityCurve.at(1) = xPosLow;
1024 opacityCurve.at(2) = double (lowSat);
1025 opacityCurve.at(3) = 0.35;
1026 opacityCurve.at(4) = 0.35;
1027 opacityCurve.at(5) = xPosMed;
1028 opacityCurve.at(6) = double (medSat);
1029 opacityCurve.at(7) = 0.35;
1030 opacityCurve.at(8) = 0.35;
1031 opacityCurve.at(9) = xPosHigh;
1032 opacityCurve.at(10) = double (highSat);
1033 opacityCurve.at(11) = 0.35;
1034 opacityCurve.at(12) = 0.35;
1035 }
1036
slidersToCurve(std::vector<double> & colorCurve,std::vector<double> & opacityCurve) const1037 void ColorToningParams::slidersToCurve(std::vector<double>& colorCurve, std::vector<double>& opacityCurve) const
1038 {
1039 if (hlColSat.getBottom() == 0 && shadowsColSat.getBottom() == 0) { // if both opacity are null, set both curves to Linear
1040 colorCurve.resize(1);
1041 colorCurve.at(0) = FCT_Linear;
1042 opacityCurve.resize(1);
1043 opacityCurve.at(0) = FCT_Linear;
1044 return;
1045 }
1046
1047 colorCurve.resize(9);
1048 colorCurve.at(0) = FCT_MinMaxCPoints;
1049 colorCurve.at(1) = 0.26 + 0.12 * double (balance) / 100.;
1050 colorCurve.at(2) = double (shadowsColSat.getTop()) / 360.;
1051 colorCurve.at(3) = 0.35;
1052 colorCurve.at(4) = 0.35;
1053 colorCurve.at(5) = 0.64 + 0.12 * double (balance) / 100.;
1054 colorCurve.at(6) = double (hlColSat.getTop()) / 360.;
1055 colorCurve.at(7) = 0.35;
1056 colorCurve.at(8) = 0.35;
1057
1058 opacityCurve.resize(9);
1059 opacityCurve.at(0) = FCT_MinMaxCPoints;
1060 opacityCurve.at(1) = colorCurve.at(1);
1061 opacityCurve.at(2) = double (shadowsColSat.getBottom()) / 100.;
1062 opacityCurve.at(3) = 0.35;
1063 opacityCurve.at(4) = 0.35;
1064 opacityCurve.at(5) = colorCurve.at(5);
1065 opacityCurve.at(6) = double (hlColSat.getBottom()) / 100.;
1066 opacityCurve.at(7) = 0.35;
1067 opacityCurve.at(8) = 0.35;
1068 }
1069
getCurves(ColorGradientCurve & colorCurveLUT,OpacityCurve & opacityCurveLUT,const double xyz_rgb[3][3],bool & opautili) const1070 void ColorToningParams::getCurves(ColorGradientCurve& colorCurveLUT, OpacityCurve& opacityCurveLUT, const double xyz_rgb[3][3], bool& opautili) const
1071 {
1072 float satur = 0.8f;
1073 float lumin = 0.5f; //middle of luminance for optimization of gamut - no real importance...as we work in XYZ and gamut control
1074
1075 // Transform slider values to control points
1076 std::vector<double> cCurve, oCurve;
1077
1078 if (method == "RGBSliders" || method == "Splitlr") {
1079 slidersToCurve(cCurve, oCurve);
1080 } else if (method == "Splitco") {
1081 mixerToCurve(cCurve, oCurve);
1082 } else {
1083 cCurve = this->colorCurve;
1084 oCurve = this->opacityCurve;
1085 }
1086
1087 if (method == "Lab") {
1088 if (twocolor == "Separ") {
1089 satur = 0.9f;
1090 }
1091
1092 if (twocolor == "All" || twocolor == "Two") {
1093 satur = 0.9f;
1094 }
1095
1096 colorCurveLUT.SetXYZ(cCurve, xyz_rgb, satur, lumin);
1097 opacityCurveLUT.Set(oCurve, opautili);
1098 } else if (method == "Splitlr" || method == "Splitco") {
1099 colorCurveLUT.SetXYZ(cCurve, xyz_rgb, satur, lumin);
1100 opacityCurveLUT.Set(oCurve, opautili);
1101 } else if (method.substr(0, 3) == "RGB") {
1102 colorCurveLUT.SetRGB(cCurve);
1103 opacityCurveLUT.Set(oCurve, opautili);
1104 }
1105 }
1106
SharpeningParams()1107 SharpeningParams::SharpeningParams() :
1108 enabled(false),
1109 contrast(20.0),
1110 autoContrast(false),
1111 blurradius(0.2),
1112 gamma(1.0),
1113 radius(0.5),
1114 amount(200),
1115 threshold(20, 80, 2000, 1200, false),
1116 edgesonly(false),
1117 edges_radius(1.9),
1118 edges_tolerance(1800),
1119 halocontrol(false),
1120 halocontrol_amount(85),
1121 method("usm"),
1122 deconvamount(100),
1123 deconvradius(0.75),
1124 deconviter(30),
1125 deconvdamping(0)
1126 {
1127 }
1128
operator ==(const SharpeningParams & other) const1129 bool SharpeningParams::operator ==(const SharpeningParams& other) const
1130 {
1131 return
1132 enabled == other.enabled
1133 && contrast == other.contrast
1134 && blurradius == other.blurradius
1135 && gamma == other.gamma
1136 && radius == other.radius
1137 && amount == other.amount
1138 && threshold == other.threshold
1139 && autoContrast == other.autoContrast
1140 && edgesonly == other.edgesonly
1141 && edges_radius == other.edges_radius
1142 && edges_tolerance == other.edges_tolerance
1143 && halocontrol == other.halocontrol
1144 && halocontrol_amount == other.halocontrol_amount
1145 && method == other.method
1146 && deconvamount == other.deconvamount
1147 && deconvradius == other.deconvradius
1148 && deconviter == other.deconviter
1149 && deconvdamping == other.deconvdamping;
1150 }
1151
operator !=(const SharpeningParams & other) const1152 bool SharpeningParams::operator !=(const SharpeningParams& other) const
1153 {
1154 return !(*this == other);
1155 }
1156
CaptureSharpeningParams()1157 CaptureSharpeningParams::CaptureSharpeningParams() :
1158 enabled(false),
1159 autoContrast(true),
1160 autoRadius(true),
1161 contrast(10.0),
1162 deconvradius(0.75),
1163 deconvradiusOffset(0.0),
1164 deconviter(20),
1165 deconvitercheck(true)
1166 {
1167 }
1168
operator ==(const CaptureSharpeningParams & other) const1169 bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) const
1170 {
1171 return
1172 enabled == other.enabled
1173 && contrast == other.contrast
1174 && autoContrast == other.autoContrast
1175 && autoRadius == other.autoRadius
1176 && deconvradius == other.deconvradius
1177 && deconvitercheck == other.deconvitercheck
1178 && deconvradiusOffset == other.deconvradiusOffset
1179 && deconviter == other.deconviter;
1180 }
1181
operator !=(const CaptureSharpeningParams & other) const1182 bool CaptureSharpeningParams::operator !=(const CaptureSharpeningParams& other) const
1183 {
1184 return !(*this == other);
1185 }
1186
SharpenEdgeParams()1187 SharpenEdgeParams::SharpenEdgeParams() :
1188 enabled(false),
1189 passes(2),
1190 amount(50.0),
1191 threechannels(false)
1192 {
1193 }
1194
operator ==(const SharpenEdgeParams & other) const1195 bool SharpenEdgeParams::operator ==(const SharpenEdgeParams& other) const
1196 {
1197 return
1198 enabled == other.enabled
1199 && passes == other.passes
1200 && amount == other.amount
1201 && threechannels == other.threechannels;
1202 }
1203
operator !=(const SharpenEdgeParams & other) const1204 bool SharpenEdgeParams::operator !=(const SharpenEdgeParams& other) const
1205 {
1206 return !(*this == other);
1207 }
1208
SharpenMicroParams()1209 SharpenMicroParams::SharpenMicroParams() :
1210 enabled(false),
1211 matrix(false),
1212 amount(20.0),
1213 contrast(20.0),
1214 uniformity(5)
1215 {
1216 }
1217
operator ==(const SharpenMicroParams & other) const1218 bool SharpenMicroParams::operator ==(const SharpenMicroParams& other) const
1219 {
1220 return
1221 enabled == other.enabled
1222 && matrix == other.matrix
1223 && amount == other.amount
1224 && contrast == other.contrast
1225 && uniformity == other.uniformity;
1226 }
1227
operator !=(const SharpenMicroParams & other) const1228 bool SharpenMicroParams::operator !=(const SharpenMicroParams& other) const
1229 {
1230 return !(*this == other);
1231 }
1232
VibranceParams()1233 VibranceParams::VibranceParams() :
1234 enabled(false),
1235 pastels(0),
1236 saturated(0),
1237 psthreshold(0, 75, false),
1238 protectskins(false),
1239 avoidcolorshift(true),
1240 pastsattog(true),
1241 skintonescurve{
1242 DCT_Linear
1243 }
1244 {
1245 }
1246
operator ==(const VibranceParams & other) const1247 bool VibranceParams::operator ==(const VibranceParams& other) const
1248 {
1249 return
1250 enabled == other.enabled
1251 && pastels == other.pastels
1252 && saturated == other.saturated
1253 && psthreshold == other.psthreshold
1254 && protectskins == other.protectskins
1255 && avoidcolorshift == other.avoidcolorshift
1256 && pastsattog == other.pastsattog
1257 && skintonescurve == other.skintonescurve;
1258 }
1259
operator !=(const VibranceParams & other) const1260 bool VibranceParams::operator !=(const VibranceParams& other) const
1261 {
1262 return !(*this == other);
1263 }
1264
WBParams()1265 WBParams::WBParams() :
1266 enabled(true),
1267 method("Camera"),
1268 temperature(6504),
1269 green(1.0),
1270 equal(1.0),
1271 tempBias(0.0)
1272 {
1273 }
1274
isPanningRelatedChange(const WBParams & other) const1275 bool WBParams::isPanningRelatedChange(const WBParams& other) const
1276 {
1277 return !
1278 (enabled == other.enabled
1279 && ((method == "Camera" && other.method == "Camera")
1280 ||
1281 (method == other.method
1282 && temperature == other.temperature
1283 && green == other.green
1284 && equal == other.equal
1285 && tempBias == other.tempBias)
1286 )
1287 );
1288 }
1289
operator ==(const WBParams & other) const1290 bool WBParams::operator ==(const WBParams& other) const
1291 {
1292 return
1293 enabled == other.enabled
1294 && method == other.method
1295 && temperature == other.temperature
1296 && green == other.green
1297 && equal == other.equal
1298 && tempBias == other.tempBias;
1299 }
1300
operator !=(const WBParams & other) const1301 bool WBParams::operator !=(const WBParams& other) const
1302 {
1303 return !(*this == other);
1304 }
1305
getWbEntries()1306 const std::vector<WBEntry>& WBParams::getWbEntries()
1307 {
1308 static const std::vector<WBEntry> wb_entries = {
1309 {"Camera", WBEntry::Type::CAMERA, M("TP_WBALANCE_CAMERA"), 0, 1.f, 1.f, 0.f},
1310 {"Auto", WBEntry::Type::AUTO, M("TP_WBALANCE_AUTO"), 0, 1.f, 1.f, 0.f},
1311 {"Daylight", WBEntry::Type::DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300, 1.f, 1.f, 0.f},
1312 {"Cloudy", WBEntry::Type::CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200, 1.f, 1.f, 0.f},
1313 {"Shade", WBEntry::Type::SHADE, M("TP_WBALANCE_SHADE"), 7600, 1.f, 1.f, 0.f},
1314 {"Water 1", WBEntry::Type::WATER, M("TP_WBALANCE_WATER1"), 35000, 0.3f, 1.1f, 0.f},
1315 {"Water 2", WBEntry::Type::WATER, M("TP_WBALANCE_WATER2"), 48000, 0.63f, 1.38f, 0.f},
1316 {"Tungsten", WBEntry::Type::TUNGSTEN, M("TP_WBALANCE_TUNGSTEN"), 2856, 1.f, 1.f, 0.f},
1317 {"Fluo F1", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO1"), 6430, 1.f, 1.f, 0.f},
1318 {"Fluo F2", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO2"), 4230, 1.f, 1.f, 0.f},
1319 {"Fluo F3", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO3"), 3450, 1.f, 1.f, 0.f},
1320 {"Fluo F4", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO4"), 2940, 1.f, 1.f, 0.f},
1321 {"Fluo F5", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO5"), 6350, 1.f, 1.f, 0.f},
1322 {"Fluo F6", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO6"), 4150, 1.f, 1.f, 0.f},
1323 {"Fluo F7", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO7"), 6500, 1.f, 1.f, 0.f},
1324 {"Fluo F8", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO8"), 5020, 1.f, 1.f, 0.f},
1325 {"Fluo F9", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO9"), 4330, 1.f, 1.f, 0.f},
1326 {"Fluo F10", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO10"), 5300, 1.f, 1.f, 0.f},
1327 {"Fluo F11", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO11"), 4000, 1.f, 1.f, 0.f},
1328 {"Fluo F12", WBEntry::Type::FLUORESCENT, M("TP_WBALANCE_FLUO12"), 3000, 1.f, 1.f, 0.f},
1329 {"HMI Lamp", WBEntry::Type::LAMP, M("TP_WBALANCE_HMI"), 4800, 1.f, 1.f, 0.f},
1330 {"GTI Lamp", WBEntry::Type::LAMP, M("TP_WBALANCE_GTI"), 5000, 1.f, 1.f, 0.f},
1331 {"JudgeIII Lamp", WBEntry::Type::LAMP, M("TP_WBALANCE_JUDGEIII"), 5100, 1.f, 1.f, 0.f},
1332 {"Solux Lamp 3500K", WBEntry::Type::LAMP, M("TP_WBALANCE_SOLUX35"), 3480, 1.f, 1.f, 0.f},
1333 {"Solux Lamp 4100K", WBEntry::Type::LAMP, M("TP_WBALANCE_SOLUX41"), 3930, 1.f, 1.f, 0.f},
1334 {"Solux Lamp 4700K", WBEntry::Type::LAMP, M("TP_WBALANCE_SOLUX47"), 4700, 1.f, 1.f, 0.f},
1335 {"NG Solux Lamp 4700K", WBEntry::Type::LAMP, M("TP_WBALANCE_SOLUX47_NG"), 4480, 1.f, 1.f, 0.f},
1336 {"LED LSI Lumelex 2040", WBEntry::Type::LED, M("TP_WBALANCE_LED_LSI"), 2970, 1.f, 1.f, 0.f},
1337 {"LED CRS SP12 WWMR16", WBEntry::Type::LED, M("TP_WBALANCE_LED_CRS"), 3050, 1.f, 1.f, 0.f},
1338 {"Flash 5500K", WBEntry::Type::FLASH, M("TP_WBALANCE_FLASH55"), 5500, 1.f, 1.f, 0.f},
1339 {"Flash 6000K", WBEntry::Type::FLASH, M("TP_WBALANCE_FLASH60"), 6000, 1.f, 1.f, 0.f},
1340 {"Flash 6500K", WBEntry::Type::FLASH, M("TP_WBALANCE_FLASH65"), 6500, 1.f, 1.f, 0.f},
1341 // Should remain the last one
1342 {"Custom", WBEntry::Type::CUSTOM, M("TP_WBALANCE_CUSTOM"), 0, 1.f, 1.f, 0.f}
1343 };
1344
1345 return wb_entries;
1346 }
1347
ColorAppearanceParams()1348 ColorAppearanceParams::ColorAppearanceParams() :
1349 enabled(false),
1350 degree(90),
1351 autodegree(true),
1352 degreeout(90),
1353 autodegreeout(true),
1354 curve{
1355 DCT_Linear
1356 },
1357 curve2{
1358 DCT_Linear
1359 },
1360 curve3{
1361 DCT_Linear
1362 },
1363 curveMode(TcMode::LIGHT),
1364 curveMode2(TcMode::LIGHT),
1365 curveMode3(CtcMode::CHROMA),
1366 surround("Average"),
1367 surrsrc("Average"),
1368 adapscen(2000.0),
1369 autoadapscen(true),
1370 ybscen(18),
1371 autoybscen(true),
1372 adaplum(16),
1373 badpixsl(0),
1374 wbmodel("RawT"),
1375 algo("No"),
1376 contrast(0.0),
1377 qcontrast(0.0),
1378 jlight(0.0),
1379 qbright(0.0),
1380 chroma(0.0),
1381 schroma(0.0),
1382 mchroma(0.0),
1383 colorh(0.0),
1384 rstprotection(0.0),
1385 surrsource(false),
1386 gamut(true),
1387 datacie(false),
1388 tonecie(false),
1389 tempout(5000),
1390 ybout(18),
1391 greenout(1.0),
1392 tempsc(5000),
1393 greensc(1.0)
1394 {
1395 }
1396
operator ==(const ColorAppearanceParams & other) const1397 bool ColorAppearanceParams::operator ==(const ColorAppearanceParams& other) const
1398 {
1399 return
1400 enabled == other.enabled
1401 && degree == other.degree
1402 && autodegree == other.autodegree
1403 && degreeout == other.degreeout
1404 && autodegreeout == other.autodegreeout
1405 && curve == other.curve
1406 && curve2 == other.curve2
1407 && curve3 == other.curve3
1408 && curveMode == other.curveMode
1409 && curveMode2 == other.curveMode2
1410 && curveMode3 == other.curveMode3
1411 && surround == other.surround
1412 && surrsrc == other.surrsrc
1413 && adapscen == other.adapscen
1414 && autoadapscen == other.autoadapscen
1415 && ybscen == other.ybscen
1416 && autoybscen == other.autoybscen
1417 && adaplum == other.adaplum
1418 && badpixsl == other.badpixsl
1419 && wbmodel == other.wbmodel
1420 && algo == other.algo
1421 && contrast == other.contrast
1422 && qcontrast == other.qcontrast
1423 && jlight == other.jlight
1424 && qbright == other.qbright
1425 && chroma == other.chroma
1426 && schroma == other.schroma
1427 && mchroma == other.mchroma
1428 && colorh == other.colorh
1429 && rstprotection == other.rstprotection
1430 && surrsource == other.surrsource
1431 && gamut == other.gamut
1432 && datacie == other.datacie
1433 && tonecie == other.tonecie
1434 && tempout == other.tempout
1435 && ybout == other.ybout
1436 && greenout == other.greenout
1437 && tempsc == other.tempsc
1438 && greensc == other.greensc;
1439 }
1440
operator !=(const ColorAppearanceParams & other) const1441 bool ColorAppearanceParams::operator !=(const ColorAppearanceParams& other) const
1442 {
1443 return !(*this == other);
1444 }
1445
DefringeParams()1446 DefringeParams::DefringeParams() :
1447 enabled(false),
1448 radius(2.0),
1449 threshold(13),
1450 huecurve{
1451 FCT_MinMaxCPoints,
1452 0.166666667,
1453 0.,
1454 0.35,
1455 0.35,
1456 0.347,
1457 0.,
1458 0.35,
1459 0.35,
1460 0.513667426,
1461 0,
1462 0.35,
1463 0.35,
1464 0.668944571,
1465 0.,
1466 0.35,
1467 0.35,
1468 0.8287775246,
1469 0.97835991,
1470 0.35,
1471 0.35,
1472 0.9908883827,
1473 0.,
1474 0.35,
1475 0.35
1476 }
1477 {
1478 }
1479
operator ==(const DefringeParams & other) const1480 bool DefringeParams::operator ==(const DefringeParams& other) const
1481 {
1482 return
1483 enabled == other.enabled
1484 && radius == other.radius
1485 && threshold == other.threshold
1486 && huecurve == other.huecurve;
1487 }
1488
operator !=(const DefringeParams & other) const1489 bool DefringeParams::operator !=(const DefringeParams& other) const
1490 {
1491 return !(*this == other);
1492 }
1493
ImpulseDenoiseParams()1494 ImpulseDenoiseParams::ImpulseDenoiseParams() :
1495 enabled(false),
1496 thresh(50)
1497 {
1498 }
1499
operator ==(const ImpulseDenoiseParams & other) const1500 bool ImpulseDenoiseParams::operator ==(const ImpulseDenoiseParams& other) const
1501 {
1502 return
1503 enabled == other.enabled
1504 && thresh == other.thresh;
1505 }
1506
operator !=(const ImpulseDenoiseParams & other) const1507 bool ImpulseDenoiseParams::operator !=(const ImpulseDenoiseParams& other) const
1508 {
1509 return !(*this == other);
1510 }
1511
DirPyrDenoiseParams()1512 DirPyrDenoiseParams::DirPyrDenoiseParams() :
1513 lcurve{
1514 FCT_MinMaxCPoints,
1515 0.05,
1516 0.15,
1517 0.35,
1518 0.35,
1519 0.55,
1520 0.04,
1521 0.35,
1522 0.35
1523 },
1524 cccurve{
1525 FCT_MinMaxCPoints,
1526 0.05,
1527 0.50,
1528 0.35,
1529 0.35,
1530 0.35,
1531 0.05,
1532 0.35,
1533 0.35
1534 },
1535 enabled(false),
1536 enhance(false),
1537 median(false),
1538 perform(false),
1539 luma(0),
1540 Ldetail(0),
1541 chroma(15),
1542 redchro(0),
1543 bluechro(0),
1544 gamma(1.7),
1545 dmethod("Lab"),
1546 Lmethod("SLI"),
1547 Cmethod("MAN"),
1548 C2method("AUTO"),
1549 smethod("shal"),
1550 medmethod("soft"),
1551 methodmed("none"),
1552 rgbmethod("soft"),
1553 passes(1)
1554 {
1555 }
1556
operator ==(const DirPyrDenoiseParams & other) const1557 bool DirPyrDenoiseParams::operator ==(const DirPyrDenoiseParams& other) const
1558 {
1559 return
1560 lcurve == other.lcurve
1561 && cccurve == other.cccurve
1562 && enabled == other.enabled
1563 && enhance == other.enhance
1564 && median == other.median
1565 && perform == other.perform
1566 && luma == other.luma
1567 && Ldetail == other.Ldetail
1568 && chroma == other.chroma
1569 && redchro == other.redchro
1570 && bluechro == other.bluechro
1571 && gamma == other.gamma
1572 && dmethod == other.dmethod
1573 && Lmethod == other.Lmethod
1574 && Cmethod == other.Cmethod
1575 && C2method == other.C2method
1576 && smethod == other.smethod
1577 && medmethod == other.medmethod
1578 && methodmed == other.methodmed
1579 && rgbmethod == other.rgbmethod
1580 && passes == other.passes;
1581 }
1582
operator !=(const DirPyrDenoiseParams & other) const1583 bool DirPyrDenoiseParams::operator !=(const DirPyrDenoiseParams& other) const
1584 {
1585 return !(*this == other);
1586 }
1587
getCurves(NoiseCurve & lCurve,NoiseCurve & cCurve) const1588 void DirPyrDenoiseParams::getCurves(NoiseCurve &lCurve, NoiseCurve &cCurve) const
1589 {
1590 lCurve.Set(this->lcurve);
1591 cCurve.Set(this->cccurve);
1592 }
1593
EPDParams()1594 EPDParams::EPDParams() :
1595 enabled(false),
1596 strength(0.5),
1597 gamma(1.0),
1598 edgeStopping(1.4),
1599 scale(1.0),
1600 reweightingIterates(0)
1601 {
1602 }
1603
operator ==(const EPDParams & other) const1604 bool EPDParams::operator ==(const EPDParams& other) const
1605 {
1606 return
1607 enabled == other.enabled
1608 && strength == other.strength
1609 && gamma == other.gamma
1610 && edgeStopping == other.edgeStopping
1611 && scale == other.scale
1612 && reweightingIterates == other.reweightingIterates;
1613 }
1614
operator !=(const EPDParams & other) const1615 bool EPDParams::operator !=(const EPDParams& other) const
1616 {
1617 return !(*this == other);
1618 }
1619
FattalToneMappingParams()1620 FattalToneMappingParams::FattalToneMappingParams() :
1621 enabled(false),
1622 threshold(30),
1623 amount(20),
1624 anchor(50)
1625 {
1626 }
1627
operator ==(const FattalToneMappingParams & other) const1628 bool FattalToneMappingParams::operator ==(const FattalToneMappingParams& other) const
1629 {
1630 return
1631 enabled == other.enabled
1632 && threshold == other.threshold
1633 && amount == other.amount
1634 && anchor == other.anchor;
1635 }
1636
operator !=(const FattalToneMappingParams & other) const1637 bool FattalToneMappingParams::operator !=(const FattalToneMappingParams& other) const
1638 {
1639 return !(*this == other);
1640 }
1641
SHParams()1642 SHParams::SHParams() :
1643 enabled(false),
1644 highlights(0),
1645 htonalwidth(70),
1646 shadows(0),
1647 stonalwidth(30),
1648 radius(40),
1649 lab(false)
1650 {
1651 }
1652
operator ==(const SHParams & other) const1653 bool SHParams::operator ==(const SHParams& other) const
1654 {
1655 return
1656 enabled == other.enabled
1657 && highlights == other.highlights
1658 && htonalwidth == other.htonalwidth
1659 && shadows == other.shadows
1660 && stonalwidth == other.stonalwidth
1661 && radius == other.radius
1662 && lab == other.lab;
1663 }
1664
operator !=(const SHParams & other) const1665 bool SHParams::operator !=(const SHParams& other) const
1666 {
1667 return !(*this == other);
1668 }
1669
CropParams()1670 CropParams::CropParams() :
1671 enabled(false),
1672 x(-1),
1673 y(-1),
1674 w(15000),
1675 h(15000),
1676 fixratio(true),
1677 ratio("As Image"),
1678 orientation("As Image"),
1679 guide("Frame")
1680 {
1681 }
1682
operator ==(const CropParams & other) const1683 bool CropParams::operator ==(const CropParams& other) const
1684 {
1685 return
1686 enabled == other.enabled
1687 && x == other.x
1688 && y == other.y
1689 && w == other.w
1690 && h == other.h
1691 && fixratio == other.fixratio
1692 && ratio == other.ratio
1693 && orientation == other.orientation
1694 && guide == other.guide;
1695 }
1696
operator !=(const CropParams & other) const1697 bool CropParams::operator !=(const CropParams& other) const
1698 {
1699 return !(*this == other);
1700 }
1701
mapToResized(int resizedWidth,int resizedHeight,int scale,int & x1,int & x2,int & y1,int & y2) const1702 void CropParams::mapToResized(int resizedWidth, int resizedHeight, int scale, int& x1, int& x2, int& y1, int& y2) const
1703 {
1704 x1 = 0, x2 = resizedWidth, y1 = 0, y2 = resizedHeight;
1705
1706 if (enabled) {
1707 x1 = min(resizedWidth - 1, max(0, x / scale));
1708 y1 = min(resizedHeight - 1, max(0, y / scale));
1709 x2 = min(resizedWidth, max(0, (x + w) / scale));
1710 y2 = min(resizedHeight, max(0, (y + h) / scale));
1711 }
1712 }
1713
CoarseTransformParams()1714 CoarseTransformParams::CoarseTransformParams() :
1715 rotate(0),
1716 hflip(false),
1717 vflip(false)
1718 {
1719 }
1720
operator ==(const CoarseTransformParams & other) const1721 bool CoarseTransformParams::operator ==(const CoarseTransformParams& other) const
1722 {
1723 return
1724 rotate == other.rotate
1725 && hflip == other.hflip
1726 && vflip == other.vflip;
1727 }
1728
operator !=(const CoarseTransformParams & other) const1729 bool CoarseTransformParams::operator !=(const CoarseTransformParams& other) const
1730 {
1731 return !(*this == other);
1732 }
1733
CommonTransformParams()1734 CommonTransformParams::CommonTransformParams() :
1735 method("log"),
1736 autofill(true)
1737 {
1738 }
1739
operator ==(const CommonTransformParams & other) const1740 bool CommonTransformParams::operator ==(const CommonTransformParams& other) const
1741 {
1742 return method == other.method && autofill == other.autofill;
1743 }
1744
operator !=(const CommonTransformParams & other) const1745 bool CommonTransformParams::operator !=(const CommonTransformParams& other) const
1746 {
1747 return !(*this == other);
1748 }
1749
RotateParams()1750 RotateParams::RotateParams() :
1751 degree(0.0)
1752 {
1753 }
1754
operator ==(const RotateParams & other) const1755 bool RotateParams::operator ==(const RotateParams& other) const
1756 {
1757 return degree == other.degree;
1758 }
1759
operator !=(const RotateParams & other) const1760 bool RotateParams::operator !=(const RotateParams& other) const
1761 {
1762 return !(*this == other);
1763 }
1764
DistortionParams()1765 DistortionParams::DistortionParams() :
1766 amount(0.0)
1767 {
1768 }
1769
operator ==(const DistortionParams & other) const1770 bool DistortionParams::operator ==(const DistortionParams& other) const
1771 {
1772 return amount == other.amount;
1773 }
1774
operator !=(const DistortionParams & other) const1775 bool DistortionParams::operator !=(const DistortionParams& other) const
1776 {
1777 return !(*this == other);
1778 }
1779
LensProfParams()1780 LensProfParams::LensProfParams() :
1781 lcMode(LcMode::NONE),
1782 useDist(true),
1783 useVign(true),
1784 useCA(false)
1785 {
1786 }
1787
operator ==(const LensProfParams & other) const1788 bool LensProfParams::operator ==(const LensProfParams& other) const
1789 {
1790 return
1791 lcMode == other.lcMode
1792 && lcpFile == other.lcpFile
1793 && useCA == other.useCA
1794 && lfCameraMake == other.lfCameraMake
1795 && lfCameraModel == other.lfCameraModel
1796 && lfLens == other.lfLens
1797 && useDist == other.useDist
1798 && useVign == other.useVign;
1799 }
1800
operator !=(const LensProfParams & other) const1801 bool LensProfParams::operator !=(const LensProfParams& other) const
1802 {
1803 return !(*this == other);
1804 }
1805
useLensfun() const1806 bool LensProfParams::useLensfun() const
1807 {
1808 return lcMode == LcMode::LENSFUNAUTOMATCH || lcMode == LcMode::LENSFUNMANUAL;
1809 }
1810
lfAutoMatch() const1811 bool LensProfParams::lfAutoMatch() const
1812 {
1813 return lcMode == LcMode::LENSFUNAUTOMATCH;
1814 }
1815
useLcp() const1816 bool LensProfParams::useLcp() const
1817 {
1818 return lcMode == LcMode::LCP && lcpFile.length() > 0;
1819 }
1820
lfManual() const1821 bool LensProfParams::lfManual() const
1822 {
1823 return lcMode == LcMode::LENSFUNMANUAL;
1824 }
1825
getMethodStrings() const1826 const std::vector<const char*>& LensProfParams::getMethodStrings() const
1827 {
1828 static const std::vector<const char*> method_strings = {
1829 "none",
1830 "lfauto",
1831 "lfmanual",
1832 "lcp"
1833 };
1834 return method_strings;
1835 }
1836
getMethodString(LcMode mode) const1837 Glib::ustring LensProfParams::getMethodString(LcMode mode) const
1838 {
1839 return getMethodStrings()[toUnderlying(mode)];
1840 }
1841
getMethodNumber(const Glib::ustring & mode) const1842 LensProfParams::LcMode LensProfParams::getMethodNumber(const Glib::ustring& mode) const
1843 {
1844 for (std::vector<const char*>::size_type i = 0; i < getMethodStrings().size(); ++i) {
1845 if (getMethodStrings()[i] == mode) {
1846 return static_cast<LcMode>(i);
1847 }
1848 }
1849
1850 return LcMode::NONE;
1851 }
1852
PerspectiveParams()1853 PerspectiveParams::PerspectiveParams() :
1854 horizontal(0.0),
1855 vertical(0.0)
1856 {
1857 }
1858
operator ==(const PerspectiveParams & other) const1859 bool PerspectiveParams::operator ==(const PerspectiveParams& other) const
1860 {
1861 return
1862 horizontal == other.horizontal
1863 && vertical == other.vertical;
1864 }
1865
operator !=(const PerspectiveParams & other) const1866 bool PerspectiveParams::operator !=(const PerspectiveParams& other) const
1867 {
1868 return !(*this == other);
1869 }
1870
GradientParams()1871 GradientParams::GradientParams() :
1872 enabled(false),
1873 degree(0.0),
1874 feather(25),
1875 strength(0.60),
1876 centerX(0),
1877 centerY(0)
1878 {
1879 }
1880
operator ==(const GradientParams & other) const1881 bool GradientParams::operator ==(const GradientParams& other) const
1882 {
1883 return
1884 enabled == other.enabled
1885 && degree == other.degree
1886 && feather == other.feather
1887 && strength == other.strength
1888 && centerX == other.centerX
1889 && centerY == other.centerY;
1890 }
1891
operator !=(const GradientParams & other) const1892 bool GradientParams::operator !=(const GradientParams& other) const
1893 {
1894 return !(*this == other);
1895 }
1896
PCVignetteParams()1897 PCVignetteParams::PCVignetteParams() :
1898 enabled(false),
1899 strength(0.60),
1900 feather(50),
1901 roundness(50)
1902 {
1903 }
1904
operator ==(const PCVignetteParams & other) const1905 bool PCVignetteParams::operator ==(const PCVignetteParams& other) const
1906 {
1907 return
1908 enabled == other.enabled
1909 && strength == other.strength
1910 && feather == other.feather
1911 && roundness == other.roundness;
1912 }
1913
operator !=(const PCVignetteParams & other) const1914 bool PCVignetteParams::operator !=(const PCVignetteParams& other) const
1915 {
1916 return !(*this == other);
1917 }
1918
VignettingParams()1919 VignettingParams::VignettingParams() :
1920 amount(0),
1921 radius(50),
1922 strength(1),
1923 centerX(0),
1924 centerY(0)
1925 {
1926 }
1927
operator ==(const VignettingParams & other) const1928 bool VignettingParams::operator ==(const VignettingParams& other) const
1929 {
1930 return
1931 amount == other.amount
1932 && radius == other.radius
1933 && strength == other.strength
1934 && centerX == other.centerX
1935 && centerY == other.centerY;
1936 }
1937
operator !=(const VignettingParams & other) const1938 bool VignettingParams::operator !=(const VignettingParams& other) const
1939 {
1940 return !(*this == other);
1941 }
1942
ChannelMixerParams()1943 ChannelMixerParams::ChannelMixerParams() :
1944 enabled(false),
1945 red{
1946 1000,
1947 0,
1948 0
1949 },
1950 green{
1951 0,
1952 1000,
1953 0
1954 },
1955 blue{
1956 0,
1957 0,
1958 1000
1959 }
1960 {
1961 }
1962
operator ==(const ChannelMixerParams & other) const1963 bool ChannelMixerParams::operator ==(const ChannelMixerParams& other) const
1964 {
1965 if (enabled != other.enabled) {
1966 return false;
1967 }
1968
1969 for (unsigned int i = 0; i < 3; ++i) {
1970 if (
1971 red[i] != other.red[i]
1972 || green[i] != other.green[i]
1973 || blue[i] != other.blue[i]
1974 ) {
1975 return false;
1976 }
1977 }
1978
1979 return true;
1980 }
1981
operator !=(const ChannelMixerParams & other) const1982 bool ChannelMixerParams::operator !=(const ChannelMixerParams& other) const
1983 {
1984 return !(*this == other);
1985 }
1986
BlackWhiteParams()1987 BlackWhiteParams::BlackWhiteParams() :
1988 beforeCurve{
1989 DCT_Linear
1990 },
1991 beforeCurveMode(BlackWhiteParams::TcMode::STD_BW),
1992 afterCurve{
1993 DCT_Linear
1994 },
1995 afterCurveMode(BlackWhiteParams::TcMode::STD_BW),
1996 algo("SP"),
1997 luminanceCurve{
1998 FCT_Linear
1999 },
2000 autoc(false),
2001 enabledcc(true),
2002 enabled(false),
2003 filter("None"),
2004 setting("RGB-Rel"),
2005 method("Desaturation"),
2006 mixerRed(33),
2007 mixerOrange(33),
2008 mixerYellow(33),
2009 mixerGreen(33),
2010 mixerCyan(33),
2011 mixerBlue(33),
2012 mixerMagenta(33),
2013 mixerPurple(33),
2014 gammaRed(0),
2015 gammaGreen(0),
2016 gammaBlue(0)
2017 {
2018 }
2019
operator ==(const BlackWhiteParams & other) const2020 bool BlackWhiteParams::operator ==(const BlackWhiteParams& other) const
2021 {
2022 return
2023 beforeCurve == other.beforeCurve
2024 && beforeCurveMode == other.beforeCurveMode
2025 && afterCurve == other.afterCurve
2026 && afterCurveMode == other.afterCurveMode
2027 && algo == other.algo
2028 && luminanceCurve == other.luminanceCurve
2029 && autoc == other.autoc
2030 && enabledcc == other.enabledcc
2031 && enabled == other.enabled
2032 && filter == other.filter
2033 && setting == other.setting
2034 && method == other.method
2035 && mixerRed == other.mixerRed
2036 && mixerOrange == other.mixerOrange
2037 && mixerYellow == other.mixerYellow
2038 && mixerGreen == other.mixerGreen
2039 && mixerCyan == other.mixerCyan
2040 && mixerBlue == other.mixerBlue
2041 && mixerMagenta == other.mixerMagenta
2042 && mixerPurple == other.mixerPurple
2043 && gammaRed == other.gammaRed
2044 && gammaGreen == other.gammaGreen
2045 && gammaBlue == other.gammaBlue;
2046 }
2047
operator !=(const BlackWhiteParams & other) const2048 bool BlackWhiteParams::operator !=(const BlackWhiteParams& other) const
2049 {
2050 return !(*this == other);
2051 }
2052
CACorrParams()2053 CACorrParams::CACorrParams() :
2054 red(0.0),
2055 blue(0.0)
2056 {
2057 }
2058
operator ==(const CACorrParams & other) const2059 bool CACorrParams::operator ==(const CACorrParams& other) const
2060 {
2061 return
2062 red == other.red
2063 && blue == other.blue;
2064 }
2065
operator !=(const CACorrParams & other) const2066 bool CACorrParams::operator !=(const CACorrParams& other) const
2067 {
2068 return !(*this == other);
2069 }
2070
ResizeParams()2071 ResizeParams::ResizeParams() :
2072 enabled(false),
2073 scale(1.0),
2074 appliesTo("Cropped area"),
2075 method("Lanczos"),
2076 dataspec(3),
2077 width(900),
2078 height(900),
2079 allowUpscaling(false)
2080 {
2081 }
2082
operator ==(const ResizeParams & other) const2083 bool ResizeParams::operator ==(const ResizeParams& other) const
2084 {
2085 return
2086 enabled == other.enabled
2087 && scale == other.scale
2088 && appliesTo == other.appliesTo
2089 && method == other.method
2090 && dataspec == other.dataspec
2091 && width == other.width
2092 && height == other.height
2093 && allowUpscaling == other.allowUpscaling;
2094 }
2095
operator !=(const ResizeParams & other) const2096 bool ResizeParams::operator !=(const ResizeParams& other) const
2097 {
2098 return !(*this == other);
2099 }
2100
2101 const Glib::ustring ColorManagementParams::NoICMString = Glib::ustring("No ICM: sRGB output");
2102
ColorManagementParams()2103 ColorManagementParams::ColorManagementParams() :
2104 inputProfile("(cameraICC)"),
2105 toneCurve(false),
2106 applyLookTable(false),
2107 applyBaselineExposureOffset(true),
2108 applyHueSatMap(true),
2109 dcpIlluminant(0),
2110 workingProfile("ProPhoto"),
2111 workingTRC("none"),
2112 workingTRCGamma(2.4),
2113 workingTRCSlope(12.92310),
2114 outputProfile(options.rtSettings.srgb),
2115 outputIntent(RI_RELATIVE),
2116 outputBPC(true)
2117 {
2118 }
2119
operator ==(const ColorManagementParams & other) const2120 bool ColorManagementParams::operator ==(const ColorManagementParams& other) const
2121 {
2122 return
2123 inputProfile == other.inputProfile
2124 && toneCurve == other.toneCurve
2125 && applyLookTable == other.applyLookTable
2126 && applyBaselineExposureOffset == other.applyBaselineExposureOffset
2127 && applyHueSatMap == other.applyHueSatMap
2128 && dcpIlluminant == other.dcpIlluminant
2129 && workingProfile == other.workingProfile
2130 && workingTRC == other.workingTRC
2131 && workingTRCGamma == other.workingTRCGamma
2132 && workingTRCSlope == other.workingTRCSlope
2133 && outputProfile == other.outputProfile
2134 && outputIntent == other.outputIntent
2135 && outputBPC == other.outputBPC;
2136 }
2137
operator !=(const ColorManagementParams & other) const2138 bool ColorManagementParams::operator !=(const ColorManagementParams& other) const
2139 {
2140 return !(*this == other);
2141 }
2142
WaveletParams()2143 WaveletParams::WaveletParams() :
2144 ccwcurve{
2145 static_cast<double>(FCT_MinMaxCPoints),
2146 0.0,
2147 0.25,
2148 0.35,
2149 0.35,
2150 0.50,
2151 0.75,
2152 0.35,
2153 0.35,
2154 0.90,
2155 0.0,
2156 0.35,
2157 0.35
2158 },
2159 opacityCurveRG{
2160 static_cast<double>(FCT_MinMaxCPoints),
2161 0.0,
2162 0.50,
2163 0.35,
2164 0.35,
2165 1.00,
2166 0.50,
2167 0.35,
2168 0.35
2169 },
2170 opacityCurveBY{
2171 static_cast<double>(FCT_MinMaxCPoints),
2172 0.0,
2173 0.50,
2174 0.35,
2175 0.35,
2176 1.00,
2177 0.50,
2178 0.35,
2179 0.35
2180 },
2181 opacityCurveW{
2182 static_cast<double>(FCT_MinMaxCPoints),
2183 0.00,
2184 0.35,
2185 0.35,
2186 0.00,
2187 0.35,
2188 0.75,
2189 0.35,
2190 0.35,
2191 0.60,
2192 0.75,
2193 0.35,
2194 0.35,
2195 1.00,
2196 0.35,
2197 0.00,
2198 0.00
2199 },
2200 opacityCurveWL{
2201 static_cast<double>(FCT_MinMaxCPoints),
2202 0.0,
2203 0.50,
2204 0.35,
2205 0.35,
2206 1.00,
2207 0.50,
2208 0.35,
2209 0.35
2210 },
2211 hhcurve{
2212 FCT_Linear
2213 },
2214 Chcurve{
2215 FCT_Linear
2216 },
2217 wavclCurve {
2218 DCT_Linear
2219 },
2220 enabled(false),
2221 median(false),
2222 medianlev(false),
2223 linkedg(true),
2224 cbenab(false),
2225 greenlow(0),
2226 bluelow(0),
2227 greenmed(0),
2228 bluemed(0),
2229 greenhigh(0),
2230 bluehigh(0),
2231 lipst(false),
2232 avoid(false),
2233 tmr(false),
2234 strength(100),
2235 balance(0),
2236 iter(0),
2237 expcontrast(false),
2238 expchroma(false),
2239 c{},
2240 ch{},
2241 expedge(false),
2242 expresid(false),
2243 expfinal(false),
2244 exptoning(false),
2245 expnoise(false),
2246 Lmethod(4),
2247 CLmethod("all"),
2248 Backmethod("grey"),
2249 Tilesmethod("full"),
2250 daubcoeffmethod("4_"),
2251 CHmethod("without"),
2252 Medgreinf("less"),
2253 CHSLmethod("SL"),
2254 EDmethod("CU"),
2255 NPmethod("none"),
2256 BAmethod("none"),
2257 TMmethod("cont"),
2258 Dirmethod("all"),
2259 HSmethod("with"),
2260 rescon(0),
2261 resconH(0),
2262 reschro(0),
2263 tmrs(0),
2264 gamma(1),
2265 sup(0),
2266 sky(0.0),
2267 thres(7),
2268 chroma(5),
2269 chro(0),
2270 threshold(5),
2271 threshold2(4),
2272 edgedetect(90),
2273 edgedetectthr(20),
2274 edgedetectthr2(0),
2275 edgesensi(60),
2276 edgeampli(10),
2277 contrast(0),
2278 edgrad(15),
2279 edgval(0),
2280 edgthresh(10),
2281 thr(35),
2282 thrH(65),
2283 skinprotect(0.0),
2284 hueskin(-5, 25, 170, 120, false),
2285 hueskin2(-260, -250, -130, -140, false),
2286 hllev(50, 75, 100, 98, false),
2287 bllev(0, 2, 50, 25, false),
2288 pastlev(0, 2, 30, 20, false),
2289 satlev(30, 45, 130, 100, false),
2290 edgcont(0, 10, 75, 40, false),
2291 level0noise(0, 0, false),
2292 level1noise(0, 0, false),
2293 level2noise(0, 0, false),
2294 level3noise(0, 0, false)
2295 {
2296 }
2297
operator ==(const WaveletParams & other) const2298 bool WaveletParams::operator ==(const WaveletParams& other) const
2299 {
2300 return
2301 ccwcurve == other.ccwcurve
2302 && opacityCurveRG == other.opacityCurveRG
2303 && opacityCurveBY == other.opacityCurveBY
2304 && opacityCurveW == other.opacityCurveW
2305 && opacityCurveWL == other.opacityCurveWL
2306 && hhcurve == other.hhcurve
2307 && Chcurve == other.Chcurve
2308 && wavclCurve == other.wavclCurve
2309 && enabled == other.enabled
2310 && median == other.median
2311 && medianlev == other.medianlev
2312 && linkedg == other.linkedg
2313 && cbenab == other.cbenab
2314 && greenlow == other.greenlow
2315 && bluelow == other.bluelow
2316 && greenmed == other.greenmed
2317 && bluemed == other.bluemed
2318 && greenhigh == other.greenhigh
2319 && bluehigh == other.bluehigh
2320 && lipst == other.lipst
2321 && avoid == other.avoid
2322 && tmr == other.tmr
2323 && strength == other.strength
2324 && balance == other.balance
2325 && iter == other.iter
2326 && expcontrast == other.expcontrast
2327 && expchroma == other.expchroma
2328 && [this, &other]() -> bool
2329 {
2330 for (unsigned int i = 0; i < 9; ++i) {
2331 if (c[i] != other.c[i] || ch[i] != other.ch[i]) {
2332 return false;
2333 }
2334 }
2335 return true;
2336 }()
2337 && expedge == other.expedge
2338 && expresid == other.expresid
2339 && expfinal == other.expfinal
2340 && exptoning == other.exptoning
2341 && expnoise == other.expnoise
2342 && Lmethod == other.Lmethod
2343 && CLmethod == other.CLmethod
2344 && Backmethod == other.Backmethod
2345 && Tilesmethod == other.Tilesmethod
2346 && daubcoeffmethod == other.daubcoeffmethod
2347 && CHmethod == other.CHmethod
2348 && Medgreinf == other.Medgreinf
2349 && CHSLmethod == other.CHSLmethod
2350 && EDmethod == other.EDmethod
2351 && NPmethod == other.NPmethod
2352 && BAmethod == other.BAmethod
2353 && TMmethod == other.TMmethod
2354 && Dirmethod == other.Dirmethod
2355 && HSmethod == other.HSmethod
2356 && rescon == other.rescon
2357 && resconH == other.resconH
2358 && reschro == other.reschro
2359 && tmrs == other.tmrs
2360 && gamma == other.gamma
2361 && sup == other.sup
2362 && sky == other.sky
2363 && thres == other.thres
2364 && chroma == other.chroma
2365 && chro == other.chro
2366 && threshold == other.threshold
2367 && threshold2 == other.threshold2
2368 && edgedetect == other.edgedetect
2369 && edgedetectthr == other.edgedetectthr
2370 && edgedetectthr2 == other.edgedetectthr2
2371 && edgesensi == other.edgesensi
2372 && edgeampli == other.edgeampli
2373 && contrast == other.contrast
2374 && edgrad == other.edgrad
2375 && edgval == other.edgval
2376 && edgthresh == other.edgthresh
2377 && thr == other.thr
2378 && thrH == other.thrH
2379 && skinprotect == other.skinprotect
2380 && hueskin == other.hueskin
2381 && hueskin2 == other.hueskin2
2382 && hllev == other.hllev
2383 && bllev == other.bllev
2384 && pastlev == other.pastlev
2385 && satlev == other.satlev
2386 && edgcont == other.edgcont
2387 && level0noise == other.level0noise
2388 && level1noise == other.level1noise
2389 && level2noise == other.level2noise
2390 && level3noise == other.level3noise;
2391 }
2392
operator !=(const WaveletParams & other) const2393 bool WaveletParams::operator !=(const WaveletParams& other) const
2394 {
2395 return !(*this == other);
2396 }
2397
getCurves(WavCurve & cCurve,WavOpacityCurveRG & opacityCurveLUTRG,WavOpacityCurveBY & opacityCurveLUTBY,WavOpacityCurveW & opacityCurveLUTW,WavOpacityCurveWL & opacityCurveLUTWL) const2398 void WaveletParams::getCurves(
2399 WavCurve& cCurve,
2400 WavOpacityCurveRG& opacityCurveLUTRG,
2401 WavOpacityCurveBY& opacityCurveLUTBY,
2402 WavOpacityCurveW& opacityCurveLUTW,
2403 WavOpacityCurveWL& opacityCurveLUTWL
2404 ) const
2405 {
2406 cCurve.Set(this->ccwcurve);
2407 opacityCurveLUTRG.Set(this->opacityCurveRG);
2408 opacityCurveLUTBY.Set(this->opacityCurveBY);
2409 opacityCurveLUTW.Set(this->opacityCurveW);
2410 opacityCurveLUTWL.Set(this->opacityCurveWL);
2411
2412 }
2413
DirPyrEqualizerParams()2414 DirPyrEqualizerParams::DirPyrEqualizerParams() :
2415 enabled(false),
2416 gamutlab(false),
2417 mult{
2418 1.0,
2419 1.0,
2420 1.0,
2421 1.0,
2422 1.0,
2423 1.0
2424 },
2425 threshold(0.2),
2426 skinprotect(0.0),
2427 hueskin (-5, 25, 170, 120, false),
2428 cbdlMethod("bef")
2429 {
2430 }
2431
operator ==(const DirPyrEqualizerParams & other) const2432 bool DirPyrEqualizerParams::operator ==(const DirPyrEqualizerParams& other) const
2433 {
2434 return
2435 enabled == other.enabled
2436 && gamutlab == other.gamutlab
2437 && [this, &other]() -> bool
2438 {
2439 for (unsigned int i = 0; i < 6; ++i) {
2440 if (mult[i] != other.mult[i]) {
2441 return false;
2442 }
2443 }
2444 return true;
2445 }()
2446 && threshold == other.threshold
2447 && skinprotect == other.skinprotect
2448 && hueskin == other.hueskin
2449 && cbdlMethod == other.cbdlMethod;
2450 }
2451
operator !=(const DirPyrEqualizerParams & other) const2452 bool DirPyrEqualizerParams::operator !=(const DirPyrEqualizerParams& other) const
2453 {
2454 return !(*this == other);
2455 }
2456
HSVEqualizerParams()2457 HSVEqualizerParams::HSVEqualizerParams() :
2458 enabled(false),
2459 hcurve{
2460 FCT_Linear
2461 },
2462 scurve{
2463 FCT_Linear
2464 },
2465 vcurve{
2466 FCT_Linear
2467 }
2468 {
2469 }
2470
operator ==(const HSVEqualizerParams & other) const2471 bool HSVEqualizerParams::operator ==(const HSVEqualizerParams& other) const
2472 {
2473 return
2474 enabled == other.enabled
2475 && hcurve == other.hcurve
2476 && scurve == other.scurve
2477 && vcurve == other.vcurve;
2478 }
2479
operator !=(const HSVEqualizerParams & other) const2480 bool HSVEqualizerParams::operator !=(const HSVEqualizerParams& other) const
2481 {
2482 return !(*this == other);
2483 }
2484
FilmSimulationParams()2485 FilmSimulationParams::FilmSimulationParams() :
2486 enabled(false),
2487 strength(100)
2488 {
2489 }
2490
operator ==(const FilmSimulationParams & other) const2491 bool FilmSimulationParams::operator ==(const FilmSimulationParams& other) const
2492 {
2493 return
2494 enabled == other.enabled
2495 && clutFilename == other.clutFilename
2496 && strength == other.strength;
2497 }
2498
operator !=(const FilmSimulationParams & other) const2499 bool FilmSimulationParams::operator !=(const FilmSimulationParams& other) const
2500 {
2501 return !(*this == other);
2502 }
2503
2504
SoftLightParams()2505 SoftLightParams::SoftLightParams() :
2506 enabled(false),
2507 strength(30)
2508 {
2509 }
2510
operator ==(const SoftLightParams & other) const2511 bool SoftLightParams::operator ==(const SoftLightParams& other) const
2512 {
2513 return
2514 enabled == other.enabled
2515 && strength == other.strength;
2516 }
2517
operator !=(const SoftLightParams & other) const2518 bool SoftLightParams::operator !=(const SoftLightParams& other) const
2519 {
2520 return !(*this == other);
2521 }
2522
2523
DehazeParams()2524 DehazeParams::DehazeParams() :
2525 enabled(false),
2526 strength(50),
2527 showDepthMap(false),
2528 depth(25),
2529 luminance(false)
2530 {
2531 }
2532
operator ==(const DehazeParams & other) const2533 bool DehazeParams::operator ==(const DehazeParams& other) const
2534 {
2535 return
2536 enabled == other.enabled
2537 && strength == other.strength
2538 && showDepthMap == other.showDepthMap
2539 && depth == other.depth
2540 && luminance == other.luminance;
2541 }
2542
operator !=(const DehazeParams & other) const2543 bool DehazeParams::operator !=(const DehazeParams& other) const
2544 {
2545 return !(*this == other);
2546 }
2547
2548
BayerSensor()2549 RAWParams::BayerSensor::BayerSensor() :
2550 method(getMethodString(Method::AMAZE)),
2551 border(4),
2552 imageNum(0),
2553 ccSteps(0),
2554 black0(0.0),
2555 black1(0.0),
2556 black2(0.0),
2557 black3(0.0),
2558 twogreen(true),
2559 linenoise(0),
2560 linenoiseDirection(LineNoiseDirection::BOTH),
2561 greenthresh(0),
2562 dcb_iterations(2),
2563 lmmse_iterations(2),
2564 dualDemosaicAutoContrast(true),
2565 dualDemosaicContrast(20),
2566 pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO),
2567 pixelShiftEperIso(0.0),
2568 pixelShiftSigma(1.0),
2569 pixelShiftShowMotion(false),
2570 pixelShiftShowMotionMaskOnly(false),
2571 pixelShiftHoleFill(true),
2572 pixelShiftMedian(false),
2573 pixelShiftGreen(true),
2574 pixelShiftBlur(true),
2575 pixelShiftSmoothFactor(0.7),
2576 pixelShiftEqualBright(false),
2577 pixelShiftEqualBrightChannel(false),
2578 pixelShiftNonGreenCross(true),
2579 pixelShiftDemosaicMethod(getPSDemosaicMethodString(PSDemosaicMethod::AMAZE)),
2580 dcb_enhance(true),
2581 pdafLinesFilter(false)
2582 {
2583 }
2584
operator ==(const BayerSensor & other) const2585 bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const
2586 {
2587 return
2588 method == other.method
2589 && border == other.border
2590 && imageNum == other.imageNum
2591 && ccSteps == other.ccSteps
2592 && black0 == other.black0
2593 && black1 == other.black1
2594 && black2 == other.black2
2595 && black3 == other.black3
2596 && twogreen == other.twogreen
2597 && linenoise == other.linenoise
2598 && linenoiseDirection == other.linenoiseDirection
2599 && greenthresh == other.greenthresh
2600 && dcb_iterations == other.dcb_iterations
2601 && lmmse_iterations == other.lmmse_iterations
2602 && dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
2603 && dualDemosaicContrast == other.dualDemosaicContrast
2604 && pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod
2605 && pixelShiftEperIso == other.pixelShiftEperIso
2606 && pixelShiftSigma == other.pixelShiftSigma
2607 && pixelShiftShowMotion == other.pixelShiftShowMotion
2608 && pixelShiftShowMotionMaskOnly == other.pixelShiftShowMotionMaskOnly
2609 && pixelShiftHoleFill == other.pixelShiftHoleFill
2610 && pixelShiftMedian == other.pixelShiftMedian
2611 && pixelShiftGreen == other.pixelShiftGreen
2612 && pixelShiftBlur == other.pixelShiftBlur
2613 && pixelShiftSmoothFactor == other.pixelShiftSmoothFactor
2614 && pixelShiftEqualBright == other.pixelShiftEqualBright
2615 && pixelShiftEqualBrightChannel == other.pixelShiftEqualBrightChannel
2616 && pixelShiftNonGreenCross == other.pixelShiftNonGreenCross
2617 && pixelShiftDemosaicMethod == other.pixelShiftDemosaicMethod
2618 && dcb_enhance == other.dcb_enhance
2619 && pdafLinesFilter == other.pdafLinesFilter;
2620 }
2621
operator !=(const BayerSensor & other) const2622 bool RAWParams::BayerSensor::operator !=(const BayerSensor& other) const
2623 {
2624 return !(*this == other);
2625 }
2626
setPixelShiftDefaults()2627 void RAWParams::BayerSensor::setPixelShiftDefaults()
2628 {
2629 pixelShiftMotionCorrectionMethod = RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO;
2630 pixelShiftEperIso = 0.0;
2631 pixelShiftSigma = 1.0;
2632 pixelShiftHoleFill = true;
2633 pixelShiftMedian = false;
2634 pixelShiftGreen = true;
2635 pixelShiftBlur = true;
2636 pixelShiftSmoothFactor = 0.7;
2637 pixelShiftEqualBright = false;
2638 pixelShiftEqualBrightChannel = false;
2639 pixelShiftNonGreenCross = true;
2640 pixelShiftDemosaicMethod = getPSDemosaicMethodString(PSDemosaicMethod::AMAZE);
2641 }
2642
getMethodStrings()2643 const std::vector<const char*>& RAWParams::BayerSensor::getMethodStrings()
2644 {
2645 static const std::vector<const char*> method_strings {
2646 "amaze",
2647 "amazevng4",
2648 "rcd",
2649 "rcdvng4",
2650 "dcb",
2651 "dcbvng4",
2652 "lmmse",
2653 "igv",
2654 "ahd",
2655 "eahd",
2656 "hphd",
2657 "vng4",
2658 "fast",
2659 "mono",
2660 "pixelshift",
2661 "none"
2662 };
2663 return method_strings;
2664 }
2665
getMethodString(Method method)2666 Glib::ustring RAWParams::BayerSensor::getMethodString(Method method)
2667 {
2668 return getMethodStrings()[toUnderlying(method)];
2669 }
2670
getPSDemosaicMethodStrings()2671 const std::vector<const char*>& RAWParams::BayerSensor::getPSDemosaicMethodStrings()
2672 {
2673 static const std::vector<const char*> method_strings {
2674 "amaze",
2675 "amazevng4",
2676 "rcdvng4",
2677 "lmmse"
2678 };
2679 return method_strings;
2680 }
2681
getPSDemosaicMethodString(PSDemosaicMethod method)2682 Glib::ustring RAWParams::BayerSensor::getPSDemosaicMethodString(PSDemosaicMethod method)
2683 {
2684 return getPSDemosaicMethodStrings()[toUnderlying(method)];
2685 }
2686
2687
2688
XTransSensor()2689 RAWParams::XTransSensor::XTransSensor() :
2690 method(getMethodString(Method::THREE_PASS)),
2691 dualDemosaicAutoContrast(true),
2692 dualDemosaicContrast(20),
2693 border(7),
2694 ccSteps(0),
2695 blackred(0.0),
2696 blackgreen(0.0),
2697 blackblue(0.0)
2698 {
2699 }
2700
operator ==(const XTransSensor & other) const2701 bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const
2702 {
2703 return
2704 method == other.method
2705 && dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
2706 && dualDemosaicContrast == other.dualDemosaicContrast
2707 && border == other.border
2708 && ccSteps == other.ccSteps
2709 && blackred == other.blackred
2710 && blackgreen == other.blackgreen
2711 && blackblue == other.blackblue;
2712 }
2713
operator !=(const XTransSensor & other) const2714 bool RAWParams::XTransSensor::operator !=(const XTransSensor& other) const
2715 {
2716 return !(*this == other);
2717 }
2718
getMethodStrings()2719 const std::vector<const char*>& RAWParams::XTransSensor::getMethodStrings()
2720 {
2721 static const std::vector<const char*> method_strings {
2722 "4-pass",
2723 "3-pass (best)",
2724 "2-pass",
2725 "1-pass (medium)",
2726 "fast",
2727 "mono",
2728 "none"
2729 };
2730 return method_strings;
2731 }
2732
getMethodString(Method method)2733 Glib::ustring RAWParams::XTransSensor::getMethodString(Method method)
2734 {
2735 return getMethodStrings()[toUnderlying(method)];
2736 }
2737
RAWParams()2738 RAWParams::RAWParams() :
2739 df_autoselect(false),
2740 ff_AutoSelect(false),
2741 ff_BlurRadius(32),
2742 ff_BlurType(getFlatFieldBlurTypeString(FlatFieldBlurType::AREA)),
2743 ff_AutoClipControl(false),
2744 ff_clipControl(0),
2745 ca_autocorrect(false),
2746 ca_avoidcolourshift(true),
2747 caautoiterations(2),
2748 cared(0.0),
2749 cablue(0.0),
2750 expos(1.0),
2751 hotPixelFilter(false),
2752 deadPixelFilter(false),
2753 hotdeadpix_thresh(100)
2754 {
2755 }
2756
operator ==(const RAWParams & other) const2757 bool RAWParams::operator ==(const RAWParams& other) const
2758 {
2759 return
2760 bayersensor == other.bayersensor
2761 && xtranssensor == other.xtranssensor
2762 && dark_frame == other.dark_frame
2763 && df_autoselect == other.df_autoselect
2764 && ff_file == other.ff_file
2765 && ff_AutoSelect == other.ff_AutoSelect
2766 && ff_BlurRadius == other.ff_BlurRadius
2767 && ff_BlurType == other.ff_BlurType
2768 && ff_AutoClipControl == other.ff_AutoClipControl
2769 && ff_clipControl == other.ff_clipControl
2770 && ca_autocorrect == other.ca_autocorrect
2771 && ca_avoidcolourshift == other.ca_avoidcolourshift
2772 && caautoiterations == other.caautoiterations
2773 && cared == other.cared
2774 && cablue == other.cablue
2775 && expos == other.expos
2776 && hotPixelFilter == other.hotPixelFilter
2777 && deadPixelFilter == other.deadPixelFilter
2778 && hotdeadpix_thresh == other.hotdeadpix_thresh;
2779 }
2780
operator !=(const RAWParams & other) const2781 bool RAWParams::operator !=(const RAWParams& other) const
2782 {
2783 return !(*this == other);
2784 }
2785
getFlatFieldBlurTypeStrings()2786 const std::vector<const char*>& RAWParams::getFlatFieldBlurTypeStrings()
2787 {
2788 static const std::vector<const char*> blur_type_strings {
2789 "Area Flatfield",
2790 "Vertical Flatfield",
2791 "Horizontal Flatfield",
2792 "V+H Flatfield"
2793 };
2794 return blur_type_strings;
2795 }
2796
getFlatFieldBlurTypeString(FlatFieldBlurType type)2797 Glib::ustring RAWParams::getFlatFieldBlurTypeString(FlatFieldBlurType type)
2798 {
2799 return getFlatFieldBlurTypeStrings()[toUnderlying(type)];
2800 }
2801
2802
MetaDataParams()2803 MetaDataParams::MetaDataParams():
2804 mode(MetaDataParams::TUNNEL)
2805 {
2806 }
2807
operator ==(const MetaDataParams & other) const2808 bool MetaDataParams::operator==(const MetaDataParams &other) const
2809 {
2810 return mode == other.mode;
2811 }
2812
operator !=(const MetaDataParams & other) const2813 bool MetaDataParams::operator!=(const MetaDataParams &other) const
2814 {
2815 return !(*this == other);
2816 }
2817
FilmNegativeParams()2818 FilmNegativeParams::FilmNegativeParams() :
2819 enabled(false),
2820 redRatio(1.36),
2821 greenExp(1.5),
2822 blueRatio(0.86)
2823 {
2824 }
2825
operator ==(const FilmNegativeParams & other) const2826 bool FilmNegativeParams::operator ==(const FilmNegativeParams& other) const
2827 {
2828 return
2829 enabled == other.enabled
2830 && redRatio == other.redRatio
2831 && greenExp == other.greenExp
2832 && blueRatio == other.blueRatio;
2833 }
2834
operator !=(const FilmNegativeParams & other) const2835 bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const
2836 {
2837 return !(*this == other);
2838 }
2839
ProcParams()2840 ProcParams::ProcParams()
2841 {
2842 setDefaults();
2843 }
2844
setDefaults()2845 void ProcParams::setDefaults()
2846 {
2847 toneCurve = {};
2848
2849 labCurve = {};
2850
2851 rgbCurves = {};
2852
2853 localContrast = {};
2854
2855 colorToning = {};
2856
2857 sharpenEdge = {};
2858
2859 sharpenMicro = {};
2860
2861 sharpening = {};
2862
2863 prsharpening = {};
2864 prsharpening.contrast = 15.0;
2865 prsharpening.method = "rld";
2866 prsharpening.deconvamount = 100;
2867 prsharpening.deconvradius = 0.45;
2868 prsharpening.deconviter = 100;
2869 prsharpening.deconvdamping = 0;
2870
2871 pdsharpening = {};
2872
2873 vibrance = {};
2874
2875 wb = {};
2876
2877 colorappearance = {};
2878
2879 defringe = {};
2880
2881 impulseDenoise = {};
2882
2883 dirpyrDenoise = {};
2884
2885 epd = {};
2886
2887 fattal = {};
2888
2889 sh = {};
2890
2891 crop = {};
2892
2893 coarse = {};
2894
2895 commonTrans = {};
2896
2897 rotate = {};
2898
2899 distortion = {};
2900
2901 lensProf = {};
2902
2903 perspective = {};
2904
2905 gradient = {};
2906
2907 pcvignette = {};
2908
2909 vignetting = {};
2910
2911 chmixer = {};
2912
2913 blackwhite = {};
2914
2915 cacorrection = {};
2916
2917 resize = {};
2918
2919 icm = {};
2920
2921 wavelet = {};
2922
2923 dirpyrequalizer = {};
2924
2925 hsvequalizer = {};
2926
2927 filmSimulation = {};
2928
2929 softlight = {};
2930
2931 dehaze = {};
2932
2933 raw = {};
2934
2935 metadata = {};
2936 exif.clear();
2937 iptc.clear();
2938
2939 // -1 means that there's no pp3 data with rank yet. In this case, the
2940 // embedded Rating metadata should take precedence. -1 should never be
2941 // written to pp3 on disk.
2942 rank = -1;
2943 colorlabel = 0;
2944 inTrash = false;
2945
2946 ppVersion = PPVERSION;
2947 }
2948
save(const Glib::ustring & fname,const Glib::ustring & fname2,bool fnameAbsolute,ParamsEdited * pedited)2949 int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bool fnameAbsolute, ParamsEdited* pedited)
2950 {
2951 if (fname.empty() && fname2.empty()) {
2952 return 0;
2953 }
2954
2955 Glib::ustring sPParams;
2956
2957 try {
2958 Glib::KeyFile keyFile;
2959
2960 // Version
2961 keyFile.set_string("Version", "AppVersion", RTVERSION);
2962 keyFile.set_integer("Version", "Version", PPVERSION);
2963
2964 saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", rank, keyFile);
2965 saveToKeyfile(!pedited || pedited->general.colorlabel, "General", "ColorLabel", colorlabel, keyFile);
2966 saveToKeyfile(!pedited || pedited->general.intrash, "General", "InTrash", inTrash, keyFile);
2967
2968 // Tone curve
2969 saveToKeyfile(!pedited || pedited->toneCurve.autoexp, "Exposure", "Auto", toneCurve.autoexp, keyFile);
2970 saveToKeyfile(!pedited || pedited->toneCurve.clip, "Exposure", "Clip", toneCurve.clip, keyFile);
2971 saveToKeyfile(!pedited || pedited->toneCurve.expcomp, "Exposure", "Compensation", toneCurve.expcomp, keyFile);
2972 saveToKeyfile(!pedited || pedited->toneCurve.brightness, "Exposure", "Brightness", toneCurve.brightness, keyFile);
2973 saveToKeyfile(!pedited || pedited->toneCurve.contrast, "Exposure", "Contrast", toneCurve.contrast, keyFile);
2974 saveToKeyfile(!pedited || pedited->toneCurve.saturation, "Exposure", "Saturation", toneCurve.saturation, keyFile);
2975 saveToKeyfile(!pedited || pedited->toneCurve.black, "Exposure", "Black", toneCurve.black, keyFile);
2976 saveToKeyfile(!pedited || pedited->toneCurve.hlcompr, "Exposure", "HighlightCompr", toneCurve.hlcompr, keyFile);
2977 saveToKeyfile(!pedited || pedited->toneCurve.hlcomprthresh, "Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh, keyFile);
2978 saveToKeyfile(!pedited || pedited->toneCurve.shcompr, "Exposure", "ShadowCompr", toneCurve.shcompr, keyFile);
2979 saveToKeyfile(!pedited || pedited->toneCurve.histmatching, "Exposure", "HistogramMatching", toneCurve.histmatching, keyFile);
2980 saveToKeyfile(!pedited || pedited->toneCurve.fromHistMatching, "Exposure", "CurveFromHistogramMatching", toneCurve.fromHistMatching, keyFile);
2981 saveToKeyfile(!pedited || pedited->toneCurve.clampOOG, "Exposure", "ClampOOG", toneCurve.clampOOG, keyFile);
2982
2983 // Highlight recovery
2984 saveToKeyfile(!pedited || pedited->toneCurve.hrenabled, "HLRecovery", "Enabled", toneCurve.hrenabled, keyFile);
2985 saveToKeyfile(!pedited || pedited->toneCurve.method, "HLRecovery", "Method", toneCurve.method, keyFile);
2986
2987 const std::map<ToneCurveMode, const char*> tc_mapping = {
2988 {ToneCurveMode::STD, "Standard"},
2989 {ToneCurveMode::FILMLIKE, "FilmLike"},
2990 {ToneCurveMode::SATANDVALBLENDING, "SatAndValueBlending"},
2991 {ToneCurveMode::WEIGHTEDSTD, "WeightedStd"},
2992 {ToneCurveMode::LUMINANCE, "Luminance"},
2993 {ToneCurveMode::PERCEPTUAL, "Perceptual"}
2994 };
2995
2996 saveToKeyfile(!pedited || pedited->toneCurve.curveMode, "Exposure", "CurveMode", tc_mapping, toneCurve.curveMode, keyFile);
2997 saveToKeyfile(!pedited || pedited->toneCurve.curveMode2, "Exposure", "CurveMode2", tc_mapping, toneCurve.curveMode2, keyFile);
2998
2999 saveToKeyfile(!pedited || pedited->toneCurve.curve, "Exposure", "Curve", toneCurve.curve, keyFile);
3000 saveToKeyfile(!pedited || pedited->toneCurve.curve2, "Exposure", "Curve2", toneCurve.curve2, keyFile);
3001
3002 // Retinex
3003 saveToKeyfile(!pedited || pedited->retinex.enabled, "Retinex", "Enabled", retinex.enabled, keyFile);
3004 saveToKeyfile(!pedited || pedited->retinex.str, "Retinex", "Str", retinex.str, keyFile);
3005 saveToKeyfile(!pedited || pedited->retinex.scal, "Retinex", "Scal", retinex.scal, keyFile);
3006 saveToKeyfile(!pedited || pedited->retinex.iter, "Retinex", "Iter", retinex.iter, keyFile);
3007 saveToKeyfile(!pedited || pedited->retinex.grad, "Retinex", "Grad", retinex.grad, keyFile);
3008 saveToKeyfile(!pedited || pedited->retinex.grads, "Retinex", "Grads", retinex.grads, keyFile);
3009 saveToKeyfile(!pedited || pedited->retinex.gam, "Retinex", "Gam", retinex.gam, keyFile);
3010 saveToKeyfile(!pedited || pedited->retinex.slope, "Retinex", "Slope", retinex.slope, keyFile);
3011 saveToKeyfile(!pedited || pedited->retinex.medianmap, "Retinex", "Median", retinex.medianmap, keyFile);
3012
3013 saveToKeyfile(!pedited || pedited->retinex.neigh, "Retinex", "Neigh", retinex.neigh, keyFile);
3014 saveToKeyfile(!pedited || pedited->retinex.offs, "Retinex", "Offs", retinex.offs, keyFile);
3015 saveToKeyfile(!pedited || pedited->retinex.vart, "Retinex", "Vart", retinex.vart, keyFile);
3016 saveToKeyfile(!pedited || pedited->retinex.limd, "Retinex", "Limd", retinex.limd, keyFile);
3017 saveToKeyfile(!pedited || pedited->retinex.highl, "Retinex", "highl", retinex.highl, keyFile);
3018 saveToKeyfile(!pedited || pedited->retinex.skal, "Retinex", "skal", retinex.skal, keyFile);
3019 saveToKeyfile(!pedited || pedited->retinex.retinexMethod, "Retinex", "RetinexMethod", retinex.retinexMethod, keyFile);
3020 saveToKeyfile(!pedited || pedited->retinex.mapMethod, "Retinex", "mapMethod", retinex.mapMethod, keyFile);
3021 saveToKeyfile(!pedited || pedited->retinex.viewMethod, "Retinex", "viewMethod", retinex.viewMethod, keyFile);
3022 saveToKeyfile(!pedited || pedited->retinex.retinexcolorspace, "Retinex", "Retinexcolorspace", retinex.retinexcolorspace, keyFile);
3023 saveToKeyfile(!pedited || pedited->retinex.gammaretinex, "Retinex", "Gammaretinex", retinex.gammaretinex, keyFile);
3024 saveToKeyfile(!pedited || pedited->retinex.cdcurve, "Retinex", "CDCurve", retinex.cdcurve, keyFile);
3025 saveToKeyfile(!pedited || pedited->retinex.mapcurve, "Retinex", "MAPCurve", retinex.mapcurve, keyFile);
3026 saveToKeyfile(!pedited || pedited->retinex.cdHcurve, "Retinex", "CDHCurve", retinex.cdHcurve, keyFile);
3027 saveToKeyfile(!pedited || pedited->retinex.lhcurve, "Retinex", "LHCurve", retinex.lhcurve, keyFile);
3028 saveToKeyfile(!pedited || pedited->retinex.highlights, "Retinex", "Highlights", retinex.highlights, keyFile);
3029 saveToKeyfile(!pedited || pedited->retinex.htonalwidth, "Retinex", "HighlightTonalWidth", retinex.htonalwidth, keyFile);
3030 saveToKeyfile(!pedited || pedited->retinex.shadows, "Retinex", "Shadows", retinex.shadows, keyFile);
3031 saveToKeyfile(!pedited || pedited->retinex.stonalwidth, "Retinex", "ShadowTonalWidth", retinex.stonalwidth, keyFile);
3032 saveToKeyfile(!pedited || pedited->retinex.radius, "Retinex", "Radius", retinex.radius, keyFile);
3033 saveToKeyfile(!pedited || pedited->retinex.transmissionCurve, "Retinex", "TransmissionCurve", retinex.transmissionCurve, keyFile);
3034 saveToKeyfile(!pedited || pedited->retinex.gaintransmissionCurve, "Retinex", "GainTransmissionCurve", retinex.gaintransmissionCurve, keyFile);
3035
3036 // Local contrast
3037 saveToKeyfile(!pedited || pedited->localContrast.enabled, "Local Contrast", "Enabled", localContrast.enabled, keyFile);
3038 saveToKeyfile(!pedited || pedited->localContrast.radius, "Local Contrast", "Radius", localContrast.radius, keyFile);
3039 saveToKeyfile(!pedited || pedited->localContrast.amount, "Local Contrast", "Amount", localContrast.amount, keyFile);
3040 saveToKeyfile(!pedited || pedited->localContrast.darkness, "Local Contrast", "Darkness", localContrast.darkness, keyFile);
3041 saveToKeyfile(!pedited || pedited->localContrast.lightness, "Local Contrast", "Lightness", localContrast.lightness, keyFile);
3042
3043
3044 // Channel mixer
3045 saveToKeyfile(!pedited || pedited->chmixer.enabled, "Channel Mixer", "Enabled", chmixer.enabled, keyFile);
3046
3047 if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) {
3048 Glib::ArrayHandle<int> rmix(chmixer.red, 3, Glib::OWNERSHIP_NONE);
3049 keyFile.set_integer_list("Channel Mixer", "Red", rmix);
3050 }
3051
3052 if (!pedited || pedited->chmixer.green[0] || pedited->chmixer.green[1] || pedited->chmixer.green[2]) {
3053 Glib::ArrayHandle<int> gmix(chmixer.green, 3, Glib::OWNERSHIP_NONE);
3054 keyFile.set_integer_list("Channel Mixer", "Green", gmix);
3055 }
3056
3057 if (!pedited || pedited->chmixer.blue[0] || pedited->chmixer.blue[1] || pedited->chmixer.blue[2]) {
3058 Glib::ArrayHandle<int> bmix(chmixer.blue, 3, Glib::OWNERSHIP_NONE);
3059 keyFile.set_integer_list("Channel Mixer", "Blue", bmix);
3060 }
3061
3062 // Black & White
3063 saveToKeyfile(!pedited || pedited->blackwhite.enabled, "Black & White", "Enabled", blackwhite.enabled, keyFile);
3064 saveToKeyfile(!pedited || pedited->blackwhite.method, "Black & White", "Method", blackwhite.method, keyFile);
3065 saveToKeyfile(!pedited || pedited->blackwhite.autoc, "Black & White", "Auto", blackwhite.autoc, keyFile);
3066 saveToKeyfile(!pedited || pedited->blackwhite.enabledcc, "Black & White", "ComplementaryColors", blackwhite.enabledcc, keyFile);
3067 saveToKeyfile(!pedited || pedited->blackwhite.setting, "Black & White", "Setting", blackwhite.setting, keyFile);
3068 saveToKeyfile(!pedited || pedited->blackwhite.filter, "Black & White", "Filter", blackwhite.filter, keyFile);
3069 saveToKeyfile(!pedited || pedited->blackwhite.mixerRed, "Black & White", "MixerRed", blackwhite.mixerRed, keyFile);
3070 saveToKeyfile(!pedited || pedited->blackwhite.mixerOrange, "Black & White", "MixerOrange", blackwhite.mixerOrange, keyFile);
3071 saveToKeyfile(!pedited || pedited->blackwhite.mixerYellow, "Black & White", "MixerYellow", blackwhite.mixerYellow, keyFile);
3072 saveToKeyfile(!pedited || pedited->blackwhite.mixerGreen, "Black & White", "MixerGreen", blackwhite.mixerGreen, keyFile);
3073 saveToKeyfile(!pedited || pedited->blackwhite.mixerCyan, "Black & White", "MixerCyan", blackwhite.mixerCyan, keyFile);
3074 saveToKeyfile(!pedited || pedited->blackwhite.mixerBlue, "Black & White", "MixerBlue", blackwhite.mixerBlue, keyFile);
3075 saveToKeyfile(!pedited || pedited->blackwhite.mixerMagenta, "Black & White", "MixerMagenta", blackwhite.mixerMagenta, keyFile);
3076 saveToKeyfile(!pedited || pedited->blackwhite.mixerPurple, "Black & White", "MixerPurple", blackwhite.mixerPurple, keyFile);
3077 saveToKeyfile(!pedited || pedited->blackwhite.gammaRed, "Black & White", "GammaRed", blackwhite.gammaRed, keyFile);
3078 saveToKeyfile(!pedited || pedited->blackwhite.gammaGreen, "Black & White", "GammaGreen", blackwhite.gammaGreen, keyFile);
3079 saveToKeyfile(!pedited || pedited->blackwhite.gammaBlue, "Black & White", "GammaBlue", blackwhite.gammaBlue, keyFile);
3080 saveToKeyfile(!pedited || pedited->blackwhite.algo, "Black & White", "Algorithm", blackwhite.algo, keyFile);
3081 saveToKeyfile(!pedited || pedited->blackwhite.luminanceCurve, "Black & White", "LuminanceCurve", blackwhite.luminanceCurve, keyFile);
3082 saveToKeyfile(
3083 !pedited || pedited->blackwhite.beforeCurveMode,
3084 "Black & White",
3085 "BeforeCurveMode",
3086 {
3087 {BlackWhiteParams::TcMode::STD_BW, "Standard"},
3088 {BlackWhiteParams::TcMode::FILMLIKE_BW, "FilmLike"},
3089 {BlackWhiteParams::TcMode::SATANDVALBLENDING_BW, "SatAndValueBlending"},
3090 {BlackWhiteParams::TcMode::WEIGHTEDSTD_BW, "WeightedStd"}
3091
3092 },
3093 blackwhite.beforeCurveMode,
3094 keyFile
3095 );
3096 saveToKeyfile(
3097 !pedited || pedited->blackwhite.afterCurveMode,
3098 "Black & White",
3099 "AfterCurveMode",
3100 {
3101 {BlackWhiteParams::TcMode::STD_BW, "Standard"},
3102 {BlackWhiteParams::TcMode::WEIGHTEDSTD_BW, "WeightedStd"}
3103
3104 },
3105 blackwhite.afterCurveMode,
3106 keyFile
3107 );
3108 saveToKeyfile(!pedited || pedited->blackwhite.beforeCurve, "Black & White", "BeforeCurve", blackwhite.beforeCurve, keyFile);
3109 saveToKeyfile(!pedited || pedited->blackwhite.afterCurve, "Black & White", "AfterCurve", blackwhite.afterCurve, keyFile);
3110
3111 // Luma curve
3112 saveToKeyfile(!pedited || pedited->labCurve.enabled, "Luminance Curve", "Enabled", labCurve.enabled, keyFile);
3113 saveToKeyfile(!pedited || pedited->labCurve.brightness, "Luminance Curve", "Brightness", labCurve.brightness, keyFile);
3114 saveToKeyfile(!pedited || pedited->labCurve.contrast, "Luminance Curve", "Contrast", labCurve.contrast, keyFile);
3115 saveToKeyfile(!pedited || pedited->labCurve.chromaticity, "Luminance Curve", "Chromaticity", labCurve.chromaticity, keyFile);
3116 saveToKeyfile(!pedited || pedited->labCurve.avoidcolorshift, "Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift, keyFile);
3117 saveToKeyfile(!pedited || pedited->labCurve.rstprotection, "Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection, keyFile);
3118 saveToKeyfile(!pedited || pedited->labCurve.lcredsk, "Luminance Curve", "LCredsk", labCurve.lcredsk, keyFile);
3119 saveToKeyfile(!pedited || pedited->labCurve.lcurve, "Luminance Curve", "LCurve", labCurve.lcurve, keyFile);
3120 saveToKeyfile(!pedited || pedited->labCurve.acurve, "Luminance Curve", "aCurve", labCurve.acurve, keyFile);
3121 saveToKeyfile(!pedited || pedited->labCurve.bcurve, "Luminance Curve", "bCurve", labCurve.bcurve, keyFile);
3122 saveToKeyfile(!pedited || pedited->labCurve.cccurve, "Luminance Curve", "ccCurve", labCurve.cccurve, keyFile);
3123 saveToKeyfile(!pedited || pedited->labCurve.chcurve, "Luminance Curve", "chCurve", labCurve.chcurve, keyFile);
3124 saveToKeyfile(!pedited || pedited->labCurve.lhcurve, "Luminance Curve", "lhCurve", labCurve.lhcurve, keyFile);
3125 saveToKeyfile(!pedited || pedited->labCurve.hhcurve, "Luminance Curve", "hhCurve", labCurve.hhcurve, keyFile);
3126 saveToKeyfile(!pedited || pedited->labCurve.lccurve, "Luminance Curve", "LcCurve", labCurve.lccurve, keyFile);
3127 saveToKeyfile(!pedited || pedited->labCurve.clcurve, "Luminance Curve", "ClCurve", labCurve.clcurve, keyFile);
3128
3129 // Sharpening
3130 saveToKeyfile(!pedited || pedited->sharpening.enabled, "Sharpening", "Enabled", sharpening.enabled, keyFile);
3131 saveToKeyfile(!pedited || pedited->sharpening.contrast, "Sharpening", "Contrast", sharpening.contrast, keyFile);
3132 saveToKeyfile(!pedited || pedited->sharpening.method, "Sharpening", "Method", sharpening.method, keyFile);
3133 saveToKeyfile(!pedited || pedited->sharpening.radius, "Sharpening", "Radius", sharpening.radius, keyFile);
3134 saveToKeyfile(!pedited || pedited->sharpening.blurradius, "Sharpening", "BlurRadius", sharpening.blurradius, keyFile);
3135 saveToKeyfile(!pedited || pedited->sharpening.amount, "Sharpening", "Amount", sharpening.amount, keyFile);
3136 saveToKeyfile(!pedited || pedited->sharpening.threshold, "Sharpening", "Threshold", sharpening.threshold.toVector(), keyFile);
3137 saveToKeyfile(!pedited || pedited->sharpening.edgesonly, "Sharpening", "OnlyEdges", sharpening.edgesonly, keyFile);
3138 saveToKeyfile(!pedited || pedited->sharpening.edges_radius, "Sharpening", "EdgedetectionRadius", sharpening.edges_radius, keyFile);
3139 saveToKeyfile(!pedited || pedited->sharpening.edges_tolerance, "Sharpening", "EdgeTolerance", sharpening.edges_tolerance, keyFile);
3140 saveToKeyfile(!pedited || pedited->sharpening.halocontrol, "Sharpening", "HalocontrolEnabled", sharpening.halocontrol, keyFile);
3141 saveToKeyfile(!pedited || pedited->sharpening.halocontrol_amount, "Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount, keyFile);
3142 saveToKeyfile(!pedited || pedited->sharpening.deconvradius, "Sharpening", "DeconvRadius", sharpening.deconvradius, keyFile);
3143 saveToKeyfile(!pedited || pedited->sharpening.deconvamount, "Sharpening", "DeconvAmount", sharpening.deconvamount, keyFile);
3144 saveToKeyfile(!pedited || pedited->sharpening.deconvdamping, "Sharpening", "DeconvDamping", sharpening.deconvdamping, keyFile);
3145 saveToKeyfile(!pedited || pedited->sharpening.deconviter, "Sharpening", "DeconvIterations", sharpening.deconviter, keyFile);
3146
3147 // Vibrance
3148 saveToKeyfile(!pedited || pedited->vibrance.enabled, "Vibrance", "Enabled", vibrance.enabled, keyFile);
3149 saveToKeyfile(!pedited || pedited->vibrance.pastels, "Vibrance", "Pastels", vibrance.pastels, keyFile);
3150 saveToKeyfile(!pedited || pedited->vibrance.saturated, "Vibrance", "Saturated", vibrance.saturated, keyFile);
3151 saveToKeyfile(!pedited || pedited->vibrance.psthreshold, "Vibrance", "PSThreshold", vibrance.psthreshold.toVector(), keyFile);
3152 saveToKeyfile(!pedited || pedited->vibrance.protectskins, "Vibrance", "ProtectSkins", vibrance.protectskins, keyFile);
3153 saveToKeyfile(!pedited || pedited->vibrance.avoidcolorshift, "Vibrance", "AvoidColorShift", vibrance.avoidcolorshift, keyFile);
3154 saveToKeyfile(!pedited || pedited->vibrance.pastsattog, "Vibrance", "PastSatTog", vibrance.pastsattog, keyFile);
3155 saveToKeyfile(!pedited || pedited->vibrance.skintonescurve, "Vibrance", "SkinTonesCurve", vibrance.skintonescurve, keyFile);
3156
3157 // Edge sharpening
3158 saveToKeyfile(!pedited || pedited->sharpenEdge.enabled, "SharpenEdge", "Enabled", sharpenEdge.enabled, keyFile);
3159 saveToKeyfile(!pedited || pedited->sharpenEdge.passes, "SharpenEdge", "Passes", sharpenEdge.passes, keyFile);
3160 saveToKeyfile(!pedited || pedited->sharpenEdge.amount, "SharpenEdge", "Strength", sharpenEdge.amount, keyFile);
3161 saveToKeyfile(!pedited || pedited->sharpenEdge.threechannels, "SharpenEdge", "ThreeChannels", sharpenEdge.threechannels, keyFile);
3162
3163 // Micro-contrast sharpening
3164 saveToKeyfile(!pedited || pedited->sharpenMicro.enabled, "SharpenMicro", "Enabled", sharpenMicro.enabled, keyFile);
3165 saveToKeyfile(!pedited || pedited->sharpenMicro.matrix, "SharpenMicro", "Matrix", sharpenMicro.matrix, keyFile);
3166 saveToKeyfile(!pedited || pedited->sharpenMicro.amount, "SharpenMicro", "Strength", sharpenMicro.amount, keyFile);
3167 saveToKeyfile(!pedited || pedited->sharpenMicro.contrast, "SharpenMicro", "Contrast", sharpenMicro.contrast, keyFile);
3168 saveToKeyfile(!pedited || pedited->sharpenMicro.uniformity, "SharpenMicro", "Uniformity", sharpenMicro.uniformity, keyFile);
3169
3170 // WB
3171 saveToKeyfile(!pedited || pedited->wb.enabled, "White Balance", "Enabled", wb.enabled, keyFile);
3172 saveToKeyfile(!pedited || pedited->wb.method, "White Balance", "Setting", wb.method, keyFile);
3173 saveToKeyfile(!pedited || pedited->wb.temperature, "White Balance", "Temperature", wb.temperature, keyFile);
3174 saveToKeyfile(!pedited || pedited->wb.green, "White Balance", "Green", wb.green, keyFile);
3175 saveToKeyfile(!pedited || pedited->wb.equal, "White Balance", "Equal", wb.equal, keyFile);
3176 saveToKeyfile(!pedited || pedited->wb.tempBias, "White Balance", "TemperatureBias", wb.tempBias, keyFile);
3177
3178 // Colorappearance
3179 saveToKeyfile(!pedited || pedited->colorappearance.enabled, "Color appearance", "Enabled", colorappearance.enabled, keyFile);
3180 saveToKeyfile(!pedited || pedited->colorappearance.degree, "Color appearance", "Degree", colorappearance.degree, keyFile);
3181 saveToKeyfile(!pedited || pedited->colorappearance.autodegree, "Color appearance", "AutoDegree", colorappearance.autodegree, keyFile);
3182 saveToKeyfile(!pedited || pedited->colorappearance.degreeout, "Color appearance", "Degreeout", colorappearance.degreeout, keyFile);
3183 saveToKeyfile(!pedited || pedited->colorappearance.autodegreeout, "Color appearance", "AutoDegreeout", colorappearance.autodegreeout, keyFile);
3184 saveToKeyfile(!pedited || pedited->colorappearance.surround, "Color appearance", "Surround", colorappearance.surround, keyFile);
3185 saveToKeyfile(!pedited || pedited->colorappearance.surrsrc, "Color appearance", "Surrsrc", colorappearance.surrsrc, keyFile);
3186 saveToKeyfile(!pedited || pedited->colorappearance.adaplum, "Color appearance", "AdaptLum", colorappearance.adaplum, keyFile);
3187 saveToKeyfile(!pedited || pedited->colorappearance.badpixsl, "Color appearance", "Badpixsl", colorappearance.badpixsl, keyFile);
3188 saveToKeyfile(!pedited || pedited->colorappearance.wbmodel, "Color appearance", "Model", colorappearance.wbmodel, keyFile);
3189 saveToKeyfile(!pedited || pedited->colorappearance.algo, "Color appearance", "Algorithm", colorappearance.algo, keyFile);
3190 saveToKeyfile(!pedited || pedited->colorappearance.jlight, "Color appearance", "J-Light", colorappearance.jlight, keyFile);
3191 saveToKeyfile(!pedited || pedited->colorappearance.qbright, "Color appearance", "Q-Bright", colorappearance.qbright, keyFile);
3192 saveToKeyfile(!pedited || pedited->colorappearance.chroma, "Color appearance", "C-Chroma", colorappearance.chroma, keyFile);
3193 saveToKeyfile(!pedited || pedited->colorappearance.schroma, "Color appearance", "S-Chroma", colorappearance.schroma, keyFile);
3194 saveToKeyfile(!pedited || pedited->colorappearance.mchroma, "Color appearance", "M-Chroma", colorappearance.mchroma, keyFile);
3195 saveToKeyfile(!pedited || pedited->colorappearance.contrast, "Color appearance", "J-Contrast", colorappearance.contrast, keyFile);
3196 saveToKeyfile(!pedited || pedited->colorappearance.qcontrast, "Color appearance", "Q-Contrast", colorappearance.qcontrast, keyFile);
3197 saveToKeyfile(!pedited || pedited->colorappearance.colorh, "Color appearance", "H-Hue", colorappearance.colorh, keyFile);
3198 saveToKeyfile(!pedited || pedited->colorappearance.rstprotection, "Color appearance", "RSTProtection", colorappearance.rstprotection, keyFile);
3199 saveToKeyfile(!pedited || pedited->colorappearance.adapscen, "Color appearance", "AdaptScene", colorappearance.adapscen, keyFile);
3200 saveToKeyfile(!pedited || pedited->colorappearance.autoadapscen, "Color appearance", "AutoAdapscen", colorappearance.autoadapscen, keyFile);
3201 saveToKeyfile(!pedited || pedited->colorappearance.ybscen, "Color appearance", "YbScene", colorappearance.ybscen, keyFile);
3202 saveToKeyfile(!pedited || pedited->colorappearance.autoybscen, "Color appearance", "Autoybscen", colorappearance.autoybscen, keyFile);
3203 saveToKeyfile(!pedited || pedited->colorappearance.surrsource, "Color appearance", "SurrSource", colorappearance.surrsource, keyFile);
3204 saveToKeyfile(!pedited || pedited->colorappearance.gamut, "Color appearance", "Gamut", colorappearance.gamut, keyFile);
3205 saveToKeyfile(!pedited || pedited->colorappearance.tempout, "Color appearance", "Tempout", colorappearance.tempout, keyFile);
3206 saveToKeyfile(!pedited || pedited->colorappearance.greenout, "Color appearance", "Greenout", colorappearance.greenout, keyFile);
3207 saveToKeyfile(!pedited || pedited->colorappearance.tempsc, "Color appearance", "Tempsc", colorappearance.tempsc, keyFile);
3208 saveToKeyfile(!pedited || pedited->colorappearance.greensc, "Color appearance", "Greensc", colorappearance.greensc, keyFile);
3209 saveToKeyfile(!pedited || pedited->colorappearance.ybout, "Color appearance", "Ybout", colorappearance.ybout, keyFile);
3210 saveToKeyfile(!pedited || pedited->colorappearance.datacie, "Color appearance", "Datacie", colorappearance.datacie, keyFile);
3211 saveToKeyfile(!pedited || pedited->colorappearance.tonecie, "Color appearance", "Tonecie", colorappearance.tonecie, keyFile);
3212
3213 const std::map<ColorAppearanceParams::TcMode, const char*> ca_mapping = {
3214 {ColorAppearanceParams::TcMode::LIGHT, "Lightness"},
3215 {ColorAppearanceParams::TcMode::BRIGHT, "Brightness"}
3216 };
3217
3218 saveToKeyfile(!pedited || pedited->colorappearance.curveMode, "Color appearance", "CurveMode", ca_mapping, colorappearance.curveMode, keyFile);
3219 saveToKeyfile(!pedited || pedited->colorappearance.curveMode2, "Color appearance", "CurveMode2", ca_mapping, colorappearance.curveMode2, keyFile);
3220 saveToKeyfile(
3221 !pedited || pedited->colorappearance.curveMode3,
3222 "Color appearance",
3223 "CurveMode3",
3224 {
3225 {ColorAppearanceParams::CtcMode::CHROMA, "Chroma"},
3226 {ColorAppearanceParams::CtcMode::SATUR, "Saturation"},
3227 {ColorAppearanceParams::CtcMode::COLORF, "Colorfullness"}
3228
3229 },
3230 colorappearance.curveMode3,
3231 keyFile
3232 );
3233 saveToKeyfile(!pedited || pedited->colorappearance.curve, "Color appearance", "Curve", colorappearance.curve, keyFile);
3234 saveToKeyfile(!pedited || pedited->colorappearance.curve2, "Color appearance", "Curve2", colorappearance.curve2, keyFile);
3235 saveToKeyfile(!pedited || pedited->colorappearance.curve3, "Color appearance", "Curve3", colorappearance.curve3, keyFile);
3236
3237 // Impulse denoise
3238 saveToKeyfile(!pedited || pedited->impulseDenoise.enabled, "Impulse Denoising", "Enabled", impulseDenoise.enabled, keyFile);
3239 saveToKeyfile(!pedited || pedited->impulseDenoise.thresh, "Impulse Denoising", "Threshold", impulseDenoise.thresh, keyFile);
3240
3241 // Defringe
3242 saveToKeyfile(!pedited || pedited->defringe.enabled, "Defringing", "Enabled", defringe.enabled, keyFile);
3243 saveToKeyfile(!pedited || pedited->defringe.radius, "Defringing", "Radius", defringe.radius, keyFile);
3244 saveToKeyfile(!pedited || pedited->defringe.threshold, "Defringing", "Threshold", defringe.threshold, keyFile);
3245 saveToKeyfile(!pedited || pedited->defringe.huecurve, "Defringing", "HueCurve", defringe.huecurve, keyFile);
3246
3247 // Dehaze
3248 saveToKeyfile(!pedited || pedited->dehaze.enabled, "Dehaze", "Enabled", dehaze.enabled, keyFile);
3249 saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile);
3250 saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile);
3251 saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile);
3252 saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Luminance", dehaze.luminance, keyFile);
3253
3254 // Directional pyramid denoising
3255 saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile);
3256 saveToKeyfile(!pedited || pedited->dirpyrDenoise.enhance, "Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance, keyFile);
3257 saveToKeyfile(!pedited || pedited->dirpyrDenoise.median, "Directional Pyramid Denoising", "Median", dirpyrDenoise.median, keyFile);
3258 saveToKeyfile(!pedited || pedited->dirpyrDenoise.luma, "Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma, keyFile);
3259 saveToKeyfile(!pedited || pedited->dirpyrDenoise.Ldetail, "Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail, keyFile);
3260 saveToKeyfile(!pedited || pedited->dirpyrDenoise.chroma, "Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma, keyFile);
3261 saveToKeyfile(!pedited || pedited->dirpyrDenoise.dmethod, "Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod, keyFile);
3262 saveToKeyfile(!pedited || pedited->dirpyrDenoise.Lmethod, "Directional Pyramid Denoising", "LMethod", dirpyrDenoise.Lmethod, keyFile);
3263
3264 if (dirpyrDenoise.Cmethod == "PRE") {
3265 dirpyrDenoise.Cmethod = "MAN"; // Never save 'auto chroma preview mode' to pp3
3266 }
3267
3268 saveToKeyfile(!pedited || pedited->dirpyrDenoise.Cmethod, "Directional Pyramid Denoising", "CMethod", dirpyrDenoise.Cmethod, keyFile);
3269
3270 if (dirpyrDenoise.C2method == "PREV") {
3271 dirpyrDenoise.C2method = "MANU";
3272 }
3273
3274 saveToKeyfile(!pedited || pedited->dirpyrDenoise.C2method, "Directional Pyramid Denoising", "C2Method", dirpyrDenoise.C2method, keyFile);
3275 saveToKeyfile(!pedited || pedited->dirpyrDenoise.smethod, "Directional Pyramid Denoising", "SMethod", dirpyrDenoise.smethod, keyFile);
3276 saveToKeyfile(!pedited || pedited->dirpyrDenoise.medmethod, "Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod, keyFile);
3277 saveToKeyfile(!pedited || pedited->dirpyrDenoise.rgbmethod, "Directional Pyramid Denoising", "RGBMethod", dirpyrDenoise.rgbmethod, keyFile);
3278 saveToKeyfile(!pedited || pedited->dirpyrDenoise.methodmed, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, keyFile);
3279 saveToKeyfile(!pedited || pedited->dirpyrDenoise.redchro, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, keyFile);
3280 saveToKeyfile(!pedited || pedited->dirpyrDenoise.bluechro, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, keyFile);
3281 saveToKeyfile(!pedited || pedited->dirpyrDenoise.gamma, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, keyFile);
3282 saveToKeyfile(!pedited || pedited->dirpyrDenoise.passes, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, keyFile);
3283 saveToKeyfile(!pedited || pedited->dirpyrDenoise.lcurve, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, keyFile);
3284 saveToKeyfile(!pedited || pedited->dirpyrDenoise.cccurve, "Directional Pyramid Denoising", "CCCurve", dirpyrDenoise.cccurve, keyFile);
3285
3286 // EPD
3287 saveToKeyfile(!pedited || pedited->epd.enabled, "EPD", "Enabled", epd.enabled, keyFile);
3288 saveToKeyfile(!pedited || pedited->epd.strength, "EPD", "Strength", epd.strength, keyFile);
3289 saveToKeyfile(!pedited || pedited->epd.gamma, "EPD", "Gamma", epd.gamma, keyFile);
3290 saveToKeyfile(!pedited || pedited->epd.edgeStopping, "EPD", "EdgeStopping", epd.edgeStopping, keyFile);
3291 saveToKeyfile(!pedited || pedited->epd.scale, "EPD", "Scale", epd.scale, keyFile);
3292 saveToKeyfile(!pedited || pedited->epd.reweightingIterates, "EPD", "ReweightingIterates", epd.reweightingIterates, keyFile);
3293
3294 // Fattal
3295 saveToKeyfile(!pedited || pedited->fattal.enabled, "FattalToneMapping", "Enabled", fattal.enabled, keyFile);
3296 saveToKeyfile(!pedited || pedited->fattal.threshold, "FattalToneMapping", "Threshold", fattal.threshold, keyFile);
3297 saveToKeyfile(!pedited || pedited->fattal.amount, "FattalToneMapping", "Amount", fattal.amount, keyFile);
3298 saveToKeyfile(!pedited || pedited->fattal.anchor, "FattalToneMapping", "Anchor", fattal.anchor, keyFile);
3299
3300 // Shadows & highlights
3301 saveToKeyfile(!pedited || pedited->sh.enabled, "Shadows & Highlights", "Enabled", sh.enabled, keyFile);
3302 saveToKeyfile(!pedited || pedited->sh.highlights, "Shadows & Highlights", "Highlights", sh.highlights, keyFile);
3303 saveToKeyfile(!pedited || pedited->sh.htonalwidth, "Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth, keyFile);
3304 saveToKeyfile(!pedited || pedited->sh.shadows, "Shadows & Highlights", "Shadows", sh.shadows, keyFile);
3305 saveToKeyfile(!pedited || pedited->sh.stonalwidth, "Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth, keyFile);
3306 saveToKeyfile(!pedited || pedited->sh.radius, "Shadows & Highlights", "Radius", sh.radius, keyFile);
3307 saveToKeyfile(!pedited || pedited->sh.lab, "Shadows & Highlights", "Lab", sh.lab, keyFile);
3308
3309 // Crop
3310 saveToKeyfile(!pedited || pedited->crop.enabled, "Crop", "Enabled", crop.enabled, keyFile);
3311 saveToKeyfile(!pedited || pedited->crop.x, "Crop", "X", crop.x, keyFile);
3312 saveToKeyfile(!pedited || pedited->crop.y, "Crop", "Y", crop.y, keyFile);
3313 saveToKeyfile(!pedited || pedited->crop.w, "Crop", "W", crop.w, keyFile);
3314 saveToKeyfile(!pedited || pedited->crop.h, "Crop", "H", crop.h, keyFile);
3315 saveToKeyfile(!pedited || pedited->crop.fixratio, "Crop", "FixedRatio", crop.fixratio, keyFile);
3316 saveToKeyfile(!pedited || pedited->crop.ratio, "Crop", "Ratio", crop.ratio, keyFile);
3317 saveToKeyfile(!pedited || pedited->crop.orientation, "Crop", "Orientation", crop.orientation, keyFile);
3318 saveToKeyfile(!pedited || pedited->crop.guide, "Crop", "Guide", crop.guide, keyFile);
3319
3320 // Coarse transformation
3321 saveToKeyfile(!pedited || pedited->coarse.rotate, "Coarse Transformation", "Rotate", coarse.rotate, keyFile);
3322 saveToKeyfile(!pedited || pedited->coarse.hflip, "Coarse Transformation", "HorizontalFlip", coarse.hflip, keyFile);
3323 saveToKeyfile(!pedited || pedited->coarse.vflip, "Coarse Transformation", "VerticalFlip", coarse.vflip, keyFile);
3324
3325 // Common properties for transformations
3326 saveToKeyfile(!pedited || pedited->commonTrans.method, "Common Properties for Transformations", "Method", commonTrans.method, keyFile);
3327 saveToKeyfile(!pedited || pedited->commonTrans.autofill, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, keyFile);
3328
3329 // Rotation
3330 saveToKeyfile(!pedited || pedited->rotate.degree, "Rotation", "Degree", rotate.degree, keyFile);
3331
3332 // Distortion
3333 saveToKeyfile(!pedited || pedited->distortion.amount, "Distortion", "Amount", distortion.amount, keyFile);
3334
3335 // Lens profile
3336 saveToKeyfile(!pedited || pedited->lensProf.lcMode, "LensProfile", "LcMode", lensProf.getMethodString(lensProf.lcMode), keyFile);
3337 saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile), keyFile);
3338 saveToKeyfile(!pedited || pedited->lensProf.useDist, "LensProfile", "UseDistortion", lensProf.useDist, keyFile);
3339 saveToKeyfile(!pedited || pedited->lensProf.useVign, "LensProfile", "UseVignette", lensProf.useVign, keyFile);
3340 saveToKeyfile(!pedited || pedited->lensProf.useCA, "LensProfile", "UseCA", lensProf.useCA, keyFile);
3341 saveToKeyfile(!pedited || pedited->lensProf.lfCameraMake, "LensProfile", "LFCameraMake", lensProf.lfCameraMake, keyFile);
3342 saveToKeyfile(!pedited || pedited->lensProf.lfCameraModel, "LensProfile", "LFCameraModel", lensProf.lfCameraModel, keyFile);
3343 saveToKeyfile(!pedited || pedited->lensProf.lfLens, "LensProfile", "LFLens", lensProf.lfLens, keyFile);
3344
3345 // Perspective correction
3346 saveToKeyfile(!pedited || pedited->perspective.horizontal, "Perspective", "Horizontal", perspective.horizontal, keyFile);
3347 saveToKeyfile(!pedited || pedited->perspective.vertical, "Perspective", "Vertical", perspective.vertical, keyFile);
3348
3349 // Gradient
3350 saveToKeyfile(!pedited || pedited->gradient.enabled, "Gradient", "Enabled", gradient.enabled, keyFile);
3351 saveToKeyfile(!pedited || pedited->gradient.degree, "Gradient", "Degree", gradient.degree, keyFile);
3352 saveToKeyfile(!pedited || pedited->gradient.feather, "Gradient", "Feather", gradient.feather, keyFile);
3353 saveToKeyfile(!pedited || pedited->gradient.strength, "Gradient", "Strength", gradient.strength, keyFile);
3354 saveToKeyfile(!pedited || pedited->gradient.centerX, "Gradient", "CenterX", gradient.centerX, keyFile);
3355 saveToKeyfile(!pedited || pedited->gradient.centerY, "Gradient", "CenterY", gradient.centerY, keyFile);
3356
3357 // Post-crop vignette
3358 saveToKeyfile(!pedited || pedited->pcvignette.enabled, "PCVignette", "Enabled", pcvignette.enabled, keyFile);
3359 saveToKeyfile(!pedited || pedited->pcvignette.strength, "PCVignette", "Strength", pcvignette.strength, keyFile);
3360 saveToKeyfile(!pedited || pedited->pcvignette.feather, "PCVignette", "Feather", pcvignette.feather, keyFile);
3361 saveToKeyfile(!pedited || pedited->pcvignette.roundness, "PCVignette", "Roundness", pcvignette.roundness, keyFile);
3362
3363 // C/A correction
3364 saveToKeyfile(!pedited || pedited->cacorrection.red, "CACorrection", "Red", cacorrection.red, keyFile);
3365 saveToKeyfile(!pedited || pedited->cacorrection.blue, "CACorrection", "Blue", cacorrection.blue, keyFile);
3366
3367 // Vignetting correction
3368 saveToKeyfile(!pedited || pedited->vignetting.amount, "Vignetting Correction", "Amount", vignetting.amount, keyFile);
3369 saveToKeyfile(!pedited || pedited->vignetting.radius, "Vignetting Correction", "Radius", vignetting.radius, keyFile);
3370 saveToKeyfile(!pedited || pedited->vignetting.strength, "Vignetting Correction", "Strength", vignetting.strength, keyFile);
3371 saveToKeyfile(!pedited || pedited->vignetting.centerX, "Vignetting Correction", "CenterX", vignetting.centerX, keyFile);
3372 saveToKeyfile(!pedited || pedited->vignetting.centerY, "Vignetting Correction", "CenterY", vignetting.centerY, keyFile);
3373
3374 // Resize
3375 saveToKeyfile(!pedited || pedited->resize.enabled, "Resize", "Enabled", resize.enabled, keyFile);
3376 saveToKeyfile(!pedited || pedited->resize.scale, "Resize", "Scale", resize.scale, keyFile);
3377 saveToKeyfile(!pedited || pedited->resize.appliesTo, "Resize", "AppliesTo", resize.appliesTo, keyFile);
3378 saveToKeyfile(!pedited || pedited->resize.method, "Resize", "Method", resize.method, keyFile);
3379 saveToKeyfile(!pedited || pedited->resize.dataspec, "Resize", "DataSpecified", resize.dataspec, keyFile);
3380 saveToKeyfile(!pedited || pedited->resize.width, "Resize", "Width", resize.width, keyFile);
3381 saveToKeyfile(!pedited || pedited->resize.height, "Resize", "Height", resize.height, keyFile);
3382 saveToKeyfile(!pedited || pedited->resize.allowUpscaling, "Resize", "AllowUpscaling", resize.allowUpscaling, keyFile);
3383
3384 // Post demosaic sharpening
3385 saveToKeyfile(!pedited || pedited->pdsharpening.enabled, "PostDemosaicSharpening", "Enabled", pdsharpening.enabled, keyFile);
3386 saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, keyFile);
3387 saveToKeyfile(!pedited || pedited->pdsharpening.autoContrast, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, keyFile);
3388 saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile);
3389 saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile);
3390 saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile);
3391 saveToKeyfile(!pedited || pedited->pdsharpening.deconvitercheck, "PostDemosaicSharpening", "DeconvIterCheck", pdsharpening.deconvitercheck, keyFile);
3392 saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile);
3393
3394 // Post resize sharpening
3395 saveToKeyfile(!pedited || pedited->prsharpening.enabled, "PostResizeSharpening", "Enabled", prsharpening.enabled, keyFile);
3396 saveToKeyfile(!pedited || pedited->prsharpening.contrast, "PostResizeSharpening", "Contrast", prsharpening.contrast, keyFile);
3397 saveToKeyfile(!pedited || pedited->prsharpening.method, "PostResizeSharpening", "Method", prsharpening.method, keyFile);
3398 saveToKeyfile(!pedited || pedited->prsharpening.radius, "PostResizeSharpening", "Radius", prsharpening.radius, keyFile);
3399 saveToKeyfile(!pedited || pedited->prsharpening.amount, "PostResizeSharpening", "Amount", prsharpening.amount, keyFile);
3400 saveToKeyfile(!pedited || pedited->prsharpening.threshold, "PostResizeSharpening", "Threshold", prsharpening.threshold.toVector(), keyFile);
3401 saveToKeyfile(!pedited || pedited->prsharpening.edgesonly, "PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly, keyFile);
3402 saveToKeyfile(!pedited || pedited->prsharpening.edges_radius, "PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius, keyFile);
3403 saveToKeyfile(!pedited || pedited->prsharpening.edges_tolerance, "PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance, keyFile);
3404 saveToKeyfile(!pedited || pedited->prsharpening.halocontrol, "PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol, keyFile);
3405 saveToKeyfile(!pedited || pedited->prsharpening.halocontrol_amount, "PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount, keyFile);
3406 saveToKeyfile(!pedited || pedited->prsharpening.deconvradius, "PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius, keyFile);
3407 saveToKeyfile(!pedited || pedited->prsharpening.deconvamount, "PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount, keyFile);
3408 saveToKeyfile(!pedited || pedited->prsharpening.deconvdamping, "PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping, keyFile);
3409 saveToKeyfile(!pedited || pedited->prsharpening.deconviter, "PostResizeSharpening", "DeconvIterations", prsharpening.deconviter, keyFile);
3410
3411 // Color management
3412 saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.inputProfile), keyFile);
3413 saveToKeyfile(!pedited || pedited->icm.toneCurve, "Color Management", "ToneCurve", icm.toneCurve, keyFile);
3414 saveToKeyfile(!pedited || pedited->icm.applyLookTable, "Color Management", "ApplyLookTable", icm.applyLookTable, keyFile);
3415 saveToKeyfile(!pedited || pedited->icm.applyBaselineExposureOffset, "Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset, keyFile);
3416 saveToKeyfile(!pedited || pedited->icm.applyHueSatMap, "Color Management", "ApplyHueSatMap", icm.applyHueSatMap, keyFile);
3417 saveToKeyfile(!pedited || pedited->icm.dcpIlluminant, "Color Management", "DCPIlluminant", icm.dcpIlluminant, keyFile);
3418 saveToKeyfile(!pedited || pedited->icm.workingProfile, "Color Management", "WorkingProfile", icm.workingProfile, keyFile);
3419 saveToKeyfile(!pedited || pedited->icm.workingTRC, "Color Management", "WorkingTRC", icm.workingTRC, keyFile);
3420 saveToKeyfile(!pedited || pedited->icm.workingTRCGamma, "Color Management", "WorkingTRCGamma", icm.workingTRCGamma, keyFile);
3421 saveToKeyfile(!pedited || pedited->icm.workingTRCSlope, "Color Management", "WorkingTRCSlope", icm.workingTRCSlope, keyFile);
3422 saveToKeyfile(!pedited || pedited->icm.outputProfile, "Color Management", "OutputProfile", icm.outputProfile, keyFile);
3423 saveToKeyfile(
3424 !pedited || pedited->icm.outputIntent,
3425 "Color Management",
3426 "OutputProfileIntent",
3427 {
3428 {RI_PERCEPTUAL, "Perceptual"},
3429 {RI_RELATIVE, "Relative"},
3430 {RI_SATURATION, "Saturation"},
3431 {RI_ABSOLUTE, "Absolute"}
3432
3433 },
3434 icm.outputIntent,
3435 keyFile
3436 );
3437 saveToKeyfile(!pedited || pedited->icm.outputBPC, "Color Management", "OutputBPC", icm.outputBPC, keyFile);
3438
3439 // Wavelet
3440 saveToKeyfile(!pedited || pedited->wavelet.enabled, "Wavelet", "Enabled", wavelet.enabled, keyFile);
3441 saveToKeyfile(!pedited || pedited->wavelet.strength, "Wavelet", "Strength", wavelet.strength, keyFile);
3442 saveToKeyfile(!pedited || pedited->wavelet.balance, "Wavelet", "Balance", wavelet.balance, keyFile);
3443 saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile);
3444 saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile);
3445 saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile);
3446 saveToKeyfile(!pedited || pedited->wavelet.daubcoeffmethod, "Wavelet", "DaubMethod", wavelet.daubcoeffmethod, keyFile);
3447 saveToKeyfile(!pedited || pedited->wavelet.CLmethod, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, keyFile);
3448 saveToKeyfile(!pedited || pedited->wavelet.Backmethod, "Wavelet", "BackMethod", wavelet.Backmethod, keyFile);
3449 saveToKeyfile(!pedited || pedited->wavelet.Lmethod, "Wavelet", "LevMethod", wavelet.Lmethod, keyFile);
3450 saveToKeyfile(!pedited || pedited->wavelet.Dirmethod, "Wavelet", "DirMethod", wavelet.Dirmethod, keyFile);
3451 saveToKeyfile(!pedited || pedited->wavelet.greenhigh, "Wavelet", "CBgreenhigh", wavelet.greenhigh, keyFile);
3452 saveToKeyfile(!pedited || pedited->wavelet.greenmed, "Wavelet", "CBgreenmed", wavelet.greenmed, keyFile);
3453 saveToKeyfile(!pedited || pedited->wavelet.greenlow, "Wavelet", "CBgreenlow", wavelet.greenlow, keyFile);
3454 saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile);
3455 saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile);
3456 saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile);
3457 saveToKeyfile(!pedited || pedited->wavelet.expcontrast, "Wavelet", "Expcontrast", wavelet.expcontrast, keyFile);
3458 saveToKeyfile(!pedited || pedited->wavelet.expchroma, "Wavelet", "Expchroma", wavelet.expchroma, keyFile);
3459 saveToKeyfile(!pedited || pedited->wavelet.expedge, "Wavelet", "Expedge", wavelet.expedge, keyFile);
3460 saveToKeyfile(!pedited || pedited->wavelet.expresid, "Wavelet", "Expresid", wavelet.expresid, keyFile);
3461 saveToKeyfile(!pedited || pedited->wavelet.expfinal, "Wavelet", "Expfinal", wavelet.expfinal, keyFile);
3462 saveToKeyfile(!pedited || pedited->wavelet.exptoning, "Wavelet", "Exptoning", wavelet.exptoning, keyFile);
3463 saveToKeyfile(!pedited || pedited->wavelet.expnoise, "Wavelet", "Expnoise", wavelet.expnoise, keyFile);
3464
3465 for (int i = 0; i < 9; i++) {
3466 std::stringstream ss;
3467 ss << "Contrast" << (i + 1);
3468
3469 saveToKeyfile(!pedited || pedited->wavelet.c[i], "Wavelet", ss.str(), wavelet.c[i], keyFile);
3470 }
3471
3472 for (int i = 0; i < 9; i++) {
3473 std::stringstream ss;
3474 ss << "Chroma" << (i + 1);
3475
3476 saveToKeyfile(!pedited || pedited->wavelet.ch[i], "Wavelet", ss.str(), wavelet.ch[i], keyFile);
3477 }
3478
3479 saveToKeyfile(!pedited || pedited->wavelet.sup, "Wavelet", "ContExtra", wavelet.sup, keyFile);
3480 saveToKeyfile(!pedited || pedited->wavelet.HSmethod, "Wavelet", "HSMethod", wavelet.HSmethod, keyFile);
3481 saveToKeyfile(!pedited || pedited->wavelet.hllev, "Wavelet", "HLRange", wavelet.hllev.toVector(), keyFile);
3482 saveToKeyfile(!pedited || pedited->wavelet.bllev, "Wavelet", "SHRange", wavelet.bllev.toVector(), keyFile);
3483 saveToKeyfile(!pedited || pedited->wavelet.edgcont, "Wavelet", "Edgcont", wavelet.edgcont.toVector(), keyFile);
3484 saveToKeyfile(!pedited || pedited->wavelet.level0noise, "Wavelet", "Level0noise", wavelet.level0noise.toVector(), keyFile);
3485 saveToKeyfile(!pedited || pedited->wavelet.level1noise, "Wavelet", "Level1noise", wavelet.level1noise.toVector(), keyFile);
3486 saveToKeyfile(!pedited || pedited->wavelet.level2noise, "Wavelet", "Level2noise", wavelet.level2noise.toVector(), keyFile);
3487 saveToKeyfile(!pedited || pedited->wavelet.level3noise, "Wavelet", "Level3noise", wavelet.level3noise.toVector(), keyFile);
3488 saveToKeyfile(!pedited || pedited->wavelet.threshold, "Wavelet", "ThresholdHighlight", wavelet.threshold, keyFile);
3489 saveToKeyfile(!pedited || pedited->wavelet.threshold2, "Wavelet", "ThresholdShadow", wavelet.threshold2, keyFile);
3490 saveToKeyfile(!pedited || pedited->wavelet.edgedetect, "Wavelet", "Edgedetect", wavelet.edgedetect, keyFile);
3491 saveToKeyfile(!pedited || pedited->wavelet.edgedetectthr, "Wavelet", "Edgedetectthr", wavelet.edgedetectthr, keyFile);
3492 saveToKeyfile(!pedited || pedited->wavelet.edgedetectthr2, "Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2, keyFile);
3493 saveToKeyfile(!pedited || pedited->wavelet.edgesensi, "Wavelet", "Edgesensi", wavelet.edgesensi, keyFile);
3494 saveToKeyfile(!pedited || pedited->wavelet.edgeampli, "Wavelet", "Edgeampli", wavelet.edgeampli, keyFile);
3495 saveToKeyfile(!pedited || pedited->wavelet.chroma, "Wavelet", "ThresholdChroma", wavelet.chroma, keyFile);
3496 saveToKeyfile(!pedited || pedited->wavelet.CHmethod, "Wavelet", "CHromaMethod", wavelet.CHmethod, keyFile);
3497 saveToKeyfile(!pedited || pedited->wavelet.Medgreinf, "Wavelet", "Medgreinf", wavelet.Medgreinf, keyFile);
3498 saveToKeyfile(!pedited || pedited->wavelet.CHSLmethod, "Wavelet", "CHSLromaMethod", wavelet.CHSLmethod, keyFile);
3499 saveToKeyfile(!pedited || pedited->wavelet.EDmethod, "Wavelet", "EDMethod", wavelet.EDmethod, keyFile);
3500 saveToKeyfile(!pedited || pedited->wavelet.NPmethod, "Wavelet", "NPMethod", wavelet.NPmethod, keyFile);
3501 saveToKeyfile(!pedited || pedited->wavelet.BAmethod, "Wavelet", "BAMethod", wavelet.BAmethod, keyFile);
3502 saveToKeyfile(!pedited || pedited->wavelet.TMmethod, "Wavelet", "TMMethod", wavelet.TMmethod, keyFile);
3503 saveToKeyfile(!pedited || pedited->wavelet.chro, "Wavelet", "ChromaLink", wavelet.chro, keyFile);
3504 saveToKeyfile(!pedited || pedited->wavelet.ccwcurve, "Wavelet", "ContrastCurve", wavelet.ccwcurve, keyFile);
3505 saveToKeyfile(!pedited || pedited->wavelet.pastlev, "Wavelet", "Pastlev", wavelet.pastlev.toVector(), keyFile);
3506 saveToKeyfile(!pedited || pedited->wavelet.satlev, "Wavelet", "Satlev", wavelet.satlev.toVector(), keyFile);
3507 saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile);
3508 saveToKeyfile(!pedited || pedited->wavelet.opacityCurveBY, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, keyFile);
3509 saveToKeyfile(!pedited || pedited->wavelet.opacityCurveW, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, keyFile);
3510 saveToKeyfile(!pedited || pedited->wavelet.opacityCurveWL, "Wavelet", "OpacityCurveWL", wavelet.opacityCurveWL, keyFile);
3511 saveToKeyfile(!pedited || pedited->wavelet.hhcurve, "Wavelet", "HHcurve", wavelet.hhcurve, keyFile);
3512 saveToKeyfile(!pedited || pedited->wavelet.Chcurve, "Wavelet", "CHcurve", wavelet.Chcurve, keyFile);
3513 saveToKeyfile(!pedited || pedited->wavelet.wavclCurve, "Wavelet", "WavclCurve", wavelet.wavclCurve, keyFile);
3514 saveToKeyfile(!pedited || pedited->wavelet.median, "Wavelet", "Median", wavelet.median, keyFile);
3515 saveToKeyfile(!pedited || pedited->wavelet.medianlev, "Wavelet", "Medianlev", wavelet.medianlev, keyFile);
3516 saveToKeyfile(!pedited || pedited->wavelet.linkedg, "Wavelet", "Linkedg", wavelet.linkedg, keyFile);
3517 saveToKeyfile(!pedited || pedited->wavelet.cbenab, "Wavelet", "CBenab", wavelet.cbenab, keyFile);
3518 saveToKeyfile(!pedited || pedited->wavelet.lipst, "Wavelet", "Lipst", wavelet.lipst, keyFile);
3519 saveToKeyfile(!pedited || pedited->wavelet.skinprotect, "Wavelet", "Skinprotect", wavelet.skinprotect, keyFile);
3520 saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile);
3521 saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile);
3522 saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile);
3523 saveToKeyfile(!pedited || pedited->wavelet.edgthresh, "Wavelet", "ThrEdg", wavelet.edgthresh, keyFile);
3524 saveToKeyfile(!pedited || pedited->wavelet.avoid, "Wavelet", "AvoidColorShift", wavelet.avoid, keyFile);
3525 saveToKeyfile(!pedited || pedited->wavelet.tmr, "Wavelet", "TMr", wavelet.tmr, keyFile);
3526 saveToKeyfile(!pedited || pedited->wavelet.rescon, "Wavelet", "ResidualcontShadow", wavelet.rescon, keyFile);
3527 saveToKeyfile(!pedited || pedited->wavelet.resconH, "Wavelet", "ResidualcontHighlight", wavelet.resconH, keyFile);
3528 saveToKeyfile(!pedited || pedited->wavelet.thr, "Wavelet", "ThresholdResidShadow", wavelet.thr, keyFile);
3529 saveToKeyfile(!pedited || pedited->wavelet.thrH, "Wavelet", "ThresholdResidHighLight", wavelet.thrH, keyFile);
3530 saveToKeyfile(!pedited || pedited->wavelet.reschro, "Wavelet", "Residualchroma", wavelet.reschro, keyFile);
3531 saveToKeyfile(!pedited || pedited->wavelet.tmrs, "Wavelet", "ResidualTM", wavelet.tmrs, keyFile);
3532 saveToKeyfile(!pedited || pedited->wavelet.gamma, "Wavelet", "Residualgamma", wavelet.gamma, keyFile);
3533 saveToKeyfile(!pedited || pedited->wavelet.sky, "Wavelet", "HueRangeResidual", wavelet.sky, keyFile);
3534 saveToKeyfile(!pedited || pedited->wavelet.hueskin2, "Wavelet", "HueRange", wavelet.hueskin2.toVector(), keyFile);
3535 saveToKeyfile(!pedited || pedited->wavelet.contrast, "Wavelet", "Contrast", wavelet.contrast, keyFile);
3536
3537 // Directional pyramid equalizer
3538 saveToKeyfile(!pedited || pedited->dirpyrequalizer.enabled, "Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled, keyFile);
3539 saveToKeyfile(!pedited || pedited->dirpyrequalizer.gamutlab, "Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab, keyFile);
3540 saveToKeyfile(!pedited || pedited->dirpyrequalizer.cbdlMethod, "Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod, keyFile);
3541
3542 for (int i = 0; i < 6; i++) {
3543 std::stringstream ss;
3544 ss << "Mult" << i;
3545
3546 saveToKeyfile(!pedited || pedited->dirpyrequalizer.mult[i], "Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i], keyFile);
3547 }
3548
3549 saveToKeyfile(!pedited || pedited->dirpyrequalizer.threshold, "Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold, keyFile);
3550 saveToKeyfile(!pedited || pedited->dirpyrequalizer.skinprotect, "Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect, keyFile);
3551 saveToKeyfile(!pedited || pedited->dirpyrequalizer.hueskin, "Directional Pyramid Equalizer", "Hueskin", dirpyrequalizer.hueskin.toVector(), keyFile);
3552
3553 // HSV Equalizer
3554 saveToKeyfile(!pedited || pedited->hsvequalizer.enabled, "HSV Equalizer", "Enabled", hsvequalizer.enabled, keyFile);
3555 saveToKeyfile(!pedited || pedited->hsvequalizer.hcurve, "HSV Equalizer", "HCurve", hsvequalizer.hcurve, keyFile);
3556 saveToKeyfile(!pedited || pedited->hsvequalizer.scurve, "HSV Equalizer", "SCurve", hsvequalizer.scurve, keyFile);
3557 saveToKeyfile(!pedited || pedited->hsvequalizer.vcurve, "HSV Equalizer", "VCurve", hsvequalizer.vcurve, keyFile);
3558
3559 // Soft Light
3560 saveToKeyfile(!pedited || pedited->softlight.enabled, "SoftLight", "Enabled", softlight.enabled, keyFile);
3561 saveToKeyfile(!pedited || pedited->softlight.strength, "SoftLight", "Strength", softlight.strength, keyFile);
3562
3563 // Film simulation
3564 saveToKeyfile(!pedited || pedited->filmSimulation.enabled, "Film Simulation", "Enabled", filmSimulation.enabled, keyFile);
3565 saveToKeyfile(!pedited || pedited->filmSimulation.clutFilename, "Film Simulation", "ClutFilename", filmSimulation.clutFilename, keyFile);
3566 saveToKeyfile(!pedited || pedited->filmSimulation.strength, "Film Simulation", "Strength", filmSimulation.strength, keyFile);
3567
3568 saveToKeyfile(!pedited || pedited->rgbCurves.enabled, "RGB Curves", "Enabled", rgbCurves.enabled, keyFile);
3569 saveToKeyfile(!pedited || pedited->rgbCurves.lumamode, "RGB Curves", "LumaMode", rgbCurves.lumamode, keyFile);
3570 saveToKeyfile(!pedited || pedited->rgbCurves.rcurve, "RGB Curves", "rCurve", rgbCurves.rcurve, keyFile);
3571 saveToKeyfile(!pedited || pedited->rgbCurves.gcurve, "RGB Curves", "gCurve", rgbCurves.gcurve, keyFile);
3572 saveToKeyfile(!pedited || pedited->rgbCurves.bcurve, "RGB Curves", "bCurve", rgbCurves.bcurve, keyFile);
3573
3574 // Color toning
3575 saveToKeyfile(!pedited || pedited->colorToning.enabled, "ColorToning", "Enabled", colorToning.enabled, keyFile);
3576 saveToKeyfile(!pedited || pedited->colorToning.method, "ColorToning", "Method", colorToning.method, keyFile);
3577 saveToKeyfile(!pedited || pedited->colorToning.lumamode, "ColorToning", "Lumamode", colorToning.lumamode, keyFile);
3578 saveToKeyfile(!pedited || pedited->colorToning.twocolor, "ColorToning", "Twocolor", colorToning.twocolor, keyFile);
3579 saveToKeyfile(!pedited || pedited->colorToning.redlow, "ColorToning", "Redlow", colorToning.redlow, keyFile);
3580 saveToKeyfile(!pedited || pedited->colorToning.greenlow, "ColorToning", "Greenlow", colorToning.greenlow, keyFile);
3581 saveToKeyfile(!pedited || pedited->colorToning.bluelow, "ColorToning", "Bluelow", colorToning.bluelow, keyFile);
3582 saveToKeyfile(!pedited || pedited->colorToning.satlow, "ColorToning", "Satlow", colorToning.satlow, keyFile);
3583 saveToKeyfile(!pedited || pedited->colorToning.balance, "ColorToning", "Balance", colorToning.balance, keyFile);
3584 saveToKeyfile(!pedited || pedited->colorToning.sathigh, "ColorToning", "Sathigh", colorToning.sathigh, keyFile);
3585 saveToKeyfile(!pedited || pedited->colorToning.redmed, "ColorToning", "Redmed", colorToning.redmed, keyFile);
3586 saveToKeyfile(!pedited || pedited->colorToning.greenmed, "ColorToning", "Greenmed", colorToning.greenmed, keyFile);
3587 saveToKeyfile(!pedited || pedited->colorToning.bluemed, "ColorToning", "Bluemed", colorToning.bluemed, keyFile);
3588 saveToKeyfile(!pedited || pedited->colorToning.redhigh, "ColorToning", "Redhigh", colorToning.redhigh, keyFile);
3589 saveToKeyfile(!pedited || pedited->colorToning.greenhigh, "ColorToning", "Greenhigh", colorToning.greenhigh, keyFile);
3590 saveToKeyfile(!pedited || pedited->colorToning.bluehigh, "ColorToning", "Bluehigh", colorToning.bluehigh, keyFile);
3591 saveToKeyfile(!pedited || pedited->colorToning.autosat, "ColorToning", "Autosat", colorToning.autosat, keyFile);
3592 saveToKeyfile(!pedited || pedited->colorToning.opacityCurve, "ColorToning", "OpacityCurve", colorToning.opacityCurve, keyFile);
3593 saveToKeyfile(!pedited || pedited->colorToning.colorCurve, "ColorToning", "ColorCurve", colorToning.colorCurve, keyFile);
3594 saveToKeyfile(!pedited || pedited->colorToning.satprotectionthreshold, "ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold, keyFile);
3595 saveToKeyfile(!pedited || pedited->colorToning.saturatedopacity, "ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity, keyFile);
3596 saveToKeyfile(!pedited || pedited->colorToning.strength, "ColorToning", "Strength", colorToning.strength, keyFile);
3597 saveToKeyfile(!pedited || pedited->colorToning.hlColSat, "ColorToning", "HighlightsColorSaturation", colorToning.hlColSat.toVector(), keyFile);
3598 saveToKeyfile(!pedited || pedited->colorToning.shadowsColSat, "ColorToning", "ShadowsColorSaturation", colorToning.shadowsColSat.toVector(), keyFile);
3599 saveToKeyfile(!pedited || pedited->colorToning.clcurve, "ColorToning", "ClCurve", colorToning.clcurve, keyFile);
3600 saveToKeyfile(!pedited || pedited->colorToning.cl2curve, "ColorToning", "Cl2Curve", colorToning.cl2curve, keyFile);
3601 saveToKeyfile(!pedited || pedited->colorToning.labgridALow, "ColorToning", "LabGridALow", colorToning.labgridALow, keyFile);
3602 saveToKeyfile(!pedited || pedited->colorToning.labgridBLow, "ColorToning", "LabGridBLow", colorToning.labgridBLow, keyFile);
3603 saveToKeyfile(!pedited || pedited->colorToning.labgridAHigh, "ColorToning", "LabGridAHigh", colorToning.labgridAHigh, keyFile);
3604 saveToKeyfile(!pedited || pedited->colorToning.labgridBHigh, "ColorToning", "LabGridBHigh", colorToning.labgridBHigh, keyFile);
3605 if (!pedited || pedited->colorToning.labregions) {
3606 for (size_t j = 0; j < colorToning.labregions.size(); ++j) {
3607 std::string n = std::to_string(j+1);
3608 auto &l = colorToning.labregions[j];
3609 putToKeyfile("ColorToning", Glib::ustring("LabRegionA_") + n, l.a, keyFile);
3610 putToKeyfile("ColorToning", Glib::ustring("LabRegionB_") + n, l.b, keyFile);
3611 putToKeyfile("ColorToning", Glib::ustring("LabRegionSaturation_") + n, l.saturation, keyFile);
3612 putToKeyfile("ColorToning", Glib::ustring("LabRegionSlope_") + n, l.slope, keyFile);
3613 putToKeyfile("ColorToning", Glib::ustring("LabRegionOffset_") + n, l.offset, keyFile);
3614 putToKeyfile("ColorToning", Glib::ustring("LabRegionPower_") + n, l.power, keyFile);
3615 putToKeyfile("ColorToning", Glib::ustring("LabRegionHueMask_") + n, l.hueMask, keyFile);
3616 putToKeyfile("ColorToning", Glib::ustring("LabRegionChromaticityMask_") + n, l.chromaticityMask, keyFile);
3617 putToKeyfile("ColorToning", Glib::ustring("LabRegionLightnessMask_") + n, l.lightnessMask, keyFile);
3618 putToKeyfile("ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, l.maskBlur, keyFile);
3619 putToKeyfile("ColorToning", Glib::ustring("LabRegionChannel_") + n, l.channel, keyFile);
3620 }
3621 }
3622 saveToKeyfile(!pedited || pedited->colorToning.labregionsShowMask, "ColorToning", "LabRegionsShowMask", colorToning.labregionsShowMask, keyFile);
3623
3624 // Raw
3625 saveToKeyfile(!pedited || pedited->raw.darkFrame, "RAW", "DarkFrame", relativePathIfInside(fname, fnameAbsolute, raw.dark_frame), keyFile);
3626 saveToKeyfile(!pedited || pedited->raw.df_autoselect, "RAW", "DarkFrameAuto", raw.df_autoselect, keyFile);
3627 saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file), keyFile);
3628 saveToKeyfile(!pedited || pedited->raw.ff_AutoSelect, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, keyFile);
3629 saveToKeyfile(!pedited || pedited->raw.ff_BlurRadius, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, keyFile);
3630 saveToKeyfile(!pedited || pedited->raw.ff_BlurType, "RAW", "FlatFieldBlurType", raw.ff_BlurType, keyFile);
3631 saveToKeyfile(!pedited || pedited->raw.ff_AutoClipControl, "RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl, keyFile);
3632 saveToKeyfile(!pedited || pedited->raw.ff_clipControl, "RAW", "FlatFieldClipControl", raw.ff_clipControl, keyFile);
3633 saveToKeyfile(!pedited || pedited->raw.ca_autocorrect, "RAW", "CA", raw.ca_autocorrect, keyFile);
3634 saveToKeyfile(!pedited || pedited->raw.ca_avoidcolourshift, "RAW", "CAAvoidColourshift", raw.ca_avoidcolourshift, keyFile);
3635 saveToKeyfile(!pedited || pedited->raw.caautoiterations, "RAW", "CAAutoIterations", raw.caautoiterations, keyFile);
3636 saveToKeyfile(!pedited || pedited->raw.cared, "RAW", "CARed", raw.cared, keyFile);
3637 saveToKeyfile(!pedited || pedited->raw.cablue, "RAW", "CABlue", raw.cablue, keyFile);
3638 saveToKeyfile(!pedited || pedited->raw.hotPixelFilter, "RAW", "HotPixelFilter", raw.hotPixelFilter, keyFile);
3639 saveToKeyfile(!pedited || pedited->raw.deadPixelFilter, "RAW", "DeadPixelFilter", raw.deadPixelFilter, keyFile);
3640 saveToKeyfile(!pedited || pedited->raw.hotdeadpix_thresh, "RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh, keyFile);
3641 saveToKeyfile(!pedited || pedited->raw.bayersensor.method, "RAW Bayer", "Method", raw.bayersensor.method, keyFile);
3642 saveToKeyfile(!pedited || pedited->raw.bayersensor.border, "RAW Bayer", "Border", raw.bayersensor.border, keyFile);
3643 saveToKeyfile(!pedited || pedited->raw.bayersensor.imageNum, "RAW Bayer", "ImageNum", raw.bayersensor.imageNum + 1, keyFile);
3644 saveToKeyfile(!pedited || pedited->raw.bayersensor.ccSteps, "RAW Bayer", "CcSteps", raw.bayersensor.ccSteps, keyFile);
3645 saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack0, "RAW Bayer", "PreBlack0", raw.bayersensor.black0, keyFile);
3646 saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack1, "RAW Bayer", "PreBlack1", raw.bayersensor.black1, keyFile);
3647 saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack2, "RAW Bayer", "PreBlack2", raw.bayersensor.black2, keyFile);
3648 saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack3, "RAW Bayer", "PreBlack3", raw.bayersensor.black3, keyFile);
3649 saveToKeyfile(!pedited || pedited->raw.bayersensor.exTwoGreen, "RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen, keyFile);
3650 saveToKeyfile(!pedited || pedited->raw.bayersensor.linenoise, "RAW Bayer", "LineDenoise", raw.bayersensor.linenoise, keyFile);
3651 saveToKeyfile(!pedited || pedited->raw.bayersensor.linenoise, "RAW Bayer", "LineDenoiseDirection", toUnderlying(raw.bayersensor.linenoiseDirection), keyFile);
3652 saveToKeyfile(!pedited || pedited->raw.bayersensor.greenEq, "RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh, keyFile);
3653 saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbIterations, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, keyFile);
3654 saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbEnhance, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, keyFile);
3655 saveToKeyfile(!pedited || pedited->raw.bayersensor.lmmseIterations, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, keyFile);
3656 saveToKeyfile(!pedited || pedited->raw.bayersensor.dualDemosaicAutoContrast, "RAW Bayer", "DualDemosaicAutoContrast", raw.bayersensor.dualDemosaicAutoContrast, keyFile);
3657 saveToKeyfile(!pedited || pedited->raw.bayersensor.dualDemosaicContrast, "RAW Bayer", "DualDemosaicContrast", raw.bayersensor.dualDemosaicContrast, keyFile);
3658 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod, "RAW Bayer", "PixelShiftMotionCorrectionMethod", toUnderlying(raw.bayersensor.pixelShiftMotionCorrectionMethod), keyFile);
3659 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile);
3660 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSigma, "RAW Bayer", "PixelShiftSigma", raw.bayersensor.pixelShiftSigma, keyFile);
3661 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotion, "RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion, keyFile);
3662 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly, "RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly, keyFile);
3663 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftHoleFill, "RAW Bayer", "pixelShiftHoleFill", raw.bayersensor.pixelShiftHoleFill, keyFile);
3664 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian, "RAW Bayer", "pixelShiftMedian", raw.bayersensor.pixelShiftMedian, keyFile);
3665 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftGreen, "RAW Bayer", "pixelShiftGreen", raw.bayersensor.pixelShiftGreen, keyFile);
3666 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftBlur, "RAW Bayer", "pixelShiftBlur", raw.bayersensor.pixelShiftBlur, keyFile);
3667 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSmooth, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, keyFile);
3668 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBright, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, keyFile);
3669 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBrightChannel, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, keyFile);
3670 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, keyFile);
3671 saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftDemosaicMethod, "RAW Bayer", "pixelShiftDemosaicMethod", raw.bayersensor.pixelShiftDemosaicMethod, keyFile);
3672 saveToKeyfile(!pedited || pedited->raw.bayersensor.pdafLinesFilter, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, keyFile);
3673 saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile);
3674 saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicAutoContrast, "RAW X-Trans", "DualDemosaicAutoContrast", raw.xtranssensor.dualDemosaicAutoContrast, keyFile);
3675 saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicContrast, "RAW X-Trans", "DualDemosaicContrast", raw.xtranssensor.dualDemosaicContrast, keyFile);
3676 saveToKeyfile(!pedited || pedited->raw.xtranssensor.border, "RAW X-Trans", "Border", raw.xtranssensor.border, keyFile);
3677 saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile);
3678 saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile);
3679 saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackGreen, "RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen, keyFile);
3680 saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackBlue, "RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue, keyFile);
3681
3682 // Raw exposition
3683 saveToKeyfile(!pedited || pedited->raw.exPos, "RAW", "PreExposure", raw.expos, keyFile);
3684
3685 // MetaData
3686 saveToKeyfile(!pedited || pedited->metadata.mode, "MetaData", "Mode", metadata.mode, keyFile);
3687
3688 // Film negative
3689 saveToKeyfile(!pedited || pedited->filmNegative.enabled, "Film Negative", "Enabled", filmNegative.enabled, keyFile);
3690 saveToKeyfile(!pedited || pedited->filmNegative.redRatio, "Film Negative", "RedRatio", filmNegative.redRatio, keyFile);
3691 saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile);
3692 saveToKeyfile(!pedited || pedited->filmNegative.blueRatio, "Film Negative", "BlueRatio", filmNegative.blueRatio, keyFile);
3693
3694 // EXIF change list
3695 if (!pedited || pedited->exif) {
3696 for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) {
3697 keyFile.set_string("Exif", i->first, i->second);
3698 }
3699 }
3700
3701 // IPTC change list
3702 if (!pedited || pedited->iptc) {
3703 for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); ++i) {
3704 Glib::ArrayHandle<Glib::ustring> values = i->second;
3705 keyFile.set_string_list("IPTC", i->first, values);
3706 }
3707 }
3708
3709 sPParams = keyFile.to_data();
3710
3711 } catch (Glib::KeyFileError&) {}
3712
3713 if (sPParams.empty()) {
3714 return 1;
3715 }
3716
3717 int error1, error2;
3718 error1 = write(fname, sPParams);
3719
3720 if (!fname2.empty()) {
3721
3722 error2 = write(fname2, sPParams);
3723 // If at least one file has been saved, it's a success
3724 return error1 & error2;
3725 } else {
3726 return error1;
3727 }
3728 }
3729
load(const Glib::ustring & fname,ParamsEdited * pedited)3730 int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
3731 {
3732 setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
3733
3734 if (fname.empty()) {
3735 return 1;
3736 }
3737
3738 Glib::KeyFile keyFile;
3739
3740 try {
3741 if (pedited) {
3742 pedited->set(false);
3743 }
3744
3745 if (!Glib::file_test(fname, Glib::FILE_TEST_EXISTS) ||
3746 !keyFile.load_from_file(fname)) {
3747 return 1;
3748 }
3749
3750 ppVersion = PPVERSION;
3751 appVersion = RTVERSION;
3752
3753 if (keyFile.has_group("Version")) {
3754 if (keyFile.has_key("Version", "AppVersion")) {
3755 appVersion = keyFile.get_string("Version", "AppVersion");
3756 }
3757
3758 if (keyFile.has_key("Version", "Version")) {
3759 ppVersion = keyFile.get_integer("Version", "Version");
3760 }
3761 }
3762
3763 if (keyFile.has_group("General")) {
3764 assignFromKeyfile(keyFile, "General", "Rank", pedited, rank, pedited->general.rank);
3765 assignFromKeyfile(keyFile, "General", "ColorLabel", pedited, colorlabel, pedited->general.colorlabel);
3766 assignFromKeyfile(keyFile, "General", "InTrash", pedited, inTrash, pedited->general.intrash);
3767 }
3768
3769 if (keyFile.has_group("Exposure")) {
3770 if (ppVersion < PPVERSION_AEXP) {
3771 toneCurve.autoexp = false; // prevent execution of autoexp when opening file created with earlier versions of autoexp algorithm
3772 } else {
3773 assignFromKeyfile(keyFile, "Exposure", "Auto", pedited, toneCurve.autoexp, pedited->toneCurve.autoexp);
3774 }
3775
3776 assignFromKeyfile(keyFile, "Exposure", "Clip", pedited, toneCurve.clip, pedited->toneCurve.clip);
3777 assignFromKeyfile(keyFile, "Exposure", "Compensation", pedited, toneCurve.expcomp, pedited->toneCurve.expcomp);
3778 assignFromKeyfile(keyFile, "Exposure", "Brightness", pedited, toneCurve.brightness, pedited->toneCurve.brightness);
3779 assignFromKeyfile(keyFile, "Exposure", "Contrast", pedited, toneCurve.contrast, pedited->toneCurve.contrast);
3780 assignFromKeyfile(keyFile, "Exposure", "Saturation", pedited, toneCurve.saturation, pedited->toneCurve.saturation);
3781 assignFromKeyfile(keyFile, "Exposure", "Black", pedited, toneCurve.black, pedited->toneCurve.black);
3782 assignFromKeyfile(keyFile, "Exposure", "HighlightCompr", pedited, toneCurve.hlcompr, pedited->toneCurve.hlcompr);
3783 assignFromKeyfile(keyFile, "Exposure", "HighlightComprThreshold", pedited, toneCurve.hlcomprthresh, pedited->toneCurve.hlcomprthresh);
3784 assignFromKeyfile(keyFile, "Exposure", "ShadowCompr", pedited, toneCurve.shcompr, pedited->toneCurve.shcompr);
3785
3786 if (toneCurve.shcompr > 100) {
3787 toneCurve.shcompr = 100; // older pp3 files can have values above 100.
3788 }
3789
3790 const std::map<std::string, ToneCurveMode> tc_mapping = {
3791 {"Standard", ToneCurveMode::STD},
3792 {"FilmLike", ToneCurveMode::FILMLIKE},
3793 {"SatAndValueBlending", ToneCurveMode::SATANDVALBLENDING},
3794 {"WeightedStd", ToneCurveMode::WEIGHTEDSTD},
3795 {"Luminance", ToneCurveMode::LUMINANCE},
3796 {"Perceptual", ToneCurveMode::PERCEPTUAL}
3797 };
3798
3799 assignFromKeyfile(keyFile, "Exposure", "CurveMode", pedited, tc_mapping, toneCurve.curveMode, pedited->toneCurve.curveMode);
3800 assignFromKeyfile(keyFile, "Exposure", "CurveMode2", pedited, tc_mapping, toneCurve.curveMode2, pedited->toneCurve.curveMode2);
3801
3802 if (ppVersion > 200) {
3803 assignFromKeyfile(keyFile, "Exposure", "Curve", pedited, toneCurve.curve, pedited->toneCurve.curve);
3804 assignFromKeyfile(keyFile, "Exposure", "Curve2", pedited, toneCurve.curve2, pedited->toneCurve.curve2);
3805 }
3806
3807 assignFromKeyfile(keyFile, "Exposure", "HistogramMatching", pedited, toneCurve.histmatching, pedited->toneCurve.histmatching);
3808 if (ppVersion < 340) {
3809 toneCurve.fromHistMatching = false;
3810 if (pedited) {
3811 pedited->toneCurve.fromHistMatching = true;
3812 }
3813 } else {
3814 assignFromKeyfile(keyFile, "Exposure", "CurveFromHistogramMatching", pedited, toneCurve.fromHistMatching, pedited->toneCurve.fromHistMatching);
3815 }
3816 assignFromKeyfile(keyFile, "Exposure", "ClampOOG", pedited, toneCurve.clampOOG, pedited->toneCurve.clampOOG);
3817 }
3818
3819 if (keyFile.has_group("HLRecovery")) {
3820 assignFromKeyfile(keyFile, "HLRecovery", "Enabled", pedited, toneCurve.hrenabled, pedited->toneCurve.hrenabled);
3821 assignFromKeyfile(keyFile, "HLRecovery", "Method", pedited, toneCurve.method, pedited->toneCurve.method);
3822 }
3823
3824 if (keyFile.has_group("Channel Mixer")) {
3825 if (ppVersion >= 329) {
3826 assignFromKeyfile(keyFile, "Channel Mixer", "Enabled", pedited, chmixer.enabled, pedited->chmixer.enabled);
3827 } else {
3828 chmixer.enabled = true;
3829
3830 if (pedited) {
3831 pedited->chmixer.enabled = true;
3832 }
3833 }
3834
3835 if (keyFile.has_key("Channel Mixer", "Red") && keyFile.has_key("Channel Mixer", "Green") && keyFile.has_key("Channel Mixer", "Blue")) {
3836 const std::vector<int> rmix = keyFile.get_integer_list("Channel Mixer", "Red");
3837 const std::vector<int> gmix = keyFile.get_integer_list("Channel Mixer", "Green");
3838 const std::vector<int> bmix = keyFile.get_integer_list("Channel Mixer", "Blue");
3839
3840 if (rmix.size() == 3 && gmix.size() == 3 && bmix.size() == 3) {
3841 memcpy(chmixer.red, rmix.data(), 3 * sizeof(int));
3842 memcpy(chmixer.green, gmix.data(), 3 * sizeof(int));
3843 memcpy(chmixer.blue, bmix.data(), 3 * sizeof(int));
3844 }
3845 if (ppVersion < 338) {
3846 for (int i = 0; i < 3; ++i) {
3847 chmixer.red[i] *= 10;
3848 chmixer.green[i] *= 10;
3849 chmixer.blue[i] *= 10;
3850 }
3851 }
3852
3853 if (pedited) {
3854 pedited->chmixer.red[0] = pedited->chmixer.red[1] = pedited->chmixer.red[2] = true;
3855 pedited->chmixer.green[0] = pedited->chmixer.green[1] = pedited->chmixer.green[2] = true;
3856 pedited->chmixer.blue[0] = pedited->chmixer.blue[1] = pedited->chmixer.blue[2] = true;
3857 }
3858 }
3859 }
3860
3861 if (keyFile.has_group("Black & White")) {
3862 assignFromKeyfile(keyFile, "Black & White", "Enabled", pedited, blackwhite.enabled, pedited->blackwhite.enabled);
3863 assignFromKeyfile(keyFile, "Black & White", "Method", pedited, blackwhite.method, pedited->blackwhite.method);
3864 assignFromKeyfile(keyFile, "Black & White", "Auto", pedited, blackwhite.autoc, pedited->blackwhite.autoc);
3865 assignFromKeyfile(keyFile, "Black & White", "ComplementaryColors", pedited, blackwhite.enabledcc, pedited->blackwhite.enabledcc);
3866 assignFromKeyfile(keyFile, "Black & White", "MixerRed", pedited, blackwhite.mixerRed, pedited->blackwhite.mixerRed);
3867 assignFromKeyfile(keyFile, "Black & White", "MixerOrange", pedited, blackwhite.mixerOrange, pedited->blackwhite.mixerOrange);
3868 assignFromKeyfile(keyFile, "Black & White", "MixerYellow", pedited, blackwhite.mixerYellow, pedited->blackwhite.mixerYellow);
3869 assignFromKeyfile(keyFile, "Black & White", "MixerGreen", pedited, blackwhite.mixerGreen, pedited->blackwhite.mixerGreen);
3870 assignFromKeyfile(keyFile, "Black & White", "MixerCyan", pedited, blackwhite.mixerCyan, pedited->blackwhite.mixerCyan);
3871 assignFromKeyfile(keyFile, "Black & White", "MixerBlue", pedited, blackwhite.mixerBlue, pedited->blackwhite.mixerBlue);
3872 assignFromKeyfile(keyFile, "Black & White", "MixerMagenta", pedited, blackwhite.mixerMagenta, pedited->blackwhite.mixerMagenta);
3873 assignFromKeyfile(keyFile, "Black & White", "MixerPurple", pedited, blackwhite.mixerPurple, pedited->blackwhite.mixerPurple);
3874 assignFromKeyfile(keyFile, "Black & White", "GammaRed", pedited, blackwhite.gammaRed, pedited->blackwhite.gammaRed);
3875 assignFromKeyfile(keyFile, "Black & White", "GammaGreen", pedited, blackwhite.gammaGreen, pedited->blackwhite.gammaGreen);
3876 assignFromKeyfile(keyFile, "Black & White", "GammaBlue", pedited, blackwhite.gammaBlue, pedited->blackwhite.gammaBlue);
3877 assignFromKeyfile(keyFile, "Black & White", "Filter", pedited, blackwhite.filter, pedited->blackwhite.filter);
3878 assignFromKeyfile(keyFile, "Black & White", "Setting", pedited, blackwhite.setting, pedited->blackwhite.setting);
3879 assignFromKeyfile(keyFile, "Black & White", "LuminanceCurve", pedited, blackwhite.luminanceCurve, pedited->blackwhite.luminanceCurve);
3880
3881 assignFromKeyfile(keyFile, "Black & White", "BeforeCurve", pedited, blackwhite.beforeCurve, pedited->blackwhite.beforeCurve);
3882
3883 assignFromKeyfile(keyFile, "Black & White", "Algorithm", pedited, blackwhite.algo, pedited->blackwhite.algo);
3884 assignFromKeyfile(
3885 keyFile,
3886 "Black & White",
3887 "BeforeCurveMode",
3888 pedited,
3889 {
3890 {"Standard", BlackWhiteParams::TcMode::STD_BW},
3891 {"FilmLike", BlackWhiteParams::TcMode::FILMLIKE_BW},
3892 {"SatAndValueBlending", BlackWhiteParams::TcMode::SATANDVALBLENDING_BW},
3893 {"WeightedStd", BlackWhiteParams::TcMode::WEIGHTEDSTD_BW}
3894 },
3895 blackwhite.beforeCurveMode,
3896 pedited->blackwhite.beforeCurveMode
3897 );
3898
3899 assignFromKeyfile(keyFile, "Black & White", "AfterCurve", pedited, blackwhite.afterCurve, pedited->blackwhite.afterCurve);
3900 assignFromKeyfile(
3901 keyFile,
3902 "Black & White",
3903 "AfterCurveMode",
3904 pedited,
3905 {
3906 {"Standard", BlackWhiteParams::TcMode::STD_BW},
3907 {"WeightedStd", BlackWhiteParams::TcMode::WEIGHTEDSTD_BW}
3908 },
3909 blackwhite.afterCurveMode,
3910 pedited->blackwhite.afterCurveMode
3911 );
3912 }
3913
3914 if (keyFile.has_group("Retinex")) {
3915 assignFromKeyfile(keyFile, "Retinex", "Median", pedited, retinex.medianmap, pedited->retinex.medianmap);
3916 assignFromKeyfile(keyFile, "Retinex", "RetinexMethod", pedited, retinex.retinexMethod, pedited->retinex.retinexMethod);
3917 assignFromKeyfile(keyFile, "Retinex", "mapMethod", pedited, retinex.mapMethod, pedited->retinex.mapMethod);
3918 assignFromKeyfile(keyFile, "Retinex", "viewMethod", pedited, retinex.viewMethod, pedited->retinex.viewMethod);
3919
3920 assignFromKeyfile(keyFile, "Retinex", "Retinexcolorspace", pedited, retinex.retinexcolorspace, pedited->retinex.retinexcolorspace);
3921 assignFromKeyfile(keyFile, "Retinex", "Gammaretinex", pedited, retinex.gammaretinex, pedited->retinex.gammaretinex);
3922 assignFromKeyfile(keyFile, "Retinex", "Enabled", pedited, retinex.enabled, pedited->retinex.enabled);
3923 assignFromKeyfile(keyFile, "Retinex", "Neigh", pedited, retinex.neigh, pedited->retinex.neigh);
3924 assignFromKeyfile(keyFile, "Retinex", "Str", pedited, retinex.str, pedited->retinex.str);
3925 assignFromKeyfile(keyFile, "Retinex", "Scal", pedited, retinex.scal, pedited->retinex.scal);
3926 assignFromKeyfile(keyFile, "Retinex", "Iter", pedited, retinex.iter, pedited->retinex.iter);
3927 assignFromKeyfile(keyFile, "Retinex", "Grad", pedited, retinex.grad, pedited->retinex.grad);
3928 assignFromKeyfile(keyFile, "Retinex", "Grads", pedited, retinex.grads, pedited->retinex.grads);
3929 assignFromKeyfile(keyFile, "Retinex", "Gam", pedited, retinex.gam, pedited->retinex.gam);
3930 assignFromKeyfile(keyFile, "Retinex", "Slope", pedited, retinex.slope, pedited->retinex.slope);
3931 assignFromKeyfile(keyFile, "Retinex", "Offs", pedited, retinex.offs, pedited->retinex.offs);
3932 assignFromKeyfile(keyFile, "Retinex", "Vart", pedited, retinex.vart, pedited->retinex.vart);
3933 assignFromKeyfile(keyFile, "Retinex", "Limd", pedited, retinex.limd, pedited->retinex.limd);
3934 assignFromKeyfile(keyFile, "Retinex", "highl", pedited, retinex.highl, pedited->retinex.highl);
3935 assignFromKeyfile(keyFile, "Retinex", "skal", pedited, retinex.skal, pedited->retinex.skal);
3936 assignFromKeyfile(keyFile, "Retinex", "CDCurve", pedited, retinex.cdcurve, pedited->retinex.cdcurve);
3937
3938 assignFromKeyfile(keyFile, "Retinex", "MAPCurve", pedited, retinex.mapcurve, pedited->retinex.mapcurve);
3939
3940 assignFromKeyfile(keyFile, "Retinex", "CDHCurve", pedited, retinex.cdHcurve, pedited->retinex.cdHcurve);
3941
3942 assignFromKeyfile(keyFile, "Retinex", "LHCurve", pedited, retinex.lhcurve, pedited->retinex.lhcurve);
3943
3944 assignFromKeyfile(keyFile, "Retinex", "Highlights", pedited, retinex.highlights, pedited->retinex.highlights);
3945 assignFromKeyfile(keyFile, "Retinex", "HighlightTonalWidth", pedited, retinex.htonalwidth, pedited->retinex.htonalwidth);
3946 assignFromKeyfile(keyFile, "Retinex", "Shadows", pedited, retinex.shadows, pedited->retinex.shadows);
3947 assignFromKeyfile(keyFile, "Retinex", "ShadowTonalWidth", pedited, retinex.stonalwidth, pedited->retinex.stonalwidth);
3948
3949 assignFromKeyfile(keyFile, "Retinex", "Radius", pedited, retinex.radius, pedited->retinex.radius);
3950
3951 assignFromKeyfile(keyFile, "Retinex", "TransmissionCurve", pedited, retinex.transmissionCurve, pedited->retinex.transmissionCurve);
3952
3953 assignFromKeyfile(keyFile, "Retinex", "GainTransmissionCurve", pedited, retinex.gaintransmissionCurve, pedited->retinex.gaintransmissionCurve);
3954 }
3955
3956 if (keyFile.has_group("Local Contrast")) {
3957 assignFromKeyfile(keyFile, "Local Contrast", "Enabled", pedited, localContrast.enabled, pedited->localContrast.enabled);
3958 assignFromKeyfile(keyFile, "Local Contrast", "Radius", pedited, localContrast.radius, pedited->localContrast.radius);
3959 assignFromKeyfile(keyFile, "Local Contrast", "Amount", pedited, localContrast.amount, pedited->localContrast.amount);
3960 assignFromKeyfile(keyFile, "Local Contrast", "Darkness", pedited, localContrast.darkness, pedited->localContrast.darkness);
3961 assignFromKeyfile(keyFile, "Local Contrast", "Lightness", pedited, localContrast.lightness, pedited->localContrast.lightness);
3962 }
3963
3964 if (keyFile.has_group("Luminance Curve")) {
3965 if (ppVersion >= 329) {
3966 assignFromKeyfile(keyFile, "Luminance Curve", "Enabled", pedited, labCurve.enabled, pedited->labCurve.enabled);
3967 } else {
3968 labCurve.enabled = true;
3969
3970 if (pedited) {
3971 pedited->labCurve.enabled = true;
3972 }
3973 }
3974
3975 assignFromKeyfile(keyFile, "Luminance Curve", "Brightness", pedited, labCurve.brightness, pedited->labCurve.brightness);
3976 assignFromKeyfile(keyFile, "Luminance Curve", "Contrast", pedited, labCurve.contrast, pedited->labCurve.contrast);
3977
3978 if (ppVersion < 303) {
3979 // transform Saturation into Chromaticity
3980 // if Saturation == 0, should we set BWToning on?
3981 assignFromKeyfile(keyFile, "Luminance Curve", "Saturation", pedited, labCurve.chromaticity, pedited->labCurve.chromaticity);
3982 // transform AvoidColorClipping into AvoidColorShift
3983 assignFromKeyfile(keyFile, "Luminance Curve", "AvoidColorClipping", pedited, labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift);
3984 } else {
3985 if (keyFile.has_key("Luminance Curve", "Chromaticity")) {
3986 labCurve.chromaticity = keyFile.get_integer("Luminance Curve", "Chromaticity");
3987
3988 if (ppVersion >= 303 && ppVersion < 314 && labCurve.chromaticity == -100) {
3989 blackwhite.enabled = true;
3990 }
3991
3992 if (pedited) {
3993 pedited->labCurve.chromaticity = true;
3994 }
3995 }
3996
3997 assignFromKeyfile(keyFile, "Luminance Curve", "AvoidColorShift", pedited, labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift);
3998 assignFromKeyfile(keyFile, "Luminance Curve", "RedAndSkinTonesProtection", pedited, labCurve.rstprotection, pedited->labCurve.rstprotection);
3999 }
4000
4001 assignFromKeyfile(keyFile, "Luminance Curve", "LCredsk", pedited, labCurve.lcredsk, pedited->labCurve.lcredsk);
4002
4003 if (ppVersion < 314) {
4004 // Backward compatibility: If BWtoning is true, Chromaticity has to be set to -100, which will produce the same effect
4005 // and will enable the b&w toning mode ('a' & 'b' curves)
4006 if (keyFile.has_key("Luminance Curve", "BWtoning")) {
4007 if (keyFile.get_boolean("Luminance Curve", "BWtoning")) {
4008 labCurve.chromaticity = -100;
4009
4010 if (pedited) {
4011 pedited->labCurve.chromaticity = true;
4012 }
4013 }
4014 }
4015 }
4016
4017 assignFromKeyfile(keyFile, "Luminance Curve", "LCurve", pedited, labCurve.lcurve, pedited->labCurve.lcurve);
4018 assignFromKeyfile(keyFile, "Luminance Curve", "aCurve", pedited, labCurve.acurve, pedited->labCurve.acurve);
4019 assignFromKeyfile(keyFile, "Luminance Curve", "bCurve", pedited, labCurve.bcurve, pedited->labCurve.bcurve);
4020 assignFromKeyfile(keyFile, "Luminance Curve", "ccCurve", pedited, labCurve.cccurve, pedited->labCurve.cccurve);
4021 assignFromKeyfile(keyFile, "Luminance Curve", "chCurve", pedited, labCurve.chcurve, pedited->labCurve.chcurve);
4022 assignFromKeyfile(keyFile, "Luminance Curve", "lhCurve", pedited, labCurve.lhcurve, pedited->labCurve.lhcurve);
4023 assignFromKeyfile(keyFile, "Luminance Curve", "hhCurve", pedited, labCurve.hhcurve, pedited->labCurve.hhcurve);
4024 assignFromKeyfile(keyFile, "Luminance Curve", "LcCurve", pedited, labCurve.lccurve, pedited->labCurve.lccurve);
4025 assignFromKeyfile(keyFile, "Luminance Curve", "ClCurve", pedited, labCurve.clcurve, pedited->labCurve.clcurve);
4026 }
4027
4028 if (keyFile.has_group("Sharpening")) {
4029 assignFromKeyfile(keyFile, "Sharpening", "Enabled", pedited, sharpening.enabled, pedited->sharpening.enabled);
4030 if (ppVersion >= 334) {
4031 assignFromKeyfile(keyFile, "Sharpening", "Contrast", pedited, sharpening.contrast, pedited->sharpening.contrast);
4032 } else {
4033 sharpening.contrast = 0;
4034 if (pedited) {
4035 pedited->sharpening.contrast = true;
4036 }
4037 }
4038 assignFromKeyfile(keyFile, "Sharpening", "Radius", pedited, sharpening.radius, pedited->sharpening.radius);
4039 assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", pedited, sharpening.blurradius, pedited->sharpening.blurradius);
4040 assignFromKeyfile(keyFile, "Sharpening", "Amount", pedited, sharpening.amount, pedited->sharpening.amount);
4041
4042 if (keyFile.has_key("Sharpening", "Threshold")) {
4043 if (ppVersion < 302) {
4044 int thresh = min(keyFile.get_integer("Sharpening", "Threshold"), 2000);
4045 sharpening.threshold.setValues(thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization
4046 } else {
4047 const std::vector<int> thresh = keyFile.get_integer_list("Sharpening", "Threshold");
4048
4049 if (thresh.size() >= 4) {
4050 sharpening.threshold.setValues(thresh[0], thresh[1], min(thresh[2], 2000), min(thresh[3], 2000));
4051 }
4052 }
4053
4054 if (pedited) {
4055 pedited->sharpening.threshold = true;
4056 }
4057 }
4058
4059 assignFromKeyfile(keyFile, "Sharpening", "OnlyEdges", pedited, sharpening.edgesonly, pedited->sharpening.edgesonly);
4060 assignFromKeyfile(keyFile, "Sharpening", "EdgedetectionRadius", pedited, sharpening.edges_radius, pedited->sharpening.edges_radius);
4061 assignFromKeyfile(keyFile, "Sharpening", "EdgeTolerance", pedited, sharpening.edges_tolerance, pedited->sharpening.edges_tolerance);
4062 assignFromKeyfile(keyFile, "Sharpening", "HalocontrolEnabled", pedited, sharpening.halocontrol, pedited->sharpening.halocontrol);
4063 assignFromKeyfile(keyFile, "Sharpening", "HalocontrolAmount", pedited, sharpening.halocontrol_amount, pedited->sharpening.halocontrol_amount);
4064 assignFromKeyfile(keyFile, "Sharpening", "Method", pedited, sharpening.method, pedited->sharpening.method);
4065 assignFromKeyfile(keyFile, "Sharpening", "DeconvRadius", pedited, sharpening.deconvradius, pedited->sharpening.deconvradius);
4066 assignFromKeyfile(keyFile, "Sharpening", "DeconvAmount", pedited, sharpening.deconvamount, pedited->sharpening.deconvamount);
4067 assignFromKeyfile(keyFile, "Sharpening", "DeconvDamping", pedited, sharpening.deconvdamping, pedited->sharpening.deconvdamping);
4068 assignFromKeyfile(keyFile, "Sharpening", "DeconvIterations", pedited, sharpening.deconviter, pedited->sharpening.deconviter);
4069 }
4070
4071 if (keyFile.has_group("SharpenEdge")) {
4072 assignFromKeyfile(keyFile, "SharpenEdge", "Enabled", pedited, sharpenEdge.enabled, pedited->sharpenEdge.enabled);
4073 assignFromKeyfile(keyFile, "SharpenEdge", "Passes", pedited, sharpenEdge.passes, pedited->sharpenEdge.passes);
4074 assignFromKeyfile(keyFile, "SharpenEdge", "Strength", pedited, sharpenEdge.amount, pedited->sharpenEdge.amount);
4075 assignFromKeyfile(keyFile, "SharpenEdge", "ThreeChannels", pedited, sharpenEdge.threechannels, pedited->sharpenEdge.threechannels);
4076 }
4077
4078 if (keyFile.has_group("SharpenMicro")) {
4079 assignFromKeyfile(keyFile, "SharpenMicro", "Enabled", pedited, sharpenMicro.enabled, pedited->sharpenMicro.enabled);
4080 assignFromKeyfile(keyFile, "SharpenMicro", "Matrix", pedited, sharpenMicro.matrix, pedited->sharpenMicro.matrix);
4081 assignFromKeyfile(keyFile, "SharpenMicro", "Strength", pedited, sharpenMicro.amount, pedited->sharpenMicro.amount);
4082 if (ppVersion >= 334) {
4083 assignFromKeyfile(keyFile, "SharpenMicro", "Contrast", pedited, sharpenMicro.contrast, pedited->sharpenMicro.contrast);
4084 } else {
4085 sharpenMicro.contrast = 0;
4086 if (pedited) {
4087 pedited->sharpenMicro.contrast = true;
4088 }
4089 }
4090 if (ppVersion >= 346) {
4091 assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", pedited, sharpenMicro.uniformity, pedited->sharpenMicro.uniformity);
4092 } else {
4093 double temp = 50.0;
4094 assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", pedited, temp, pedited->sharpenMicro.uniformity);
4095 sharpenMicro.uniformity = temp / 10;
4096 }
4097 }
4098
4099 if (keyFile.has_group("Vibrance")) {
4100 assignFromKeyfile(keyFile, "Vibrance", "Enabled", pedited, vibrance.enabled, pedited->vibrance.enabled);
4101 assignFromKeyfile(keyFile, "Vibrance", "Pastels", pedited, vibrance.pastels, pedited->vibrance.pastels);
4102 assignFromKeyfile(keyFile, "Vibrance", "Saturated", pedited, vibrance.saturated, pedited->vibrance.saturated);
4103
4104 if (keyFile.has_key("Vibrance", "PSThreshold")) {
4105 if (ppVersion < 302) {
4106 int thresh = keyFile.get_integer("Vibrance", "PSThreshold");
4107 vibrance.psthreshold.setValues(thresh, thresh);
4108 } else {
4109 const std::vector<int> thresh = keyFile.get_integer_list("Vibrance", "PSThreshold");
4110
4111 if (thresh.size() >= 2) {
4112 vibrance.psthreshold.setValues(thresh[0], thresh[1]);
4113 }
4114 }
4115
4116 if (pedited) {
4117 pedited->vibrance.psthreshold = true;
4118 }
4119 }
4120
4121 assignFromKeyfile(keyFile, "Vibrance", "ProtectSkins", pedited, vibrance.protectskins, pedited->vibrance.protectskins);
4122 assignFromKeyfile(keyFile, "Vibrance", "AvoidColorShift", pedited, vibrance.avoidcolorshift, pedited->vibrance.avoidcolorshift);
4123 assignFromKeyfile(keyFile, "Vibrance", "PastSatTog", pedited, vibrance.pastsattog, pedited->vibrance.pastsattog);
4124 assignFromKeyfile(keyFile, "Vibrance", "SkinTonesCurve", pedited, vibrance.skintonescurve, pedited->vibrance.skintonescurve);
4125 }
4126
4127 if (keyFile.has_group("White Balance")) {
4128 assignFromKeyfile(keyFile, "White Balance", "Enabled", pedited, wb.enabled, pedited->wb.enabled);
4129 assignFromKeyfile(keyFile, "White Balance", "Setting", pedited, wb.method, pedited->wb.method);
4130 assignFromKeyfile(keyFile, "White Balance", "Temperature", pedited, wb.temperature, pedited->wb.temperature);
4131 assignFromKeyfile(keyFile, "White Balance", "Green", pedited, wb.green, pedited->wb.green);
4132 assignFromKeyfile(keyFile, "White Balance", "Equal", pedited, wb.equal, pedited->wb.equal);
4133 assignFromKeyfile(keyFile, "White Balance", "TemperatureBias", pedited, wb.tempBias, pedited->wb.tempBias);
4134 }
4135
4136 if (keyFile.has_group("Defringing")) {
4137 assignFromKeyfile(keyFile, "Defringing", "Enabled", pedited, defringe.enabled, pedited->defringe.enabled);
4138 assignFromKeyfile(keyFile, "Defringing", "Radius", pedited, defringe.radius, pedited->defringe.radius);
4139
4140 if (keyFile.has_key("Defringing", "Threshold")) {
4141 defringe.threshold = (float)keyFile.get_integer("Defringing", "Threshold");
4142
4143 if (pedited) {
4144 pedited->defringe.threshold = true;
4145 }
4146 }
4147
4148 if (ppVersion < 310) {
4149 defringe.threshold = sqrt(defringe.threshold * 33.f / 5.f);
4150 }
4151
4152 assignFromKeyfile(keyFile, "Defringing", "HueCurve", pedited, defringe.huecurve, pedited->defringe.huecurve);
4153 }
4154
4155 if (keyFile.has_group("Color appearance")) {
4156 assignFromKeyfile(keyFile, "Color appearance", "Enabled", pedited, colorappearance.enabled, pedited->colorappearance.enabled);
4157 assignFromKeyfile(keyFile, "Color appearance", "Degree", pedited, colorappearance.degree, pedited->colorappearance.degree);
4158 assignFromKeyfile(keyFile, "Color appearance", "AutoDegree", pedited, colorappearance.autodegree, pedited->colorappearance.autodegree);
4159 assignFromKeyfile(keyFile, "Color appearance", "Degreeout", pedited, colorappearance.degreeout, pedited->colorappearance.degreeout);
4160
4161 assignFromKeyfile(keyFile, "Color appearance", "AutoDegreeout", pedited, colorappearance.autodegreeout, pedited->colorappearance.autodegreeout);
4162
4163 assignFromKeyfile(keyFile, "Color appearance", "Surround", pedited, colorappearance.surround, pedited->colorappearance.surround);
4164 assignFromKeyfile(keyFile, "Color appearance", "Surrsrc", pedited, colorappearance.surrsrc, pedited->colorappearance.surrsrc);
4165 assignFromKeyfile(keyFile, "Color appearance", "AdaptLum", pedited, colorappearance.adaplum, pedited->colorappearance.adaplum);
4166 assignFromKeyfile(keyFile, "Color appearance", "Badpixsl", pedited, colorappearance.badpixsl, pedited->colorappearance.badpixsl);
4167 assignFromKeyfile(keyFile, "Color appearance", "Model", pedited, colorappearance.wbmodel, pedited->colorappearance.wbmodel);
4168 assignFromKeyfile(keyFile, "Color appearance", "Algorithm", pedited, colorappearance.algo, pedited->colorappearance.algo);
4169 assignFromKeyfile(keyFile, "Color appearance", "J-Light", pedited, colorappearance.jlight, pedited->colorappearance.jlight);
4170 assignFromKeyfile(keyFile, "Color appearance", "Q-Bright", pedited, colorappearance.qbright, pedited->colorappearance.qbright);
4171 assignFromKeyfile(keyFile, "Color appearance", "C-Chroma", pedited, colorappearance.chroma, pedited->colorappearance.chroma);
4172 assignFromKeyfile(keyFile, "Color appearance", "S-Chroma", pedited, colorappearance.schroma, pedited->colorappearance.schroma);
4173 assignFromKeyfile(keyFile, "Color appearance", "M-Chroma", pedited, colorappearance.mchroma, pedited->colorappearance.mchroma);
4174 assignFromKeyfile(keyFile, "Color appearance", "RSTProtection", pedited, colorappearance.rstprotection, pedited->colorappearance.rstprotection);
4175 assignFromKeyfile(keyFile, "Color appearance", "J-Contrast", pedited, colorappearance.contrast, pedited->colorappearance.contrast);
4176 assignFromKeyfile(keyFile, "Color appearance", "Q-Contrast", pedited, colorappearance.qcontrast, pedited->colorappearance.qcontrast);
4177 assignFromKeyfile(keyFile, "Color appearance", "H-Hue", pedited, colorappearance.colorh, pedited->colorappearance.colorh);
4178 assignFromKeyfile(keyFile, "Color appearance", "AdaptScene", pedited, colorappearance.adapscen, pedited->colorappearance.adapscen);
4179 assignFromKeyfile(keyFile, "Color appearance", "AutoAdapscen", pedited, colorappearance.autoadapscen, pedited->colorappearance.autoadapscen);
4180 assignFromKeyfile(keyFile, "Color appearance", "YbScene", pedited, colorappearance.ybscen, pedited->colorappearance.ybscen);
4181 assignFromKeyfile(keyFile, "Color appearance", "Autoybscen", pedited, colorappearance.autoybscen, pedited->colorappearance.autoybscen);
4182 assignFromKeyfile(keyFile, "Color appearance", "SurrSource", pedited, colorappearance.surrsource, pedited->colorappearance.surrsource);
4183 assignFromKeyfile(keyFile, "Color appearance", "Gamut", pedited, colorappearance.gamut, pedited->colorappearance.gamut);
4184 assignFromKeyfile(keyFile, "Color appearance", "Tempout", pedited, colorappearance.tempout, pedited->colorappearance.tempout);
4185 assignFromKeyfile(keyFile, "Color appearance", "Greenout", pedited, colorappearance.greenout, pedited->colorappearance.greenout);
4186 assignFromKeyfile(keyFile, "Color appearance", "Tempsc", pedited, colorappearance.tempsc, pedited->colorappearance.tempsc);
4187 assignFromKeyfile(keyFile, "Color appearance", "Greensc", pedited, colorappearance.greensc, pedited->colorappearance.greensc);
4188 assignFromKeyfile(keyFile, "Color appearance", "Ybout", pedited, colorappearance.ybout, pedited->colorappearance.ybout);
4189 assignFromKeyfile(keyFile, "Color appearance", "Datacie", pedited, colorappearance.datacie, pedited->colorappearance.datacie);
4190 assignFromKeyfile(keyFile, "Color appearance", "Tonecie", pedited, colorappearance.tonecie, pedited->colorappearance.tonecie);
4191
4192 const std::map<std::string, ColorAppearanceParams::TcMode> tc_mapping = {
4193 {"Lightness", ColorAppearanceParams::TcMode::LIGHT},
4194 {"Brightness", ColorAppearanceParams::TcMode::BRIGHT}
4195 };
4196 assignFromKeyfile(keyFile, "Color appearance", "CurveMode", pedited, tc_mapping, colorappearance.curveMode, pedited->colorappearance.curveMode);
4197 assignFromKeyfile(keyFile, "Color appearance", "CurveMode2", pedited, tc_mapping, colorappearance.curveMode2, pedited->colorappearance.curveMode2);
4198
4199 assignFromKeyfile(
4200 keyFile,
4201 "Color appearance",
4202 "CurveMode3",
4203 pedited,
4204 {
4205 {"Chroma", ColorAppearanceParams::CtcMode::CHROMA},
4206 {"Saturation", ColorAppearanceParams::CtcMode::SATUR},
4207 {"Colorfullness", ColorAppearanceParams::CtcMode::COLORF}
4208 },
4209 colorappearance.curveMode3,
4210 pedited->colorappearance.curveMode3
4211 );
4212
4213 if (ppVersion > 200) {
4214 assignFromKeyfile(keyFile, "Color appearance", "Curve", pedited, colorappearance.curve, pedited->colorappearance.curve);
4215 assignFromKeyfile(keyFile, "Color appearance", "Curve2", pedited, colorappearance.curve2, pedited->colorappearance.curve2);
4216 assignFromKeyfile(keyFile, "Color appearance", "Curve3", pedited, colorappearance.curve3, pedited->colorappearance.curve3);
4217 }
4218
4219 }
4220
4221 if (keyFile.has_group("Impulse Denoising")) {
4222 assignFromKeyfile(keyFile, "Impulse Denoising", "Enabled", pedited, impulseDenoise.enabled, pedited->impulseDenoise.enabled);
4223 assignFromKeyfile(keyFile, "Impulse Denoising", "Threshold", pedited, impulseDenoise.thresh, pedited->impulseDenoise.thresh);
4224 }
4225
4226 if (keyFile.has_group("Directional Pyramid Denoising")) { //TODO: No longer an accurate description for FT denoise
4227 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enabled", pedited, dirpyrDenoise.enabled, pedited->dirpyrDenoise.enabled);
4228 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enhance", pedited, dirpyrDenoise.enhance, pedited->dirpyrDenoise.enhance);
4229 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Median", pedited, dirpyrDenoise.median, pedited->dirpyrDenoise.median);
4230 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Luma", pedited, dirpyrDenoise.luma, pedited->dirpyrDenoise.luma);
4231 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Ldetail", pedited, dirpyrDenoise.Ldetail, pedited->dirpyrDenoise.Ldetail);
4232 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Chroma", pedited, dirpyrDenoise.chroma, pedited->dirpyrDenoise.chroma);
4233 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Method", pedited, dirpyrDenoise.dmethod, pedited->dirpyrDenoise.dmethod);
4234 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LMethod", pedited, dirpyrDenoise.Lmethod, pedited->dirpyrDenoise.Lmethod);
4235 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CMethod", pedited, dirpyrDenoise.Cmethod, pedited->dirpyrDenoise.Cmethod);
4236
4237 if (dirpyrDenoise.Cmethod == "PRE") {
4238 dirpyrDenoise.Cmethod = "MAN"; // Never load 'auto chroma preview mode' from pp3
4239 }
4240
4241 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "C2Method", pedited, dirpyrDenoise.C2method, pedited->dirpyrDenoise.C2method);
4242
4243 if (dirpyrDenoise.C2method == "PREV") {
4244 dirpyrDenoise.C2method = "MANU";
4245 }
4246
4247 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "SMethod", pedited, dirpyrDenoise.smethod, pedited->dirpyrDenoise.smethod);
4248 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MedMethod", pedited, dirpyrDenoise.medmethod, pedited->dirpyrDenoise.medmethod);
4249 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MethodMed", pedited, dirpyrDenoise.methodmed, pedited->dirpyrDenoise.methodmed);
4250 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "RGBMethod", pedited, dirpyrDenoise.rgbmethod, pedited->dirpyrDenoise.rgbmethod);
4251 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LCurve", pedited, dirpyrDenoise.lcurve, pedited->dirpyrDenoise.lcurve);
4252
4253 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CCCurve", pedited, dirpyrDenoise.cccurve, pedited->dirpyrDenoise.cccurve);
4254
4255 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", pedited, dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro);
4256 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", pedited, dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro);
4257 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", pedited, dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma);
4258 assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", pedited, dirpyrDenoise.passes, pedited->dirpyrDenoise.passes);
4259 }
4260
4261 if (keyFile.has_group("EPD")) {
4262 assignFromKeyfile(keyFile, "EPD", "Enabled", pedited, epd.enabled, pedited->epd.enabled);
4263 assignFromKeyfile(keyFile, "EPD", "Strength", pedited, epd.strength, pedited->epd.strength);
4264 assignFromKeyfile(keyFile, "EPD", "Gamma", pedited, epd.gamma, pedited->epd.gamma);
4265 assignFromKeyfile(keyFile, "EPD", "EdgeStopping", pedited, epd.edgeStopping, pedited->epd.edgeStopping);
4266 assignFromKeyfile(keyFile, "EPD", "Scale", pedited, epd.scale, pedited->epd.scale);
4267 assignFromKeyfile(keyFile, "EPD", "ReweightingIterates", pedited, epd.reweightingIterates, pedited->epd.reweightingIterates);
4268 }
4269
4270 if (keyFile.has_group("FattalToneMapping")) {
4271 assignFromKeyfile(keyFile, "FattalToneMapping", "Enabled", pedited, fattal.enabled, pedited->fattal.enabled);
4272 assignFromKeyfile(keyFile, "FattalToneMapping", "Threshold", pedited, fattal.threshold, pedited->fattal.threshold);
4273 assignFromKeyfile(keyFile, "FattalToneMapping", "Amount", pedited, fattal.amount, pedited->fattal.amount);
4274 assignFromKeyfile(keyFile, "FattalToneMapping", "Anchor", pedited, fattal.anchor, pedited->fattal.anchor);
4275 }
4276
4277 if (keyFile.has_group ("Shadows & Highlights") && ppVersion >= 333) {
4278 assignFromKeyfile(keyFile, "Shadows & Highlights", "Enabled", pedited, sh.enabled, pedited->sh.enabled);
4279 assignFromKeyfile(keyFile, "Shadows & Highlights", "Highlights", pedited, sh.highlights, pedited->sh.highlights);
4280 assignFromKeyfile(keyFile, "Shadows & Highlights", "HighlightTonalWidth", pedited, sh.htonalwidth, pedited->sh.htonalwidth);
4281 assignFromKeyfile(keyFile, "Shadows & Highlights", "Shadows", pedited, sh.shadows, pedited->sh.shadows);
4282 assignFromKeyfile(keyFile, "Shadows & Highlights", "ShadowTonalWidth", pedited, sh.stonalwidth, pedited->sh.stonalwidth);
4283 assignFromKeyfile(keyFile, "Shadows & Highlights", "Radius", pedited, sh.radius, pedited->sh.radius);
4284 if (ppVersion >= 344) {
4285 assignFromKeyfile(keyFile, "Shadows & Highlights", "Lab", pedited, sh.lab, pedited->sh.lab);
4286 } else {
4287 sh.lab = true;
4288 }
4289
4290 if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) {
4291 int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast");
4292 localContrast.amount = float(lc) / 30.;
4293
4294 if (pedited) {
4295 pedited->localContrast.amount = true;
4296 }
4297
4298 localContrast.enabled = sh.enabled;
4299
4300 if (pedited) {
4301 pedited->localContrast.enabled = true;
4302 }
4303
4304 localContrast.radius = sh.radius;
4305
4306 if (pedited) {
4307 pedited->localContrast.radius = true;
4308 }
4309 }
4310 }
4311
4312 if (keyFile.has_group("Crop")) {
4313 assignFromKeyfile(keyFile, "Crop", "Enabled", pedited, crop.enabled, pedited->crop.enabled);
4314 assignFromKeyfile(keyFile, "Crop", "X", pedited, crop.x, pedited->crop.x);
4315 assignFromKeyfile(keyFile, "Crop", "Y", pedited, crop.y, pedited->crop.y);
4316
4317 if (keyFile.has_key("Crop", "W")) {
4318 crop.w = std::max(keyFile.get_integer("Crop", "W"), 1);
4319
4320 if (pedited) {
4321 pedited->crop.w = true;
4322 }
4323 }
4324
4325 if (keyFile.has_key("Crop", "H")) {
4326 crop.h = std::max(keyFile.get_integer("Crop", "H"), 1);
4327
4328 if (pedited) {
4329 pedited->crop.h = true;
4330 }
4331 }
4332
4333 assignFromKeyfile(keyFile, "Crop", "FixedRatio", pedited, crop.fixratio, pedited->crop.fixratio);
4334
4335 if (assignFromKeyfile(keyFile, "Crop", "Ratio", pedited, crop.ratio, pedited->crop.ratio)) {
4336 //backwards compatibility for crop.ratio
4337 if (crop.ratio == "DIN") {
4338 crop.ratio = "1.414 - DIN EN ISO 216";
4339 }
4340
4341 if (crop.ratio == "8.5:11") {
4342 crop.ratio = "8.5:11 - US Letter";
4343 }
4344
4345 if (crop.ratio == "11:17") {
4346 crop.ratio = "11:17 - Tabloid";
4347 }
4348 }
4349
4350 assignFromKeyfile(keyFile, "Crop", "Orientation", pedited, crop.orientation, pedited->crop.orientation);
4351 assignFromKeyfile(keyFile, "Crop", "Guide", pedited, crop.guide, pedited->crop.guide);
4352 }
4353
4354 if (keyFile.has_group("Coarse Transformation")) {
4355 assignFromKeyfile(keyFile, "Coarse Transformation", "Rotate", pedited, coarse.rotate, pedited->coarse.rotate);
4356 assignFromKeyfile(keyFile, "Coarse Transformation", "HorizontalFlip", pedited, coarse.hflip, pedited->coarse.hflip);
4357 assignFromKeyfile(keyFile, "Coarse Transformation", "VerticalFlip", pedited, coarse.vflip, pedited->coarse.vflip);
4358 }
4359
4360 if (keyFile.has_group("Rotation")) {
4361 assignFromKeyfile(keyFile, "Rotation", "Degree", pedited, rotate.degree, pedited->rotate.degree);
4362 }
4363
4364 if (keyFile.has_group("Common Properties for Transformations")) {
4365 if (keyFile.has_key("Common Properties for Transformations", "Method")) {
4366 assignFromKeyfile(keyFile, "Common Properties for Transformations", "Method", pedited, commonTrans.method, pedited->commonTrans.method);
4367 } else {
4368 commonTrans.method = "lin";
4369 }
4370 assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", pedited, commonTrans.autofill, pedited->commonTrans.autofill);
4371 }
4372
4373 if (keyFile.has_group("Distortion")) {
4374 assignFromKeyfile(keyFile, "Distortion", "Amount", pedited, distortion.amount, pedited->distortion.amount);
4375 }
4376
4377 if (keyFile.has_group("LensProfile")) {
4378 if (keyFile.has_key("LensProfile", "LcMode")) {
4379 lensProf.lcMode = lensProf.getMethodNumber(keyFile.get_string("LensProfile", "LcMode"));
4380
4381 if (pedited) {
4382 pedited->lensProf.lcMode = true;
4383 }
4384 }
4385
4386 if (keyFile.has_key("LensProfile", "LCPFile")) {
4387 lensProf.lcpFile = expandRelativePath(fname, "", keyFile.get_string("LensProfile", "LCPFile"));
4388
4389 if (pedited) {
4390 pedited->lensProf.lcpFile = true;
4391 }
4392
4393 if (ppVersion < 327 && !lensProf.lcpFile.empty()) {
4394 lensProf.lcMode = LensProfParams::LcMode::LCP;
4395 }
4396 }
4397
4398 assignFromKeyfile(keyFile, "LensProfile", "UseDistortion", pedited, lensProf.useDist, pedited->lensProf.useDist);
4399 assignFromKeyfile(keyFile, "LensProfile", "UseVignette", pedited, lensProf.useVign, pedited->lensProf.useVign);
4400 assignFromKeyfile(keyFile, "LensProfile", "UseCA", pedited, lensProf.useCA, pedited->lensProf.useCA);
4401
4402 if (keyFile.has_key("LensProfile", "LFCameraMake")) {
4403 lensProf.lfCameraMake = keyFile.get_string("LensProfile", "LFCameraMake");
4404
4405 if (pedited) {
4406 pedited->lensProf.lfCameraMake = true;
4407 }
4408 }
4409
4410 if (keyFile.has_key("LensProfile", "LFCameraModel")) {
4411 lensProf.lfCameraModel = keyFile.get_string("LensProfile", "LFCameraModel");
4412
4413 if (pedited) {
4414 pedited->lensProf.lfCameraModel = true;
4415 }
4416 }
4417
4418 if (keyFile.has_key("LensProfile", "LFLens")) {
4419 lensProf.lfLens = keyFile.get_string("LensProfile", "LFLens");
4420
4421 if (pedited) {
4422 pedited->lensProf.lfLens = true;
4423 }
4424 }
4425 }
4426
4427 if (keyFile.has_group("Perspective")) {
4428 assignFromKeyfile(keyFile, "Perspective", "Horizontal", pedited, perspective.horizontal, pedited->perspective.horizontal);
4429 assignFromKeyfile(keyFile, "Perspective", "Vertical", pedited, perspective.vertical, pedited->perspective.vertical);
4430 }
4431
4432 if (keyFile.has_group("Gradient")) {
4433 assignFromKeyfile(keyFile, "Gradient", "Enabled", pedited, gradient.enabled, pedited->gradient.enabled);
4434 assignFromKeyfile(keyFile, "Gradient", "Degree", pedited, gradient.degree, pedited->gradient.degree);
4435 assignFromKeyfile(keyFile, "Gradient", "Feather", pedited, gradient.feather, pedited->gradient.feather);
4436 assignFromKeyfile(keyFile, "Gradient", "Strength", pedited, gradient.strength, pedited->gradient.strength);
4437 assignFromKeyfile(keyFile, "Gradient", "CenterX", pedited, gradient.centerX, pedited->gradient.centerX);
4438 assignFromKeyfile(keyFile, "Gradient", "CenterY", pedited, gradient.centerY, pedited->gradient.centerY);
4439 }
4440
4441 if (keyFile.has_group("PCVignette")) {
4442 assignFromKeyfile(keyFile, "PCVignette", "Enabled", pedited, pcvignette.enabled, pedited->pcvignette.enabled);
4443 assignFromKeyfile(keyFile, "PCVignette", "Strength", pedited, pcvignette.strength, pedited->pcvignette.strength);
4444 assignFromKeyfile(keyFile, "PCVignette", "Feather", pedited, pcvignette.feather, pedited->pcvignette.feather);
4445 assignFromKeyfile(keyFile, "PCVignette", "Roundness", pedited, pcvignette.roundness, pedited->pcvignette.roundness);
4446 }
4447
4448 if (keyFile.has_group("CACorrection")) {
4449 assignFromKeyfile(keyFile, "CACorrection", "Red", pedited, cacorrection.red, pedited->cacorrection.red);
4450 assignFromKeyfile(keyFile, "CACorrection", "Blue", pedited, cacorrection.blue, pedited->cacorrection.blue);
4451 }
4452
4453 if (keyFile.has_group("Vignetting Correction")) {
4454 assignFromKeyfile(keyFile, "Vignetting Correction", "Amount", pedited, vignetting.amount, pedited->vignetting.amount);
4455 assignFromKeyfile(keyFile, "Vignetting Correction", "Radius", pedited, vignetting.radius, pedited->vignetting.radius);
4456 assignFromKeyfile(keyFile, "Vignetting Correction", "Strength", pedited, vignetting.strength, pedited->vignetting.strength);
4457 assignFromKeyfile(keyFile, "Vignetting Correction", "CenterX", pedited, vignetting.centerX, pedited->vignetting.centerX);
4458 assignFromKeyfile(keyFile, "Vignetting Correction", "CenterY", pedited, vignetting.centerY, pedited->vignetting.centerY);
4459 }
4460
4461 if (keyFile.has_group("Resize")) {
4462 assignFromKeyfile(keyFile, "Resize", "Enabled", pedited, resize.enabled, pedited->resize.enabled);
4463 assignFromKeyfile(keyFile, "Resize", "Scale", pedited, resize.scale, pedited->resize.scale);
4464 assignFromKeyfile(keyFile, "Resize", "AppliesTo", pedited, resize.appliesTo, pedited->resize.appliesTo);
4465 assignFromKeyfile(keyFile, "Resize", "Method", pedited, resize.method, pedited->resize.method);
4466 assignFromKeyfile(keyFile, "Resize", "DataSpecified", pedited, resize.dataspec, pedited->resize.dataspec);
4467 assignFromKeyfile(keyFile, "Resize", "Width", pedited, resize.width, pedited->resize.width);
4468 assignFromKeyfile(keyFile, "Resize", "Height", pedited, resize.height, pedited->resize.height);
4469 if (ppVersion >= 339) {
4470 assignFromKeyfile(keyFile, "Resize", "AllowUpscaling", pedited, resize.allowUpscaling, pedited->resize.allowUpscaling);
4471 } else {
4472 resize.allowUpscaling = false;
4473 if (pedited) {
4474 pedited->resize.allowUpscaling = true;
4475 }
4476 }
4477 }
4478
4479 if (keyFile.has_group("PostDemosaicSharpening")) {
4480 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pedited, pdsharpening.enabled, pedited->pdsharpening.enabled);
4481 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast);
4482 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast);
4483 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius);
4484 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius);
4485 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset);
4486 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterCheck", pedited, pdsharpening.deconvitercheck, pedited->pdsharpening.deconvitercheck);
4487 assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter);
4488 }
4489
4490 if (keyFile.has_group("PostResizeSharpening")) {
4491 assignFromKeyfile(keyFile, "PostResizeSharpening", "Enabled", pedited, prsharpening.enabled, pedited->prsharpening.enabled);
4492 assignFromKeyfile(keyFile, "PostResizeSharpening", "Contrast", pedited, prsharpening.contrast, pedited->prsharpening.contrast);
4493 assignFromKeyfile(keyFile, "PostResizeSharpening", "Radius", pedited, prsharpening.radius, pedited->prsharpening.radius);
4494 assignFromKeyfile(keyFile, "PostResizeSharpening", "Amount", pedited, prsharpening.amount, pedited->prsharpening.amount);
4495
4496 if (keyFile.has_key("PostResizeSharpening", "Threshold")) {
4497 if (ppVersion < 302) {
4498 int thresh = min(keyFile.get_integer("PostResizeSharpening", "Threshold"), 2000);
4499 prsharpening.threshold.setValues(thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization
4500 } else {
4501 const std::vector<int> thresh = keyFile.get_integer_list("PostResizeSharpening", "Threshold");
4502
4503 if (thresh.size() >= 4) {
4504 prsharpening.threshold.setValues(thresh[0], thresh[1], min(thresh[2], 2000), min(thresh[3], 2000));
4505 }
4506 }
4507
4508 if (pedited) {
4509 pedited->prsharpening.threshold = true;
4510 }
4511 }
4512
4513 assignFromKeyfile(keyFile, "PostResizeSharpening", "OnlyEdges", pedited, prsharpening.edgesonly, pedited->prsharpening.edgesonly);
4514 assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgedetectionRadius", pedited, prsharpening.edges_radius, pedited->prsharpening.edges_radius);
4515 assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgeTolerance", pedited, prsharpening.edges_tolerance, pedited->prsharpening.edges_tolerance);
4516 assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolEnabled", pedited, prsharpening.halocontrol, pedited->prsharpening.halocontrol);
4517 assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolAmount", pedited, prsharpening.halocontrol_amount, pedited->prsharpening.halocontrol_amount);
4518 assignFromKeyfile(keyFile, "PostResizeSharpening", "Method", pedited, prsharpening.method, pedited->prsharpening.method);
4519 assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvRadius", pedited, prsharpening.deconvradius, pedited->prsharpening.deconvradius);
4520 assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvAmount", pedited, prsharpening.deconvamount, pedited->prsharpening.deconvamount);
4521 assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvDamping", pedited, prsharpening.deconvdamping, pedited->prsharpening.deconvdamping);
4522 assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvIterations", pedited, prsharpening.deconviter, pedited->prsharpening.deconviter);
4523 }
4524
4525 if (keyFile.has_group("Color Management")) {
4526 if (keyFile.has_key("Color Management", "InputProfile")) {
4527 icm.inputProfile = expandRelativePath(fname, "file:", keyFile.get_string("Color Management", "InputProfile"));
4528
4529 if (pedited) {
4530 pedited->icm.inputProfile = true;
4531 }
4532 }
4533
4534 assignFromKeyfile(keyFile, "Color Management", "ToneCurve", pedited, icm.toneCurve, pedited->icm.toneCurve);
4535 assignFromKeyfile(keyFile, "Color Management", "ApplyLookTable", pedited, icm.applyLookTable, pedited->icm.applyLookTable);
4536 assignFromKeyfile(keyFile, "Color Management", "ApplyBaselineExposureOffset", pedited, icm.applyBaselineExposureOffset, pedited->icm.applyBaselineExposureOffset);
4537 assignFromKeyfile(keyFile, "Color Management", "ApplyHueSatMap", pedited, icm.applyHueSatMap, pedited->icm.applyHueSatMap);
4538 assignFromKeyfile(keyFile, "Color Management", "DCPIlluminant", pedited, icm.dcpIlluminant, pedited->icm.dcpIlluminant);
4539 assignFromKeyfile(keyFile, "Color Management", "WorkingProfile", pedited, icm.workingProfile, pedited->icm.workingProfile);
4540 assignFromKeyfile(keyFile, "Color Management", "WorkingTRC", pedited, icm.workingTRC, pedited->icm.workingTRC);
4541 assignFromKeyfile(keyFile, "Color Management", "WorkingTRCGamma", pedited, icm.workingTRCGamma, pedited->icm.workingTRCGamma);
4542 assignFromKeyfile(keyFile, "Color Management", "WorkingTRCSlope", pedited, icm.workingTRCSlope, pedited->icm.workingTRCSlope);
4543
4544 assignFromKeyfile(keyFile, "Color Management", "OutputProfile", pedited, icm.outputProfile, pedited->icm.outputProfile);
4545 if (ppVersion < 341) {
4546 if (icm.outputProfile == "RT_Medium_gsRGB") {
4547 icm.outputProfile = "RTv4_Medium";
4548 } else if (icm.outputProfile == "RT_Large_gBT709" || icm.outputProfile == "RT_Large_g10" || icm.outputProfile == "RT_Large_gsRGB") {
4549 icm.outputProfile = "RTv4_Large";
4550 } else if (icm.outputProfile == "WideGamutRGB") {
4551 icm.outputProfile = "RTv4_Wide";
4552 } else if (icm.outputProfile == "RT_sRGB_gBT709" || icm.outputProfile == "RT_sRGB_g10" || icm.outputProfile == "RT_sRGB") {
4553 icm.outputProfile = "RTv4_sRGB";
4554 } else if (icm.outputProfile == "BetaRGB") { // Have we ever provided this profile ? Should we convert this filename ?
4555 icm.outputProfile = "RTv4_Beta";
4556 } else if (icm.outputProfile == "BestRGB") { // Have we ever provided this profile ? Should we convert this filename ?
4557 icm.outputProfile = "RTv4_Best";
4558 } else if (icm.outputProfile == "Rec2020") {
4559 icm.outputProfile = "RTv4_Rec2020";
4560 } else if (icm.outputProfile == "Bruce") { // Have we ever provided this profile ? Should we convert this filename ?
4561 icm.outputProfile = "RTv4_Bruce";
4562 } else if (icm.outputProfile == "ACES") {
4563 icm.outputProfile = "RTv4_ACES-AP0";
4564 }
4565 }
4566 if (keyFile.has_key("Color Management", "OutputProfileIntent")) {
4567 Glib::ustring intent = keyFile.get_string("Color Management", "OutputProfileIntent");
4568
4569 if (intent == "Perceptual") {
4570 icm.outputIntent = RI_PERCEPTUAL;
4571 } else if (intent == "Relative") {
4572 icm.outputIntent = RI_RELATIVE;
4573 } else if (intent == "Saturation") {
4574 icm.outputIntent = RI_SATURATION;
4575 } else if (intent == "Absolute") {
4576 icm.outputIntent = RI_ABSOLUTE;
4577 }
4578
4579 if (pedited) {
4580 pedited->icm.outputIntent = true;
4581 }
4582 }
4583 assignFromKeyfile(keyFile, "Color Management", "OutputBPC", pedited, icm.outputBPC, pedited->icm.outputBPC);
4584 }
4585
4586 if (keyFile.has_group("Wavelet")) {
4587 assignFromKeyfile(keyFile, "Wavelet", "Enabled", pedited, wavelet.enabled, pedited->wavelet.enabled);
4588 assignFromKeyfile(keyFile, "Wavelet", "Strength", pedited, wavelet.strength, pedited->wavelet.strength);
4589 assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance);
4590 assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter);
4591 assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median);
4592 assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev);
4593 assignFromKeyfile(keyFile, "Wavelet", "Linkedg", pedited, wavelet.linkedg, pedited->wavelet.linkedg);
4594 assignFromKeyfile(keyFile, "Wavelet", "CBenab", pedited, wavelet.cbenab, pedited->wavelet.cbenab);
4595 assignFromKeyfile(keyFile, "Wavelet", "CBgreenhigh", pedited, wavelet.greenhigh, pedited->wavelet.greenhigh);
4596 assignFromKeyfile(keyFile, "Wavelet", "CBgreenmed", pedited, wavelet.greenmed, pedited->wavelet.greenmed);
4597 assignFromKeyfile(keyFile, "Wavelet", "CBgreenlow", pedited, wavelet.greenlow, pedited->wavelet.greenlow);
4598 assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh);
4599 assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed);
4600 assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow);
4601 assignFromKeyfile(keyFile, "Wavelet", "Lipst", pedited, wavelet.lipst, pedited->wavelet.lipst);
4602 assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", pedited, wavelet.avoid, pedited->wavelet.avoid);
4603 assignFromKeyfile(keyFile, "Wavelet", "TMr", pedited, wavelet.tmr, pedited->wavelet.tmr);
4604
4605 if (ppVersion < 331) { // wavelet.Lmethod was a string before version 331
4606 Glib::ustring temp;
4607 assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, temp, pedited->wavelet.Lmethod);
4608
4609 if (!temp.empty()) {
4610 wavelet.Lmethod = std::stoi(temp);
4611 }
4612 } else {
4613 assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, wavelet.Lmethod, pedited->wavelet.Lmethod);
4614 }
4615
4616 assignFromKeyfile(keyFile, "Wavelet", "ChoiceLevMethod", pedited, wavelet.CLmethod, pedited->wavelet.CLmethod);
4617 assignFromKeyfile(keyFile, "Wavelet", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod);
4618 assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", pedited, wavelet.Tilesmethod, pedited->wavelet.Tilesmethod);
4619 assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod);
4620 assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod);
4621 assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf);
4622 assignFromKeyfile(keyFile, "Wavelet", "CHSLromaMethod", pedited, wavelet.CHSLmethod, pedited->wavelet.CHSLmethod);
4623 assignFromKeyfile(keyFile, "Wavelet", "EDMethod", pedited, wavelet.EDmethod, pedited->wavelet.EDmethod);
4624 assignFromKeyfile(keyFile, "Wavelet", "NPMethod", pedited, wavelet.NPmethod, pedited->wavelet.NPmethod);
4625 assignFromKeyfile(keyFile, "Wavelet", "BAMethod", pedited, wavelet.BAmethod, pedited->wavelet.BAmethod);
4626 assignFromKeyfile(keyFile, "Wavelet", "TMMethod", pedited, wavelet.TMmethod, pedited->wavelet.TMmethod);
4627 assignFromKeyfile(keyFile, "Wavelet", "HSMethod", pedited, wavelet.HSmethod, pedited->wavelet.HSmethod);
4628 assignFromKeyfile(keyFile, "Wavelet", "DirMethod", pedited, wavelet.Dirmethod, pedited->wavelet.Dirmethod);
4629 assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", pedited, wavelet.rescon, pedited->wavelet.rescon);
4630 assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", pedited, wavelet.resconH, pedited->wavelet.resconH);
4631 assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", pedited, wavelet.reschro, pedited->wavelet.reschro);
4632 assignFromKeyfile(keyFile, "Wavelet", "ResidualTM", pedited, wavelet.tmrs, pedited->wavelet.tmrs);
4633 assignFromKeyfile(keyFile, "Wavelet", "Residualgamma", pedited, wavelet.gamma, pedited->wavelet.gamma);
4634 assignFromKeyfile(keyFile, "Wavelet", "ContExtra", pedited, wavelet.sup, pedited->wavelet.sup);
4635 assignFromKeyfile(keyFile, "Wavelet", "HueRangeResidual", pedited, wavelet.sky, pedited->wavelet.sky);
4636 assignFromKeyfile(keyFile, "Wavelet", "MaxLev", pedited, wavelet.thres, pedited->wavelet.thres);
4637 assignFromKeyfile(keyFile, "Wavelet", "ThresholdHighlight", pedited, wavelet.threshold, pedited->wavelet.threshold);
4638 assignFromKeyfile(keyFile, "Wavelet", "ThresholdShadow", pedited, wavelet.threshold2, pedited->wavelet.threshold2);
4639 assignFromKeyfile(keyFile, "Wavelet", "Edgedetect", pedited, wavelet.edgedetect, pedited->wavelet.edgedetect);
4640 assignFromKeyfile(keyFile, "Wavelet", "Edgedetectthr", pedited, wavelet.edgedetectthr, pedited->wavelet.edgedetectthr);
4641 assignFromKeyfile(keyFile, "Wavelet", "EdgedetectthrHi", pedited, wavelet.edgedetectthr2, pedited->wavelet.edgedetectthr2);
4642 assignFromKeyfile(keyFile, "Wavelet", "Edgesensi", pedited, wavelet.edgesensi, pedited->wavelet.edgesensi);
4643 assignFromKeyfile(keyFile, "Wavelet", "Edgeampli", pedited, wavelet.edgeampli, pedited->wavelet.edgeampli);
4644 assignFromKeyfile(keyFile, "Wavelet", "ThresholdChroma", pedited, wavelet.chroma, pedited->wavelet.chroma);
4645 assignFromKeyfile(keyFile, "Wavelet", "ChromaLink", pedited, wavelet.chro, pedited->wavelet.chro);
4646 assignFromKeyfile(keyFile, "Wavelet", "Contrast", pedited, wavelet.contrast, pedited->wavelet.contrast);
4647 assignFromKeyfile(keyFile, "Wavelet", "Edgrad", pedited, wavelet.edgrad, pedited->wavelet.edgrad);
4648 assignFromKeyfile(keyFile, "Wavelet", "Edgval", pedited, wavelet.edgval, pedited->wavelet.edgval);
4649 assignFromKeyfile(keyFile, "Wavelet", "ThrEdg", pedited, wavelet.edgthresh, pedited->wavelet.edgthresh);
4650 assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidShadow", pedited, wavelet.thr, pedited->wavelet.thr);
4651 assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidHighLight", pedited, wavelet.thrH, pedited->wavelet.thrH);
4652 assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve);
4653 assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG);
4654 assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY);
4655 assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW);
4656 assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", pedited, wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL);
4657 assignFromKeyfile(keyFile, "Wavelet", "HHcurve", pedited, wavelet.hhcurve, pedited->wavelet.hhcurve);
4658 assignFromKeyfile(keyFile, "Wavelet", "CHcurve", pedited, wavelet.Chcurve, pedited->wavelet.Chcurve);
4659 assignFromKeyfile(keyFile, "Wavelet", "WavclCurve", pedited, wavelet.wavclCurve, pedited->wavelet.wavclCurve);
4660
4661 if (keyFile.has_key("Wavelet", "Hueskin")) {
4662 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "Hueskin");
4663
4664 if (thresh.size() >= 4) {
4665 wavelet.hueskin.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4666 }
4667
4668 if (pedited) {
4669 pedited->wavelet.hueskin = true;
4670 }
4671 }
4672
4673 if (keyFile.has_key("Wavelet", "HueRange")) {
4674 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "HueRange");
4675
4676 if (thresh.size() >= 4) {
4677 wavelet.hueskin2.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4678 }
4679
4680 if (pedited) {
4681 pedited->wavelet.hueskin2 = true;
4682 }
4683 }
4684
4685 if (keyFile.has_key("Wavelet", "HLRange")) {
4686 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "HLRange");
4687
4688 if (thresh.size() >= 4) {
4689 wavelet.hllev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4690 }
4691
4692 if (pedited) {
4693 pedited->wavelet.hllev = true;
4694 }
4695 }
4696
4697 if (keyFile.has_key("Wavelet", "SHRange")) {
4698 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "SHRange");
4699
4700 if (thresh.size() >= 4) {
4701 wavelet.bllev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4702 }
4703
4704 if (pedited) {
4705 pedited->wavelet.bllev = true;
4706 }
4707 }
4708
4709 if (keyFile.has_key("Wavelet", "Edgcont")) {
4710 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "Edgcont");
4711
4712 if (thresh.size() >= 4) {
4713 wavelet.edgcont.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4714 }
4715
4716 if (pedited) {
4717 pedited->wavelet.edgcont = true;
4718 }
4719 }
4720
4721 if (keyFile.has_key("Wavelet", "Level0noise")) {
4722 const std::vector<double> thresh = keyFile.get_double_list("Wavelet", "Level0noise");
4723
4724 if (thresh.size() >= 2) {
4725 wavelet.level0noise.setValues(thresh[0], thresh[1]);
4726 }
4727
4728 if (pedited) {
4729 pedited->wavelet.level0noise = true;
4730 }
4731 }
4732
4733 if (keyFile.has_key("Wavelet", "Level1noise")) {
4734 const std::vector<double> thresh = keyFile.get_double_list("Wavelet", "Level1noise");
4735
4736 if (thresh.size() >= 2) {
4737 wavelet.level1noise.setValues(thresh[0], thresh[1]);
4738 }
4739
4740 if (pedited) {
4741 pedited->wavelet.level1noise = true;
4742 }
4743 }
4744
4745 if (keyFile.has_key("Wavelet", "Level2noise")) {
4746 const std::vector<double> thresh = keyFile.get_double_list("Wavelet", "Level2noise");
4747
4748 if (thresh.size() >= 2) {
4749 wavelet.level2noise.setValues(thresh[0], thresh[1]);
4750 }
4751
4752 if (pedited) {
4753 pedited->wavelet.level2noise = true;
4754 }
4755 }
4756
4757 if (keyFile.has_key("Wavelet", "Level3noise")) {
4758 const std::vector<double> thresh = keyFile.get_double_list("Wavelet", "Level3noise");
4759
4760 if (thresh.size() >= 2) {
4761 wavelet.level3noise.setValues(thresh[0], thresh[1]);
4762 }
4763
4764 if (pedited) {
4765 pedited->wavelet.level3noise = true;
4766 }
4767 }
4768
4769 if (keyFile.has_key("Wavelet", "Pastlev")) {
4770 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "Pastlev");
4771
4772 if (thresh.size() >= 4) {
4773 wavelet.pastlev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4774 }
4775
4776 if (pedited) {
4777 pedited->wavelet.pastlev = true;
4778 }
4779 }
4780
4781 if (keyFile.has_key("Wavelet", "Satlev")) {
4782 const std::vector<int> thresh = keyFile.get_integer_list("Wavelet", "Satlev");
4783
4784 if (thresh.size() >= 4) {
4785 wavelet.satlev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4786 }
4787
4788 if (pedited) {
4789 pedited->wavelet.satlev = true;
4790 }
4791 }
4792
4793 assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", pedited, wavelet.skinprotect, pedited->wavelet.skinprotect);
4794 assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", pedited, wavelet.expcontrast, pedited->wavelet.expcontrast);
4795 assignFromKeyfile(keyFile, "Wavelet", "Expchroma", pedited, wavelet.expchroma, pedited->wavelet.expchroma);
4796
4797 for (int i = 0; i < 9; ++i) {
4798 std::stringstream ss;
4799 ss << "Contrast" << (i + 1);
4800
4801 if (keyFile.has_key("Wavelet", ss.str())) {
4802 wavelet.c[i] = keyFile.get_integer("Wavelet", ss.str());
4803
4804 if (pedited) {
4805 pedited->wavelet.c[i] = true;
4806 }
4807 }
4808 }
4809
4810 for (int i = 0; i < 9; ++i) {
4811 std::stringstream ss;
4812 ss << "Chroma" << (i + 1);
4813
4814 if (keyFile.has_key("Wavelet", ss.str())) {
4815 wavelet.ch[i] = keyFile.get_integer("Wavelet", ss.str());
4816
4817 if (pedited) {
4818 pedited->wavelet.ch[i] = true;
4819 }
4820 }
4821 }
4822
4823 assignFromKeyfile(keyFile, "Wavelet", "Expedge", pedited, wavelet.expedge, pedited->wavelet.expedge);
4824 assignFromKeyfile(keyFile, "Wavelet", "Expresid", pedited, wavelet.expresid, pedited->wavelet.expresid);
4825 assignFromKeyfile(keyFile, "Wavelet", "Expfinal", pedited, wavelet.expfinal, pedited->wavelet.expfinal);
4826 assignFromKeyfile(keyFile, "Wavelet", "Exptoning", pedited, wavelet.exptoning, pedited->wavelet.exptoning);
4827 assignFromKeyfile(keyFile, "Wavelet", "Expnoise", pedited, wavelet.expnoise, pedited->wavelet.expnoise);
4828 }
4829
4830 if (keyFile.has_group("Directional Pyramid Equalizer")) {
4831 assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Enabled", pedited, dirpyrequalizer.enabled, pedited->dirpyrequalizer.enabled);
4832 assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Gamutlab", pedited, dirpyrequalizer.gamutlab, pedited->dirpyrequalizer.gamutlab);
4833 assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "cbdlMethod", pedited, dirpyrequalizer.cbdlMethod, pedited->dirpyrequalizer.cbdlMethod);
4834
4835 if (keyFile.has_key("Directional Pyramid Equalizer", "Hueskin")) {
4836 const std::vector<int> thresh = keyFile.get_integer_list("Directional Pyramid Equalizer", "Hueskin");
4837
4838 if (thresh.size() >= 4) {
4839 dirpyrequalizer.hueskin.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300));
4840 }
4841
4842 if (pedited) {
4843 pedited->dirpyrequalizer.hueskin = true;
4844 }
4845 }
4846
4847 if (ppVersion < 316) {
4848 for (int i = 0; i < 5; i ++) {
4849 std::stringstream ss;
4850 ss << "Mult" << i;
4851
4852 if (keyFile.has_key("Directional Pyramid Equalizer", ss.str())) {
4853 if (i == 4) {
4854 dirpyrequalizer.threshold = keyFile.get_double("Directional Pyramid Equalizer", ss.str());
4855
4856 if (pedited) {
4857 pedited->dirpyrequalizer.threshold = true;
4858 }
4859 } else {
4860 dirpyrequalizer.mult[i] = keyFile.get_double("Directional Pyramid Equalizer", ss.str());
4861
4862 if (pedited) {
4863 pedited->dirpyrequalizer.mult[i] = true;
4864 }
4865 }
4866 }
4867 }
4868
4869 dirpyrequalizer.mult[4] = 1.0;
4870 } else {
4871 // 5 level wavelet + dedicated threshold parameter
4872 for (int i = 0; i < 6; i ++) {
4873 std::stringstream ss;
4874 ss << "Mult" << i;
4875
4876 if (keyFile.has_key("Directional Pyramid Equalizer", ss.str())) {
4877 dirpyrequalizer.mult[i] = keyFile.get_double("Directional Pyramid Equalizer", ss.str());
4878
4879 if (pedited) {
4880 pedited->dirpyrequalizer.mult[i] = true;
4881 }
4882 }
4883 }
4884
4885 assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Threshold", pedited, dirpyrequalizer.threshold, pedited->dirpyrequalizer.threshold);
4886 assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Skinprotect", pedited, dirpyrequalizer.skinprotect, pedited->dirpyrequalizer.skinprotect);
4887 }
4888 }
4889
4890 if (keyFile.has_group("SoftLight")) {
4891 assignFromKeyfile(keyFile, "SoftLight", "Enabled", pedited, softlight.enabled, pedited->softlight.enabled);
4892 assignFromKeyfile(keyFile, "SoftLight", "Strength", pedited, softlight.strength, pedited->softlight.strength);
4893 }
4894
4895 if (keyFile.has_group("Dehaze")) {
4896 assignFromKeyfile(keyFile, "Dehaze", "Enabled", pedited, dehaze.enabled, pedited->dehaze.enabled);
4897 assignFromKeyfile(keyFile, "Dehaze", "Strength", pedited, dehaze.strength, pedited->dehaze.strength);
4898 assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap);
4899 assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth);
4900 assignFromKeyfile(keyFile, "Dehaze", "Luminance", pedited, dehaze.luminance, pedited->dehaze.luminance);
4901 }
4902
4903 if (keyFile.has_group("Film Simulation")) {
4904 assignFromKeyfile(keyFile, "Film Simulation", "Enabled", pedited, filmSimulation.enabled, pedited->filmSimulation.enabled);
4905 assignFromKeyfile(keyFile, "Film Simulation", "ClutFilename", pedited, filmSimulation.clutFilename, pedited->filmSimulation.clutFilename);
4906
4907 if (keyFile.has_key("Film Simulation", "Strength")) {
4908 if (ppVersion < 321) {
4909 filmSimulation.strength = keyFile.get_double("Film Simulation", "Strength") * 100 + 0.1;
4910 } else {
4911 filmSimulation.strength = keyFile.get_integer("Film Simulation", "Strength");
4912 }
4913
4914 if (pedited) {
4915 pedited->filmSimulation.strength = true;
4916 }
4917 }
4918 }
4919
4920 if (keyFile.has_group("HSV Equalizer")) {
4921 if (ppVersion >= 329) {
4922 assignFromKeyfile(keyFile, "HSV Equalizer", "Enabled", pedited, hsvequalizer.enabled, pedited->hsvequalizer.enabled);
4923 } else {
4924 hsvequalizer.enabled = true;
4925
4926 if (pedited) {
4927 pedited->hsvequalizer.enabled = true;
4928 }
4929 }
4930
4931 if (ppVersion >= 300) {
4932 assignFromKeyfile(keyFile, "HSV Equalizer", "HCurve", pedited, hsvequalizer.hcurve, pedited->hsvequalizer.hcurve);
4933 assignFromKeyfile(keyFile, "HSV Equalizer", "SCurve", pedited, hsvequalizer.scurve, pedited->hsvequalizer.scurve);
4934 assignFromKeyfile(keyFile, "HSV Equalizer", "VCurve", pedited, hsvequalizer.vcurve, pedited->hsvequalizer.vcurve);
4935 }
4936 }
4937
4938 if (keyFile.has_group("RGB Curves")) {
4939 if (ppVersion >= 329) {
4940 assignFromKeyfile(keyFile, "RGB Curves", "Enabled", pedited, rgbCurves.enabled, pedited->rgbCurves.enabled);
4941 } else {
4942 rgbCurves.enabled = true;
4943
4944 if (pedited) {
4945 pedited->rgbCurves.enabled = true;
4946 }
4947 }
4948
4949 assignFromKeyfile(keyFile, "RGB Curves", "LumaMode", pedited, rgbCurves.lumamode, pedited->rgbCurves.lumamode);
4950 assignFromKeyfile(keyFile, "RGB Curves", "rCurve", pedited, rgbCurves.rcurve, pedited->rgbCurves.rcurve);
4951 assignFromKeyfile(keyFile, "RGB Curves", "gCurve", pedited, rgbCurves.gcurve, pedited->rgbCurves.gcurve);
4952 assignFromKeyfile(keyFile, "RGB Curves", "bCurve", pedited, rgbCurves.bcurve, pedited->rgbCurves.bcurve);
4953 }
4954
4955 if (keyFile.has_group("ColorToning")) {
4956 assignFromKeyfile(keyFile, "ColorToning", "Enabled", pedited, colorToning.enabled, pedited->colorToning.enabled);
4957 assignFromKeyfile(keyFile, "ColorToning", "Method", pedited, colorToning.method, pedited->colorToning.method);
4958 assignFromKeyfile(keyFile, "ColorToning", "Lumamode", pedited, colorToning.lumamode, pedited->colorToning.lumamode);
4959 assignFromKeyfile(keyFile, "ColorToning", "Twocolor", pedited, colorToning.twocolor, pedited->colorToning.twocolor);
4960 assignFromKeyfile(keyFile, "ColorToning", "OpacityCurve", pedited, colorToning.opacityCurve, pedited->colorToning.opacityCurve);
4961 assignFromKeyfile(keyFile, "ColorToning", "ColorCurve", pedited, colorToning.colorCurve, pedited->colorToning.colorCurve);
4962 assignFromKeyfile(keyFile, "ColorToning", "Autosat", pedited, colorToning.autosat, pedited->colorToning.autosat);
4963 assignFromKeyfile(keyFile, "ColorToning", "SatProtectionThreshold", pedited, colorToning.satProtectionThreshold, pedited->colorToning.satprotectionthreshold);
4964 assignFromKeyfile(keyFile, "ColorToning", "SaturatedOpacity", pedited, colorToning.saturatedOpacity, pedited->colorToning.saturatedopacity);
4965 assignFromKeyfile(keyFile, "ColorToning", "Strength", pedited, colorToning.strength, pedited->colorToning.strength);
4966
4967 if (keyFile.has_key("ColorToning", "HighlightsColorSaturation")) {
4968 const std::vector<int> thresh = keyFile.get_integer_list("ColorToning", "HighlightsColorSaturation");
4969
4970 if (thresh.size() >= 2) {
4971 colorToning.hlColSat.setValues(thresh[0], thresh[1]);
4972 }
4973
4974 if (pedited) {
4975 pedited->colorToning.hlColSat = true;
4976 }
4977 }
4978
4979 if (keyFile.has_key("ColorToning", "ShadowsColorSaturation")) {
4980 const std::vector<int> thresh = keyFile.get_integer_list("ColorToning", "ShadowsColorSaturation");
4981
4982 if (thresh.size() >= 2) {
4983 colorToning.shadowsColSat.setValues(thresh[0], thresh[1]);
4984 }
4985
4986 if (pedited) {
4987 pedited->colorToning.shadowsColSat = true;
4988 }
4989 }
4990
4991 assignFromKeyfile(keyFile, "ColorToning", "ClCurve", pedited, colorToning.clcurve, pedited->colorToning.clcurve);
4992 assignFromKeyfile(keyFile, "ColorToning", "Cl2Curve", pedited, colorToning.cl2curve, pedited->colorToning.cl2curve);
4993 assignFromKeyfile(keyFile, "ColorToning", "Redlow", pedited, colorToning.redlow, pedited->colorToning.redlow);
4994 assignFromKeyfile(keyFile, "ColorToning", "Greenlow", pedited, colorToning.greenlow, pedited->colorToning.greenlow);
4995 assignFromKeyfile(keyFile, "ColorToning", "Bluelow", pedited, colorToning.bluelow, pedited->colorToning.bluelow);
4996 assignFromKeyfile(keyFile, "ColorToning", "Satlow", pedited, colorToning.satlow, pedited->colorToning.satlow);
4997 assignFromKeyfile(keyFile, "ColorToning", "Balance", pedited, colorToning.balance, pedited->colorToning.balance);
4998 assignFromKeyfile(keyFile, "ColorToning", "Sathigh", pedited, colorToning.sathigh, pedited->colorToning.sathigh);
4999 assignFromKeyfile(keyFile, "ColorToning", "Redmed", pedited, colorToning.redmed, pedited->colorToning.redmed);
5000 assignFromKeyfile(keyFile, "ColorToning", "Greenmed", pedited, colorToning.greenmed, pedited->colorToning.greenmed);
5001 assignFromKeyfile(keyFile, "ColorToning", "Bluemed", pedited, colorToning.bluemed, pedited->colorToning.bluemed);
5002 assignFromKeyfile(keyFile, "ColorToning", "Redhigh", pedited, colorToning.redhigh, pedited->colorToning.redhigh);
5003 assignFromKeyfile(keyFile, "ColorToning", "Greenhigh", pedited, colorToning.greenhigh, pedited->colorToning.greenhigh);
5004 assignFromKeyfile(keyFile, "ColorToning", "Bluehigh", pedited, colorToning.bluehigh, pedited->colorToning.bluehigh);
5005
5006 assignFromKeyfile(keyFile, "ColorToning", "LabGridALow", pedited, colorToning.labgridALow, pedited->colorToning.labgridALow);
5007 assignFromKeyfile(keyFile, "ColorToning", "LabGridBLow", pedited, colorToning.labgridBLow, pedited->colorToning.labgridBLow);
5008 assignFromKeyfile(keyFile, "ColorToning", "LabGridAHigh", pedited, colorToning.labgridAHigh, pedited->colorToning.labgridAHigh);
5009 assignFromKeyfile(keyFile, "ColorToning", "LabGridBHigh", pedited, colorToning.labgridBHigh, pedited->colorToning.labgridBHigh);
5010 if (ppVersion < 337) {
5011 const double scale = ColorToningParams::LABGRID_CORR_SCALE;
5012 colorToning.labgridALow *= scale;
5013 colorToning.labgridAHigh *= scale;
5014 colorToning.labgridBLow *= scale;
5015 colorToning.labgridBHigh *= scale;
5016 }
5017 std::vector<ColorToningParams::LabCorrectionRegion> lg;
5018 bool found = false;
5019 bool done = false;
5020 for (int i = 1; !done; ++i) {
5021 ColorToningParams::LabCorrectionRegion cur;
5022 done = true;
5023 std::string n = std::to_string(i);
5024 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionA_") + n, pedited, cur.a, pedited->colorToning.labregions)) {
5025 found = true;
5026 done = false;
5027 }
5028 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionB_") + n, pedited, cur.b, pedited->colorToning.labregions)) {
5029 found = true;
5030 done = false;
5031 }
5032 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSaturation_") + n, pedited, cur.saturation, pedited->colorToning.labregions)) {
5033 found = true;
5034 done = false;
5035 }
5036 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSlope_") + n, pedited, cur.slope, pedited->colorToning.labregions)) {
5037 found = true;
5038 done = false;
5039 }
5040 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionOffset_") + n, pedited, cur.offset, pedited->colorToning.labregions)) {
5041 found = true;
5042 done = false;
5043 }
5044 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionPower_") + n, pedited, cur.power, pedited->colorToning.labregions)) {
5045 found = true;
5046 done = false;
5047 }
5048 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionHueMask_") + n, pedited, cur.hueMask, pedited->colorToning.labregions)) {
5049 found = true;
5050 done = false;
5051 }
5052 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChromaticityMask_") + n, pedited, cur.chromaticityMask, pedited->colorToning.labregions)) {
5053 found = true;
5054 done = false;
5055 }
5056 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionLightnessMask_") + n, pedited, cur.lightnessMask, pedited->colorToning.labregions)) {
5057 found = true;
5058 done = false;
5059 }
5060 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, pedited, cur.maskBlur, pedited->colorToning.labregions)) {
5061 found = true;
5062 done = false;
5063 }
5064 if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChannel_") + n, pedited, cur.channel, pedited->colorToning.labregions)) {
5065 found = true;
5066 done = false;
5067 }
5068 if (!done) {
5069 lg.emplace_back(cur);
5070 }
5071 }
5072 if (found) {
5073 colorToning.labregions = std::move(lg);
5074 }
5075 assignFromKeyfile(keyFile, "ColorToning", "LabRegionsShowMask", pedited, colorToning.labregionsShowMask, pedited->colorToning.labregionsShowMask);
5076 }
5077
5078 if (keyFile.has_group("RAW")) {
5079 if (keyFile.has_key("RAW", "DarkFrame")) {
5080 raw.dark_frame = expandRelativePath(fname, "", keyFile.get_string("RAW", "DarkFrame"));
5081
5082 if (pedited) {
5083 pedited->raw.darkFrame = true;
5084 }
5085 }
5086
5087 assignFromKeyfile(keyFile, "RAW", "DarkFrameAuto", pedited, raw.df_autoselect, pedited->raw.df_autoselect);
5088
5089 if (keyFile.has_key("RAW", "FlatFieldFile")) {
5090 raw.ff_file = expandRelativePath(fname, "", keyFile.get_string("RAW", "FlatFieldFile"));
5091
5092 if (pedited) {
5093 pedited->raw.ff_file = true;
5094 }
5095 }
5096
5097 assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", pedited, raw.ff_AutoSelect, pedited->raw.ff_AutoSelect);
5098 assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", pedited, raw.ff_BlurRadius, pedited->raw.ff_BlurRadius);
5099 assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", pedited, raw.ff_BlurType, pedited->raw.ff_BlurType);
5100 assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoClipControl", pedited, raw.ff_AutoClipControl, pedited->raw.ff_AutoClipControl);
5101
5102 if (ppVersion < 328) {
5103 // With ppversion < 328 this value was stored as a boolean, which is nonsense.
5104 // To avoid annoying warnings we skip reading and assume 0.
5105 raw.ff_clipControl = 0;
5106 } else {
5107 assignFromKeyfile(keyFile, "RAW", "FlatFieldClipControl", pedited, raw.ff_clipControl, pedited->raw.ff_clipControl);
5108 }
5109
5110 assignFromKeyfile(keyFile, "RAW", "CA", pedited, raw.ca_autocorrect, pedited->raw.ca_autocorrect);
5111 if (ppVersion >= 342) {
5112 assignFromKeyfile(keyFile, "RAW", "CAAutoIterations", pedited, raw.caautoiterations, pedited->raw.caautoiterations);
5113 } else {
5114 raw.caautoiterations = 1;
5115 }
5116
5117 if (ppVersion >= 343) {
5118 assignFromKeyfile(keyFile, "RAW", "CAAvoidColourshift", pedited, raw.ca_avoidcolourshift, pedited->raw.ca_avoidcolourshift);
5119 } else {
5120 raw.ca_avoidcolourshift = false;
5121 }
5122 assignFromKeyfile(keyFile, "RAW", "CARed", pedited, raw.cared, pedited->raw.cared);
5123 assignFromKeyfile(keyFile, "RAW", "CABlue", pedited, raw.cablue, pedited->raw.cablue);
5124 // For compatibility to elder pp3 versions
5125 assignFromKeyfile(keyFile, "RAW", "HotDeadPixels", pedited, raw.hotPixelFilter, pedited->raw.hotPixelFilter);
5126 raw.deadPixelFilter = raw.hotPixelFilter;
5127
5128 if (pedited) {
5129 pedited->raw.deadPixelFilter = pedited->raw.hotPixelFilter;
5130 }
5131
5132 assignFromKeyfile(keyFile, "RAW", "HotPixelFilter", pedited, raw.hotPixelFilter, pedited->raw.hotPixelFilter);
5133 assignFromKeyfile(keyFile, "RAW", "DeadPixelFilter", pedited, raw.deadPixelFilter, pedited->raw.deadPixelFilter);
5134 assignFromKeyfile(keyFile, "RAW", "HotDeadPixelThresh", pedited, raw.hotdeadpix_thresh, pedited->raw.hotdeadpix_thresh);
5135 assignFromKeyfile(keyFile, "RAW", "PreExposure", pedited, raw.expos, pedited->raw.exPos);
5136
5137 if (ppVersion < 320) {
5138 assignFromKeyfile(keyFile, "RAW", "Method", pedited, raw.bayersensor.method, pedited->raw.bayersensor.method);
5139 assignFromKeyfile(keyFile, "RAW", "CcSteps", pedited, raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps);
5140 assignFromKeyfile(keyFile, "RAW", "LineDenoise", pedited, raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise);
5141 assignFromKeyfile(keyFile, "RAW", "GreenEqThreshold", pedited, raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq);
5142 assignFromKeyfile(keyFile, "RAW", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations);
5143 assignFromKeyfile(keyFile, "RAW", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance);
5144 assignFromKeyfile(keyFile, "RAW", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations);
5145 assignFromKeyfile(keyFile, "RAW", "PreBlackzero", pedited, raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0);
5146 assignFromKeyfile(keyFile, "RAW", "PreBlackone", pedited, raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1);
5147 assignFromKeyfile(keyFile, "RAW", "PreBlacktwo", pedited, raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2);
5148 assignFromKeyfile(keyFile, "RAW", "PreBlackthree", pedited, raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3);
5149 assignFromKeyfile(keyFile, "RAW", "PreTwoGreen", pedited, raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen);
5150 }
5151 }
5152
5153 if (keyFile.has_group("RAW Bayer")) {
5154 assignFromKeyfile(keyFile, "RAW Bayer", "Method", pedited, raw.bayersensor.method, pedited->raw.bayersensor.method);
5155 assignFromKeyfile(keyFile, "RAW Bayer", "Border", pedited, raw.bayersensor.border, pedited->raw.bayersensor.border);
5156
5157 if (keyFile.has_key("RAW Bayer", "ImageNum")) {
5158 raw.bayersensor.imageNum = keyFile.get_integer("RAW Bayer", "ImageNum") - 1;
5159
5160 if (pedited) {
5161 pedited->raw.bayersensor.imageNum = true;
5162 }
5163 }
5164
5165 assignFromKeyfile(keyFile, "RAW Bayer", "CcSteps", pedited, raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps);
5166 assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack0", pedited, raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0);
5167 assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack1", pedited, raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1);
5168 assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack2", pedited, raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2);
5169 assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack3", pedited, raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3);
5170 assignFromKeyfile(keyFile, "RAW Bayer", "PreTwoGreen", pedited, raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen);
5171 assignFromKeyfile(keyFile, "RAW Bayer", "LineDenoise", pedited, raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise);
5172
5173 if (keyFile.has_key("RAW Bayer", "LineDenoiseDirection")) {
5174 raw.bayersensor.linenoiseDirection = RAWParams::BayerSensor::LineNoiseDirection(keyFile.get_integer("RAW Bayer", "LineDenoiseDirection"));
5175
5176 if (pedited) {
5177 pedited->raw.bayersensor.linenoiseDirection = true;
5178 }
5179 }
5180
5181 assignFromKeyfile(keyFile, "RAW Bayer", "GreenEqThreshold", pedited, raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq);
5182 assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations);
5183 assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance);
5184 assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations);
5185 assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicAutoContrast", pedited, raw.bayersensor.dualDemosaicAutoContrast, pedited->raw.bayersensor.dualDemosaicAutoContrast);
5186 if (ppVersion < 345) {
5187 raw.bayersensor.dualDemosaicAutoContrast = false;
5188 if (pedited) {
5189 pedited->raw.bayersensor.dualDemosaicAutoContrast = true;
5190 }
5191 }
5192 assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast);
5193
5194 if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) {
5195 raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)keyFile.get_integer("RAW Bayer", "PixelShiftMotionCorrectionMethod");
5196
5197 if (pedited) {
5198 pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = true;
5199 }
5200 }
5201
5202 assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", pedited, raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso);
5203 if (ppVersion < 332) {
5204 raw.bayersensor.pixelShiftEperIso += 1.0;
5205 }
5206 assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", pedited, raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma);
5207 assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion);
5208 assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly);
5209 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", pedited, raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill);
5210 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", pedited, raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian);
5211 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftGreen", pedited, raw.bayersensor.pixelShiftGreen, pedited->raw.bayersensor.pixelShiftGreen);
5212 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftBlur", pedited, raw.bayersensor.pixelShiftBlur, pedited->raw.bayersensor.pixelShiftBlur);
5213 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth);
5214 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright);
5215 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel);
5216 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross);
5217
5218 if (ppVersion < 336) {
5219 if (keyFile.has_key("RAW Bayer", "pixelShiftLmmse")) {
5220 bool useLmmse = keyFile.get_boolean ("RAW Bayer", "pixelShiftLmmse");
5221 if (useLmmse) {
5222 raw.bayersensor.pixelShiftDemosaicMethod = raw.bayersensor.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::LMMSE);
5223 } else {
5224 raw.bayersensor.pixelShiftDemosaicMethod = raw.bayersensor.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZE);
5225 }
5226 if (pedited) {
5227 pedited->raw.bayersensor.pixelShiftDemosaicMethod = true;
5228 }
5229 }
5230 } else {
5231 assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftDemosaicMethod", pedited, raw.bayersensor.pixelShiftDemosaicMethod, pedited->raw.bayersensor.pixelShiftDemosaicMethod);
5232 }
5233
5234 assignFromKeyfile(keyFile, "RAW Bayer", "PDAFLinesFilter", pedited, raw.bayersensor.pdafLinesFilter, pedited->raw.bayersensor.pdafLinesFilter);
5235 }
5236
5237 if (keyFile.has_group("RAW X-Trans")) {
5238 assignFromKeyfile(keyFile, "RAW X-Trans", "Method", pedited, raw.xtranssensor.method, pedited->raw.xtranssensor.method);
5239 assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicAutoContrast", pedited, raw.xtranssensor.dualDemosaicAutoContrast, pedited->raw.xtranssensor.dualDemosaicAutoContrast);
5240 if (ppVersion < 345) {
5241 raw.xtranssensor.dualDemosaicAutoContrast = false;
5242 if (pedited) {
5243 pedited->raw.xtranssensor.dualDemosaicAutoContrast = true;
5244 }
5245 }
5246 assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", pedited, raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast);
5247 assignFromKeyfile(keyFile, "RAW X-Trans", "Border", pedited, raw.xtranssensor.border, pedited->raw.xtranssensor.border);
5248 assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps);
5249 assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed);
5250 assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackGreen", pedited, raw.xtranssensor.blackgreen, pedited->raw.xtranssensor.exBlackGreen);
5251 assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", pedited, raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue);
5252 }
5253
5254 if (keyFile.has_group("Film Negative")) {
5255 assignFromKeyfile(keyFile, "Film Negative", "Enabled", pedited, filmNegative.enabled, pedited->filmNegative.enabled);
5256 assignFromKeyfile(keyFile, "Film Negative", "RedRatio", pedited, filmNegative.redRatio, pedited->filmNegative.redRatio);
5257 assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp);
5258 assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio);
5259 }
5260
5261 if (keyFile.has_group("MetaData")) {
5262 int mode = int(MetaDataParams::TUNNEL);
5263 assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode);
5264
5265 if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) {
5266 metadata.mode = static_cast<MetaDataParams::Mode>(mode);
5267 }
5268 }
5269
5270 if (keyFile.has_group("Exif")) {
5271 for (const auto& key : keyFile.get_keys("Exif")) {
5272 exif[key] = keyFile.get_string("Exif", key);
5273
5274 if (pedited) {
5275 pedited->exif = true;
5276 }
5277 }
5278 }
5279
5280 /*
5281 * Load iptc change settings
5282 *
5283 * Existing values are preserved, and the stored values
5284 * are added to the list. To reset a field, the user has to
5285 * save the profile with the field leaved empty, but still
5286 * terminated by a semi-column ";"
5287 *
5288 * Please note that the old Keywords and SupplementalCategories
5289 * tag content is fully replaced by the new one,
5290 * i.e. they don't merge
5291 */
5292 if (keyFile.has_group("IPTC")) {
5293 for (const auto& key : keyFile.get_keys("IPTC")) {
5294 // does this key already exist?
5295 const IPTCPairs::iterator element = iptc.find(key);
5296
5297 if (element != iptc.end()) {
5298 // it already exist so we cleanup the values
5299 element->second.clear();
5300 }
5301
5302 // TODO: look out if merging Keywords and SupplementalCategories from the procparams chain would be interesting
5303 for (const auto& currLoadedTagValue : keyFile.get_string_list("IPTC", key)) {
5304 iptc[key].push_back(currLoadedTagValue);
5305 }
5306
5307 if (pedited) {
5308 pedited->iptc = true;
5309 }
5310 }
5311 }
5312
5313 return 0;
5314 } catch (const Glib::Error& e) {
5315 printf("-->%s\n", e.what().c_str());
5316 setDefaults();
5317 return 1;
5318 } catch (...) {
5319 printf("-->unknown exception!\n");
5320 setDefaults();
5321 return 1;
5322 }
5323
5324 return 0;
5325 }
5326
create()5327 ProcParams* ProcParams::create()
5328 {
5329 return new ProcParams();
5330 }
5331
destroy(ProcParams * pp)5332 void ProcParams::destroy(ProcParams* pp)
5333 {
5334 delete pp;
5335 }
5336
operator ==(const ProcParams & other) const5337 bool ProcParams::operator ==(const ProcParams& other) const
5338 {
5339 return
5340 toneCurve == other.toneCurve
5341 && retinex == other.retinex
5342 && localContrast == other.localContrast
5343 && labCurve == other.labCurve
5344 && sharpenEdge == other.sharpenEdge
5345 && sharpenMicro == other.sharpenMicro
5346 && sharpening == other.sharpening
5347 && prsharpening == other.prsharpening
5348 && vibrance == other.vibrance
5349 && wb == other.wb
5350 && colorappearance == other.colorappearance
5351 && impulseDenoise == other.impulseDenoise
5352 && dirpyrDenoise == other.dirpyrDenoise
5353 && epd == other.epd
5354 && fattal == other.fattal
5355 && defringe == other.defringe
5356 && sh == other.sh
5357 && crop == other.crop
5358 && coarse == other.coarse
5359 && rotate == other.rotate
5360 && commonTrans == other.commonTrans
5361 && distortion == other.distortion
5362 && lensProf == other.lensProf
5363 && perspective == other.perspective
5364 && gradient == other.gradient
5365 && pcvignette == other.pcvignette
5366 && cacorrection == other.cacorrection
5367 && vignetting == other.vignetting
5368 && chmixer == other.chmixer
5369 && blackwhite == other.blackwhite
5370 && resize == other.resize
5371 && raw == other.raw
5372 && icm == other.icm
5373 && wavelet == other.wavelet
5374 && dirpyrequalizer == other.dirpyrequalizer
5375 && hsvequalizer == other.hsvequalizer
5376 && filmSimulation == other.filmSimulation
5377 && softlight == other.softlight
5378 && rgbCurves == other.rgbCurves
5379 && colorToning == other.colorToning
5380 && metadata == other.metadata
5381 && exif == other.exif
5382 && iptc == other.iptc
5383 && dehaze == other.dehaze
5384 && filmNegative == other.filmNegative;
5385 }
5386
operator !=(const ProcParams & other) const5387 bool ProcParams::operator !=(const ProcParams& other) const
5388 {
5389 return !(*this == other);
5390 }
5391
init()5392 void ProcParams::init()
5393 {
5394 }
5395
cleanup()5396 void ProcParams::cleanup()
5397 {
5398 }
5399
write(const Glib::ustring & fname,const Glib::ustring & content) const5400 int ProcParams::write(const Glib::ustring& fname, const Glib::ustring& content) const
5401 {
5402 int error = 0;
5403
5404 if (fname.length()) {
5405 FILE *f;
5406 f = g_fopen(fname.c_str(), "wt");
5407
5408 if (f == nullptr) {
5409 error = 1;
5410 } else {
5411 fprintf(f, "%s", content.c_str());
5412 fclose(f);
5413 }
5414 }
5415
5416 return error;
5417 }
5418
PartialProfile(bool createInstance,bool paramsEditedValue)5419 PartialProfile::PartialProfile(bool createInstance, bool paramsEditedValue)
5420 {
5421 if (createInstance) {
5422 pparams = new ProcParams();
5423 pedited = new ParamsEdited(paramsEditedValue);
5424 } else {
5425 pparams = nullptr;
5426 pedited = nullptr;
5427 }
5428 }
5429
PartialProfile(ProcParams * pp,ParamsEdited * pe,bool fullCopy)5430 PartialProfile::PartialProfile(ProcParams* pp, ParamsEdited* pe, bool fullCopy)
5431 {
5432 if (fullCopy && pp) {
5433 pparams = new ProcParams(*pp);
5434 } else {
5435 pparams = pp;
5436 }
5437
5438 if (fullCopy && pe) {
5439 pedited = new ParamsEdited(*pe);
5440 } else {
5441 pedited = pe;
5442 }
5443 }
5444
PartialProfile(const ProcParams * pp,const ParamsEdited * pe)5445 PartialProfile::PartialProfile(const ProcParams* pp, const ParamsEdited* pe)
5446 {
5447 if (pp) {
5448 pparams = new ProcParams(*pp);
5449 } else {
5450 pparams = nullptr;
5451 }
5452
5453 if (pe) {
5454 pedited = new ParamsEdited(*pe);
5455 } else {
5456 pedited = nullptr;
5457 }
5458 }
5459
deleteInstance()5460 void PartialProfile::deleteInstance()
5461 {
5462 if (pparams) {
5463 delete pparams;
5464 pparams = nullptr;
5465 }
5466
5467 if (pedited) {
5468 delete pedited;
5469 pedited = nullptr;
5470 }
5471 }
5472
clearGeneral()5473 void PartialProfile::clearGeneral()
5474 {
5475 if (pedited) {
5476 pedited->general.colorlabel = false;
5477 pedited->general.intrash = false;
5478 pedited->general.rank = false;
5479 }
5480 }
5481
load(const Glib::ustring & fName)5482 int PartialProfile::load(const Glib::ustring& fName)
5483 {
5484 if (!pparams) {
5485 pparams = new ProcParams();
5486 }
5487
5488 if (!pedited) {
5489 pedited = new ParamsEdited();
5490 }
5491
5492 if (fName == DEFPROFILE_INTERNAL) {
5493 return 0;
5494 } else if (fName == DEFPROFILE_DYNAMIC) {
5495 return -1; // should not happen here
5496 } else {
5497 return pparams->load(fName, pedited);
5498 }
5499 }
5500
5501 /*
5502 * Set the all values of the General section to false
5503 * in order to preserve them in applyTo
5504 */
set(bool v)5505 void PartialProfile::set(bool v)
5506 {
5507 if (pedited) {
5508 pedited->set(v);
5509 }
5510 }
5511
applyTo(ProcParams * destParams,bool fromLastSave) const5512 void PartialProfile::applyTo(ProcParams* destParams, bool fromLastSave) const
5513 {
5514 if (destParams && pparams && pedited) {
5515 bool fromHistMatching = fromLastSave && destParams->toneCurve.histmatching && pparams->toneCurve.histmatching;
5516 pedited->combine(*destParams, *pparams, true);
5517 if (!fromLastSave) {
5518 destParams->toneCurve.fromHistMatching = fromHistMatching;
5519 }
5520 }
5521 }
5522
AutoPartialProfile()5523 AutoPartialProfile::AutoPartialProfile() :
5524 PartialProfile(true)
5525 {
5526 }
5527
~AutoPartialProfile()5528 AutoPartialProfile::~AutoPartialProfile()
5529 {
5530 deleteInstance();
5531 }
5532
5533 }
5534
5535 }
5536