1 /* -*- C++ -*-
2  *
3  *  This file is part of RawTherapee.
4  *
5  *  Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6  *
7  *  RawTherapee is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  RawTherapee is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with RawTherapee.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 #pragma once
21 
22 #include <cmath>
23 #include <cstdio>
24 #include <map>
25 #include <type_traits>
26 #include <vector>
27 #include <array>
28 
29 #include <glibmm.h>
30 #include <lcms2.h>
31 
32 #include "coord.h"
33 #include "noncopyable.h"
34 #include "../rtgui/paramsedited.h"
35 
36 class ParamsEdited;
37 
38 namespace rtengine {
39 
40 class ProgressListener;
41 
42 enum RenderingIntent {
43     RI_PERCEPTUAL = INTENT_PERCEPTUAL,
44     RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC,
45     RI_SATURATION = INTENT_SATURATION,
46     RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC,
47     RI__COUNT
48 };
49 
50 
51 namespace procparams {
52 
53 class KeyFile {
54 public:
55     explicit KeyFile(const Glib::ustring &prefix=""):
prefix_(prefix)56         prefix_(prefix), pl_(nullptr) {}
setProgressListener(ProgressListener * pl)57     void setProgressListener(ProgressListener *pl) { pl_ = pl; }
progressListener()58     ProgressListener *progressListener() const { return pl_; }
59 
60     bool has_group(const Glib::ustring &grp) const;
61     bool has_key(const Glib::ustring &grp, const Glib::ustring &key) const;
62     Glib::ArrayHandle<Glib::ustring> get_keys(const Glib::ustring &grp) const;
63 
64     Glib::ustring get_string(const Glib::ustring &grp, const Glib::ustring &key) const;
65     int get_integer(const Glib::ustring &grp, const Glib::ustring &key) const;
66     double get_double(const Glib::ustring &grp, const Glib::ustring &key) const;
67     bool get_boolean(const Glib::ustring &grp, const Glib::ustring &key) const;
68     Glib::ArrayHandle<Glib::ustring> get_string_list(const Glib::ustring &grp, const Glib::ustring &key) const;
69     Glib::ArrayHandle<int> get_integer_list(const Glib::ustring &grp, const Glib::ustring &key) const;
70     Glib::ArrayHandle<double> get_double_list(const Glib::ustring &grp, const Glib::ustring &key) const;
71 
72     void set_string(const Glib::ustring &grp, const Glib::ustring &key, const Glib::ustring& string);
73     void set_boolean(const Glib::ustring &grp, const Glib::ustring &key, bool value);
74     void set_integer(const Glib::ustring &grp, const Glib::ustring &key, int value);
75     void set_double(const Glib::ustring &grp, const Glib::ustring &key, double value);
76     void set_string_list(const Glib::ustring &grp, const Glib::ustring &key, const Glib::ArrayHandle<Glib::ustring> &list);
77     void set_integer_list(const Glib::ustring &grp, const Glib::ustring &key, const Glib::ArrayHandle<int> &list);
78     void set_double_list(const Glib::ustring &grp, const Glib::ustring &key, const Glib::ArrayHandle<double> &list);
79 
80     bool load_from_file(const Glib::ustring &fn);
81     bool load_from_data(const Glib::ustring &data);
82     Glib::ustring to_data();
83 
get_prefix()84     Glib::ustring get_prefix() const { return prefix_; }
set_prefix(const Glib::ustring & prefix)85     void set_prefix(const Glib::ustring &prefix) { prefix_ = prefix; }
86 
filename()87     const Glib::ustring &filename() const { return filename_; }
88 
89 private:
GRP(const Glib::ustring & g)90     Glib::ustring GRP(const Glib::ustring &g) const { return prefix_ + g; }
91 
92     Glib::ustring prefix_;
93     Glib::KeyFile kf_;
94 
95     Glib::ustring filename_;
96     mutable ProgressListener *pl_;
97 };
98 
99 
100 struct AreaMask {
101     struct Shape {
102         enum Mode {
103             ADD,
104             SUBTRACT,
105             INTERSECT
106         };
107         enum Type {
108             RECTANGLE,
109             POLYGON,
110             GRADIENT
111         };
112         Mode mode;
113         double feather; // [0,100]
114         double blur;
115 
116         Shape();
~ShapeAreaMask::Shape117         virtual ~Shape() {}
118         virtual Type getType() const = 0 ;
119         virtual bool operator==(const Shape &other) const;
120         virtual bool operator!=(const Shape &other) const;
121 
122         static int toImgSpace(double v, int imSize);
123         static double toParamRange(int v, int imSize);
124         virtual std::unique_ptr<Shape> clone() const = 0;
125     };
126 
127     struct Rectangle: public Shape {
128         double x; // [-100,100], with 0 as center of the image
129         double y; // [-100,100]
130         double width; // [0,200], with 100 as image width
131         double height; // [0,200]
132         double angle; // in degrees
133         double roundness; // [0,100] (0 = rectangle, 100 = ellipse)
134 
135         Rectangle();
getTypeAreaMask::Rectangle136         Type getType() const override { return Type::RECTANGLE; };
137         bool operator==(const Shape &other) const override;
138         bool operator!=(const Shape &other) const override;
139         std::unique_ptr<Shape> clone() const override;
140     };
141 
142     struct Polygon: public Shape {
143         struct Knot {
144             double x; // [-200,200], with 0 as center of the image, 100 = half width of the image
145                       //             200 as a limit means that knot can be out of the image
146                       //             up to twice the image size
147             double y; // [-200,200]
148             double roundness; // [0,100] (0 = sharp corner, 100 = entirely round corner)
149 
150             Knot();
151             void setPos(CoordD &pos);
152             bool operator==(const Knot &other) const;
153             bool operator!=(const Knot &other) const;
154         };
155         std::vector<Knot> knots;
156 
157         // Convert the Polygon object into a drawable polygon (for rtengine and rtgui)
158         static std::vector<CoordD> get_tessellation(std::vector<Knot> &knots);
159         void knots_to_list(std::vector<double> &out) const;
160         void knots_from_list(const std::vector<double> &v);
161 
getTypeAreaMask::Polygon162         Type getType() const override { return Type::POLYGON; };
163         bool operator==(const Shape &other) const override;
164         bool operator!=(const Shape &other) const override;
165         std::unique_ptr<Shape> clone() const override;
166     };
167 
168     struct Gradient: public Shape {
169         double x;             // [-100; 100] Percentage of image's width
170         double y;             // [-100; 100] Percentage of image's height
171         double strengthStart; // [0; 100] Strenght of the mask at the transition's begin
172         double strengthEnd;   // [0; 100] Strenght of the mask at the transition's end
173         double angle;         // [0; 360[ Angle of the gradient
174 
175         Gradient();
getTypeAreaMask::Gradient176         Type getType() const override { return Type::GRADIENT; };
177         bool operator==(const Shape &other) const override;
178         bool operator!=(const Shape &other) const override;
179         std::unique_ptr<Shape> clone() const override;
180     };
181 
182     bool enabled;
183     double feather; // [0,100]
184     double blur;
185     std::vector<double> contrast; // curve
186     std::vector<std::unique_ptr<Shape>> shapes;
187 
188     AreaMask();
189     AreaMask(const AreaMask &other);
190     AreaMask &operator=(const AreaMask &other);
191 
192     bool operator==(const AreaMask &other) const;
193     bool operator!=(const AreaMask &other) const;
194     bool isTrivial() const;
195 };
196 
197 class DeltaEMask {
198 public:
199     bool enabled;
200     double L;
201     double C;
202     double H;
203     double range;
204     double decay;
205     int weight_L;
206     int weight_C;
207     int weight_H;
208 
209     DeltaEMask();
210     bool operator==(const DeltaEMask &other) const;
211     bool operator!=(const DeltaEMask &other) const;
212 };
213 
214 
215 struct DrawnMask {
216     struct Stroke {
217         double x; // [0,1], with 0 as leftmost point of the image
218         double y; // [0,1]
219         double radius; // [0,1], with 1 as 10% of the image smallest dimension
220         double hardness; // [0,1] with 1 as opaque (strongest)
221         bool erase;
222         Stroke();
223         bool operator==(const Stroke &other) const;
224         bool operator!=(const Stroke &other) const;
225     };
226     bool enabled;
227     double feather; // [0,100]
228     double transparency; // [0,1] (0 = opaque, 1 = fully transparent)
229     double smoothness; // [0,1] (0 = harsh edges, 1 = fully blurred)
230     std::vector<double> contrast; // curve
231     std::vector<Stroke> strokes;
232     enum Mode {
233         INTERSECT,
234         ADD,
235         ADD_BOUNDED
236     };
237     Mode mode;
238 
239     DrawnMask();
240     bool operator==(const DrawnMask &other) const;
241     bool operator!=(const DrawnMask &other) const;
242     bool isTrivial() const;
243 
244     void strokes_to_list(std::vector<double> &out) const;
245     void strokes_from_list(const std::vector<double> &v);
246 };
247 
248 
249 class ParametricMask {
250 public:
251     bool enabled;
252     double blur;
253     std::vector<double> hue;
254     std::vector<double> chromaticity;
255     std::vector<double> lightness;
256     int lightnessDetail;
257     int contrastThreshold;
258 
259     ParametricMask();
260     bool operator==(const ParametricMask &other) const;
261     bool operator!=(const ParametricMask &other) const;
262 };
263 
264 
265 class Mask {
266 public:
267     bool enabled;
268     bool inverted;
269     ParametricMask parametricMask;
270     AreaMask areaMask;
271     DeltaEMask deltaEMask;
272     DrawnMask drawnMask;
273     Glib::ustring name;
274 
275     Mask();
276     bool operator==(const Mask &other) const;
277     bool operator!=(const Mask &other) const;
278 
279     bool load(int ppVersion,
280               const KeyFile &keyfile, const Glib::ustring &group_name,
281               const Glib::ustring &prefix, const Glib::ustring &suffix);
282     void save(KeyFile &keyfile, const Glib::ustring &group_name,
283               const Glib::ustring &prefix, const Glib::ustring &suffix) const;
284 };
285 
286 
287 template<typename T>
288 class Threshold final
289 {
290 public:
Threshold(T _bottom,T _top,bool _start_at_one)291     Threshold(T _bottom, T _top, bool _start_at_one) :
292         Threshold(_bottom, _top, 0, 0, _start_at_one, false)
293     {
294     }
295 
Threshold(T _bottom_left,T _top_left,T _bottom_right,T _top_right,bool _start_at_one)296     Threshold(T _bottom_left, T _top_left, T _bottom_right, T _top_right, bool _start_at_one) :
297         Threshold(_bottom_left, _top_left, _bottom_right, _top_right, _start_at_one, true)
298     {
299     }
300 
301     template<typename U = T>
302     typename std::enable_if<std::is_floating_point<U>::value, bool>::type operator ==(const Threshold<U>& rhs) const
303     {
304         if (is_double) {
305             return
306                 std::fabs(bottom_left - rhs.bottom_left) < 1e-10
307                 && std::fabs(top_left - rhs.top_left) < 1e-10
308                 && std::fabs(bottom_right - rhs.bottom_right) < 1e-10
309                 && std::fabs(top_right - rhs.top_right) < 1e-10;
310         } else {
311             return
312                 std::fabs(bottom_left - rhs.bottom_left) < 1e-10
313                 && std::fabs(top_left - rhs.top_left) < 1e-10;
314         }
315     }
316 
317     template<typename U = T>
318     typename std::enable_if<std::is_integral<U>::value, bool>::type operator ==(const Threshold<U>& rhs) const
319     {
320         if (is_double) {
321             return
322                 bottom_left == rhs.bottom_left
323                 && top_left == rhs.top_left
324                 && bottom_right == rhs.bottom_right
325                 && top_right == rhs.top_right;
326         } else {
327             return
328                 bottom_left == rhs.bottom_left
329                 && top_left == rhs.top_left;
330         }
331     }
332 
getBottom()333     T getBottom() const
334     {
335         return bottom_left;
336     }
337 
getTop()338     T getTop() const
339     {
340         return top_left;
341     }
342 
getBottomLeft()343     T getBottomLeft() const
344     {
345         return bottom_left;
346     }
347 
getTopLeft()348     T getTopLeft() const
349     {
350         return top_left;
351     }
352 
getBottomRight()353     T getBottomRight() const
354     {
355         return bottom_right;
356     }
357 
getTopRight()358     T getTopRight() const
359     {
360         return top_right;
361     }
362 
setValues(T bottom,T top)363     void setValues(T bottom, T top)
364     {
365         bottom_left = bottom;
366         top_left = top;
367     }
368 
setValues(T bottom_left,T top_left,T bottom_right,T top_right)369     void setValues(T bottom_left, T top_left, T bottom_right, T top_right)
370     {
371         this->bottom_left = bottom_left;
372         this->top_left = top_left;
373         this->bottom_right = bottom_right;
374         this->top_right = top_right;
375     }
376 
isDouble()377     bool isDouble() const
378     {
379         return is_double;
380     }
381 
toVector()382     std::vector<T> toVector() const
383     {
384         if (is_double) {
385             return {
386                 bottom_left,
387                 top_left,
388                 bottom_right,
389                 top_right
390             };
391         } else {
392             return {
393                 bottom_left,
394                 top_left
395             };
396         }
397     }
398 
399     // RT: Type of the returned value
400     // RV: Type of the value on the X axis
401     // RV2: Type of the maximum value on the Y axis
402     template <typename RT, typename RV, typename RV2>
multiply(RV x,RV2 y_max)403     RT multiply(RV x, RV2 y_max) const
404     {
405         const double val = x;
406 
407         if (init_eql) {
408             if (is_double) {
409                 if (val == static_cast<double>(bottom_right) && static_cast<double>(bottom_right) == static_cast<double>(top_right)) {
410                     // This handles the special case where the 2 right values are the same, then bottom one is sent back,
411                     // useful if one wants to keep the bottom value even beyond the x max bound
412                     return 0;
413                 }
414 
415                 if (val >= static_cast<double>(top_right)) {
416                     return y_max;
417                 }
418 
419                 if (val > static_cast<double>(bottom_right)) {
420                     return static_cast<double>(y_max * (val - static_cast<double>(bottom_right)) / (static_cast<double>(top_right) - static_cast<double>(bottom_right)));
421                 }
422             }
423 
424             if (val >= static_cast<double>(bottom_left)) {
425                 return 0;
426             }
427 
428             if (val > static_cast<double>(top_left)) {
429                 return static_cast<double>(y_max * (1. - (val - static_cast<double>(bottom_left)) / (static_cast<double>(top_left) - static_cast<double>(bottom_left))));
430             }
431 
432             return y_max;
433         } else {
434             if (is_double) {
435                 if (val == static_cast<double>(bottom_right) && static_cast<double>(bottom_right) == static_cast<double>(top_right)) {
436                     // This handles the special case where the 2 right values are the same, then top one is sent back,
437                     // useful if one wants to keep the top value even beyond the x max bound
438                     return y_max;
439                 }
440 
441                 if (val >= static_cast<double>(bottom_right)) {
442                     return 0;
443                 }
444 
445                 if (val > static_cast<double>(top_right)) {
446                     return static_cast<double>(y_max * (1.0 - (val - static_cast<double>(top_right)) / (static_cast<double>(bottom_right) - static_cast<double>(top_right))));
447                 }
448             }
449 
450             if (val >= static_cast<double>(top_left)) {
451                 return y_max;
452             }
453 
454             if (val > static_cast<double>(bottom_left)) {
455                 return static_cast<double>(y_max * (val - static_cast<double>(bottom_left)) / (static_cast<double>(top_left) - static_cast<double>(bottom_left)));
456             }
457 
458             return 0;
459         }
460     }
461 
462 private:
Threshold(T _bottom_left,T _top_left,T _bottom_right,T _top_right,bool _start_at_one,bool _is_double)463     Threshold(T _bottom_left, T _top_left, T _bottom_right, T _top_right, bool _start_at_one, bool _is_double) :
464         bottom_left(_bottom_left),
465         top_left(_top_left),
466         bottom_right(_bottom_right),
467         top_right(_top_right),
468         init_eql(_start_at_one),
469         is_double(_is_double)
470     {
471     }
472 
473     T bottom_left;
474     T top_left;
475     T bottom_right;
476     T top_right;
477     bool init_eql;
478     bool is_double;
479 };
480 
481 
482 struct ExposureParams {
483     bool enabled;
484     enum HighlightReconstruction {
485         HR_OFF,
486         HR_BLEND,
487         HR_COLOR,
488         HR_COLORSOFT
489     };
490     HighlightReconstruction hrmode;
491     double expcomp;
492     double black;
493 
494     ExposureParams();
495 
496     bool operator==(const ExposureParams &other) const;
497     bool operator!=(const ExposureParams &other) const;
498 };
499 
500 
501 struct SaturationParams {
502     bool enabled;
503     int saturation;
504     int vibrance;
505 
506     SaturationParams();
507 
508     bool operator ==(const SaturationParams &other) const;
509     bool operator !=(const SaturationParams &other) const;
510 };
511 
512 /**
513   * Parameters of the tone curve
514   */
515 struct ToneCurveParams {
516     bool enabled;
517 
518     enum class TcMode {
519         STD,               // Standard modes, the curve is applied on all component individually
520         WEIGHTEDSTD,       // Weighted standard mode
521         FILMLIKE,          // Film-like mode, as defined in Adobe's reference code
522         SATANDVALBLENDING, // Modify the Saturation and Value channel
523         LUMINANCE,         // Modify the Luminance channel with coefficients from Rec 709's
524         PERCEPTUAL         // Keep color appearance constant using perceptual modeling
525     };
526 
527     int contrast;
528     std::vector<double> curve;
529     std::vector<double> curve2;
530     TcMode curveMode;
531     TcMode curveMode2;
532     bool histmatching; // histogram matching
533     bool fromHistMatching;
534     std::vector<double> saturation;
535     int perceptualStrength;
536 
537     ToneCurveParams();
538 
539     bool operator==(const ToneCurveParams &other) const;
540     bool operator!=(const ToneCurveParams &other) const;
541 };
542 
543 
544 /**
545   * Parameters of the luminance curve
546   */
547 struct LabCurveParams {
548     bool enabled;
549     int brightness;
550     int contrast;
551     int chromaticity;
552     std::vector<double> lcurve;
553     std::vector<double> acurve;
554     std::vector<double> bcurve;
555 
556     LabCurveParams();
557 
558     bool operator ==(const LabCurveParams& other) const;
559     bool operator !=(const LabCurveParams& other) const;
560 };
561 
562 
563 /**
564  * Parameters for local contrast
565  */
566 struct LocalContrastParams {
567     struct Region {
568         double contrast;
569         std::vector<double> curve;
570 
571         Region();
572         bool operator==(const Region &other) const;
573         bool operator!=(const Region &other) const;
574     };
575 
576     bool enabled;
577     std::vector<Region> regions;
578     std::vector<Mask> labmasks;
579     int showMask;
580 
581     LocalContrastParams();
582 
583     bool operator==(const LocalContrastParams &other) const;
584     bool operator!=(const LocalContrastParams &other) const;
585 };
586 
587 
588 /**
589   * Parameters of the RGB curves
590   */
591 struct RGBCurvesParams {
592     bool enabled;
593     std::vector<double>   rcurve;
594     std::vector<double>   gcurve;
595     std::vector<double>   bcurve;
596 
597     RGBCurvesParams();
598 
599     bool operator ==(const RGBCurvesParams& other) const;
600     bool operator !=(const RGBCurvesParams& other) const;
601 };
602 
603 
604 /**
605   * Parameters of the sharpening
606   */
607 struct SharpeningParams {
608     bool           enabled;
609     double         contrast;
610     double         radius;
611     int            amount;
612     Threshold<int> threshold;
613     bool           edgesonly;
614     double         edges_radius;
615     int            edges_tolerance;
616     bool           halocontrol;
617     int            halocontrol_amount;
618     Glib::ustring  method;
619     int            deconvamount;
620     double         deconvradius;
621     bool deconvAutoRadius;
622     double deconvCornerBoost;
623     int deconvCornerLatitude;
624 
625     SharpeningParams();
626 
627     bool operator ==(const SharpeningParams& other) const;
628     bool operator !=(const SharpeningParams& other) const;
629 };
630 
631 
632 struct WBParams {
633     bool enabled;
634     enum Type {
635         CAMERA,
636         AUTO,
637         CUSTOM_TEMP,
638         CUSTOM_MULT
639     };
640     Type method;
641     int temperature;
642     double green;
643     double equal;
644     std::array<double, 3> mult;
645 
646     WBParams();
647 
648     bool operator==(const WBParams &other) const;
649     bool operator!=(const WBParams &other) const;
650 };
651 
652 
653 /**
654  * Parameters of defringing
655  */
656 struct DefringeParams {
657     bool    enabled;
658     double  radius;
659     int     threshold;
660     std::vector<double> huecurve;
661 
662     DefringeParams();
663 
664     bool operator ==(const DefringeParams& other) const;
665     bool operator !=(const DefringeParams& other) const;
666 };
667 
668 /**
669   * Parameters of impulse denoising
670   */
671 struct ImpulseDenoiseParams {
672     bool    enabled;
673     int     thresh;
674 
675     ImpulseDenoiseParams();
676 
677     bool operator ==(const ImpulseDenoiseParams& other) const;
678     bool operator !=(const ImpulseDenoiseParams& other) const;
679 };
680 
681 /**
682  * Parameters of the directional pyramid denoising
683  */
684 struct DenoiseParams {
685     enum class ChrominanceMethod {
686         MANUAL,
687         AUTOMATIC
688     };
689 
690     enum class ColorSpace {
691         RGB,
692         LAB
693     };
694 
695     bool enabled;
696     ColorSpace colorSpace;
697 
698     bool aggressive;
699     double gamma;
700 
701     double luminance;
702     double luminanceDetail;
703     int luminanceDetailThreshold;
704 
705     ChrominanceMethod chrominanceMethod;
706     double chrominanceAutoFactor;
707     double chrominance;
708     double chrominanceRedGreen;
709     double chrominanceBlueYellow;
710 
711     bool smoothingEnabled;
712     int guidedChromaRadius;
713     int nlDetail;
714     int nlStrength;
715 
716     DenoiseParams();
717 
718     bool operator ==(const DenoiseParams& other) const;
719     bool operator !=(const DenoiseParams& other) const;
720 };
721 
722 
723 struct TextureBoostParams {
724     struct Region {
725         double strength;
726         double detailThreshold;
727         int iterations;
728 
729         Region();
730         bool operator==(const Region &other) const;
731         bool operator!=(const Region &other) const;
732     };
733 
734     bool enabled;
735     std::vector<Region> regions;
736     std::vector<Mask> labmasks;
737     int showMask;
738 
739     TextureBoostParams();
740 
741     bool operator ==(const TextureBoostParams& other) const;
742     bool operator !=(const TextureBoostParams& other) const;
743 };
744 
745 
746 struct LogEncodingParams {
747     bool enabled;
748     bool autocompute;
749     bool autogain;
750     double gain;
751     double targetGray;
752     double blackEv;
753     double whiteEv;
754     int regularization;
755 
756     LogEncodingParams();
757 
758     bool operator==(const LogEncodingParams &other) const;
759     bool operator !=(const LogEncodingParams &other) const;
760 };
761 
762 
763 struct FattalToneMappingParams {
764     bool enabled;
765     int threshold;
766     int amount;
767     bool satcontrol;
768 
769     FattalToneMappingParams();
770 
771     bool operator ==(const FattalToneMappingParams& other) const;
772     bool operator !=(const FattalToneMappingParams& other) const;
773 };
774 
775 
776 struct ToneEqualizerParams {
777     bool enabled;
778     std::array<int, 5> bands;
779     int regularization;
780     bool show_colormap;
781 
782     ToneEqualizerParams();
783 
784     bool operator==(const ToneEqualizerParams &other) const;
785     bool operator!=(const ToneEqualizerParams &other) const;
786 };
787 
788 /**
789   * Parameters of the cropping
790   */
791 struct CropParams {
792     bool    enabled;
793     int     x;
794     int     y;
795     int     w;
796     int     h;
797     bool    fixratio;
798     Glib::ustring   ratio;
799     Glib::ustring   orientation;
800     Glib::ustring   guide;
801 
802     CropParams();
803 
804     bool operator ==(const CropParams& other) const;
805     bool operator !=(const CropParams& other) const;
806 
807     void mapToResized(int resizedWidth, int resizedHeight, int scale, int& x1, int& x2, int& y1, int& y2) const;
808 };
809 
810 /**
811   * Parameters of the coarse transformations like 90 deg rotations and h/v flipping
812   */
813 struct CoarseTransformParams {
814     int     rotate;
815     bool    hflip;
816     bool    vflip;
817 
818     CoarseTransformParams();
819 
820     bool operator ==(const CoarseTransformParams& other) const;
821     bool operator !=(const CoarseTransformParams& other) const;
822 };
823 
824 /**
825   * Common transformation parameters
826   */
827 struct CommonTransformParams {
828     bool autofill;
829 
830     CommonTransformParams();
831 
832     bool operator ==(const CommonTransformParams& other) const;
833     bool operator !=(const CommonTransformParams& other) const;
834 };
835 
836 /**
837   * Parameters of the rotation
838   */
839 struct RotateParams {
840     bool enabled;
841     double  degree;
842 
843     RotateParams();
844 
845     bool operator ==(const RotateParams& other) const;
846     bool operator !=(const RotateParams& other) const;
847 };
848 
849 /**
850   * Parameters of the distortion correction
851   */
852 struct DistortionParams {
853     bool enabled;
854     double amount;
855     bool autocompute;
856 
857     DistortionParams();
858 
859     bool operator ==(const DistortionParams& other) const;
860     bool operator !=(const DistortionParams& other) const;
861 };
862 
863 // Lens profile correction parameters
864 struct LensProfParams {
865     enum class LcMode {
866         NONE,               // No lens correction
867         LENSFUNAUTOMATCH,   // Lens correction using auto matched lensfun database entry
868         LENSFUNMANUAL,      // Lens correction using manually selected lensfun database entry
869         LCP,                // Lens correction using lcp file
870         EXIF                // Lens correction from EXIF metadata
871     };
872 
873     LcMode lcMode;
874     Glib::ustring lcpFile;
875     bool useDist, useVign, useCA;
876     Glib::ustring lfCameraMake;
877     Glib::ustring lfCameraModel;
878     Glib::ustring lfLens;
879 
880     LensProfParams();
881 
882     bool operator ==(const LensProfParams& other) const;
883     bool operator !=(const LensProfParams& other) const;
884 
885     bool useLensfun() const;
886     bool lfAutoMatch() const;
887     bool useLcp() const;
888     bool lfManual() const;
889     bool useExif() const;
890     bool needed() const;
891 
892     const std::vector<const char*>& getMethodStrings() const;
893     Glib::ustring getMethodString(LcMode mode) const;
894     LcMode getMethodNumber(const Glib::ustring& mode) const;
895 };
896 
897 
898 /**
899   * Parameters of the perspective correction
900   */
901 struct PerspectiveParams {
902     bool enabled;
903     double horizontal;
904     double vertical;
905     double angle;
906     double shear;
907     double flength;
908     double cropfactor;
909     double aspect;
910     std::vector<int> control_lines;
911 
912     PerspectiveParams();
913 
914     bool operator ==(const PerspectiveParams& other) const;
915     bool operator !=(const PerspectiveParams& other) const;
916 };
917 
918 /**
919   * Parameters of the gradient filter
920   */
921 struct GradientParams {
922     bool   enabled;
923     double degree;
924     int    feather;
925     double strength;
926     int    centerX;
927     int    centerY;
928 
929     GradientParams();
930 
931     bool operator ==(const GradientParams& other) const;
932     bool operator !=(const GradientParams& other) const;
933 };
934 
935 /**
936   * Parameters of the post-crop vignette filter
937   */
938 struct PCVignetteParams {
939     bool   enabled;
940     double strength;
941     int    feather;
942     int    roundness;
943     int centerX;
944     int centerY;
945 
946     PCVignetteParams();
947 
948     bool operator ==(const PCVignetteParams& other) const;
949     bool operator !=(const PCVignetteParams& other) const;
950 };
951 
952 /**
953   * Parameters of the vignetting correction
954   */
955 struct VignettingParams {
956     bool enabled;
957     int  amount;
958     int  radius;
959     int  strength;
960     int  centerX;
961     int  centerY;
962 
963     VignettingParams();
964 
965     bool operator ==(const VignettingParams& other) const;
966     bool operator !=(const VignettingParams& other) const;
967 };
968 
969 /**
970   * Parameters of the color mixer
971   */
972 struct ChannelMixerParams {
973     bool enabled;
974     enum Mode {
975         RGB_MATRIX,
976         PRIMARIES_CHROMA
977     };
978     Mode mode;
979 
980     int red[3];
981     int green[3];
982     int blue[3];
983 
984     int hue_tweak[3];
985     int sat_tweak[3];
986 
987     ChannelMixerParams();
988 
989     bool operator ==(const ChannelMixerParams& other) const;
990     bool operator !=(const ChannelMixerParams& other) const;
991 };
992 
993 struct BlackWhiteParams {
994     bool enabled;
995 
996     Glib::ustring filter;
997     Glib::ustring setting;
998     int mixerRed;
999     int mixerGreen;
1000     int mixerBlue;
1001     int gammaRed;
1002     int gammaGreen;
1003     int gammaBlue;
1004     Threshold<int> colorCast;
1005 
1006     BlackWhiteParams();
1007 
1008     bool operator ==(const BlackWhiteParams& other) const;
1009     bool operator !=(const BlackWhiteParams& other) const;
1010 };
1011 
1012 struct HSLEqualizerParams {
1013     bool enabled;
1014     std::vector<double> hCurve;
1015     std::vector<double> sCurve;
1016     std::vector<double> lCurve;
1017     int smoothing;
1018 
1019     HSLEqualizerParams();
1020 
1021     bool operator==(const HSLEqualizerParams &other) const;
1022     bool operator!=(const HSLEqualizerParams &other) const;
1023 };
1024 
1025 /**
1026   * Parameters of the c/a correction
1027   */
1028 struct CACorrParams {
1029     bool enabled;
1030     double red;
1031     double blue;
1032 
1033     CACorrParams();
1034 
1035     bool operator ==(const CACorrParams& other) const;
1036     bool operator !=(const CACorrParams& other) const;
1037 };
1038 
1039 /**
1040   * Parameters of the resizing
1041   */
1042 struct ResizeParams {
1043     bool enabled;
1044     double scale;
1045     Glib::ustring appliesTo;
1046     int dataspec;
1047     double width;
1048     double height;
1049     bool allowUpscaling;
1050     int ppi;
1051     enum Unit {
1052         PX,
1053         CM,
1054         INCHES
1055     };
1056     Unit unit;
1057 
1058     ResizeParams();
1059 
1060     bool operator ==(const ResizeParams& other) const;
1061     bool operator !=(const ResizeParams& other) const;
1062 
1063     int get_width() const;
1064     int get_height() const;
1065 };
1066 
1067 
1068 /**
1069   * Parameters entry
1070   */
1071 struct SpotEntry {
1072     Coord sourcePos;
1073     Coord targetPos;
1074     int radius;
1075     float feather;
1076     float opacity;
1077     int detail;
1078 
1079     SpotEntry();
1080     float getFeatherRadius() const;
1081 
1082     bool operator ==(const SpotEntry& other) const;
1083     bool operator !=(const SpotEntry& other) const;
1084 };
1085 
1086 /**
1087   * Parameters of the dust removal tool
1088   */
1089 struct SpotParams {
1090     bool enabled;
1091     std::vector<SpotEntry> entries;
1092 
1093     // the following constant can be used for experimentation before the final merge
1094     static const short minRadius;
1095     static const short maxRadius;
1096 
1097     SpotParams();
1098 
1099     bool operator ==(const SpotParams& other) const;
1100     bool operator !=(const SpotParams& other) const;
1101 };
1102 
1103 /**
1104   * Parameters of the color spaces used during the processing
1105   */
1106 struct ColorManagementParams {
1107     Glib::ustring inputProfile;
1108     bool toneCurve;
1109     bool applyLookTable;
1110     bool applyBaselineExposureOffset;
1111     bool applyHueSatMap;
1112     int dcpIlluminant;
1113 
1114     Glib::ustring workingProfile;
1115 
1116     Glib::ustring outputProfile;
1117     RenderingIntent outputIntent;
1118     bool outputBPC;
1119 
1120     static const Glib::ustring NoICMString;
1121     static const Glib::ustring NoProfileString;
1122 
1123     ColorManagementParams();
1124 
1125     bool operator ==(const ColorManagementParams& other) const;
1126     bool operator !=(const ColorManagementParams& other) const;
1127 };
1128 
1129 
1130 /**
1131   * Parameters for metadata handling
1132   */
1133 
1134 typedef std::map<Glib::ustring, Glib::ustring> ExifPairs;
1135 typedef std::map<Glib::ustring, std::vector<Glib::ustring>> IPTCPairs;
1136 
1137 struct MetaDataParams {
1138     enum Mode {
1139         TUNNEL,
1140         EDIT,
1141         STRIP
1142     };
1143     Mode mode;
1144     std::vector<std::string> exifKeys;
1145     ExifPairs exif;
1146     IPTCPairs iptc;
1147 
1148     MetaDataParams();
1149 
1150     bool operator==(const MetaDataParams &other) const;
1151     bool operator!=(const MetaDataParams &other) const;
1152 
1153     static std::vector<std::string> basicExifKeys;
1154 };
1155 
1156 
1157 /**
1158  *  Film simualtion params
1159  */
1160 struct FilmSimulationParams {
1161     bool enabled;
1162     Glib::ustring clutFilename;
1163     int strength;
1164 
1165     FilmSimulationParams();
1166 
1167     bool operator ==(const FilmSimulationParams& other) const;
1168     bool operator !=(const FilmSimulationParams& other) const;
1169 };
1170 
1171 
1172 struct SoftLightParams {
1173     bool enabled;
1174     int strength;
1175 
1176     SoftLightParams();
1177 
1178     bool operator==(const SoftLightParams &other) const;
1179     bool operator!=(const SoftLightParams &other) const;
1180 };
1181 
1182 
1183 struct DehazeParams {
1184     bool enabled;
1185     std::vector<double> strength;
1186     bool showDepthMap;
1187     int depth;
1188     bool luminance;
1189     int blackpoint;
1190 
1191     DehazeParams();
1192 
1193     bool operator==(const DehazeParams &other) const;
1194     bool operator!=(const DehazeParams &other) const;
1195 };
1196 
1197 
1198 struct GrainParams {
1199     bool enabled;
1200     int iso;
1201     int strength;
1202     int scale;
1203 
1204     GrainParams();
1205 
1206     bool operator==(const GrainParams &other) const;
1207     bool operator!=(const GrainParams &other) const;
1208 };
1209 
1210 
1211 struct SmoothingParams {
1212     struct Region {
1213         enum class Channel {
1214             LUMINANCE,
1215             CHROMINANCE,
1216             RGB
1217         };
1218         enum class Mode {
1219             GUIDED,
1220             GAUSSIAN,
1221             GAUSSIAN_GLOW,
1222             NLMEANS
1223         };
1224         Mode mode;
1225         Channel channel;
1226         int radius;
1227         double sigma;
1228         int epsilon;
1229         int iterations;
1230         double falloff;
1231         int nldetail;
1232         int nlstrength;
1233 
1234         Region();
1235         bool operator==(const Region &other) const;
1236         bool operator!=(const Region &other) const;
1237     };
1238     bool enabled;
1239     std::vector<Region> regions;
1240     std::vector<Mask> labmasks;
1241     int showMask;
1242 
1243     SmoothingParams();
1244 
1245     bool operator==(const SmoothingParams &other) const;
1246     bool operator!=(const SmoothingParams &other) const;
1247 };
1248 
1249 
1250 struct ColorCorrectionParams {
1251     enum class Mode {
1252         YUV,
1253         RGB,
1254         HSL
1255     };
1256     struct Region {
1257         double a;
1258         double b;
1259         double abscale;
1260         double inSaturation;
1261         double outSaturation;
1262         std::array<double, 3> slope;
1263         std::array<double, 3> offset;
1264         std::array<double, 3> power;
1265         std::array<double, 3> pivot;
1266         std::array<double, 3> hue;
1267         std::array<double, 3> sat;
1268         std::array<double, 3> factor;
1269         bool rgbluminance;
1270         Mode mode;
1271 
1272         Region();
1273         bool operator==(const Region &other) const;
1274         bool operator!=(const Region &other) const;
1275     };
1276 
1277     bool enabled;
1278     std::vector<Region> regions;
1279     std::vector<Mask> labmasks;
1280     int showMask;
1281 
1282     ColorCorrectionParams();
1283     bool operator==(const ColorCorrectionParams &other) const;
1284     bool operator!=(const ColorCorrectionParams &other) const;
1285 };
1286 
1287 
1288 /**
1289   * Parameters for RAW demosaicing, common to all sensor type
1290   */
1291 struct RAWParams {
1292     /**
1293      * Parameters for RAW demosaicing specific to Bayer sensors
1294      */
1295     struct BayerSensor {
1296         enum class Method {
1297             AMAZE,
1298             RCD,
1299             LMMSE,
1300             IGV,
1301             AMAZEBILINEAR,
1302             RCDBILINEAR,
1303             VNG4,
1304             FAST,
1305             MONO,
1306             PIXELSHIFT,
1307             NONE,
1308             AMAZEVNG4,
1309             RCDVNG4,
1310             DCB,
1311             DCBBILINEAR,
1312             DCBVNG4,
1313             AHD,
1314             EAHD,
1315             HPHD
1316         };
1317 
1318         enum class PSMotionCorrectionMethod {
1319             OFF,
1320             AUTO,
1321             CUSTOM
1322         };
1323 
1324         enum class PSDemosaicMethod {
1325             AMAZE,
1326             AMAZEVNG4,
1327             LMMSE
1328         };
1329 
1330         Method method;
1331         int border;
1332         int imageNum;
1333         int ccSteps;
1334         double black0;
1335         double black1;
1336         double black2;
1337         double black3;
1338         bool twogreen;
1339         int linenoise;
1340         enum class LineNoiseDirection {
1341             HORIZONTAL = 1,
1342             VERTICAL,
1343             BOTH,
1344             PDAF_LINES = 5
1345         };
1346         LineNoiseDirection linenoiseDirection;
1347         int greenthresh;
1348         int dcb_iterations;
1349         int lmmse_iterations;
1350         bool dualDemosaicAutoContrast;
1351         double dualDemosaicContrast;
1352         PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod;
1353         double pixelShiftEperIso;
1354         double pixelShiftSigma;
1355         bool pixelShiftShowMotion;
1356         bool pixelShiftShowMotionMaskOnly;
1357         bool pixelShiftHoleFill;
1358         bool pixelShiftMedian;
1359         bool pixelShiftGreen;
1360         bool pixelShiftBlur;
1361         double pixelShiftSmoothFactor;
1362         bool pixelShiftEqualBright;
1363         bool pixelShiftEqualBrightChannel;
1364         bool pixelShiftNonGreenCross;
1365         Glib::ustring pixelShiftDemosaicMethod;
1366         bool dcb_enhance;
1367         bool pdafLinesFilter;
1368         bool dynamicRowNoiseFilter;
1369 
1370         // some enable flags
1371         bool enable_black;
1372         bool enable_preproc;
1373 
1374         BayerSensor();
1375 
1376         bool operator ==(const BayerSensor& other) const;
1377         bool operator !=(const BayerSensor& other) const;
1378 
1379         void setPixelShiftDefaults();
1380 
1381         static const std::vector<const char*>& getMethodStrings();
1382         static Glib::ustring getMethodString(Method method);
1383 
1384         static const std::vector<const char*>& getPSDemosaicMethodStrings();
1385         static Glib::ustring getPSDemosaicMethodString(PSDemosaicMethod method);
1386     };
1387 
1388     /**
1389      * Parameters for RAW demosaicing specific to X-Trans sensors
1390      */
1391     struct XTransSensor {
1392         enum class Method {
1393             FOUR_PASS,
1394             THREE_PASS,
1395             TWO_PASS,
1396             ONE_PASS,
1397             FAST,
1398             MONO,
1399             NONE
1400         };
1401 
1402         Method method;
1403         bool dualDemosaicAutoContrast;
1404         double dualDemosaicContrast;
1405         int border;
1406         int ccSteps;
1407         double blackred;
1408         double blackgreen;
1409         double blackblue;
1410 
1411         bool enable_black;
1412 
1413         XTransSensor();
1414 
1415         bool operator ==(const XTransSensor& other) const;
1416         bool operator !=(const XTransSensor& other) const;
1417 
1418         static const std::vector<const char*>& getMethodStrings();
1419         static Glib::ustring getMethodString(Method method);
1420     };
1421 
1422     BayerSensor bayersensor;         ///< RAW parameters for Bayer sensors
1423     XTransSensor xtranssensor;       ///< RAW parameters for X-Trans sensors
1424 
1425     enum class FlatFieldBlurType {
1426         AREA,
1427         V,
1428         H,
1429         VH,
1430     };
1431 
1432     Glib::ustring dark_frame;
1433     bool df_autoselect;
1434 
1435     Glib::ustring ff_file;
1436     bool ff_AutoSelect;
1437     int ff_BlurRadius;
1438     Glib::ustring ff_BlurType;
1439     bool ff_AutoClipControl;
1440     int ff_clipControl;
1441     bool ff_embedded;
1442 
1443     bool ca_autocorrect;
1444     bool ca_avoidcolourshift;
1445     int caautoiterations;
1446     double cared;
1447     double cablue;
1448 
1449     // exposure before interpolation
1450     double expos;
1451 
1452     bool hotPixelFilter;
1453     bool deadPixelFilter;
1454     int hotdeadpix_thresh;
1455 
1456     // some enable flags
1457     bool enable_darkframe;
1458     bool enable_flatfield;
1459     bool enable_ca;
1460     bool enable_hotdeadpix;
1461     bool enable_whitepoint;
1462 
1463     RAWParams();
1464 
1465     bool operator ==(const RAWParams& other) const;
1466     bool operator !=(const RAWParams& other) const;
1467 
1468     static const std::vector<const char*>& getFlatFieldBlurTypeStrings();
1469     static Glib::ustring getFlatFieldBlurTypeString(FlatFieldBlurType type);
1470 };
1471 
1472 
1473 /**
1474   * Parameters of film negative
1475   */
1476 struct FilmNegativeParams {
1477     bool enabled;
1478     double redRatio;
1479     double greenExp;
1480     double blueRatio;
1481 
1482     double redBase;
1483     double greenBase;
1484     double blueBase;
1485 
1486     FilmNegativeParams();
1487 
1488     bool operator ==(const FilmNegativeParams& other) const;
1489     bool operator !=(const FilmNegativeParams& other) const;
1490 };
1491 
1492 
1493 /**
1494   * This class holds all the processing parameters applied on the images
1495   */
1496 class ProcParams {
1497 public:
1498     ExposureParams          exposure;
1499     SaturationParams saturation;
1500     ToneCurveParams         toneCurve;       ///< Tone curve parameters
1501     LabCurveParams          labCurve;        ///< CIELAB luminance curve parameters
1502     LocalContrastParams     localContrast;   ////< Local contrast parameters
1503     RGBCurvesParams         rgbCurves;       ///< RGB curves parameters
1504     SharpeningParams        sharpening;      ///< Sharpening parameters
1505     SharpeningParams        prsharpening;    ///< Sharpening parameters for post resize sharpening
1506     WBParams                wb;              ///< White balance parameters
1507     DefringeParams          defringe;        ///< Defringing parameters
1508     ImpulseDenoiseParams    impulseDenoise;  ///< Impulse denoising parameters
1509     DenoiseParams           denoise;   ///< Directional Pyramid denoising parameters
1510     TextureBoostParams      textureBoost;  ///< Edge Preserving Decomposition parameters
1511     FattalToneMappingParams fattal;          ///< Dynamic Range Compression
1512     LogEncodingParams       logenc;
1513     ToneEqualizerParams     toneEqualizer;
1514     CropParams              crop;            ///< Crop parameters
1515     CoarseTransformParams   coarse;          ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters
1516     CommonTransformParams   commonTrans;     ///< Common transformation parameters (autofill)
1517     RotateParams            rotate;          ///< Rotation parameters
1518     DistortionParams        distortion;      ///< Lens distortion correction parameters
1519     LensProfParams          lensProf;        ///< Lens correction profile parameters
1520     PerspectiveParams       perspective;     ///< Perspective correction parameters
1521     GradientParams          gradient;        ///< Gradient filter parameters
1522     PCVignetteParams        pcvignette;      ///< Post-crop vignette filter parameters
1523     CACorrParams            cacorrection;    ///< Lens c/a correction parameters
1524     VignettingParams        vignetting;      ///< Lens vignetting correction parameters
1525     ChannelMixerParams      chmixer;         ///< Channel mixer parameters
1526     BlackWhiteParams        blackwhite;      ///< Black&  White parameters
1527     HSLEqualizerParams      hsl;
1528     ResizeParams            resize;          ///< Resize parameters
1529     SpotParams              spot;            ///< Spot removal tool
1530     ColorManagementParams   icm;             ///< profiles/color spaces used during the image processing
1531     RAWParams               raw;             ///< RAW parameters before demosaicing
1532     FilmSimulationParams    filmSimulation;  ///< film simulation parameters
1533     SoftLightParams         softlight;       ///< softlight parameters
1534     DehazeParams            dehaze;          ///< dehaze parameters
1535     GrainParams             grain;
1536     SmoothingParams         smoothing;
1537     ColorCorrectionParams   colorcorrection;
1538     FilmNegativeParams      filmNegative;
1539     int                     rank;            ///< Custom image quality ranking
1540     int                     colorlabel;      ///< Custom color label
1541     bool                    inTrash;         ///< Marks deleted image
1542     Glib::ustring           appVersion;      ///< Version of the application that generated the parameters
1543     int                     ppVersion;       ///< Version of the PP file from which the parameters have been read
1544 
1545     MetaDataParams          metadata;        ///< Metadata parameters
1546     // ExifPairs               exif;            ///< List of modifications appplied on the exif tags of the input image
1547     // IPTCPairs               iptc;            ///< The IPTC tags and values to be saved to the output image
1548 
1549     /**
1550       * The constructor only sets the hand-wired defaults.
1551       */
1552     ProcParams();
1553     /**
1554       * Sets the hand-wired defaults parameters.
1555       */
1556     void setDefaults();
1557 
1558     /**
1559       * Loads the parameters from a file.
1560       * @param fname the name of the file
1561       * @params pedited pointer to a ParamsEdited object (optional) to store which values has been loaded
1562       * @return Error code (=0 if no error)
1563       */
1564     int load(ProgressListener *pl,
1565              const Glib::ustring& fname, const ParamsEdited *pedited=nullptr);
1566 
1567     int load(ProgressListener *pl,
1568              const KeyFile &keyFile, const ParamsEdited *pedited=nullptr,
1569              bool resetOnError=true, const Glib::ustring &fname="");
1570     int save(ProgressListener *pl,
1571              KeyFile &keyFile, const ParamsEdited *pedited=nullptr,
1572              const Glib::ustring &fname="") const;
1573     /**
1574       * Saves the parameters to possibly two files. This is a performance improvement if a function has to
1575       * save the same file in two different location, i.e. the cache and the image's directory
1576       * @param fname   the name of the first file (can be an empty string)
1577       * @param fname2  the name of the second file (can be an empty string) (optional)
1578       * @param fnameAbsolute set to false if embedded filenames (if any, darkframe/flatfield) should be stored as relative
1579       * filenames if they are inside the same directory or in a sub-directory to fname's directory.
1580       * @param pedited pointer to a ParamsEdited object (optional) to store which values has to be saved
1581       * @return Error code (=0 if all supplied filenames where created correctly)
1582       */
1583     int save(ProgressListener *pl,
1584              const Glib::ustring &fname, const Glib::ustring &fname2=Glib::ustring(), const ParamsEdited *pedited=nullptr);
1585 
1586     int saveEmbedded(ProgressListener *pl, const Glib::ustring &fname);
1587 
1588     /** Creates a new instance of ProcParams.
1589       * @return a pointer to the new ProcParams instance. */
1590     static ProcParams *create();
1591 
1592     /** Destroys an instance of ProcParams.
1593       * @param pp a pointer to the ProcParams instance to destroy. */
1594     static void destroy(ProcParams* pp);
1595 
1596     static void init();
1597     static void cleanup();
1598 
1599     bool operator ==(const ProcParams& other) const;
1600     bool operator !=(const ProcParams& other) const;
1601 
1602 private:
1603     /** Write the ProcParams's text in the file of the given name.
1604     * @param fname the name of the file
1605     * @param content the text to write
1606     * @return Error code (=0 if no error)
1607     * */
1608     int write(ProgressListener *pl,
1609               const Glib::ustring& fname, const Glib::ustring& content) const;
1610 
1611     int load(ProgressListener *pl,
1612              bool load_general,
1613              const KeyFile &keyFile, const ParamsEdited *pedited,
1614              bool resetOnError, const Glib::ustring &fname);
1615     int save(ProgressListener *pl,
1616              bool save_general,
1617              KeyFile &keyFile, const ParamsEdited *pedited,
1618              const Glib::ustring &fname) const;
1619 
1620     friend class ProcParamsWithSnapshots;
1621 };
1622 
1623 
1624 class ProcParamsWithSnapshots {
1625 public:
1626     int load(ProgressListener *pl, const Glib::ustring &fname);
1627     int save(ProgressListener *pl, const Glib::ustring &fname, const Glib::ustring &fname2=Glib::ustring());
1628 
1629     ProcParams master;
1630     std::vector<std::pair<Glib::ustring, ProcParams>> snapshots;
1631 };
1632 
1633 
1634 class PartialProfile {
1635 public:
1636     virtual ~PartialProfile() = default;
1637     virtual bool applyTo(ProcParams &pp) const = 0;
1638 };
1639 
1640 
1641 class FullPartialProfile: public PartialProfile {
1642 public:
1643     explicit FullPartialProfile(const ProcParams &pp);
1644     bool applyTo(ProcParams &pp) const override;
1645 
1646 private:
1647     ProcParams pp_;
1648 };
1649 
1650 
1651 class FilePartialProfile: public PartialProfile {
1652 public:
FilePartialProfile()1653     FilePartialProfile(): pl_(nullptr), fname_(""), full_(true) {}
1654     explicit FilePartialProfile(ProgressListener *pl, const Glib::ustring &fname, bool full=false);
1655     bool applyTo(ProcParams &pp) const override;
1656 
1657 private:
1658     ProgressListener *pl_;
1659     Glib::ustring fname_;
1660     bool full_;
1661 };
1662 
1663 
1664 class PEditedPartialProfile: public PartialProfile {
1665 public:
1666     PEditedPartialProfile(ProgressListener *pl, const Glib::ustring &fname, const ParamsEdited &pe);
1667     PEditedPartialProfile(const ProcParams &pp, const ParamsEdited &pe);
1668     bool applyTo(ProcParams &pp) const override;
1669 
1670 private:
1671     ProgressListener *pl_;
1672     Glib::ustring fname_;
1673     ProcParams pp_;
1674     ParamsEdited pe_;
1675 };
1676 
1677 
1678 }} // namespace rtengine::procparams
1679 
1680