diff --git a/rtengine/curves.cc b/rtengine/curves.cc index aab74a7de..9e3c6527e 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -45,6 +45,42 @@ using namespace std; namespace rtengine { +bool sanitizeCurve(std::vector& curve) +{ + // A curve is valid under one of the following conditions: + // 1) Curve has exactly one entry which is D(F)CT_Linear + // 2) Number of curve entries is > 3 and odd + // 3) curve[0] == DCT_Parametric and curve size is >= 8 and curve[1] .. curve[3] are ordered ascending and are distinct + if (curve.empty()) { + curve.push_back (DCT_Linear); + return true; + } else if(curve.size() == 1 && curve[0] != DCT_Linear) { + curve[0] = DCT_Linear; + return true; + } else if((curve.size() % 2 == 0 || curve.size() < 5) && curve[0] != DCT_Parametric) { + curve.clear(); + curve.push_back (DCT_Linear); + return true; + } else if(curve[0] == DCT_Parametric) { + if (curve.size() < 8) { + curve.clear(); + curve.push_back (DCT_Linear); + return true; + } else { + // curve[1] to curve[3] must be ordered ascending and distinct + for (int i = 1; i < 3; i++) { + if (curve[i] >= curve[i + 1]) { + curve[1] = 0.25f; + curve[2] = 0.5f; + curve[3] = 0.75f; + break; + } + } + } + } + return false; +} + Curve::Curve () : N(0), ppn(0), x(nullptr), y(nullptr), mc(0.0), mfc(0.0), msc(0.0), mhc(0.0), hashSize(1000 /* has to be initialized to the maximum value */), ypp(nullptr), x1(0.0), y1(0.0), x2(0.0), y2(0.0), x3(0.0), y3(0.0), firstPointIncluded(false), increment(0.0), nbr_points(0) {} void Curve::AddPolygons () diff --git a/rtengine/curves.h b/rtengine/curves.h index a9f4b4ace..30fb01102 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -19,9 +19,12 @@ #ifndef __CURVES_H__ #define __CURVES_H__ -#include #include #include +#include + +#include + #include "rt_math.h" #include "../rtgui/mycurve.h" #include "../rtgui/myflatcurve.h" @@ -42,6 +45,7 @@ using namespace std; namespace rtengine { + class ToneCurve; class ColorAppearance; @@ -55,6 +59,8 @@ void setUnlessOOG(T &r, T &g, T &b, const T &rr, const T &gg, const T &bb) } } +bool sanitizeCurve(std::vector& curve); + namespace curves { inline void setLutVal(const LUTf &lut, float &val) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 526a36765..b07778c55 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -87,13 +87,6 @@ Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool f return prefix + embedded_fname.substr(dir1.length()); } -void avoidEmptyCurve(std::vector &curve) -{ - if (curve.empty()) { - curve.push_back(FCT_Linear); - } -} - void getFromKeyfile( const Glib::KeyFile& keyfile, const Glib::ustring& group_name, @@ -142,7 +135,7 @@ void getFromKeyfile( ) { value = keyfile.get_double_list(group_name, key); - avoidEmptyCurve(value); + rtengine::sanitizeCurve(value); } template diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index a022c8650..c23b25f9a 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -32,6 +32,8 @@ #include "diagonalcurveeditorsubgroup.h" #include "rtimage.h" +#include "../rtengine/curves.h" + DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { @@ -814,6 +816,8 @@ void DiagonalCurveEditorSubGroup::loadPressed () } } + rtengine::sanitizeCurve(p); + if (p[0] == (double)(DCT_Spline)) { customCurve->setPoints (p); customCurve->queue_draw (); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 2cc96a184..27b7ac940 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -33,6 +33,8 @@ #include "flatcurveeditorsubgroup.h" #include "rtimage.h" +#include "../rtengine/curves.h" + FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { @@ -418,6 +420,8 @@ void FlatCurveEditorSubGroup::loadPressed () } } + rtengine::sanitizeCurve(p); + if (p[0] == (double)(FCT_MinMaxCPoints)) { CPointsCurve->setPoints (p); CPointsCurve->queue_draw ();