Modifications to exposure controls to prevent color shifts in highlights.
This commit is contained in:
@@ -587,7 +587,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
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) {
|
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* hlCurve, int* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) {
|
||||||
|
|
||||||
double def_mul = pow (2.0, defmul);
|
double def_mul = pow (2.0, defmul);
|
||||||
|
|
||||||
@@ -622,57 +622,47 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery
|
// 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 blackx = MIN(1,black/(a*def_mul));
|
||||||
|
float whitex = 1/(a*def_mul);//point in x at which line of slope a*def_mul starting at (0,0) reaches y=1
|
||||||
|
float toneslope=(1-0)/(shoulderx-toex);
|
||||||
|
toey = 0.01 + 0.3*(MAX(0,shcompr/100.0-0.25));
|
||||||
|
toex = blackx + toey/toneslope;
|
||||||
|
if (whitex<1) {//a>1; positive EC
|
||||||
|
//move shoulder down if there is highlight rolloff
|
||||||
|
shouldery = 1-(0.3)*(MAX(0,hlcompr/100.0-0.25));
|
||||||
|
shoulderx = whitex - (1-shouldery)/toneslope;
|
||||||
|
} else {//a<1; negative EC
|
||||||
|
//if (shoulderx>1) {
|
||||||
|
shoulderx = 1;
|
||||||
|
shouldery = a*def_mul;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> basecurvePoints;
|
basecurvePoints.push_back(MAX(0,blackx*(1-shcompr/25.0))); //black point. Value in [0 ; 1] range
|
||||||
basecurvePoints.push_back((double)((CurveType)NURBS));
|
basecurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||||
float toex = MIN(1,black/(a*def_mul));
|
|
||||||
float toey = 0;//MAX(0,toex*a*def_mul*(shcompr/50.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);
|
|
||||||
toey = toey + 0.25*(shcompr/100.0);
|
|
||||||
toex = toex + toey/toneslope;
|
|
||||||
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/33.0))); //black point. Value in [0 ; 1] range
|
basecurvePoints.push_back(toex); //toe point
|
||||||
basecurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
basecurvePoints.push_back(toey); //value at toe point
|
||||||
|
|
||||||
basecurvePoints.push_back(toex); //toe point
|
if (toex<1) {
|
||||||
basecurvePoints.push_back(toey); //value at toe point
|
//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
|
||||||
|
|
||||||
if (toex<1) {
|
basecurvePoints.push_back(shoulderx); //shoulder point
|
||||||
//add a point along the line between the toe point and shoulder point
|
basecurvePoints.push_back(shouldery); //value at shoulder point
|
||||||
basecurvePoints.push_back(0.4*toex+0.6*shoulderx); //mid point
|
if (shoulderx<1) {
|
||||||
basecurvePoints.push_back(0.4*toey+0.6*shouldery); //value at mid point
|
basecurvePoints.push_back(MIN(0.99,whitex+0.01+(1-whitex-0.01)*(hlcompr/70.0)); // lead into white point
|
||||||
|
basecurvePoints.push_back(1); // value near white point
|
||||||
basecurvePoints.push_back(shoulderx); //shoulder point
|
basecurvePoints.push_back(1); // white point
|
||||||
basecurvePoints.push_back(shouldery); //value at shoulder point
|
basecurvePoints.push_back(1); // value at white 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
|
Curve* basecurve = NULL;
|
||||||
basecurvePoints.push_back(1); // white point
|
basecurve = new Curve (basecurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||||
basecurvePoints.push_back(1); // value at white point
|
*/
|
||||||
}
|
|
||||||
}
|
|
||||||
Curve* basecurvenew = NULL;
|
|
||||||
basecurvenew = new Curve (basecurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
std::vector<double> brightcurvePoints;
|
std::vector<double> brightcurvePoints;
|
||||||
@@ -710,11 +700,21 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
// val *= def_mul;
|
// val *= def_mul;
|
||||||
|
|
||||||
// apply base curve, thus, exposure compensation and black point with shadow and highlight protection
|
// apply base curve, thus, exposure compensation and black point with shadow and highlight protection
|
||||||
//val = basecurve (val*def_mul, a, black, def_mul, hlcompr/70.0, shcompr/70.0);
|
val = basecurve (val*def_mul, a, 0, def_mul, hlcompr/100.0, 0);
|
||||||
val = basecurvenew->getVal (val);
|
//val = basecurve (val*def_mul, a, black, def_mul, hlcompr/100.0, 1.5*shcompr/100.0);
|
||||||
|
//val = basecurvenew->getVal (val);
|
||||||
|
|
||||||
outCurve1[i] = (int) (65535.0 * CLIPD(val));
|
hlCurve[i] = (int) (65535.0 * CLIPD(val));
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
// change to [0,1] range
|
||||||
|
val = (double)i / 65535.0;
|
||||||
|
|
||||||
|
val = basecurve (val, 1, black, def_mul, 1, 1.5*shcompr/100.0);
|
||||||
|
|
||||||
|
shCurve[i] = (int) (65535.0 * CLIPD(val));
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// change to [0,1] range
|
// change to [0,1] range
|
||||||
val = (double)i / 65535.0;
|
val = (double)i / 65535.0;
|
||||||
|
|
||||||
@@ -747,7 +747,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
}
|
}
|
||||||
delete tcurve;
|
delete tcurve;
|
||||||
|
|
||||||
delete basecurvenew; // ...when you don't need it anymore
|
//delete basecurvenew; // ...when you don't need it anymore
|
||||||
delete brightcurve;
|
delete brightcurve;
|
||||||
|
|
||||||
// if skip>1, let apply linear interpolation in the skipped points of the curve
|
// if skip>1, let apply linear interpolation in the skipped points of the curve
|
||||||
@@ -757,7 +757,8 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
prev+=skip;
|
prev+=skip;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
outCurve1[i] = ( outCurve1[prev] * (skip - i%skip) + outCurve1[prev+skip] * (i%skip) ) / skip;
|
hlCurve[i] = ( hlCurve[prev] * (skip - i%skip) + hlCurve[prev+skip] * (i%skip) ) / skip;
|
||||||
|
shCurve[i] = ( shCurve[prev] * (skip - i%skip) + shCurve[prev+skip] * (i%skip) ) / skip;
|
||||||
dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip;
|
dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,12 +805,12 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
|
|||||||
double val = contrastcurve->getVal (dcurve[i]);
|
double val = contrastcurve->getVal (dcurve[i]);
|
||||||
if (igamma && gamma_>0)
|
if (igamma && gamma_>0)
|
||||||
val = igamma2 (val);
|
val = igamma2 (val);
|
||||||
outCurve2[i] = (int) (65535.0 * CLIPD(val));
|
outCurve[i] = (int) (65535.0 * CLIPD(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (int i=0; i<=0xffff; i++)
|
for (int i=0; i<=0xffff; i++)
|
||||||
outCurve2[i] = (int) (65535.0 * dcurve[i]);
|
outCurve[i] = (int) (65535.0 * dcurve[i]);
|
||||||
delete [] dcurve;
|
delete [] dcurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -73,17 +73,26 @@ class CurveFactory {
|
|||||||
// concave curve between (0,0) and (1,1) with slope m at (1,1). sr controls the shadow recovery
|
// concave curve between (0,0) and (1,1) with slope m at (1,1). sr controls the shadow recovery
|
||||||
static inline double clower (double x, double m, double sr) {
|
static inline double clower (double x, double m, double sr) {
|
||||||
return 1.0 - cupper(1.0-x, m, sr);
|
return 1.0 - cupper(1.0-x, m, sr);
|
||||||
|
}
|
||||||
|
// convex curve between (0,0) and (1,1) with slope m at (0,0). hr controls the highlight recovery
|
||||||
|
static inline double cupper2 (double x, double m, double hr) {
|
||||||
|
double x1 = (1.0-hr)/m;
|
||||||
|
double x2 = x1 + hr;
|
||||||
|
if (x>=x2) return 1.0;
|
||||||
|
if (x<x1) return x*m;
|
||||||
|
return 1.0 - hr + hr*baseu((x-x1)/hr, m, 0.3*hr);
|
||||||
}
|
}
|
||||||
// tone curve base. a: slope (from exp.comp.), b: black, D: max. x value (can be>1), hr,sr: highlight,shadow recovery
|
// tone curve base. a: slope (from exp.comp.), b: black, D: max. x value (can be>1), hr,sr: highlight,shadow recovery
|
||||||
static inline double basecurve (double x, double a, double b, double D, double hr, double sr) {
|
static inline double basecurve (double x, double a, double b, double D, double hr, double sr) {
|
||||||
double m = b+0.5/a<D ? b+0.5/a : D;
|
double m = a>1 ? b+0.25*(1-b)/a : b+(1-b)/4;
|
||||||
double y = (D-b)*a<0.5 ? (D-b)*a : 0.5;
|
double y = a>1 ? 0.25 : 0.25*a;
|
||||||
|
double slope = a/(1-b);
|
||||||
if (x<=m)
|
if (x<=m)
|
||||||
return b==0 ? x*a : clower (x/m, a*m/y, sr) * y;
|
return b==0 ? x*a : clower (x/m, slope*m/y, sr) * y;
|
||||||
else if (b+1.0/a<D)
|
else if (a>1)
|
||||||
return y+(1.0-y)*cupper((x-m)/(D-m), a*(D-m)/(1.0-y), hr);
|
return y+(1.0-y)*cupper2((x-m)/(1-m), slope*(1-m)/(1.0-y), hr);
|
||||||
else
|
else
|
||||||
return y+(x-m)*a;
|
return y+(x-m)*slope;
|
||||||
}
|
}
|
||||||
// brightness curve at point x, only positive amount it supported
|
// brightness curve at point x, only positive amount it supported
|
||||||
static inline double brightnessbase (double x, double amount) {
|
static inline double brightnessbase (double x, double amount) {
|
||||||
@@ -128,7 +137,7 @@ class CurveFactory {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// static void updateCurve3 (int* curve, int* ohistogram, const std::vector<double>& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1);
|
// static void updateCurve3 (int* curve, int* ohistogram, const std::vector<double>& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1);
|
||||||
static void 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=1);
|
static void 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* hlCurve, int* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1);
|
||||||
static void complexsgnCurve (double satclip, double satcompr, double saturation, double colormult, const std::vector<double>& curvePoints, int* outCurve, int skip=1);
|
static void complexsgnCurve (double satclip, double satcompr, double saturation, double colormult, const std::vector<double>& curvePoints, int* outCurve, int skip=1);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -167,12 +167,12 @@ void Crop::update (int todo, bool internal) {
|
|||||||
|
|
||||||
// shadows & highlights & tone curve & convert to cielab
|
// shadows & highlights & tone curve & convert to cielab
|
||||||
if (todo & M_RGBCURVE)
|
if (todo & M_RGBCURVE)
|
||||||
parent->ipf.rgbProc (baseCrop, laboCrop, parent->tonecurve1, parent->tonecurve2, cshmap);
|
parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap);
|
||||||
|
|
||||||
|
|
||||||
// apply luminance operations
|
// apply luminance operations
|
||||||
if (todo & (M_LUMINANCE+M_COLOR)) {
|
if (todo & (M_LUMINANCE+M_COLOR)) {
|
||||||
parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve2, 0, croph);
|
parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve, 0, croph);
|
||||||
parent->ipf.chrominanceCurve (laboCrop, labnCrop, 0, parent->chroma_acurve, 0, croph);
|
parent->ipf.chrominanceCurve (laboCrop, labnCrop, 0, parent->chroma_acurve, 0, croph);
|
||||||
parent->ipf.chrominanceCurve (laboCrop, labnCrop, 1, parent->chroma_bcurve, 0, croph);
|
parent->ipf.chrominanceCurve (laboCrop, labnCrop, 1, parent->chroma_bcurve, 0, croph);
|
||||||
|
|
||||||
|
@@ -166,8 +166,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
|||||||
|
|
||||||
progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases);
|
progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases);
|
||||||
if (todo & M_RGBCURVE) {
|
if (todo & M_RGBCURVE) {
|
||||||
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, vhist16, tonecurve1, tonecurve2, bcrgbhist, scale==1 ? 1 : 1);
|
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, vhist16, hltonecurve, shtonecurve, tonecurve, bcrgbhist, scale==1 ? 1 : 1);
|
||||||
ipf.rgbProc (oprevi, oprevl, tonecurve1, tonecurve2, shmap);
|
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap);
|
||||||
|
|
||||||
// recompute luminance histogram
|
// recompute luminance histogram
|
||||||
memset (lhist16, 0, 65536*sizeof(int));
|
memset (lhist16, 0, 65536*sizeof(int));
|
||||||
@@ -178,7 +178,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
|||||||
readyphase++;
|
readyphase++;
|
||||||
|
|
||||||
if (todo & M_LUMACURVE) {
|
if (todo & M_LUMACURVE) {
|
||||||
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, lhist16, lumacurve1, lumacurve2, bcLhist, scale==1 ? 1 : 16);
|
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, lhist16, chroma_acurve, chroma_bcurve, lumacurve, bcLhist, scale==1 ? 1 : 16);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, chroma_acurve, scale==1 ? 1 : 16);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, chroma_acurve, scale==1 ? 1 : 16);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, chroma_bcurve, scale==1 ? 1 : 16);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, chroma_bcurve, scale==1 ? 1 : 16);
|
||||||
}
|
}
|
||||||
@@ -186,7 +186,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
|||||||
|
|
||||||
if (todo & (M_LUMINANCE+M_COLOR) ) {
|
if (todo & (M_LUMINANCE+M_COLOR) ) {
|
||||||
progress ("Applying Luminance Curve...",100*readyphase/numofphases);
|
progress ("Applying Luminance Curve...",100*readyphase/numofphases);
|
||||||
ipf.luminanceCurve (oprevl, nprevl, lumacurve2, 0, pH);
|
ipf.luminanceCurve (oprevl, nprevl, lumacurve, 0, pH);
|
||||||
|
|
||||||
readyphase++;
|
readyphase++;
|
||||||
progress ("Applying Color Boost...",100*readyphase/numofphases);
|
progress ("Applying Color Boost...",100*readyphase/numofphases);
|
||||||
|
@@ -62,11 +62,11 @@ class ImProcCoordinator : public StagedImageProcessor {
|
|||||||
|
|
||||||
void freeAll ();
|
void freeAll ();
|
||||||
|
|
||||||
int tonecurve1 [65536];
|
int hltonecurve [65536];
|
||||||
int tonecurve2 [65536];
|
int shtonecurve [65536];
|
||||||
|
int tonecurve [65536];
|
||||||
|
|
||||||
int lumacurve1 [65536];
|
int lumacurve [65536];
|
||||||
int lumacurve2 [65536];
|
|
||||||
int chroma_acurve [65536];
|
int chroma_acurve [65536];
|
||||||
int chroma_bcurve [65536];
|
int chroma_bcurve [65536];
|
||||||
|
|
||||||
|
@@ -245,7 +245,7 @@ void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params
|
|||||||
delete [] hist;
|
delete [] hist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve1, int* tonecurve2, SHMap* shmap) {
|
void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* hltonecurve, int* shtonecurve, int* tonecurve, SHMap* shmap) {
|
||||||
|
|
||||||
int h_th, s_th;
|
int h_th, s_th;
|
||||||
if (shmap) {
|
if (shmap) {
|
||||||
@@ -321,42 +321,34 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve1,
|
|||||||
b = CLIP((int)(factor*b));
|
b = CLIP((int)(factor*b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*r = tonecurve[r];
|
|
||||||
g = tonecurve[g];
|
|
||||||
b = tonecurve[b];*/
|
|
||||||
int Y = (0.299*r + 0.587*g + 0.114*b);
|
|
||||||
int Ynew = tonecurve1[Y];
|
|
||||||
float tonefactor = (Y>0 ? (float)Ynew/Y : 1);
|
|
||||||
|
|
||||||
|
//highlight tone curve
|
||||||
|
/*r = tonecurve[r];
|
||||||
|
g = tonecurve[g];
|
||||||
|
b = tonecurve[b];*/
|
||||||
|
//int Y = (int)(0.299*r + 0.587*g + 0.114*b);
|
||||||
|
//float tonefactor = (Y>0 ? (float)tonecurve1[Y]/Y : 1);
|
||||||
|
float rtonefactor = (r>0 ? (float)hltonecurve[r]/r : 1);
|
||||||
|
float gtonefactor = (g>0 ? (float)hltonecurve[g]/g : 1);
|
||||||
|
float btonefactor = (b>0 ? (float)hltonecurve[b]/b : 1);
|
||||||
|
//float tonefactor = MIN(rtonefactor, MIN(gtonefactor,btonefactor));
|
||||||
|
float tonefactor = (rtonefactor+gtonefactor+btonefactor)/3;
|
||||||
|
//float tonefactor = (0.299*rtonefactor+0.587*gtonefactor+0.114*btonefactor);
|
||||||
|
r = CLIP(r*tonefactor);
|
||||||
|
g = CLIP(g*tonefactor);
|
||||||
|
b = CLIP(b*tonefactor);
|
||||||
|
|
||||||
|
//shadow tone curve
|
||||||
|
int Y = (int)(0.299*r + 0.587*g + 0.114*b);
|
||||||
|
tonefactor = (Y>0 ? (float)shtonecurve[Y]/Y : 1);
|
||||||
r *= tonefactor;
|
r *= tonefactor;
|
||||||
g *= tonefactor;
|
g *= tonefactor;
|
||||||
b *= tonefactor;
|
b *= tonefactor;
|
||||||
/*float maxfactor = 1;
|
|
||||||
if (r>65535)
|
|
||||||
maxfactor = MIN(maxfactor, (float)(65535.0f-Ynew)/(r-Ynew));
|
|
||||||
if (g>65535)
|
|
||||||
maxfactor = MIN(maxfactor, (float)(65535.0f-Ynew)/(g-Ynew));
|
|
||||||
if (b>65535)
|
|
||||||
maxfactor = MIN(maxfactor, (float)(65535.0f-Ynew)/(b-Ynew));
|
|
||||||
|
|
||||||
if (r<0)
|
|
||||||
maxfactor = MIN(maxfactor, ((float)Ynew)/(Ynew-r));
|
|
||||||
if (g<0)
|
|
||||||
maxfactor = MIN(maxfactor, ((float)Ynew)/(Ynew-g));
|
|
||||||
if (b<0)
|
|
||||||
maxfactor = MIN(maxfactor, ((float)Ynew)/(Ynew-b));
|
|
||||||
|
|
||||||
float U = (float)(-0.14713*r - 0.28886*g + 0.436*b)*maxfactor;
|
|
||||||
float V = (float)(0.615*r - 0.51499*g - 0.10001*b)*maxfactor;
|
|
||||||
|
|
||||||
r = CLIP(Ynew + 1.13983*V);
|
|
||||||
g = CLIP(Ynew - 0.39465*U - 0.58060*V);
|
|
||||||
b = CLIP(Ynew + 2.03211*U);*/
|
|
||||||
|
|
||||||
r = tonecurve2[CLIP(r)];
|
|
||||||
g = tonecurve2[CLIP(g)];
|
|
||||||
b = tonecurve2[CLIP(b)];
|
|
||||||
|
|
||||||
|
//brightness/contrast and user tone curve
|
||||||
|
r = tonecurve[r];
|
||||||
|
g = tonecurve[g];
|
||||||
|
b = tonecurve[b];
|
||||||
|
|
||||||
int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15;
|
int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15;
|
||||||
int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15;
|
int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15;
|
||||||
|
@@ -79,7 +79,7 @@ class ImProcFunctions {
|
|||||||
bool needsTransform ();
|
bool needsTransform ();
|
||||||
|
|
||||||
void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma);
|
void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma);
|
||||||
void rgbProc (Image16* working, LabImage* lab, int* tonecurve1, int* tonecurve2, SHMap* shmap);
|
void rgbProc (Image16* working, LabImage* lab, int* hltonecurve, int* shtonecurve, int* tonecurve, SHMap* shmap);
|
||||||
void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to);
|
void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to);
|
||||||
void chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to);
|
void chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to);
|
||||||
void colorCurve (LabImage* lold, LabImage* lnew);
|
void colorCurve (LabImage* lold, LabImage* lnew);
|
||||||
|
@@ -400,12 +400,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
|||||||
if (params.toneCurve.autoexp && aeHistogram)
|
if (params.toneCurve.autoexp && aeHistogram)
|
||||||
ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, br, bl);
|
ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, br, bl);
|
||||||
|
|
||||||
int* curve1 = new int [65536];
|
int* curve1 = new int [65536];
|
||||||
int* curve2 = new int [65536];
|
int* curve2 = new int [65536];
|
||||||
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, logDefGain, isRaw ? 2.2 : 0, true, params.toneCurve.curve, hist16, curve1, curve2, NULL, 16);
|
int* curve = new int [65536];
|
||||||
|
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, logDefGain, isRaw ? 2.2 : 0, true, params.toneCurve.curve, hist16, curve1, curve2, curve, NULL, 16);
|
||||||
|
|
||||||
LabImage* labView = new LabImage (baseImg);
|
LabImage* labView = new LabImage (baseImg);
|
||||||
ipf.rgbProc (baseImg, labView, curve1, curve2, shmap);
|
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap);
|
||||||
|
|
||||||
if (shmap)
|
if (shmap)
|
||||||
delete shmap;
|
delete shmap;
|
||||||
@@ -417,15 +418,16 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
|||||||
hist16[labView->L[i][j]]++;
|
hist16[labView->L[i][j]]++;
|
||||||
|
|
||||||
// luminance processing
|
// luminance processing
|
||||||
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, NULL, 16);
|
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, curve, NULL, 16);
|
||||||
ipf.luminanceCurve (labView, labView, curve2, 0, fh);
|
ipf.luminanceCurve (labView, labView, curve, 0, fh);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 16);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 16);
|
||||||
ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh);
|
ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 16);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 16);
|
||||||
ipf.chrominanceCurve (labView, labView, 1, curve1, 0, fh);
|
ipf.chrominanceCurve (labView, labView, 1, curve1, 0, fh);
|
||||||
|
|
||||||
delete [] curve1;
|
delete [] curve1;
|
||||||
delete [] curve2;
|
delete [] curve2;
|
||||||
|
delete [] curve;
|
||||||
delete [] hist16;
|
delete [] hist16;
|
||||||
|
|
||||||
// color processing
|
// color processing
|
||||||
|
@@ -130,11 +130,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
|
|
||||||
int* curve1 = new int [65536];
|
int* curve1 = new int [65536];
|
||||||
int* curve2 = new int [65536];
|
int* curve2 = new int [65536];
|
||||||
|
int* curve = new int [65536];
|
||||||
|
|
||||||
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve1, curve2, NULL);
|
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve1, curve2, curve, NULL);
|
||||||
|
|
||||||
LabImage* labView = new LabImage (baseImg);
|
LabImage* labView = new LabImage (baseImg);
|
||||||
ipf.rgbProc (baseImg, labView, curve1, curve2, shmap);
|
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap);
|
||||||
|
|
||||||
if (shmap)
|
if (shmap)
|
||||||
delete shmap;
|
delete shmap;
|
||||||
@@ -150,8 +151,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
hist16[labView->L[i][j]]++;
|
hist16[labView->L[i][j]]++;
|
||||||
|
|
||||||
// luminance processing
|
// luminance processing
|
||||||
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, NULL);
|
CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, curve, NULL);
|
||||||
ipf.luminanceCurve (labView, labView, curve2, 0, fh);
|
ipf.luminanceCurve (labView, labView, curve, 0, fh);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 1);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 1);
|
||||||
ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh);
|
ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh);
|
||||||
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 1);
|
CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 1);
|
||||||
@@ -163,6 +164,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
|
|
||||||
delete [] curve1;
|
delete [] curve1;
|
||||||
delete [] curve2;
|
delete [] curve2;
|
||||||
|
delete [] curve;
|
||||||
delete [] hist16;
|
delete [] hist16;
|
||||||
|
|
||||||
// color processing
|
// color processing
|
||||||
|
Reference in New Issue
Block a user