diff --git a/rtengine/curves.h b/rtengine/curves.h index 27cd9366c..bb2daab5b 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -61,8 +61,8 @@ class CurveFactory { return 0.0; double k = sqrt ((m1-1.0)*(m1-m2)/2) / (1.0-m2); double l = (m1-m2) / (1.0-m2) + k; - double lx = log(x); - return m2*x + (1.0-m2)*(2.0 - exp(k*lx))*exp(l*lx); + double lx = xlog(x); + return m2*x + (1.0-m2)*(2.0 - xexp(k*lx))*xexp(l*lx); } // basic concave function between (0,0) and (1,1). m1 and m2 controls the slope at the start and end point static inline double baseu (double x, double m1, double m2) { @@ -220,6 +220,12 @@ class Curve { int ppn; // targeted polyline point number double* x; double* y; + // begin of variables used in Parametric curves only + double mc; + double mfc; + double msc; + double mhc; + // end of variables used in Parametric curves only std::vector poly_x; // X points of the faceted curve std::vector poly_y; // Y points of the faceted curve std::vector hash; diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index 545759b4e..fe816b736 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -80,6 +80,11 @@ DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) { x[8] = 1.0; else x[8] = p[8]/100.0; + mc = -xlog(2.0)/xlog(x[2]); + double mbase = pfull (0.5, x[8], x[6], x[5]); + mfc = mbase<=1e-14 ? 0.0 : xexp(xlog(mbase)/mc); // value of the curve at the center point + msc = -xlog(2.0)/xlog(x[1]/x[2]); + mhc = -xlog(2.0)/xlog((x[3]-x[2])/(1-x[2])); } } if (identity) { @@ -221,28 +226,21 @@ double DiagonalCurve::getVal (double t) const { case DCT_Parametric : { if (t<=1e-14) return 0.0; - double c = -log(2.0)/log(x[2]); - double tv = exp(c*log(t)); + double tv = xexp(mc*xlog(t)); double base = pfull (tv, x[8], x[6], x[5]); - double stretched = base<=1e-14 ? 0.0 : exp(log(base)/c); + double stretched = base<=1e-14 ? 0.0 : xexp(xlog(base)/mc); - base = pfull (0.5, x[8], x[6], x[5]); - double fc = base<=1e-14 ? 0.0 : exp(log(base)/c); // value of the curve at the center point if (tgetVal( double(i)/65535.0 ); - } - - // if skip>1, let apply linear interpolation in the skipped points of the curve - if (skip > 1) { - int prev = 0; - for (int i=1; i<=0xffff-skip; i++) { - int iMod = i%skip; - if (!iMod) { - prev+=skip; - continue; - } - lutCurve[i] = ( lutCurve[prev] * (skip-iMod) + lutCurve[prev+skip]*iMod ) / skip; - } - } - - for (int i=0; i<=0xffff; i++) { - outCurve[i] = (65535.0f * lutCurve[i]); - } + outCurve[i] = 65535.f*diagCurve->getVal( double(i)/65535.0 ); + } } else { for (int i=0; i<=0xffff; i++) { outCurve[i] = float(i); } - } + } } - /* * Vibrance correction * copyright (c)2011 Jacques Desmis and Jean-Christophe Frisch @@ -88,10 +72,12 @@ void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool */ void ImProcFunctions::vibrance (LabImage* lab) { - int skip=1; //scale==1 ? 1 : 16; + if (!params->vibrance.enabled) + return; +// int skip=1; //scale==1 ? 1 : 16; bool skinCurveIsSet=false; DiagonalCurve* dcurve = NULL; - dcurve = new DiagonalCurve (params->vibrance.skintonescurve, CURVES_MIN_POLY_POINTS/skip); + dcurve = new DiagonalCurve (params->vibrance.skintonescurve, CURVES_MIN_POLY_POINTS); if (dcurve) { if (!dcurve->isIdentity()) { skinCurveIsSet = true; @@ -102,11 +88,11 @@ void ImProcFunctions::vibrance (LabImage* lab) { } } - if (!params->vibrance.enabled || (!skinCurveIsSet && !params->vibrance.pastels && !params->vibrance.saturated)) { + if (!skinCurveIsSet && !params->vibrance.pastels && !params->vibrance.saturated) { if (dcurve) { delete dcurve; dcurve = NULL; - } + } return; } @@ -121,8 +107,8 @@ void ImProcFunctions::vibrance (LabImage* lab) { // skin hue curve // I use diagonal because I think it's better LUTf skin_curve (65536,0); - - fillCurveArrayVib(dcurve, skin_curve, skip, skinCurveIsSet); + if(skinCurveIsSet) + fillCurveArrayVib(dcurve, skin_curve, skinCurveIsSet); if (dcurve) { delete dcurve; dcurve = NULL;