Issue 2850: normalized RGB-pipeline curve gammas to sRGB, make curve algorithms operate on linear image data

This commit is contained in:
torger
2015-07-23 21:34:00 +02:00
parent db306ccfed
commit b2836b388f
10 changed files with 80 additions and 100 deletions

View File

@@ -340,6 +340,11 @@ void CurveFactory::curveBW (
LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance
ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip)
{ {
const float gamma_ = Color::sRGBGamma;
const float start = expf(gamma_*logf( -0.055 / ((1.0/gamma_-1.0)*1.055 )));
const float slope = 1.055 * powf (start, 1.0/gamma_-1) - 0.055/start;
const float mul = 1.055;
const float add = 0.055;
outBeforeCCurveHistogrambw.clear(); outBeforeCCurveHistogrambw.clear();
bool histNeeded = false; bool histNeeded = false;
@@ -355,7 +360,7 @@ void CurveFactory::curveBW (
} }
if (tcurve) { if (tcurve) {
if (!tcurve->isIdentity()) if (!tcurve->isIdentity())
customToneCurvebw2.Set(tcurve); customToneCurvebw2.Set(tcurve, gamma_, start, slope, mul, add);
delete tcurve; delete tcurve;
tcurve = NULL; tcurve = NULL;
} }
@@ -370,7 +375,7 @@ void CurveFactory::curveBW (
} }
if (tcurve) { if (tcurve) {
if (!tcurve->isIdentity()) if (!tcurve->isIdentity())
customToneCurvebw1.Set(tcurve); customToneCurvebw1.Set(tcurve, gamma_, start, slope, mul, add);
delete tcurve; delete tcurve;
tcurve = NULL; tcurve = NULL;
} }
@@ -617,7 +622,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh,
double shcompr, double br, double contr, double gamma_, bool igamma_, double shcompr, double br, double contr,
procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints,
procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
LUTu & histogram, LUTu & histogramCropped, LUTu & histogram, LUTu & histogramCropped,
@@ -627,31 +632,16 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
ToneCurve & customToneCurve2, ToneCurve & customToneCurve2,
int skip) { int skip) {
// the curve shapes are defined in sRGB gamma, but the output curves will operate on linear floating point data,
//double def_mul = pow (2.0, defmul); // hence we do both forward and inverse gamma conversions here.
const float gamma_ = Color::sRGBGamma;
/*printf ("def_mul= %f ecomp= %f black= %f hlcompr= %f shcompr= %f br= %f contr= %f defmul= %f const float start = expf(gamma_*logf( -0.055 / ((1.0/gamma_-1.0)*1.055 )));
gamma= %f, skip= %d \n",def_mul,ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);*/ const float slope = 1.055 * powf (start, 1.0/gamma_-1) - 0.055/start;
const float mul = 1.055;
// compute parameters of the gamma curve const float add = 0.055;
/*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;
// gamma BT709*/
//normalize gamma to sRGB
double start = exp(gamma_*log( -0.055 / ((1.0/gamma_-1.0)*1.055 )));
double slope = 1.055 * pow (start, 1.0/gamma_-1) - 0.055/start;
double mul = 1.055;
double add = 0.055;
// a: slope of the curve, black: starting point at the x axis // a: slope of the curve, black: starting point at the x axis
double a = pow (2.0, ecomp); const float a = powf (2.0, ecomp);
// check if inverse gamma is needed at the end
bool needigamma = igamma_ && gamma_>1.;
// clear array that stores histogram valid before applying the custom curve // clear array that stores histogram valid before applying the custom curve
outBeforeCCurveHistogram.clear(); outBeforeCCurveHistogram.clear();
@@ -727,9 +717,8 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
float val2 = simplebasecurve (val, black, 0.015*shcompr); float val2 = simplebasecurve (val, black, 0.015*shcompr);
shCurve[0] = CLIPD(val2)/val; shCurve[0] = CLIPD(val2)/val;
val = 0.0; val = 0.0;
// gamma correction // gamma correction
if (gamma_>1.) val = gamma (val, gamma_, start, slope, mul, add);
val = gamma (val, gamma_, start, slope, mul, add);
// apply brightness curve // apply brightness curve
if (brightcurve) if (brightcurve)
@@ -747,8 +736,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
shCurve[i] = CLIPD(val2)/val; shCurve[i] = CLIPD(val2)/val;
// gamma correction // gamma correction
if (gamma_>1.) val = gamma (val, gamma_, start, slope, mul, add);
val = gamma (val, gamma_, start, slope, mul, add);
// apply brightness curve // apply brightness curve
if (brightcurve) if (brightcurve)
@@ -825,7 +813,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
} }
if (tcurve) { if (tcurve) {
if (!tcurve->isIdentity()) if (!tcurve->isIdentity())
customToneCurve2.Set(tcurve); customToneCurve2.Set(tcurve, gamma_, start, slope, mul, add);
delete tcurve; delete tcurve;
tcurve = NULL; tcurve = NULL;
} }
@@ -844,7 +832,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
} }
if (tcurve) { if (tcurve) {
if (!tcurve->isIdentity()) if (!tcurve->isIdentity())
customToneCurve1.Set(tcurve); customToneCurve1.Set(tcurve, gamma_, start, slope, mul, add);
delete tcurve; delete tcurve;
tcurve = NULL; tcurve = NULL;
} }
@@ -904,11 +892,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
int hi = (int)(255.0*(hval)); int hi = (int)(255.0*(hval));
outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ; outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ;
} }
val = igamma (val, gamma_, start, slope, mul, add);
// if inverse gamma is needed, do it (standard sRGB inverse gamma is applied)
if (needigamma)
val = igamma (val, gamma_, start, slope, mul, add);
outCurve[i] = (65535.f * val); outCurve[i] = (65535.f * val);
} }
@@ -1137,7 +1121,13 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
outCurve(65536, 0); outCurve(65536, 0);
for (int i=0; i<65536; i++) { for (int i=0; i<65536; i++) {
// apply custom/parametric/NURBS curve, if any // apply custom/parametric/NURBS curve, if any
float val = tcurve->getVal ((float)i/65536.0f);
// RGB curves are defined with sRGB gamma, but operate on linear data
float val = float(i)/65535.f;
val = CurveFactory::gamma2 (val);
val = tcurve->getVal(val);
val = CurveFactory::igamma2 (val);
//float val = tcurve->getVal ((float)i/65536.0f);
outCurve[i] = (65536.0f * val); outCurve[i] = (65536.0f * val);
} }
delete tcurve; delete tcurve;
@@ -1165,9 +1155,20 @@ void ToneCurve::Reset() {
} }
// Fill a LUT with X/Y, ranged 0xffff // Fill a LUT with X/Y, ranged 0xffff
void ToneCurve::Set(Curve *pCurve) { void ToneCurve::Set(Curve *pCurve, float gamma, float start, float slope, float mul, float add) {
lutToneCurve(65536); lutToneCurve(65536);
for (int i=0; i<65536; i++) lutToneCurve[i] = pCurve->getVal(double(i)/65535.) * 65535.; if (gamma <= 0.0 || gamma == 1.) {
for (int i=0; i<65536; i++) lutToneCurve[i] = (float)pCurve->getVal(float(i)/65535.f) * 65535.f;
} else {
// apply gamma, that is 'pCurve' is defined with the given gamma and here we convert it to a curve in linear space
for (int i=0; i<65536; i++) {
float val = float(i)/65535.f;
val = CurveFactory::gamma (val, gamma, start, slope, mul, add);
val = pCurve->getVal(val);
val = CurveFactory::igamma (val, gamma, start, slope, mul, add);
lutToneCurve[i] = val * 65535.f;
}
}
} }
void OpacityCurve::Reset() { void OpacityCurve::Reset() {

View File

@@ -181,6 +181,12 @@ class CurveFactory {
static inline double igamma2 (double x) { static inline double igamma2 (double x) {
return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve); return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve);
} }
static inline float gamma2 (float x) {
return x <= 0.00304 ? x*12.92 : 1.055*expf(logf(x)/sRGBGammaCurve)-0.055;
}
static inline float igamma2 (float x) {
return x <= 0.03928 ? x/12.92 : expf(logf((x+0.055)/1.055)*sRGBGammaCurve);
}
// gamma function with adjustable parameters // gamma function with adjustable parameters
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){ static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){
return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add); return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add);
@@ -188,6 +194,12 @@ class CurveFactory {
static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){ static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){
return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) ); return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) );
} }
static inline float gamma (float x, float gamma, float start, float slope, float mul, float add){
return (x <= start ? x*slope : expf(logf(x)/gamma)*mul-add);
}
static inline float igamma (float x, float gamma, float start, float slope, float mul, float add){
return (x <= start*slope ? x/slope : expf(logf((x+add)/mul)*gamma) );
}
static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level) static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
{ {
@@ -208,7 +220,7 @@ class CurveFactory {
public: public:
static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr,
double gamma_, bool igamma_, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
LUTu & histogram, LUTu & histogramCropped, LUTu & histogram, LUTu & histogramCropped,
LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2,
@@ -348,7 +360,7 @@ class ToneCurve {
virtual ~ToneCurve() {}; virtual ~ToneCurve() {};
void Reset(); void Reset();
void Set(Curve *pCurve); void Set(Curve *pCurve, float gamma=0, float start=0, float slope=0, float mul=0, float add=0);
operator bool (void) const { return lutToneCurve; } operator bool (void) const { return lutToneCurve; }
}; };

View File

@@ -86,8 +86,6 @@ class ImageSource : public InitialImage {
virtual double getDefGain () { return 1.0; } virtual double getDefGain () { return 1.0; }
virtual double getGamma () { return 0.0; }
virtual void getFullSize (int& w, int& h, int tr = TR_NONE) {} virtual void getFullSize (int& w, int& h, int tr = TR_NONE) {}
virtual void getSize (int tran, PreviewProps pp, int& w, int& h) {} virtual void getSize (int tran, PreviewProps pp, int& w, int& h) {}
virtual int getRotateDegree() const { return 0; } virtual int getRotateDegree() const { return 0; }

View File

@@ -354,12 +354,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped); // if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
//complexCurve also calculated pre-curves histogram depending on crop //complexCurve also calculated pre-curves histogram depending on crop
ipf.g = imgsrc->getGamma();
ipf.iGamma = true;
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0,
params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh,
params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast,
ipf.g, !ipf.iGamma, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2,
vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale==1 ? 1 : 1); vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale==1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1);

View File

@@ -2432,7 +2432,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit ,float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve,LUTf & cl2Toningcurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit ,float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve,LUTf & cl2Toningcurve,
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2,double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf) { const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2,double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf) {
LUTf iGammaLUTf; LUTf fGammaLUTf;
Imagefloat *tmpImage=NULL; Imagefloat *tmpImage=NULL;
// NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this // NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this
@@ -2688,20 +2688,11 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
} }
bool hasgammabw = gammabwr!=1.f || gammabwg!=1.f || gammabwb!=1.f; bool hasgammabw = gammabwr!=1.f || gammabwg!=1.f || gammabwb!=1.f;
//normalize gamma to sRGB fGammaLUTf(65535);
double start = exp(g*log( -0.055 / ((1.0/g-1.0)*1.055 )));
double slope = 1.055 * pow (start, 1.0/g-1) - 0.055/start;
double mul = 1.055;
double add = 0.055;
if (iGamma && g > 1.) {
iGammaLUTf(65535);
#pragma omp parallel for #pragma omp parallel for
for (int i=0; i<65536; i++) { for (int i=0; i<65536; i++) {
iGammaLUTf[i] = float(CurveFactory::igamma (double(i)/65535., g, start, slope, mul, add)*65535.); fGammaLUTf[i] = CurveFactory::gamma2 (float(i)/65535.f) * 65535.f;
}
} }
if (hasColorToning || blackwhite) if (hasColorToning || blackwhite)
tmpImage = new Imagefloat(working->width,working->height); tmpImage = new Imagefloat(working->width,working->height);
@@ -2887,9 +2878,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
if (editID == EUID_ToneCurve1) { // filling the pipette buffer if (editID == EUID_ToneCurve1) { // filling the pipette buffer
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editIFloatTmpR[ti*TS+tj] = CLIP(rtemp[ti*TS+tj]/65535.f); editIFloatTmpR[ti*TS+tj] = CLIP(fGammaLUTf[rtemp[ti*TS+tj]]/65535.f);
editIFloatTmpG[ti*TS+tj] = CLIP(gtemp[ti*TS+tj]/65535.f); editIFloatTmpG[ti*TS+tj] = CLIP(fGammaLUTf[gtemp[ti*TS+tj]]/65535.f);
editIFloatTmpB[ti*TS+tj] = CLIP(btemp[ti*TS+tj]/65535.f); editIFloatTmpB[ti*TS+tj] = CLIP(fGammaLUTf[btemp[ti*TS+tj]]/65535.f);
} }
} }
} }
@@ -2949,9 +2940,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
if (editID == EUID_ToneCurve2) { // filling the pipette buffer if (editID == EUID_ToneCurve2) { // filling the pipette buffer
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editIFloatTmpR[ti*TS+tj] = CLIP(rtemp[ti*TS+tj]/65535.f); editIFloatTmpR[ti*TS+tj] = CLIP(fGammaLUTf[rtemp[ti*TS+tj]]/65535.f);
editIFloatTmpG[ti*TS+tj] = CLIP(gtemp[ti*TS+tj]/65535.f); editIFloatTmpG[ti*TS+tj] = CLIP(fGammaLUTf[gtemp[ti*TS+tj]]/65535.f);
editIFloatTmpB[ti*TS+tj] = CLIP(btemp[ti*TS+tj]/65535.f); editIFloatTmpB[ti*TS+tj] = CLIP(fGammaLUTf[btemp[ti*TS+tj]]/65535.f);
} }
} }
} }
@@ -2999,35 +2990,24 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
} }
} }
if (iGammaLUTf) {
for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) {
// apply inverse gamma
rtemp[ti*TS+tj] = iGammaLUTf[ rtemp[ti*TS+tj] ];
gtemp[ti*TS+tj] = iGammaLUTf[ gtemp[ti*TS+tj] ];
btemp[ti*TS+tj] = iGammaLUTf[ btemp[ti*TS+tj] ];
}
}
}
if (editID == EUID_RGB_R) { if (editID == EUID_RGB_R) {
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editWhateverTmp[ti*TS+tj] = rtemp[ti*TS+tj]/65536.f; editWhateverTmp[ti*TS+tj] = fGammaLUTf[rtemp[ti*TS+tj]]/65536.f;
} }
} }
} }
else if (editID == EUID_RGB_G) { else if (editID == EUID_RGB_G) {
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editWhateverTmp[ti*TS+tj] = gtemp[ti*TS+tj]/65536.f; editWhateverTmp[ti*TS+tj] = fGammaLUTf[gtemp[ti*TS+tj]]/65536.f;
} }
} }
} }
else if (editID == EUID_RGB_B) { else if (editID == EUID_RGB_B) {
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editWhateverTmp[ti*TS+tj] = btemp[ti*TS+tj]/65536.f; editWhateverTmp[ti*TS+tj] = fGammaLUTf[btemp[ti*TS+tj]]/65536.f;
} }
} }
} }
@@ -3379,9 +3359,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
if (editID == EUID_BlackWhiteBeforeCurve) { if (editID == EUID_BlackWhiteBeforeCurve) {
for (int i=istart,ti=0; i<tH; i++,ti++) { for (int i=istart,ti=0; i<tH; i++,ti++) {
for (int j=jstart,tj=0; j<tW; j++,tj++) { for (int j=jstart,tj=0; j<tW; j++,tj++) {
editIFloatTmpR[ti*TS+tj] = CLIP(rtemp[ti*TS+tj]/65535.f); editIFloatTmpR[ti*TS+tj] = CLIP(fGammaLUTf[rtemp[ti*TS+tj]]/65535.f);
editIFloatTmpG[ti*TS+tj] = CLIP(gtemp[ti*TS+tj]/65535.f); editIFloatTmpG[ti*TS+tj] = CLIP(fGammaLUTf[gtemp[ti*TS+tj]]/65535.f);
editIFloatTmpB[ti*TS+tj] = CLIP(btemp[ti*TS+tj]/65535.f); editIFloatTmpB[ti*TS+tj] = CLIP(fGammaLUTf[btemp[ti*TS+tj]]/65535.f);
} }
} }
} }
@@ -3748,7 +3728,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e
#endif #endif
for (int i=0; i<tH; i++) { for (int i=0; i<tH; i++) {
for (int j=0; j<tW; j++) { for (int j=0; j<tW; j++) {
editWhatever->v(i,j) = CLIP(tmpImage->r(i,j)/65535.f); // assuming that r=g=b editWhatever->v(i,j) = CLIP(fGammaLUTf[tmpImage->r(i,j)]/65535.f); // assuming that r=g=b
} }
} }
} }
@@ -5732,7 +5712,7 @@ fclose(f);*/
double gavg = 0.; double gavg = 0.;
for (int i=0; i<65536>>histcompr; i++) for (int i=0; i<65536>>histcompr; i++)
gavg += histogram[i] * CurveFactory::gamma2((int)(corr*(i<<histcompr)<65535 ? corr*(i<<histcompr) : 65535)) / sum; gavg += histogram[i] * CurveFactory::gamma2((float)(corr*(i<<histcompr)<65535 ? corr*(i<<histcompr) : 65535)) / sum;
if (black < gavg) { if (black < gavg) {
int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4 int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4
if (whiteclipg < maxwhiteclip) if (whiteclipg < maxwhiteclip)

View File

@@ -185,8 +185,6 @@ class ImProcFunctions {
public: public:
bool iGamma; // true if inverse gamma has to be applied in rgbProc
double g;
static LUTf cachef; static LUTf cachef;
double lumimul[3]; double lumimul[3];
// float chau; // float chau;
@@ -211,7 +209,7 @@ class ImProcFunctions {
static void cleanupCache (); static void cleanupCache ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), iGamma(true), g(0.0) {} : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {}
~ImProcFunctions (); ~ImProcFunctions ();
void setScale (double iscale); void setScale (double iscale);

View File

@@ -162,8 +162,6 @@ class RawImageSource : public ImageSource {
double getDefGain () { return defGain; } double getDefGain () { return defGain; }
double getGamma () { return Color::sRGBGamma; }
void getFullSize (int& w, int& h, int tr = TR_NONE); void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (int tran, PreviewProps pp, int& w, int& h); void getSize (int tran, PreviewProps pp, int& w, int& h);
int getRotateDegree() const { return ri->get_rotateDegree(); } int getRotateDegree() const { return ri->get_rotateDegree(); }

View File

@@ -910,10 +910,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ToneCurve customToneCurvebw1; ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2; ToneCurve customToneCurvebw2;
ipf.g = gamma;
ipf.iGamma = true;
CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh, CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh,
params.toneCurve.shcompr, bright, contr, ipf.g, !ipf.iGamma, params.toneCurve.shcompr, bright, contr,
params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode, params.toneCurve.curve,
params.toneCurve.curveMode2, params.toneCurve.curve2, params.toneCurve.curveMode2, params.toneCurve.curve2,
hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16);

View File

@@ -606,9 +606,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
ToneCurve customToneCurvebw2; ToneCurve customToneCurvebw2;
//if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
ipf.g = imgsrc->getGamma(); CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr,
ipf.iGamma = true;
CurveFactory::complexCurve (expcomp, black/65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, ipf.g, !ipf.iGamma,
params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2,
hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 );

View File

@@ -53,7 +53,6 @@ class StdImageSource : public ImageSource {
void getAutoExpHistogram (LUTu &histogram, int& histcompr); void getAutoExpHistogram (LUTu &histogram, int& histcompr);
double getDefGain () { return 0.0; } double getDefGain () { return 0.0; }
double getGamma () { return 0.0; }
void getFullSize (int& w, int& h, int tr = TR_NONE); void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (int tran, PreviewProps pp, int& w, int& h); void getSize (int tran, PreviewProps pp, int& w, int& h);