diff --git a/rtdata/languages/default b/rtdata/languages/default index acd69a349..97f552717 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -397,6 +397,8 @@ PARTIALPASTE_DISTORTION;Distortion correction PARTIALPASTE_EXIFCHANGES;Changes to exif data PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount +PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold PARTIALPASTE_ICMSETTINGS;ICM settings PARTIALPASTE_IPTCINFO;IPTC info PARTIALPASTE_LABCURVE;Lab curve @@ -647,7 +649,8 @@ TP_EXPOSURE_AUTOLEVELS;Auto Levels TP_EXPOSURE_BLACKLEVEL;Black TP_EXPOSURE_BRIGHTNESS;Brightness TP_EXPOSURE_CLIP;Clip -TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight recovery +TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight recovery amount +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight recovery threshold TP_EXPOSURE_COMPRSHADOWS;Shadow recovery TP_EXPOSURE_CONTRAST;Contrast TP_EXPOSURE_CURVEEDITOR;Tone Curve diff --git a/rtdata/profiles/crisp.pp3 b/rtdata/profiles/crisp.pp3 index f80eecc70..1c50c7bdf 100644 --- a/rtdata/profiles/crisp.pp3 +++ b/rtdata/profiles/crisp.pp3 @@ -11,6 +11,7 @@ Contrast=12 Saturation=0 Black=0 HighlightCompr=70 +HighlightComprThreshold=0 ShadowCompr=50 Curve=0; diff --git a/rtdata/profiles/default.pp3 b/rtdata/profiles/default.pp3 index 94d6a1631..49b3a6680 100644 --- a/rtdata/profiles/default.pp3 +++ b/rtdata/profiles/default.pp3 @@ -11,6 +11,7 @@ Contrast=0 Saturation=0 Black=0 HighlightCompr=70 +HighlightComprThreshold=0 ShadowCompr=50 Curve=0; diff --git a/rtdata/profiles/neutral.pp3 b/rtdata/profiles/neutral.pp3 index e2b413353..fdecac574 100644 --- a/rtdata/profiles/neutral.pp3 +++ b/rtdata/profiles/neutral.pp3 @@ -10,6 +10,7 @@ Contrast=0 Saturation=0 Black=0 HighlightCompr=0 +HighlightComprThreshold=0 ShadowCompr=0 Curve=0; diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 3088ea415..ef5d17175 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -319,191 +319,7 @@ double CurveFactory::centercontrast (double x, double b, double m) { } } -/* -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* 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 - 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; - - // theoretical maximum of the curve - double D = def_mul; - - // 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)); - - 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, D, hlcompr/100.0, shcompr/100.0); - - // gamma correction - if (gamma_>0) - val = gamma (val, gamma_, start, slope, mul, add); - - // apply brightness curve - val = brightness (val, br/100.0); - - // 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; - - // 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 (needcontrast) { - // compute mean luminance of the image with the curve applied - int sum = 0; - double avg = 0; - for (int i=0; i<=0xffff; i++) { - avg += dcurve[i] * histogram[i]; - sum += histogram[i]; - } - avg /= sum; - - // compute contrast parameter - double contr_b = contr / 20; - if (contr_b>=0 && contr_b < 0.00001) - contr_b = 0.00001; - else if (contr_b<0 && contr_b > -0.00001) - contr_b = -0.00001; - - // apply contrast enhancement - for (int i=0; i<=0xffff; i++) { - double val = centercontrast (dcurve[i], contr_b, avg); - if (igamma && gamma_>0) - val = igamma2 (val); - 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& 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& curvePoints, int* outCurve, int skip) { @@ -586,195 +402,14 @@ 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, float* hlCurve, float* shCurve, int* outCurve, 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 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++) { - - // 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*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); - - hlCurve[i] = (65535.0 * CLIPD(val)); - - //%%%%%%%%%%%%%%%%%%%%%%%%%% - // change to [0,1] range - val = (double)i / 65535.0; - - val = basecurve (val, 1, black, 1, 0, 1.5*shcompr/100.0); - - shCurve[i] = (65535.0 * CLIPD(val)); - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%% - for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { - - // change to [0,1] range - double val = (double)i / 65535.0; - float val0 = val; - - // 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) { - float hval = shCurve[(int)(hlCurve[i])]*(float)val/(65535*val0); - //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 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; - } - 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[(int)shCurve[(int)hlCurve[i]]] * histogram[i]; - //sqavg += dcurve[i]*dcurve[i] * histogram[i]; - sum += histogram[i]; - } - avg /= sum; - //sqavg /= sum; - //double stddev = sqrt(sqavg-avg*avg); - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - std::vector 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-avg*(0.6-contr/250.0)); //toe point - contrastcurvePoints.push_back(avg-avg*(0.6+contr/250.0)); //value at toe point - - contrastcurvePoints.push_back(avg+(1-avg)*(0.6-contr/250.0)); //shoulder point - contrastcurvePoints.push_back(avg+(1-avg)*(0.6+contr/250.0)); //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); - outCurve[i] = (int) (65535.0 * CLIPD(val)); - } - delete contrastcurve; - } - else - for (int i=0; i<=0xffff; i++) - outCurve[i] = (int) (65535.0 * dcurve[i]); - 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& curvePoints, unsigned int* histogram, float* hlCurve, float* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) { + void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, \ + double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, \ + const std::vector& curvePoints, unsigned int* histogram, \ + float* hlCurve, float* shCurve, int* outCurve, \ + unsigned int* outBeforeCCurveHistogram, int skip) { double def_mul = pow (2.0, defmul); @@ -837,6 +472,11 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou brightcurve = new Curve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000, //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + float exp_scale = a*def_mul ; + float scale = 65536.0; + float comp = (ecomp + defmul)*hlcompr/100.0; + int shoulder = (int)((scale/exp_scale)*(hlcomprthresh/200.0)); + for (int i=0; i<=0xffff; i++) { // change to [0,1] range @@ -846,10 +486,22 @@ 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, 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 = basecurve (val*def_mul, a, 0, def_mul, hlcompr/100.0, 0); - hlCurve[i] = (65535.0 * CLIPD(val)); + //hlCurve[i] = (65535.0 * CLIPD(val)); + + if ((hlcompr>0)&&(exp_scale>1.0)) + { + if (i>shoulder) { + float Y = (float)(i-shoulder)*exp_scale/(scale-shoulder); + float R = (float)(i-shoulder)*comp/(scale-shoulder); + hlCurve[i] = log(1+Y*comp)/R; + } else { + hlCurve[i]=exp_scale; + } + } else { + hlCurve[i]=exp_scale; + } //%%%%%%%%%%%%%%%%%%%%%%%%%% // change to [0,1] range @@ -885,7 +537,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou double avg = 0; //double sqavg = 0; for (int i=0; i<=0xffff; i++) { - avg += dcurve[(int)shCurve[(int)hlCurve[i]]] * histogram[i]; + avg += dcurve[(int)shCurve[(int)hlCurve[i]*i]] * histogram[i]; //sqavg += dcurve[i]*dcurve[i] * histogram[i]; sum += histogram[i]; } diff --git a/rtengine/curves.h b/rtengine/curves.h index 49624f8ea..d20219888 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -158,7 +158,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, float* hlCurve, float* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1); + static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, float* hlCurve, float* 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/improccoordinator.cc b/rtengine/improccoordinator.cc index 82b0a6bbc..c73a6bdff 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -203,7 +203,7 @@ 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, hltonecurve, shtonecurve, tonecurve, bcrgbhist, scale==1 ? 1 : 1); + CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, 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, params.toneCurve.saturation); // recompute luminance histogram @@ -215,7 +215,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, dummy1, dummy2, lumacurve, bcLhist, scale==1 ? 1 : 16); + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, lhist16, dummy1, dummy2, 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); } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index ac6ff808c..872ea6025 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -257,7 +257,7 @@ void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params delete [] hist; } -void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecurve, float* shtonecurve, int* tonecurve, SHMap* shmap, int sat) { +void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecurve, float* shtonecurve, int* tonecurve, SHMap* shmap, /*float defmul,*/ int sat) { int h_th, s_th; if (shmap) { @@ -343,34 +343,28 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur b = CLIP((int)(factor*b)); } } - //float h, s, v; - //rgb2hsv(r,g,b,h,s,v); - //highlight tone curve - //v = (float)hltonecurve[(int)(65535*v)]/65535; - float rtonefactor = (r>0 ? (float)hltonecurve[r]/r : (float)hltonecurve[1]); - float gtonefactor = (g>0 ? (float)hltonecurve[g]/g : (float)hltonecurve[1]); - float btonefactor = (b>0 ? (float)hltonecurve[b]/b : (float)hltonecurve[1]); - //float tonefactor = MIN(rtonefactor, MIN(gtonefactor,btonefactor)); - float tonefactor = (rtonefactor+gtonefactor+btonefactor)/3; + //float rtonefactor = (r>0 ? (float)hltonecurve[r]/r : (float)hltonecurve[1]); + //float gtonefactor = (g>0 ? (float)hltonecurve[g]/g : (float)hltonecurve[1]); + //float btonefactor = (b>0 ? (float)hltonecurve[b]/b : (float)hltonecurve[1]); + //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); + + //float tonefactor=(my_tonecurve[r]+my_tonecurve[g]+my_tonecurve[b])/3; + float tonefactor=(hltonecurve[r]+hltonecurve[g]+hltonecurve[b])/3; + + r = (r*tonefactor); + g = (g*tonefactor); + b = (b*tonefactor); //shadow tone curve - int Y = (int)(0.299*r + 0.587*g + 0.114*b); + int Y = CLIP((int)(0.299*r + 0.587*g + 0.114*b)); tonefactor = (Y>0 ? (float)shtonecurve[Y]/Y : 1); r *= tonefactor; g *= tonefactor; b *= tonefactor; //brightness/contrast and user tone curve - //Y = (int)(0.299*r + 0.587*g + 0.114*b); - //tonefactor = (Y>0 ? (float)tonecurve[Y]/Y : 1); - //r *= tonefactor; - //g *= tonefactor; - //b *= tonefactor; r = tonecurve[CLIP(r)]; g = tonecurve[CLIP(g)]; b = tonecurve[CLIP(b)]; @@ -438,7 +432,7 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur } delete [] cossq; - + //delete [] my_tonecurve; } void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 99fa59409..c0122bd93 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -55,6 +55,7 @@ void ProcParams::setDefaults () { toneCurve.saturation = 0; toneCurve.black = 0; toneCurve.hlcompr = 70; + toneCurve.hlcomprthresh = 0; toneCurve.shcompr = 25; toneCurve.curve.clear (); @@ -236,6 +237,7 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_integer ("Exposure", "Saturation", toneCurve.saturation); keyFile.set_integer ("Exposure", "Black", toneCurve.black); keyFile.set_integer ("Exposure", "HighlightCompr", toneCurve.hlcompr); + keyFile.set_integer ("Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh); keyFile.set_integer ("Exposure", "ShadowCompr", toneCurve.shcompr); Glib::ArrayHandle tcurve = toneCurve.curve; keyFile.set_double_list("Exposure", "Curve", tcurve); @@ -502,6 +504,7 @@ if (keyFile.has_group ("Exposure")) { if (keyFile.has_key ("Exposure", "Black")) toneCurve.black = keyFile.get_integer ("Exposure", "Black"); if (keyFile.has_key ("Exposure", "HighlightCompr")) toneCurve.hlcompr = keyFile.get_integer ("Exposure", "HighlightCompr"); if (toneCurve.hlcompr > 100) toneCurve.hlcompr = 100; // older pp3 files can have values above 100. + if (keyFile.has_key ("Exposure", "HighlightComprThreshold")) toneCurve.hlcomprthresh = keyFile.get_integer ("Exposure", "HighlightComprThreshold"); if (keyFile.has_key ("Exposure", "ShadowCompr")) toneCurve.shcompr = keyFile.get_integer ("Exposure", "ShadowCompr"); if (toneCurve.shcompr > 100) toneCurve.shcompr = 100; // older pp3 files can have values above 100. if (version>200) @@ -854,6 +857,7 @@ bool ProcParams::operator== (const ProcParams& other) { && toneCurve.saturation == other.toneCurve.saturation && toneCurve.shcompr == other.toneCurve.shcompr && toneCurve.hlcompr == other.toneCurve.hlcompr + && toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh && toneCurve.autoexp == other.toneCurve.autoexp && toneCurve.clip == other.toneCurve.clip && toneCurve.expcomp == other.toneCurve.expcomp diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c5d91588a..20f8174fe 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -41,6 +41,7 @@ class ToneCurveParams { int saturation; int shcompr; int hlcompr; + int hlcomprthresh; }; /** diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index aefb6e2e5..26349665b 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -701,7 +701,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei float* curve1 = new float [65536]; float* curve2 = new float [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); + CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, 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, curve, shmap, params.toneCurve.saturation); @@ -716,7 +716,7 @@ 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, curve, NULL, 16); + CurveFactory::complexCurve (0.0, 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, curve, 16); ipf.chrominanceCurve (labView, labView, 0, curve, 0, fh); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 23580eaea..3d28e83f3 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -146,10 +146,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p float* curve2 = new float [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, curve, NULL); + CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, 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, curve, shmap, params.toneCurve.saturation); + ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); if (shmap) delete shmap; @@ -165,7 +165,7 @@ 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, curve, NULL); + CurveFactory::complexCurve (0.0, 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, curve, 1); ipf.chrominanceCurve (labView, labView, 0, curve, 0, fh); diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index e28a366e5..b0281b562 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -24,8 +24,12 @@ #define ADDSET_VIGN_AMOUNT 20 #define ADDSET_LC_SATURATION 21 #define ADDSET_TC_SATURATION 22 + +#define ADDSET_TC_HLCOMPAMOUNT 23 +#define ADDSET_TC_HLCOMPTHRESH 24 +#define ADDSET_TC_SHCOMP 25 // When adding items, make sure to update ADDSET_PARAM_NUM -#define ADDSET_PARAM_NUM 23 // THIS IS USED AS A DELIMITER!! +#define ADDSET_PARAM_NUM 26 // THIS IS USED AS A DELIMITER!! #endif diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 82cab50f0..76559cca5 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -120,7 +120,7 @@ void BatchToolPanelCoordinator::initSession () { pparams = selected[0]->getProcParams (); coarse->initBatchBehavior (); - curve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]); + curve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]); lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_SATURATION]); whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]); vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]); @@ -135,8 +135,11 @@ void BatchToolPanelCoordinator::initSession () { shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); if (options.baBehav[ADDSET_TC_EXPCOMP]) pparams.toneCurve.expcomp = 0; + if (options.baBehav[ADDSET_TC_HLCOMPAMOUNT]) pparams.toneCurve.hlcompr = 0; + if (options.baBehav[ADDSET_TC_HLCOMPTHRESH]) pparams.toneCurve.hlcomprthresh = 0; if (options.baBehav[ADDSET_TC_BRIGHTNESS]) pparams.toneCurve.brightness = 0; if (options.baBehav[ADDSET_TC_BLACKLEVEL]) pparams.toneCurve.black = 0; + if (options.baBehav[ADDSET_TC_SHCOMP]) pparams.toneCurve.shcompr = 0; if (options.baBehav[ADDSET_TC_CONTRAST]) pparams.toneCurve.contrast = 0; if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) pparams.sh.highlights = 0; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index a5b92cffd..5a2fffbb1 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -35,6 +35,7 @@ void ParamsEdited::set (bool v) { toneCurve.saturation = v; toneCurve.shcompr = v; toneCurve.hlcompr = v; + toneCurve.hlcomprthresh = v; toneCurve.autoexp = v; toneCurve.clip = v; toneCurve.expcomp = v; @@ -177,6 +178,7 @@ void ParamsEdited::initFrom (const std::vector toneCurve.saturation = toneCurve.saturation && p.toneCurve.saturation == other.toneCurve.saturation; toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr; toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr; + toneCurve.hlcomprthresh = toneCurve.hlcomprthresh && p.toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh; toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp; toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip; toneCurve.expcomp = toneCurve.expcomp && p.toneCurve.expcomp == other.toneCurve.expcomp; @@ -322,12 +324,13 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (toneCurve.brightness) toEdit.toneCurve.brightness = options.baBehav[ADDSET_TC_BRIGHTNESS] ? toEdit.toneCurve.brightness + mods.toneCurve.brightness : mods.toneCurve.brightness; if (toneCurve.black) toEdit.toneCurve.black = options.baBehav[ADDSET_TC_BLACKLEVEL] ? toEdit.toneCurve.black + mods.toneCurve.black : mods.toneCurve.black; if (toneCurve.contrast) toEdit.toneCurve.contrast = options.baBehav[ADDSET_TC_CONTRAST] ? toEdit.toneCurve.contrast + mods.toneCurve.contrast : mods.toneCurve.contrast; - if (toneCurve.saturation) toEdit.toneCurve.saturation = options.baBehav[ADDSET_TC_SATURATION] ? toEdit.toneCurve.saturation + mods.toneCurve.saturation : mods.toneCurve.saturation; - if (toneCurve.shcompr) toEdit.toneCurve.shcompr = mods.toneCurve.shcompr; - if (toneCurve.hlcompr) toEdit.toneCurve.hlcompr = mods.toneCurve.hlcompr; + if (toneCurve.saturation) toEdit.toneCurve.saturation = options.baBehav[ADDSET_TC_SATURATION] ? toEdit.toneCurve.saturation + mods.toneCurve.saturation : mods.toneCurve.saturation; + if (toneCurve.shcompr) toEdit.toneCurve.shcompr = options.baBehav[ADDSET_TC_SHCOMP] ? toEdit.toneCurve.shcompr + mods.toneCurve.shcompr : mods.toneCurve.shcompr; if (toneCurve.autoexp) toEdit.toneCurve.autoexp = mods.toneCurve.autoexp; if (toneCurve.clip) toEdit.toneCurve.clip = mods.toneCurve.clip; if (toneCurve.expcomp) toEdit.toneCurve.expcomp = options.baBehav[ADDSET_TC_EXPCOMP] ? toEdit.toneCurve.expcomp + mods.toneCurve.expcomp : mods.toneCurve.expcomp; + if (toneCurve.hlcompr) toEdit.toneCurve.hlcompr = options.baBehav[ADDSET_TC_HLCOMPAMOUNT] ? toEdit.toneCurve.hlcompr + mods.toneCurve.hlcompr : mods.toneCurve.hlcompr; + if (toneCurve.hlcomprthresh) toEdit.toneCurve.hlcomprthresh = options.baBehav[ADDSET_TC_HLCOMPTHRESH] ? toEdit.toneCurve.hlcomprthresh + mods.toneCurve.hlcomprthresh : mods.toneCurve.hlcomprthresh; if (labCurve.lcurve) toEdit.labCurve.lcurve = mods.labCurve.lcurve; if (labCurve.acurve) toEdit.labCurve.acurve = mods.labCurve.acurve; if (labCurve.bcurve) toEdit.labCurve.bcurve = mods.labCurve.bcurve; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index b0de09599..4706b2891 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -34,6 +34,7 @@ class ToneCurveParamsEdited { bool saturation; bool shcompr; bool hlcompr; + bool hlcomprthresh; bool autoexp; bool clip; bool expcomp; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index ad90d866e..0a192511e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -133,8 +133,11 @@ Gtk::Widget* Preferences::getBatchProcPanel () { mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_EXPOSURE_LABEL")); appendBehavList (mi, M("TP_EXPOSURE_EXPCOMP"), ADDSET_TC_EXPCOMP, false); - appendBehavList (mi, M("TP_EXPOSURE_BRIGHTNESS"), ADDSET_TC_BRIGHTNESS, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRHIGHLIGHTS"), ADDSET_TC_HLCOMPAMOUNT, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), ADDSET_TC_HLCOMPTHRESH, false); appendBehavList (mi, M("TP_EXPOSURE_BLACKLEVEL"), ADDSET_TC_BLACKLEVEL, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRSHADOWS"), ADDSET_TC_SHCOMP, false); + appendBehavList (mi, M("TP_EXPOSURE_BRIGHTNESS"), ADDSET_TC_BRIGHTNESS, false); appendBehavList (mi, M("TP_EXPOSURE_CONTRAST"), ADDSET_TC_CONTRAST, false); appendBehavList (mi, M("TP_EXPOSURE_SATURATION"), ADDSET_TC_SATURATION, false); diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 67bb46329..0200aaab5 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -25,7 +25,7 @@ using namespace rtengine; using namespace rtengine::procparams; -ToneCurve::ToneCurve () : ToolPanel(), expAdd(false), blackAdd(false), brAdd(false), contrAdd(false) { +ToneCurve::ToneCurve () : ToolPanel(), expAdd(false),hlcompAdd(false),hlcompthreshAdd(false), blackAdd(false), shcompAdd(false), brAdd(false), contrAdd(false) { //----------- Auto Levels ---------------------------------- abox = Gtk::manage (new Gtk::HBox ()); @@ -53,6 +53,8 @@ ToneCurve::ToneCurve () : ToolPanel(), expAdd(false), blackAdd(false), brAdd(fal pack_start (*expcomp); hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 100, 1, 70)); pack_start (*hlcompr); + hlcomprthresh = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), 0, 100, 1, 0)); + pack_start (*hlcomprthresh); //----------- Black Level ---------------------------------- black = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BLACKLEVEL"), -16384, 32768, 1, 0)); @@ -90,6 +92,7 @@ ToneCurve::ToneCurve () : ToolPanel(), expAdd(false), blackAdd(false), brAdd(fal brightness->setAdjusterListener (this); black->setAdjusterListener (this); hlcompr->setAdjusterListener (this); + hlcomprthresh->setAdjusterListener (this); shcompr->setAdjusterListener (this); contrast->setAdjusterListener (this); saturation->setAdjusterListener (this); @@ -103,6 +106,7 @@ void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { expcomp->setEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); black->setEditedState (pedited->toneCurve.black ? Edited : UnEdited); hlcompr->setEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlcomprthresh->setEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); shcompr->setEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); brightness->setEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); contrast->setEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); @@ -121,6 +125,7 @@ void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { expcomp->setValue (pp->toneCurve.expcomp); black->setValue (pp->toneCurve.black); hlcompr->setValue (pp->toneCurve.hlcompr); + hlcomprthresh->setValue (pp->toneCurve.hlcomprthresh); shcompr->setValue (pp->toneCurve.shcompr); brightness->setValue (pp->toneCurve.brightness); contrast->setValue (pp->toneCurve.contrast); @@ -137,6 +142,7 @@ void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) { pp->toneCurve.expcomp = expcomp->getValue (); pp->toneCurve.black = (int)black->getValue (); pp->toneCurve.hlcompr = (int)hlcompr->getValue (); + pp->toneCurve.hlcomprthresh = (int)hlcomprthresh->getValue (); pp->toneCurve.shcompr = (int)shcompr->getValue (); pp->toneCurve.brightness = (int)brightness->getValue (); pp->toneCurve.contrast = (int)contrast->getValue (); @@ -147,6 +153,7 @@ void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) { pedited->toneCurve.expcomp = expcomp->getEditedState (); pedited->toneCurve.black = black->getEditedState (); pedited->toneCurve.hlcompr = hlcompr->getEditedState (); + pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState (); pedited->toneCurve.shcompr = shcompr->getEditedState (); pedited->toneCurve.brightness = brightness->getEditedState (); pedited->toneCurve.contrast = contrast->getEditedState (); @@ -163,6 +170,7 @@ void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pe brightness->setDefault (defParams->toneCurve.brightness); black->setDefault (defParams->toneCurve.black); hlcompr->setDefault (defParams->toneCurve.hlcompr); + hlcomprthresh->setDefault (defParams->toneCurve.hlcomprthresh); shcompr->setDefault (defParams->toneCurve.shcompr); contrast->setDefault (defParams->toneCurve.contrast); saturation->setDefault (defParams->toneCurve.saturation); @@ -171,6 +179,7 @@ void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pe expcomp->setDefaultEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); black->setDefaultEditedState (pedited->toneCurve.black ? Edited : UnEdited); hlcompr->setDefaultEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlcomprthresh->setDefaultEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); shcompr->setDefaultEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); brightness->setDefaultEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); contrast->setDefaultEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); @@ -180,6 +189,7 @@ void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pe expcomp->setDefaultEditedState (Irrelevant); black->setDefaultEditedState (Irrelevant); hlcompr->setDefaultEditedState (Irrelevant); + hlcomprthresh->setDefaultEditedState (Irrelevant); shcompr->setDefaultEditedState (Irrelevant); brightness->setDefaultEditedState (Irrelevant); contrast->setDefaultEditedState (Irrelevant); @@ -196,7 +206,7 @@ void ToneCurve::curveChanged () { void ToneCurve::adjusterChanged (Adjuster* a, double newval) { - if (autolevels->get_active() && (a==expcomp || a==black || a==hlcompr || a==shcompr)) { + if (autolevels->get_active() && (a==expcomp || a==black || a==hlcompr || a==hlcomprthresh || a==shcompr)) { autolevels->set_active (false); autolevels->set_inconsistent (false); } @@ -220,8 +230,8 @@ void ToneCurve::adjusterChanged (Adjuster* a, double newval) { listener->panelChanged (EvContrast, costr); else if (a==saturation) listener->panelChanged (EvSaturation, costr); - else if (a==hlcompr) - listener->panelChanged (EvHLCompr, costr); + else if (a==hlcompr || a==hlcomprthresh) + listener->panelChanged (EvHLCompr, Glib::ustring::compose ("%1=%2\n%3=%4",M("TP_EXPOSURE_COMPRHIGHLIGHTS"),(int)hlcompr->getValue(),M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"),(int)hlcomprthresh->getValue())); else if (a==shcompr) listener->panelChanged (EvSHCompr, costr); } @@ -281,6 +291,7 @@ void ToneCurve::waitForAutoExp () { brightness->setEnabled (false); black->setEnabled (false); hlcompr->setEnabled (false); + hlcomprthresh->setEnabled (false); shcompr->setEnabled (false); contrast->setEnabled (false); saturation->setEnabled (false); @@ -311,6 +322,7 @@ void ToneCurve::enableAll () { brightness->setEnabled (true); black->setEnabled (true); hlcompr->setEnabled (true); + hlcomprthresh->setEnabled (true); shcompr->setEnabled (true); contrast->setEnabled (true); saturation->setEnabled (true); @@ -339,6 +351,7 @@ void ToneCurve::setBatchMode (bool batchMode) { expcomp->showEditedCB (); black->showEditedCB (); hlcompr->showEditedCB (); + hlcomprthresh->showEditedCB (); shcompr->showEditedCB (); brightness->showEditedCB (); contrast->showEditedCB (); @@ -347,14 +360,20 @@ void ToneCurve::setBatchMode (bool batchMode) { curveEditorG->setBatchMode (batchMode); } -void ToneCurve::setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, bool contradd, bool satadd) { +void ToneCurve::setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd) { if ((!expAdd && expadd) || (expAdd && !expadd)) expcomp->setLimits (-5, 5, 0.01, 0); + if ((!hlcompAdd && hlcompadd) || (hlcompAdd && !hlcompadd)) + hlcompr->setLimits (0, 100, 1, 0); + if ((!hlcompthreshAdd && hlcompthreshadd) || (hlcompthreshAdd && !hlcompthreshadd)) + hlcomprthresh->setLimits (0, 100, 1, 0); if (!blackAdd && blackadd) black->setLimits (0, 16384, 1, 0); else if (blackAdd && !blackadd) black->setLimits (0, 32768, 1, 0); + if ((!shcompAdd && shcompadd) || (shcompAdd && !shcompadd)) + shcompr->setLimits (0, 100, 1, 0); if ((!brAdd && bradd) || (brAdd && !bradd)) brightness->setLimits (-100, 100, 1, 0); if ((!contrAdd && contradd) || (contrAdd && !contradd)) @@ -363,7 +382,10 @@ void ToneCurve::setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, boo saturation->setLimits (-100, 100, 1, 0); expAdd = expadd; + hlcompAdd = hlcompadd; + hlcompthreshAdd = hlcompthreshadd; blackAdd = blackadd; + shcompAdd = shcompadd; brAdd = bradd; contrAdd = contradd; satAdd = satadd; diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 0f3ed8eff..63aca20aa 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -36,11 +36,12 @@ class ToneCurve : public Gtk::VBox, public AdjusterListener, public ToolPanel, p Adjuster* brightness; Adjuster* black; Adjuster* hlcompr; + Adjuster* hlcomprthresh; Adjuster* shcompr; Adjuster* contrast; Adjuster* saturation; - bool expAdd, blackAdd, brAdd, contrAdd, satAdd, clipDirty, lastAuto; + bool expAdd,hlcompAdd,hlcompthreshAdd, blackAdd, shcompAdd, brAdd, contrAdd, satAdd, clipDirty, lastAuto; sigc::connection autoconn; CurveEditorGroup* curveEditorG; CurveEditor* shape; @@ -55,7 +56,7 @@ class ToneCurve : public Gtk::VBox, public AdjusterListener, public ToolPanel, p void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); void setBatchMode (bool batchMode); - void setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, bool contradd, bool satadd); + void setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd); void adjusterChanged (Adjuster* a, double newval); void autolevels_toggled ();