From 6bc115fe8ba72bf4308f19c5023a2636f2671403 Mon Sep 17 00:00:00 2001 From: Ingo Date: Wed, 1 Oct 2014 21:29:14 +0200 Subject: [PATCH] Speedup for thumbnail processing, Issue 2503 --- rtengine/colortemp.cc | 65 +++++----- rtengine/colortemp.h | 18 +-- rtengine/curves.cc | 235 ++++++++++++++++++---------------- rtengine/curves.h | 28 +++- rtengine/diagonalcurves.cc | 4 +- rtengine/imagefloat.cc | 27 ++-- rtengine/improccoordinator.cc | 118 +++++++++-------- rtengine/improccoordinator.h | 2 - rtengine/rtthumbnail.cc | 12 +- 9 files changed, 279 insertions(+), 230 deletions(-) diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 39dce8096..cca40eaa0 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -110,8 +110,7 @@ void ColorTemp::clip (double &temp, double &green, double &equal) { equal = MAXEQUAL; } -ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) { - method = "Custom"; +ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e), method("Custom") { mul2temp (mulr, mulg, mulb, equal, temp, green); } @@ -1205,7 +1204,7 @@ void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00,doub } -void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,double &Xxyz, double &Zxyz) { +void ColorTemp::temp2mulxyz (double tem, double gree, std::string method ,double &Xxyz, double &Zxyz) { double xD, yD, x_D, y_D, interm; double x, y, z; @@ -1239,10 +1238,10 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub else if(method == "Flash 6500K" ) spectrum_to_xyz_preset(Flash6500_spect, x, y, z); else { // otherwise we use the Temp+Green generic solution - if (tem <= 4000) { + if (tem <= INITIALBLACKBODY) { // if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K... // of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw). - spectrum_to_xyz_blackbody(0., 0., tem, x, y, z); + spectrum_to_xyz_blackbody(tem, x, y, z); } else { // from 4000K up to 25000K: using the D illuminant (daylight) which is standard @@ -1260,7 +1259,7 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub interm=(0.0241+0.2562*x_D-0.734*y_D); m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm; m2=(0.03-31.4424*x_D+30.0717*y_D)/interm; - spectrum_to_xyz_daylight(m1, m2, 0., x, y, z); + spectrum_to_xyz_daylight(m1, m2, x, y, z); xD=x;yD=y; } @@ -1307,7 +1306,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double Lpal[50],apal[50],bpal[50]; int palet=-1; - bool palette=true; + bool palette=false; // double tempalet; // correlated temperature // We first test for specially handled methods @@ -1341,10 +1340,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, else if(method == "Flash 6500K" ) {spectrum_to_xyz_preset(Flash6500_spect, x, y, z);palet=27; /*tempalet=6500;*/ } else { // otherwise we use the Temp+Green generic solution - if (temp <= 4000) { + if (temp <= INITIALBLACKBODY) { // if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K... // of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw). - spectrum_to_xyz_blackbody(0., 0., temp, x, y, z);palet=28; + spectrum_to_xyz_blackbody(temp, x, y, z);palet=28; } else { // from 4000K up to 25000K: using the D illuminant (daylight) which is standard @@ -1362,7 +1361,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, interm=(0.0241+0.2562*x_D-0.734*y_D); m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm; m2=(0.03-31.4424*x_D+30.0717*y_D)/interm; - spectrum_to_xyz_daylight(m1, m2, 0., x, y, z); + spectrum_to_xyz_daylight(m1, m2, x, y, z); xD=x;yD=y; } } @@ -1442,9 +1441,9 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, } } else if(palet>=28) { - if(temp<4000) { + if(tempequal = equal; mul2temp (rmul, gmul, bmul, this->equal, temp, green); } void useDefaults (const double equal) { temp = 6504; green = 1.0; this->equal = equal; } // Values copied from procparams.cc - inline Glib::ustring getMethod() { return method; } + inline std::string getMethod() { return method; } inline double getTemp () { return temp; } inline double getGreen () { return green; } inline double getEqual () { return equal; } @@ -71,7 +71,7 @@ class ColorTemp { void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green); void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul); - static void temp2mulxyz (double tem, double gree, Glib::ustring method, double &Xxyz, double &Zxyz); + static void temp2mulxyz (double tem, double gree, std::string method, double &Xxyz, double &Zxyz); int XYZtoCorColorTemp(double x0,double y0 ,double z0, double &temp); static void cieCAT02(double Xw, double Yw, double Zw,double &CAM02BB00,double &CAM02BB01,double &CAM02BB02, double &CAM02BB10,double &CAM02BB11,double &CAM02BB12,double &CAM02BB20,double &CAM02BB21,double &CAM02BB22, double adap ); @@ -204,8 +204,8 @@ class ColorTemp { bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; } bool operator!= (const ColorTemp& other) { return !(*this==other); } - static double blackbody_spect (double wavelength, double m1, double m2, double temp); - static double daylight_spect (double wavelength, double m1, double m2, double temp); + static double blackbody_spect (double wavelength, double temperature); + static double daylight_spect (double wavelength, double m1, double m2); static const double Cloudy6200_spect[97]; static const double Daylight5300_spect[97]; static const double Shade7600_spect[97]; @@ -294,12 +294,12 @@ class ColorTemp { static const double ColabSky60_0_m31_spect[97];//Sky L=60 static const double ColabSky42_0_m24_spect[97];//Sky L=42 - static void spectrum_to_xyz_daylight (double _m1, double _m2, double _temp, double &x, double &y, double &z); - static void spectrum_to_xyz_blackbody (double _m1, double _m2, double _temp, double &x, double &y, double &z); + static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z); + static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z); static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z); - static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz); - static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz); static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz); diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 5b127e8cc..d0b28b4ae 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -29,7 +29,7 @@ #include "array2D.h" #include "LUT.h" #include "curves.h" - +#include "opthelper.h" #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -136,13 +136,14 @@ namespace rtengine { const double CurveFactory::sRGBGamma = 2.2; const double CurveFactory::sRGBGammaCurve = 2.4; - void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) { + SSEFUNCTION void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) { + if (needed) { LUTf lutCurve (65536); for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { // change to [0,1] range - double val = (double)i / 65535.0; + float val = (float)i / 65535.f; // apply custom/parametric/NURBS curve, if any val = diagCurve->getVal (val); // store result in a temporary array @@ -162,14 +163,24 @@ namespace rtengine { } for (int i=0; i<=0xffff; i++) { - outCurve[i] = (65535.0 * lutCurve[i]); + outCurve[i] = (65535.f * lutCurve[i]); } } else { +#ifdef __SSE2__ + __m128 fourv = _mm_set1_ps(4.f); + __m128 iv = _mm_set_ps(3.f,2.f,1.f,0.f); + for (int i=0; i<=0xfffc; i+=4) { + _mm_storeu_ps(&outCurve[i],iv); + iv += fourv; + } +#else for (int i=0; i<=0xffff; i++) { outCurve[i] = (float)i; } +#endif } + } void CurveFactory::updatechroma ( @@ -214,18 +225,6 @@ void CurveFactory::curveLightBrightColor ( ColorAppearance & customColCurve3, int skip) { - LUTf dcurve(65536,0); - LUTf dCcurve(65536,0); - - float val; - for (int i=0; i<32768; i++) { - val = (double)i / 32767.0; - dcurve[i] = CLIPD(val); - } - for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma - val = (double)i / 47999.0; - dCcurve[i] = CLIPD(val); - } outBeforeCCurveHistogram.clear(); outBeforeCCurveHistogramC.clear(); @@ -290,22 +289,19 @@ void CurveFactory::curveLightBrightColor ( tcurve = NULL; } } - for (int i=0; i<32768; i++) { - float val; - - if (histNeeded) { - float hval = dcurve[i]; - int hi = (int)(255.0*CLIPD(hval)); - outBeforeCCurveHistogram[hi] += histogram[i] ; - } + if (histNeeded) { + for (int i=0; i<32768; i++) { + double hval = CLIPD((double)i / 32767.0); + int hi = (int)(255.0*hval); + outBeforeCCurveHistogram[hi] += histogram[i] ; + } } - for (int i=0; i<48000; i++) {//32768*1.414 + ... - float val; - if (histNeededC) { - float hval = dCcurve[i]; - int hi = (int)(255.0*CLIPD(hval)); // - outBeforeCCurveHistogramC[hi] += histogramC[i] ; - } + if (histNeededC) { + for (int i=0; i<48000; i++) {//32768*1.414 + ... + double hval = CLIPD((double)i / 47999.0); + int hi = (int)(255.0*hval); // + outBeforeCCurveHistogramC[hi] += histogramC[i] ; + } } if (tcurve) delete tcurve; @@ -344,13 +340,6 @@ void CurveFactory::curveBW ( LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) { - LUTf dcurve(65536,0); - - float val; - for (int i=0; i<32768; i++) { - val = (double)i / 32767.0; - dcurve[i] = CLIPD(val); - } outBeforeCCurveHistogrambw.clear(); bool histNeeded = false; @@ -386,15 +375,20 @@ void CurveFactory::curveBW ( tcurve = NULL; } // create first curve if needed - - for (int i=0; i<32768; i++) { + if (histNeeded) { + LUTf dcurve(65536,0); + float val; - - if (histNeeded) { - float hval = dcurve[i]; - int hi = (int)(255.0*CLIPD(hval)); - outBeforeCCurveHistogrambw[hi] += histogrambw[i] ; + for (int i=0; i<32768; i++) { + val = (float)i / 32767.f; + dcurve[i] = CLIPD(val); } + + for (int i=0; i<32768; i++) { + float hval = dcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); + outBeforeCCurveHistogrambw[hi] += histogrambw[i] ; + } } if (tcurve) delete tcurve; @@ -404,12 +398,6 @@ void CurveFactory::curveBW ( void CurveFactory::curveCL ( bool & clcutili,const std::vector& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram,int skip){ bool needed; DiagonalCurve* dCurve = NULL; - LUTf dCcurve(65536,0); - - float val; - for (int i=0; i<50000; i++) { //# 32768*1.414 approximation maxi for chroma - dCcurve[i] = (float)i / 49999.0; - } if (outBeforeCLurveHistogram) outBeforeCLurveHistogram.clear(); @@ -424,14 +412,12 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector& clcurveP if (dCurve && !dCurve->isIdentity()) {needed = true;clcutili=true;} } - for (int i=0; i<50000; i++) {//32768*1.414 + ... - float val; - if (histNeededCL) { - float hval = dCcurve[i]; - int hi = (int)(255.0*CLIPD(hval)); // + if(histNeededCL) + for (int i=0; i<50000; i++) {//32768*1.414 + ... + int hi = (int)(255.0*CLIPD((float)i / 49999.0)); // outBeforeCLurveHistogram[hi] += histogramcl[i] ; } - } + fillCurveArray(dCurve, clCurve, skip, needed); if (dCurve) { @@ -444,12 +430,6 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector& clcurveP void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector& clcurvePoints, LUTf & clToningCurve,int skip){ bool needed; DiagonalCurve* dCurve = NULL; - LUTf dCcurve(65536,0); - - float val; - for (int i=0; i<32768; i++) { - dCcurve[i] = (float)i / 32767.0; - } needed = false; if (!clcurvePoints.empty() && clcurvePoints[0]!=0) { @@ -470,12 +450,7 @@ void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector& llcurvePoints, LUTf & llToningCurve, int skip){ bool needed; DiagonalCurve* dCurve = NULL; - LUTf dCcurve(65536,0); - - float val; - for (int i=0; i<32768; i++) { - dCcurve[i] = (float)i / 32767.0; - } + needed = false; if (!llcurvePoints.empty() && llcurvePoints[0]!=0) { dCurve = new DiagonalCurve (llcurvePoints, CURVES_MIN_POLY_POINTS/skip); @@ -506,10 +481,11 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vectorisIdentity()) {needed = true;ccutili=true;} } - for (int i=0; iisIdentity()) {needed = true;cclutili=true;} } - for (int i=0; i& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, @@ -643,8 +617,6 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector1.; @@ -695,38 +667,77 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector0.0) - { - if (val>0.0) { - float R = val*comp/(scale-shoulder); - hlCurve[i] = log(1.0+R*exp_scale)/R; - } else { - hlCurve[i]=exp_scale; - } - } else { + if (comp<=0.0f) + for (int i=0; i<0x10000; i++) hlCurve[i]=exp_scale; + else { + for (int i=0; i<=shoulder; i++) + hlCurve[i]=exp_scale; + float scalemshoulder = scale - shoulder; + + // SSE makes more sense than omp here +#ifdef __SSE2__ + int i; + __m128 exp_scalev = _mm_set1_ps(exp_scale); + __m128 scalemshoulderv = _mm_set1_ps(scalemshoulder); + __m128 compv = _mm_set1_ps(comp); + __m128 valv = _mm_set_ps(4.f,3.f,2.f,1.f); + __m128 onev = _mm_set1_ps(1.f); + __m128 fourv = _mm_set1_ps(4.f); + for (i=shoulder+1; i<0xFFFD; i+=4) { + // change to [0,1] range + __m128 Rv = valv*compv/(scalemshoulderv); + _mm_storeu_ps(&hlCurve[i],xlogf(onev+Rv*exp_scalev)/Rv); + valv += fourv; } - - //%%%%%%%%%%%%%%%%%%%%%%%%%% - // change to [0,1] range - if (i!=0) { + for (; i<0x10000; i++) { + // change to [0,1] range + float val = (float)i-shoulder; + float R = val*comp/(scalemshoulder); + hlCurve[i] = xlogf(1.f+R*exp_scale)/R; + } + +#else + for (int i=shoulder+1; i<0x10000; i++) { + // change to [0,1] range + float val = (float)i-shoulder; + float R = val*comp/(scalemshoulder); + hlCurve[i] = xlogf(1.f+R*exp_scale)/R; + } +#endif + + } + + + // curve without contrast + LUTf dcurve(0x10000); + + //%%%%%%%%%%%%%%%%%%%%%%%%%% + // change to [0,1] range + + float val = 1.f/65535.f; + float val2 = simplebasecurve (val, black, 0.015*shcompr); + shCurve[0] = CLIPD(val2)/val; + val = 0.0; + // gamma correction + if (gamma_>1.) + val = gamma (val, gamma_, start, slope, mul, add); + + // apply brightness curve + if (brightcurve) + val = brightcurve->getVal (val); // TODO: getVal(double) is very slow! Optimize with a LUTf + + // store result in a temporary array + dcurve[0] = CLIPD(val); + +#pragma omp parallel for + for (int i=1; i<0x10000; i++) { + float val; val = (float)i / 65535.0f; - } else { - val = 1.0/65535.0; - } - float val2 = basecurve (val, 1.0, black, 1.0, 0.0, 1.5*shcompr/100.0); + float val2 = simplebasecurve (val, black, 0.015*shcompr); shCurve[i] = CLIPD(val2)/val; - //%%%%%%%%%%%%%%%%%%%%%%%%%% - // change to [0,1] range - val = (double)i / 65535.0; - // gamma correction if (gamma_>1.) val = gamma (val, gamma_, start, slope, mul, add); @@ -750,16 +761,17 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector0.00001 || contr<-0.00001) { // compute mean luminance of the image with the curve applied - int sum = 0; + unsigned int sum = 0; float avg = 0; //double sqavg = 0; for (int i=0; i<=0xffff; i++) { float fi=i; - fi = hlCurve[fi]*fi; + fi *= hlCurve[i]; avg += dcurve[(int)(shCurve[fi]*fi)] * histogram[i]; //sqavg += dcurve[i]*dcurve[i] * histogram[i]; sum += histogram[i]; } + avg /= sum; //sqavg /= sum; //double stddev = sqrt(sqavg-avg*avg); @@ -783,7 +795,6 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vectorgetVal (dcurve[i]); @@ -874,7 +885,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vectorx1 || sr<0.001) return 1-(1-x)*m; else + { + double y1 = 1-(1-x1)*m; return y1+m*(x-x1)-(1-m)*SQR(SQR(1-x/x1)); + } } // tone curve base. a: slope (from exp.comp.), b: black point normalized by 65535, // D: max. x value (can be>1), hr,sr: highlight,shadow recovery @@ -123,6 +125,26 @@ class CurveFactory { return y+(x-m)*slope; } } + static inline double simplebasecurve (double x, double b, double sr) { + // a = 1, D = 1, hr = 0 (unused for a = D = 1) + if (b<0) { + double m = 0.5;//midpoint + double slope = 1.0+b;//slope of straight line between (0,-b) and (1,1) + double y = -b+m*slope;//value at midpoint + if (x>m) + return y + (x - m)*slope;//value on straight line between (m,y) and (1,1) + else + return y*clower2(x/m, slope*m/y, 2.0-sr); + } else { + double slope = 1.0/(1.0-b); + double m = b+(1-b)*0.25; + double y = (m-b)*slope; + if (x<=m) + return b==0 ? x*slope : clower (x/m, slope*m/y, sr) * y; + else + return y+(x-m)*slope; + } + } public: diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index fe816b736..abc0349f1 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -285,8 +285,8 @@ double DiagonalCurve::getVal (double t) const { return t; } - unsigned int k_lo = 0; - unsigned int k_hi = 0; + unsigned int k_lo; + unsigned int k_hi; k_lo = hash.at(i).smallerValue; k_hi = hash.at(i).higherValue; diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 2b3f53137..fd71a7108 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -345,6 +345,7 @@ void Imagefloat::normalizeFloatTo65535() { } void Imagefloat::calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist) { + hist.clear(); // Set up factors to calc the lightness @@ -359,21 +360,29 @@ void Imagefloat::calcCroppedHistogram(const ProcParams ¶ms, float scale, LUT int x1, x2, y1, y2; params.crop.mapToResized(width, height, scale, x1, x2, y1, y2); -#ifdef _OPENMP -#pragma omp parallel for -#endif +#pragma omp parallel +{ + LUTu histThr(65536); + histThr.clear(); +#pragma omp for nowait for (int y=y1; y65535) i=65535; -#ifdef _OPENMP -// Access to hist[] must be atomic. In this case, we may need to see if this parallelization is worth it -#pragma omp atomic -#endif - hist[i]++; + if (i<0) + i=0; + else if (i>65535) + i=65535; + histThr[i]++; } } +#pragma omp critical +{ + for(int i=0;i<=0xffff;i++) + hist[i] += histThr[i]; +} +} + } // Parallelized transformation; create transform with cmsFLAGS_NOCACHE! diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8ccd7184e..da183cc07 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -51,7 +51,6 @@ ImProcCoordinator::ImProcCoordinator () lhist16(65536), lhist16Cropped(65536), lhist16CAM(65536), lhist16CroppedCAM(65536), lhist16CCAM(65536), - lhist16CCAMAF(65536), lhist16ClabAF(65536), histCropped(65536), lhist16Clad(65536),lhist16CLlad(65536), lhist16LClad(65536), lhist16LLClad(65536), @@ -121,7 +120,6 @@ DetailedCrop* ImProcCoordinator::createCrop (::EditDataProvider *editDataProvid void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { MyMutex::MyLock processingLock(mProcessing); - int numofphases = 14; int readyphase = 0; @@ -330,9 +328,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); if ((todo & M_RGBCURVE) || (todo & M_CROP)) { - 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, @@ -367,10 +365,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { CurveFactory::curveBW (params.blackwhite.beforeCurve,params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW,scale==1 ? 1 : 1); - //initialize rrm bbm ggm different from zero to avoid black screen in some cases - double rrm=33.; - double ggm=33.; - double bbm=33.; float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f); @@ -412,6 +406,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } // if it's just crop we just need the histogram, no image updates if ( todo & M_RGBCURVE ) { + //initialize rrm bbm ggm different from zero to avoid black screen in some cases + double rrm=33.; + double ggm=33.; + double bbm=33.; ipf.rgbProc (oprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2,beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) { @@ -426,20 +424,18 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } // correct GUI black and white with value } - // compute L channel histogram int x1, y1, x2, y2, pos; params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); lhist16.clear(); lhist16Cropped.clear(); lhist16Clad.clear(); lhist16CLlad.clear();lhist16LLClad.clear(); - lhist16ClabAF.clear(); for (int x=0; xL[x][y])); lhist16[pos]++; - if (y>=y1 && y=x1 && x=y1 && y=x1 && x170.. @@ -472,7 +468,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { else if (params.icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;} else if (params.icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;} */ - adjustr=1.f; CurveFactory::complexsgnCurve (adjustr, autili, butili,ccutili,cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve,chroma_acurve, chroma_bcurve, satcurve,lhskcurve, lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale==1 ? 1 : 16); @@ -534,34 +529,38 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } //} - //L histo and Chroma histo for ciecam - // histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C - int x1, y1, x2, y2, pos, posc; - params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); - lhist16CAM.clear(); lhist16CroppedCAM.clear(); - lhist16CCAM.clear(); - lhist16CCAMAF.clear(); - for (int x=0; xL[x][y])); - posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y])); - if(!params.colorappearance.datacie) lhist16CCAM[posc]++; - if(!params.colorappearance.datacie)lhist16CAM[pos]++; - if (y>=y1 && y=x1 && xL[x][y])); + if(!params.colorappearance.datacie) { + posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y])); + lhist16CAM[pos]++; + lhist16CCAM[posc]++; + } + if (y>=y1 && y=x1 && xgetMetaData()->getFNumber (); // F number float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed @@ -757,6 +756,26 @@ void ImProcCoordinator::updateLRGBHistograms () { int x1, y1, x2, y2; params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); +#pragma omp parallel sections +{ +#pragma omp section +{ + histChroma.clear(); + for (int i=y1; ia[i][j]) + SQR(nprevl->b[i][j]))/188.f)]++;//188 = 48000/256 + } +} +#pragma omp section +{ + histLuma.clear(); + for (int i=y1; iL[i][j]/128.f)]++; + } +} +#pragma omp section +{ histRed.clear(); histGreen.clear(); histBlue.clear(); @@ -773,22 +792,9 @@ void ImProcCoordinator::updateLRGBHistograms () { histBlue[b]++; } } - histLuma.clear(); - histChroma.clear(); - for (int i=y1; ia[i][j]*nprevl->a[i][j] + nprevl->b[i][j]*nprevl->b[i][j]))/188]++;//188 = 48000/256 - histLuma[(int)(nprevl->L[i][j]/128)]++; - } +} +} - /*for (int i=0; i<256; i++) { - Lhist[i] = (int)(256*sqrt(Lhist[i])); - rhist[i] = (int)(256*sqrt(rhist[i])); - ghist[i] = (int)(256*sqrt(ghist[i])); - bhist[i] = (int)(256*sqrt(bhist[i])); - bcrgbhist[i] = (int)(256*sqrt(bcrgbhist[i])); - bcLhist[i] = (int)(256*sqrt(bcLhist[i])); - }*/ } void ImProcCoordinator::progress (Glib::ustring str, int pr) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 3ab5bc9b8..79c7351bd 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -99,8 +99,6 @@ class ImProcCoordinator : public StagedImageProcessor { LUTu lhist16,lhist16Cropped; LUTu lhist16CAM,lhist16CroppedCAM; LUTu lhist16CCAM; - LUTu lhist16CCAMAF; - LUTu lhist16ClabAF; LUTu histCropped; LUTu lhist16Clad,lhist16CLlad,lhist16LClad,lhist16LLClad; LUTu histRed, histRedRaw; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 6a0ea177b..62292a33e 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -870,8 +870,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); //params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili); - LabImage* labView = new LabImage (fw,fh); - CieImage* cieView = new CieImage (fw,fh); bool clctoningutili=false; bool llctoningutili=false; CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve,scale==1 ? 1 : 16); @@ -899,6 +897,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool + + LabImage* labView = new LabImage (fw,fh); ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh); // freeing up some memory @@ -940,10 +940,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei hist16C, hist16C, dummy, dummy, 16); //ipf.luminanceCurve (labView, labView, curve); + + ipf.chromiLuminanceCurve (NULL, 1,labView, labView, curve1, curve2, satcurve,lhskcurve, clcurve, curve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); ipf.vibrance(labView); - int begh = 0, endh = labView->H; if((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) ipf.EPDToneMap(labView,5,6); @@ -961,6 +962,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei 16); if(params.colorappearance.enabled){ + int begh = 0, endh = labView->H; float** buffer = new float*[fh]; for (int i=0; iwidth / fh; @@ -1030,6 +1033,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei else ix += 3; }*/ + return readyImg; }