Merge
Demosaicing and pre-processing parameters selectable for each image. Dark frames subtraction and badpixels file support Fast loading in editor.
This commit is contained in:
@@ -51,7 +51,8 @@ Curve::Curve (const std::vector<double>& p, int poly_pn) : x(NULL), y(NULL), ypp
|
||||
if (kind==Spline)
|
||||
spline_cubic_set ();
|
||||
else if (kind==NURBS && N > 2)
|
||||
NURBS_set ();
|
||||
NURBS_set ();
|
||||
else kind=Linear;
|
||||
}
|
||||
else if (kind==Parametric) {
|
||||
if (p.size()!=8 && p.size()!=9)
|
||||
@@ -110,7 +111,7 @@ void Curve::NURBS_set () {
|
||||
|
||||
std::vector<double> sc_x(nbSubCurvesPoints); // X sub-curve points ( XP0,XP1,XP2, XP2,XP3,XP4, ...)
|
||||
std::vector<double> sc_y(nbSubCurvesPoints); // Y sub-curve points ( YP0,YP1,YP2, YP2,YP3,YP4, ...)
|
||||
std::vector<double> sc_length(N-2); // Length of the subcurves
|
||||
std::vector<double> sc_length(N+2); // Length of the subcurves
|
||||
double total_length=0.;
|
||||
|
||||
// Create the list of Bezier sub-curves
|
||||
@@ -120,6 +121,8 @@ void Curve::NURBS_set () {
|
||||
int k = 0;
|
||||
for (int i = 0; i < N-1;) {
|
||||
double length;
|
||||
double dx;
|
||||
double dy;
|
||||
|
||||
// first point (on the curve)
|
||||
if (!i) {
|
||||
@@ -146,7 +149,9 @@ void Curve::NURBS_set () {
|
||||
sc_x[j] = (x[i-1] + x[i]) / 2.;
|
||||
sc_y[j] = (y[i-1] + y[i]) / 2.;
|
||||
}
|
||||
length += sqrt(pow(sc_x[j] - sc_x[j-1],2) + pow(sc_y[j] - sc_y[j-1],2));
|
||||
dx = sc_x[j] - sc_x[j-1];
|
||||
dy = sc_y[j] - sc_y[j-1];
|
||||
length += sqrt(dx*dx + dy*dy);
|
||||
j++;
|
||||
|
||||
// Storing the length of all sub-curves and the total length (to have a better distribution
|
||||
@@ -155,24 +160,24 @@ void Curve::NURBS_set () {
|
||||
total_length += length;
|
||||
}
|
||||
|
||||
unsigned int total_points = 0;
|
||||
for (unsigned int i=0; i < sc_x.size(); i+=3) {
|
||||
total_points += (int)(((double)ppn+N-2) * sc_length[i/3] / total_length) + (i==0 ? 1 : 0) - 1;
|
||||
}
|
||||
poly_x.resize(total_points);
|
||||
poly_y.resize(total_points);
|
||||
|
||||
poly_x.clear();
|
||||
poly_y.clear();
|
||||
unsigned int sc_xsize=j-1;
|
||||
j = 0;
|
||||
// create the polyline with the number of points adapted to the X range of the sub-curve
|
||||
for (unsigned int i=0; i < sc_x.size(); i+=3) {
|
||||
for (unsigned int i=0; i < sc_xsize /*sc_x.size()*/; i+=3) {
|
||||
// TODO: Speeding-up the interface by caching the polyline, instead of rebuilding it at each action on sliders !!!
|
||||
int nbr_points = (int)(((double)ppn+N-2) * sc_length[i/3] / total_length);
|
||||
|
||||
int nbr_points = (int)(((double)(ppn+N-2) * sc_length[i/3] )/ total_length);
|
||||
if (nbr_points<0){
|
||||
for(int it=0;it < sc_x.size(); it+=3) printf("sc_length[%d/3]=%f \n",it,sc_length[it/3]);
|
||||
printf("NURBS: error detected!\n i=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f",i,nbr_points,ppn,N,sc_length[i/3],total_length);
|
||||
exit(0);
|
||||
}
|
||||
// increment along the curve, not along the X axis
|
||||
double increment = 1.0 / (double)(nbr_points-1);
|
||||
if (!i) {
|
||||
poly_x[j ] = sc_x[i];
|
||||
poly_y[j++] = sc_y[i];
|
||||
poly_x.push_back( sc_x[i]);
|
||||
poly_y.push_back(sc_y[i]);
|
||||
}
|
||||
for (k=1; k<(nbr_points-1); k++) {
|
||||
double t = k*increment;
|
||||
@@ -182,12 +187,12 @@ void Curve::NURBS_set () {
|
||||
double tr2t = tr*2*t;
|
||||
|
||||
// adding a point to the polyline
|
||||
poly_x[j ] = tr2*sc_x[i] + tr2t*sc_x[i+1] + t2*sc_x[i+2];
|
||||
poly_y[j++] = tr2*sc_y[i] + tr2t*sc_y[i+1] + t2*sc_y[i+2];
|
||||
poly_x.push_back( tr2*sc_x[i] + tr2t*sc_x[i+1] + t2*sc_x[i+2]);
|
||||
poly_y.push_back( tr2*sc_y[i] + tr2t*sc_y[i+1] + t2*sc_y[i+2]);
|
||||
}
|
||||
// adding the last point of the sub-curve
|
||||
poly_x[j ] = sc_x[i+2];
|
||||
poly_y[j++] = sc_y[i+2];
|
||||
poly_x.push_back( sc_x[i+2]);
|
||||
poly_y.push_back(sc_y[i+2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,8 +422,11 @@ if (igamma) {
|
||||
delete [] dcurve;
|
||||
}*/
|
||||
|
||||
/*
|
||||
void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector<double>& curvePoints, unsigned int* histogram, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) {
|
||||
|
||||
printf ("ecomp= %f black= %f hlcompr= %f shcompr= %f br= %f contr= %f defmul= %f gamma= %f, skip= %d \n",ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);
|
||||
|
||||
double def_mul = pow (2.0, defmul);
|
||||
|
||||
// compute parameters of the gamma curve
|
||||
@@ -428,7 +436,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
||||
double add = 0.099;
|
||||
|
||||
// theoretical maximum of the curve
|
||||
double D = /* gamma_>0 ? gamma (def_mul, gamma_, start, slope, mul, add) : */ def_mul;
|
||||
double D = def_mul;
|
||||
|
||||
// a: slope of the curve, black: starting point at the x axis
|
||||
double a = pow (2.0, ecomp);
|
||||
@@ -450,9 +458,6 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
||||
// clear array that stores histogram valid before applying the custom curve
|
||||
if (outBeforeCCurveHistogram)
|
||||
memset (outBeforeCCurveHistogram, 0, 256*sizeof(int));
|
||||
|
||||
//float atmp=a;
|
||||
//a = 1;
|
||||
|
||||
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
|
||||
|
||||
@@ -461,13 +466,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
||||
|
||||
// apply default multiplier (that is >1 if highlight recovery is on)
|
||||
val *= def_mul;
|
||||
|
||||
//exposure compensation
|
||||
//val *= atmp;
|
||||
//black *= atmp;
|
||||
//D *= atmp;
|
||||
|
||||
|
||||
|
||||
// apply base curve, thus, exposure compensation and black point with shadow and highlight protection
|
||||
val = basecurve (val, a, black, D, hlcompr/100.0, shcompr/100.0);
|
||||
|
||||
@@ -539,7 +538,391 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
||||
outCurve[i] = (int) (65535.0 * dcurve[i]);
|
||||
delete [] dcurve;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void CurveFactory::complexsgnCurve (double satclip, double satcompr, double saturation, double colormult, const std::vector<double>& curvePoints, int* outCurve, int skip) {
|
||||
|
||||
//colormult = chroma_scale for Lab manipulations
|
||||
|
||||
bool needsaturation = (saturation<-0.0001 || saturation>0.0001);
|
||||
|
||||
// curve without contrast
|
||||
double* dcurve = new double[65536];
|
||||
|
||||
// create a curve if needed
|
||||
Curve* tcurve = NULL;
|
||||
if (curvePoints.size()>0 && curvePoints[0]!=0)
|
||||
tcurve = new Curve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
|
||||
|
||||
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
|
||||
|
||||
// change to [0,1] range
|
||||
double val = (double)i / 65535.0;
|
||||
|
||||
// apply default multiplier (that is >1 if highlight recovery is on)
|
||||
val *= colormult;
|
||||
|
||||
// apply base curve, thus, exposure compensation and black point with shadow and highlight protection
|
||||
//val = basecurve (val, 1.0, 0, colormult, satcompr/100.0, satcompr/100.0);
|
||||
|
||||
// apply custom/parametric/NURBS curve, if any
|
||||
if (tcurve) {
|
||||
val = tcurve->getVal (val);
|
||||
}
|
||||
|
||||
// store result in a temporary array
|
||||
dcurve[i] = CLIPD(val);
|
||||
}
|
||||
delete tcurve;
|
||||
|
||||
// if skip>1, let apply linear interpolation in the skipped points of the curve
|
||||
int prev = 0;
|
||||
for (int i=1; i<=0xffff-skip; i++) {
|
||||
if (i%skip==0) {
|
||||
prev+=skip;
|
||||
continue;
|
||||
}
|
||||
dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip;
|
||||
}
|
||||
|
||||
if (needsaturation) {
|
||||
float avg = 0.5;
|
||||
|
||||
// compute contrast parameter
|
||||
double saturation_b = saturation / 20;
|
||||
if (saturation_b>=0 && saturation_b < 0.00001)
|
||||
saturation_b = 0.00001;
|
||||
else if (saturation_b<0 && saturation_b > -0.00001)
|
||||
saturation_b = -0.00001;
|
||||
|
||||
// apply contrast enhancement
|
||||
for (int i=0; i<=0xffff; i++) {
|
||||
double val = centercontrast (dcurve[i], saturation_b, avg);
|
||||
outCurve[i] = (int) (65535.0 * CLIPD(val));
|
||||
}
|
||||
}
|
||||
else
|
||||
for (int i=0; i<=0xffff; i++)
|
||||
outCurve[i] = (int) (65535.0 * dcurve[i]);
|
||||
delete [] dcurve;
|
||||
}
|
||||
*/
|
||||
|
||||
void CurveFactory::complexsgnCurve (double satclip, double satcompr, double saturation, double colormult, const std::vector<double>& curvePoints, int* outCurve, int skip) {
|
||||
|
||||
//colormult = chroma_scale for Lab manipulations
|
||||
|
||||
// check if contrast curve is needed
|
||||
bool needsaturation = (saturation<-0.0001 || saturation>0.0001);
|
||||
|
||||
// curve without contrast
|
||||
double* dcurve = new double[65536];
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
std::vector<double> satcurvePoints;
|
||||
satcurvePoints.push_back((double)((CurveType)NURBS));
|
||||
if (saturation>0) {
|
||||
satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
|
||||
satcurvePoints.push_back(0.25+saturation/500.0); //toe point
|
||||
satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point
|
||||
|
||||
satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point
|
||||
satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point
|
||||
|
||||
satcurvePoints.push_back(1); // white point
|
||||
satcurvePoints.push_back(1); // value at white point
|
||||
} else {
|
||||
satcurvePoints.push_back(0);
|
||||
satcurvePoints.push_back(-0.5*(saturation/100.0));
|
||||
|
||||
satcurvePoints.push_back(1);
|
||||
satcurvePoints.push_back(1+saturation/200.0);
|
||||
}
|
||||
Curve* satcurve = NULL;
|
||||
satcurve = new Curve (satcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
// create a curve if needed
|
||||
Curve* tcurve = NULL;
|
||||
if (curvePoints.size()>0 && curvePoints[0]!=0)
|
||||
tcurve = new Curve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
|
||||
|
||||
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
|
||||
|
||||
// change to [0,1] range
|
||||
double val = (double)i / 65535.0;
|
||||
|
||||
// apply default multiplier (that is >1 if highlight recovery is on)
|
||||
val *= colormult;
|
||||
|
||||
// apply saturation curve
|
||||
if (needsaturation)
|
||||
val = satcurve->getVal (val);
|
||||
|
||||
// apply custom/parametric/NURBS curve, if any
|
||||
if (tcurve) {
|
||||
val = tcurve->getVal (val);
|
||||
}
|
||||
|
||||
// store result in a temporary array
|
||||
dcurve[i] = CLIPD(val);
|
||||
}
|
||||
delete tcurve;
|
||||
|
||||
// if skip>1, let apply linear interpolation in the skipped points of the curve
|
||||
int prev = 0;
|
||||
for (int i=1; i<=0xffff-skip; i++) {
|
||||
if (i%skip==0) {
|
||||
prev+=skip;
|
||||
continue;
|
||||
}
|
||||
dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip;
|
||||
}
|
||||
|
||||
for (int i=0; i<=0xffff; i++)
|
||||
outCurve[i] = (int) (65535.0 * dcurve[i]);
|
||||
delete [] dcurve;
|
||||
delete satcurve;
|
||||
}
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector<double>& curvePoints, unsigned int* histogram, int* outCurve1, int* outCurve2, unsigned int* outBeforeCCurveHistogram, int skip) {
|
||||
|
||||
double def_mul = pow (2.0, defmul);
|
||||
|
||||
//printf ("def_mul= %f ecomp= %f black= %f hlcompr= %f shcompr= %f br= %f contr= %f defmul= %f gamma= %f, skip= %d \n",def_mul,ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);
|
||||
|
||||
// compute parameters of the gamma curve
|
||||
double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 )));
|
||||
double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start;
|
||||
double mul = 1.099;
|
||||
double add = 0.099;
|
||||
|
||||
// a: slope of the curve, black: starting point at the x axis
|
||||
double a = pow (2.0, ecomp);
|
||||
|
||||
// curve without contrast
|
||||
double* dcurve = new double[65536];
|
||||
|
||||
// check if contrast curve is needed
|
||||
bool needcontrast = contr>0.00001 || contr<-0.00001;
|
||||
|
||||
// check if inverse gamma is needed at the end
|
||||
bool needigamma = !needcontrast && igamma && gamma_>0;
|
||||
|
||||
// create a curve if needed
|
||||
Curve* tcurve = NULL;
|
||||
if (curvePoints.size()>0 && curvePoints[0]!=0)
|
||||
tcurve = new Curve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
|
||||
|
||||
// clear array that stores histogram valid before applying the custom curve
|
||||
if (outBeforeCCurveHistogram)
|
||||
memset (outBeforeCCurveHistogram, 0, 256*sizeof(int));
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery
|
||||
|
||||
std::vector<double> basecurvePoints;
|
||||
basecurvePoints.push_back((double)((CurveType)NURBS));
|
||||
//float toex = MIN(1,black/(a*def_mul));
|
||||
//float toey = MAX(0,toex*a*def_mul*(shcompr/25.0-1));
|
||||
float toex = black;
|
||||
float toey = MAX(0,toex*(shcompr/25.0-1));
|
||||
float shoulderx = MAX(black,1/(a*def_mul));//point in x at which line of slope a starting at (0,0) reaches y=1
|
||||
float shouldery=1;
|
||||
float toneslope=(shouldery-toey)/(shoulderx-toex);
|
||||
if (shoulderx<1) {//a>1; positive EC
|
||||
//move shoulder down if there is highlight rolloff
|
||||
shouldery = shouldery-(0.3)*(hlcompr/100.0);
|
||||
shoulderx = shoulderx - (1-shouldery)/toneslope;
|
||||
} else {//a<1; negative EC
|
||||
//if (shoulderx>1) {
|
||||
shoulderx = 1;
|
||||
shouldery = a*def_mul;
|
||||
}
|
||||
/*float shoulderx = toex+(1-toey)/a;//point in x at which line of slope a starting at toe point reaches y=1
|
||||
float shouldery;
|
||||
if (shoulderx<1) {
|
||||
shouldery = MAX(2*toey, 1-(1-shoulderx)*(hlcompr/200.0));
|
||||
shoulderx = shoulderx - (1-shouldery)/a;
|
||||
} else {
|
||||
shoulderx = 1;
|
||||
shouldery = toey + (1-toex)*a;
|
||||
}*/
|
||||
|
||||
basecurvePoints.push_back(MAX(0,0.99*toex*(1-shcompr/25.0))); //black point. Value in [0 ; 1] range
|
||||
basecurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
|
||||
basecurvePoints.push_back(toex); //toe point
|
||||
basecurvePoints.push_back(toey); //value at toe point
|
||||
|
||||
if (toex<1) {
|
||||
//add a point along the line between the toe point and shoulder point
|
||||
basecurvePoints.push_back(0.4*toex+0.6*shoulderx); //mid point
|
||||
basecurvePoints.push_back(0.4*toey+0.6*shouldery); //value at mid point
|
||||
|
||||
basecurvePoints.push_back(shoulderx); //shoulder point
|
||||
basecurvePoints.push_back(shouldery); //value at shoulder point
|
||||
if (shoulderx<1) {
|
||||
basecurvePoints.push_back(1-0.95*(1-shoulderx)*(1-hlcompr/105.0)); // lead into point
|
||||
basecurvePoints.push_back(1); // value near white point
|
||||
basecurvePoints.push_back(1); // white point
|
||||
basecurvePoints.push_back(1); // value at white point
|
||||
}
|
||||
}
|
||||
Curve* basecurve = NULL;
|
||||
basecurve = new Curve (basecurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
std::vector<double> brightcurvePoints;
|
||||
brightcurvePoints.push_back((double)((CurveType)NURBS));
|
||||
|
||||
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
|
||||
if(br>0) {
|
||||
brightcurvePoints.push_back(0.1); //toe point
|
||||
brightcurvePoints.push_back(0.1+br/150.0); //value at toe point
|
||||
|
||||
brightcurvePoints.push_back(0.7); //shoulder point
|
||||
brightcurvePoints.push_back(MIN(1.0,0.7+br/300.0)); //value at shoulder point
|
||||
} else {
|
||||
brightcurvePoints.push_back(0.1-br/150.0); //toe point
|
||||
brightcurvePoints.push_back(0.1); //value at toe point
|
||||
|
||||
brightcurvePoints.push_back(MIN(1.0,0.7-br/300.0)); //shoulder point
|
||||
brightcurvePoints.push_back(0.7); //value at shoulder point
|
||||
}
|
||||
brightcurvePoints.push_back(1); // white point
|
||||
brightcurvePoints.push_back(1); // value at white point
|
||||
|
||||
Curve* brightcurve = NULL;
|
||||
brightcurve = new Curve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
|
||||
|
||||
// change to [0,1] range
|
||||
double val = (double)i / 65535.0;
|
||||
|
||||
// apply default multiplier (that is >1 if highlight recovery is on)
|
||||
// val *= def_mul;
|
||||
|
||||
// apply base curve, thus, exposure compensation and black point with shadow and highlight protection
|
||||
//val = basecurve (val, a, black, def_mul, hlcompr/100.0, shcompr/100.0);
|
||||
val = basecurve->getVal (val);
|
||||
|
||||
outCurve1[i] = (int) (65535.0 * CLIPD(val));
|
||||
|
||||
// change to [0,1] range
|
||||
val = (double)i / 65535.0;
|
||||
|
||||
// gamma correction
|
||||
if (gamma_>0)
|
||||
val = gamma (val, gamma_, start, slope, mul, add);
|
||||
|
||||
// apply brightness curve
|
||||
//val = brightness (val, br/100.0);
|
||||
val = brightcurve->getVal (val);
|
||||
|
||||
// apply custom/parametric/NURBS curve, if any
|
||||
if (tcurve) {
|
||||
if (outBeforeCCurveHistogram) {
|
||||
double hval = val;
|
||||
//if (needigamma)
|
||||
// hval = igamma2 (hval);
|
||||
int hi = (int)(255.0*CLIPD(hval));
|
||||
outBeforeCCurveHistogram[hi]+=histogram[i] ;
|
||||
}
|
||||
val = tcurve->getVal (val);
|
||||
}
|
||||
|
||||
// if inverse gamma is needed, do it (standard sRGB inverse gamma is applied)
|
||||
if (needigamma)
|
||||
val = igamma2 (val);
|
||||
|
||||
// store result in a temporary array
|
||||
dcurve[i] = CLIPD(val);
|
||||
}
|
||||
delete tcurve;
|
||||
|
||||
delete basecurve; // ...when you don't need it anymore
|
||||
delete brightcurve;
|
||||
|
||||
// if skip>1, let apply linear interpolation in the skipped points of the curve
|
||||
int prev = 0;
|
||||
for (int i=1; i<=0xffff-skip; i++) {
|
||||
if (i%skip==0) {
|
||||
prev+=skip;
|
||||
continue;
|
||||
}
|
||||
outCurve1[i] = ( outCurve1[prev] * (skip - i%skip) + outCurve1[prev+skip] * (i%skip) ) / skip;
|
||||
dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip;
|
||||
}
|
||||
|
||||
if (needcontrast) {
|
||||
// compute mean luminance of the image with the curve applied
|
||||
int sum = 0;
|
||||
double avg = 0;
|
||||
//double sqavg = 0;
|
||||
for (int i=0; i<=0xffff; i++) {
|
||||
avg += dcurve[i] * histogram[i];
|
||||
//sqavg += dcurve[i]*dcurve[i] * histogram[i];
|
||||
sum += histogram[i];
|
||||
}
|
||||
avg /= sum;
|
||||
//sqavg /= sum;
|
||||
//double stddev = sqrt(sqavg-avg*avg);
|
||||
float contrslope = (50)/(50-0.25*contr);
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
std::vector<double> contrastcurvePoints;
|
||||
contrastcurvePoints.push_back((double)((CurveType)NURBS));
|
||||
|
||||
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
|
||||
contrastcurvePoints.push_back(avg*(1-1/contrslope)); //toe point
|
||||
contrastcurvePoints.push_back(0); //value at toe point
|
||||
|
||||
contrastcurvePoints.push_back(avg); //mid point
|
||||
contrastcurvePoints.push_back(avg); //value at mid point
|
||||
|
||||
contrastcurvePoints.push_back(avg+(1-avg)/contrslope); // shoulder point
|
||||
contrastcurvePoints.push_back(1); // value at shoulder point
|
||||
|
||||
contrastcurvePoints.push_back(1); // white point
|
||||
contrastcurvePoints.push_back(1); // value at white point
|
||||
|
||||
Curve* contrastcurve = NULL;
|
||||
contrastcurve = new Curve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
// apply contrast enhancement
|
||||
for (int i=0; i<=0xffff; i++) {
|
||||
//double val = centercontrast (dcurve[i], contr_b, avg);
|
||||
double val = contrastcurve->getVal (dcurve[i]);
|
||||
if (igamma && gamma_>0)
|
||||
val = igamma2 (val);
|
||||
outCurve2[i] = (int) (65535.0 * CLIPD(val));
|
||||
}
|
||||
}
|
||||
else
|
||||
for (int i=0; i<=0xffff; i++)
|
||||
outCurve2[i] = (int) (65535.0 * dcurve[i]);
|
||||
delete [] dcurve;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
|
||||
int CurveFactory::gammatab [65536];
|
||||
int CurveFactory::igammatab_srgb [65536];
|
||||
|
Reference in New Issue
Block a user