Speedup for Parametric Curves, Issue 2021
This commit is contained in:
@@ -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<double> poly_x; // X points of the faceted curve
|
||||
std::vector<double> poly_y; // Y points of the faceted curve
|
||||
std::vector<HashEntry> hash;
|
||||
|
@@ -80,6 +80,11 @@ DiagonalCurve::DiagonalCurve (const std::vector<double>& 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 (t<x[2]) {
|
||||
// add shadows effect:
|
||||
double sc = -log(2.0)/log(x[1]/x[2]);
|
||||
double stv = exp(sc*log(stretched/fc));
|
||||
double stv = xexp(msc*xlog(stretched/mfc));
|
||||
double sbase = pfull (stv, x[8], x[7], 0.5);
|
||||
double sstretched = fc*(sbase<=1e-14 ? 0.0 : exp(log(sbase)/sc));
|
||||
return sstretched;
|
||||
return mfc*(sbase<=1e-14 ? 0.0 : xexp(xlog(sbase)/msc));
|
||||
}
|
||||
else {
|
||||
// add highlights effect:
|
||||
double hc = -log(2.0)/log((x[3]-x[2])/(1-x[2]));
|
||||
double htv = exp(hc*log((stretched-fc)/(1-fc)));
|
||||
double htv = xexp(mhc*xlog((stretched-mfc)/(1-mfc)));
|
||||
double hbase = pfull (htv, x[8], 0.5, x[4]);
|
||||
double hstretched = fc + (1-fc)*(hbase<=1e-14 ? 0.0 : exp(log(hbase)/hc));
|
||||
return hstretched;
|
||||
return mfc + (1-mfc)*(hbase<=1e-14 ? 0.0 : xexp(xlog(hbase)/mhc));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -44,43 +44,27 @@ using namespace procparams;
|
||||
|
||||
extern const Settings* settings;
|
||||
|
||||
void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) {
|
||||
if (needed && diagCurve) {
|
||||
LUTf lutCurve (65536);
|
||||
void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve, bool needed) {
|
||||
|
||||
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
|
||||
if (needed && diagCurve) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (int i=0; i<=0xffff; i++ ) {
|
||||
// change to [0,1] range
|
||||
// apply custom/parametric/NURBS curve, if any
|
||||
// and store result in a temporary array
|
||||
lutCurve[i] = diagCurve->getVal( 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 <jdesmis@gmail.com> and Jean-Christophe Frisch <natureh@free.fr>
|
||||
@@ -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;
|
||||
|
Reference in New Issue
Block a user