From 4c5ceab60d951e0b4f23e9313830ad6aae60ba54 Mon Sep 17 00:00:00 2001 From: Emil Martinec Date: Thu, 4 Nov 2010 08:15:38 -0500 Subject: [PATCH] Modifications to exposure controls to prevent color shifts in highlights. --- rtengine/curves.cc | 119 +++++++++++++++++----------------- rtengine/curves.h | 23 +++++-- rtengine/dcrop.cc | 4 +- rtengine/improccoordinator.cc | 8 +-- rtengine/improccoordinator.h | 8 +-- rtengine/improcfun.cc | 56 +++++++--------- rtengine/improcfun.h | 2 +- rtengine/rtthumbnail.cc | 28 ++++---- rtengine/simpleprocess.cc | 12 ++-- 9 files changed, 133 insertions(+), 127 deletions(-) diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 1a83ad296..f03d76752 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -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& 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& curvePoints, unsigned int* histogram, int* hlCurve, int* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) { 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 - - std::vector basecurvePoints; - basecurvePoints.push_back((double)((CurveType)NURBS)); - 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(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* basecurvenew = NULL; - basecurvenew = new Curve (basecurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000, + /* + std::vector 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; + } + + basecurvePoints.push_back(MAX(0,blackx*(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(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(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 brightcurvePoints; @@ -710,11 +700,21 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou // val *= def_mul; // 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 = basecurvenew->getVal (val); + val = basecurve (val*def_mul, a, 0, def_mul, hlcompr/100.0, 0); + //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 val = (double)i / 65535.0; @@ -747,7 +747,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou } delete tcurve; - delete basecurvenew; // ...when you don't need it anymore + //delete basecurvenew; // ...when you don't need it anymore delete brightcurve; // 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; 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; } @@ -804,12 +805,12 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou double val = contrastcurve->getVal (dcurve[i]); if (igamma && gamma_>0) val = igamma2 (val); - outCurve2[i] = (int) (65535.0 * CLIPD(val)); + outCurve[i] = (int) (65535.0 * CLIPD(val)); } } else for (int i=0; i<=0xffff; i++) - outCurve2[i] = (int) (65535.0 * dcurve[i]); + outCurve[i] = (int) (65535.0 * dcurve[i]); delete [] dcurve; } diff --git a/rtengine/curves.h b/rtengine/curves.h index fb81f3ce6..79aafa319 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -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 static inline double clower (double x, double m, double 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 (x1), hr,sr: highlight,shadow recovery static inline double basecurve (double x, double a, double b, double D, double hr, double sr) { - double m = b+0.5/a1 ? b+0.25*(1-b)/a : b+(1-b)/4; + double y = a>1 ? 0.25 : 0.25*a; + double slope = a/(1-b); if (x<=m) - return b==0 ? x*a : clower (x/m, a*m/y, sr) * y; - else if (b+1.0/a1) + return y+(1.0-y)*cupper2((x-m)/(1-m), slope*(1-m)/(1.0-y), hr); else - return y+(x-m)*a; + return y+(x-m)*slope; } // brightness curve at point x, only positive amount it supported static inline double brightnessbase (double x, double amount) { @@ -128,7 +137,7 @@ class CurveFactory { public: // static void updateCurve3 (int* curve, int* ohistogram, const std::vector& 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& 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& 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& curvePoints, int* outCurve, int skip=1); }; diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index dc54910cf..b272728ec 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -167,12 +167,12 @@ void Crop::update (int todo, bool internal) { // shadows & highlights & tone curve & convert to cielab 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 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, 1, parent->chroma_bcurve, 0, croph); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 44715697d..09f1c2227 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -166,8 +166,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); 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); - ipf.rgbProc (oprevi, oprevl, tonecurve1, tonecurve2, shmap); + 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, hltonecurve, shtonecurve, tonecurve, shmap); // recompute luminance histogram memset (lhist16, 0, 65536*sizeof(int)); @@ -178,7 +178,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { readyphase++; 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.bcurve, chroma_bcurve, scale==1 ? 1 : 16); } @@ -186,7 +186,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { if (todo & (M_LUMINANCE+M_COLOR) ) { progress ("Applying Luminance Curve...",100*readyphase/numofphases); - ipf.luminanceCurve (oprevl, nprevl, lumacurve2, 0, pH); + ipf.luminanceCurve (oprevl, nprevl, lumacurve, 0, pH); readyphase++; progress ("Applying Color Boost...",100*readyphase/numofphases); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index b45857acb..81045c5f7 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -62,11 +62,11 @@ class ImProcCoordinator : public StagedImageProcessor { void freeAll (); - int tonecurve1 [65536]; - int tonecurve2 [65536]; + int hltonecurve [65536]; + int shtonecurve [65536]; + int tonecurve [65536]; - int lumacurve1 [65536]; - int lumacurve2 [65536]; + int lumacurve [65536]; int chroma_acurve [65536]; int chroma_bcurve [65536]; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 07e771092..f1c36b898 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -245,7 +245,7 @@ void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params 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; if (shmap) { @@ -321,42 +321,34 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve1, b = CLIP((int)(factor*b)); } } + + //highlight tone curve /*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); - + 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; g *= 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 y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 7de8b703b..b8dc328ad 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -79,7 +79,7 @@ class ImProcFunctions { bool needsTransform (); 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 chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to); void colorCurve (LabImage* lold, LabImage* lnew); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index d91705227..f60f7a37a 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -400,12 +400,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei if (params.toneCurve.autoexp && aeHistogram) ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, br, bl); - int* curve1 = 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* curve1 = 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, logDefGain, isRaw ? 2.2 : 0, true, params.toneCurve.curve, hist16, curve1, curve2, curve, NULL, 16); LabImage* labView = new LabImage (baseImg); - ipf.rgbProc (baseImg, labView, curve1, curve2, shmap); + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap); if (shmap) delete shmap; @@ -417,15 +418,16 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei hist16[labView->L[i][j]]++; // 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); - ipf.luminanceCurve (labView, labView, curve2, 0, fh); + 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, curve, 0, fh); CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 16); ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh); CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 16); ipf.chrominanceCurve (labView, labView, 1, curve1, 0, fh); - delete [] curve1; + delete [] curve1; delete [] curve2; + delete [] curve; delete [] hist16; // color processing @@ -690,12 +692,12 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format) { cinfo.input_components = 3; jpeg_set_defaults (&cinfo); cinfo.write_JFIF_header = FALSE; - - // compute optimal Huffman coding tables for the image. Bit slower to generate, but size of result image is a bit less (default was FALSE) - cinfo.optimize_coding = TRUE; - - // Since math coprocessors are common these days, FLOAT should be a bit more accurate AND fast (default is ISLOW) - // (machine dependency is not really an issue, since we all run on x86 and having exactly the same file is not a requirement) + + // compute optimal Huffman coding tables for the image. Bit slower to generate, but size of result image is a bit less (default was FALSE) + cinfo.optimize_coding = TRUE; + + // Since math coprocessors are common these days, FLOAT should be a bit more accurate AND fast (default is ISLOW) + // (machine dependency is not really an issue, since we all run on x86 and having exactly the same file is not a requirement) cinfo.dct_method = JDCT_FLOAT; jpeg_set_quality (&cinfo, 85, true); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 44c041565..d102a0101 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -130,11 +130,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p int* curve1 = 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, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve1, curve2, NULL); + 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, curve, NULL); LabImage* labView = new LabImage (baseImg); - ipf.rgbProc (baseImg, labView, curve1, curve2, shmap); + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap); if (shmap) delete shmap; @@ -150,8 +151,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p hist16[labView->L[i][j]]++; // 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); - ipf.luminanceCurve (labView, labView, curve2, 0, fh); + 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, curve, 0, fh); CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 1); ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh); 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 [] curve2; + delete [] curve; delete [] hist16; // color processing