diff --git a/rtengine/LUT.h b/rtengine/LUT.h index 6203cfb92..00c7b1858 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -64,10 +64,10 @@ #define LUT_CLIP_ABOVE 2 #define LUTf LUT -#define LUTi LUT -#define LUTu LUT +#define LUTi LUT +#define LUTu LUT #define LUTd LUT -#define LUTuc LUT +#define LUTuc LUT #include #ifndef NDEBUG @@ -155,41 +155,6 @@ public: #endif } - LUT(int s, T * source, int flags = 0xfffffff) - { -#ifndef NDEBUG - - if (s <= 0) { - printf("s<=0!\n"); - } - - assert (s > 0); - - if (!source) { - printf("source is NULL!\n"); - } - - assert (source != nullptr); -#endif - dirty = false; // Assumption - clip = flags; - data = new T[s]; - owner = 1; - size = s; - upperBound = size - 1; - maxs = size - 2; - maxsf = (float)maxs; -#if defined( __SSE2__ ) && defined( __x86_64__ ) - maxsv = F2V( size - 2); - sizeiv = _mm_set1_epi32( (int)(size - 1) ); - sizev = F2V( size - 1 ); -#endif - - for (int i = 0; i < s; i++) { - data[i] = source[i]; - } - } - LUT() { data = nullptr; @@ -224,7 +189,7 @@ public: * For a LUT(500), it will return 499, because 500 elements, starting from 0, goes up to 499 * @return number of element in the array */ - int getUpperBound() + unsigned int getUpperBound() const { return size > 0 ? upperBound : 0; } @@ -258,7 +223,8 @@ public: return *this; } - // handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (unsigned int). + // handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (uint32_t). + template::value>::type> LUT & operator+=(LUT &rhs) { if (rhs.size == this->size) { @@ -274,7 +240,8 @@ public: return *this; } - // mutliply all elements of LUT with a constant float value + // multiply all elements of LUT with a constant float value + template::value>::type> LUT & operator*=(float factor) { #ifdef _OPENMP @@ -362,6 +329,7 @@ public: } */ #ifdef __SSE4_1__ + template::value>::type> vfloat operator[](vint idxv ) const { vfloat tempv, p1v; @@ -401,6 +369,7 @@ public: return p1v; } #else + template::value>::type> vfloat operator[](vint idxv ) const { vfloat tempv, p1v; @@ -445,6 +414,7 @@ public: #endif // use with float indices + template::value>::type> T operator[](float index) const { int idx = (int)index; // don't use floor! The difference in negative space is no problems here @@ -470,9 +440,10 @@ public: } // Return the value for "index" that is in the [0-1] range. + template::value>::type> T getVal01 (float index) const { - index *= float(upperBound); + index *= (float)upperBound; int idx = (int)index; // don't use floor! The difference in negative space is no problems here if (index < 0.f) { @@ -542,6 +513,7 @@ public: } // create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor) + template::value>::type> void makeIdentity(float divisor = 1.f) { if(divisor == 1.f) { @@ -555,9 +527,11 @@ public: } } - // compress a LUT with size y into a LUT with size y (y &dest, unsigned int numVals) const + // compress a LUT with size y into a LUT with size x (y>x) + template::value>::type> + void compressTo(LUT &dest, unsigned int numVals = 0) const { + numVals = numVals == 0 ? size : numVals; numVals = std::min(numVals, size); float divisor = numVals - 1; float mult = (dest.size - 1) / divisor; @@ -568,7 +542,8 @@ public: } } - // compress a LUT with size y into a LUT with size y (y with size y into a LUT with size x (y>x) by using the passTrough LUT to calculate indexes + template::value>::type> void compressTo(LUT &dest, unsigned int numVals, const LUT &passThrough) const { if(passThrough) { @@ -583,15 +558,74 @@ public: } } + // compute sum and average of a LUT + template::value>::type> + void getSumAndAverage(float &sum, float &avg) const + { + sum = 0.f; + avg = 0.f; + int i = 0; +#ifdef __SSE2__ + vfloat iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f); + vfloat fourv = F2V(4.f); + vint sumv = (vint)ZEROV; + vfloat avgv = ZEROV; + + for(; i < size - 3; i += 4) { + vint datav = _mm_loadu_si128((__m128i*)&data[i]); + sumv += datav; + avgv += iv * _mm_cvtepi32_ps(datav); + iv += fourv; + + } + + sum = vhadd(_mm_cvtepi32_ps(sumv)); + avg = vhadd(avgv); +#endif + + for (; i < size; i++) { + T val = data[i]; + sum += val; + avg += i * val; + } + + avg /= sum; + } + + + template::value>::type> void makeConstant(float value, unsigned int numVals = 0) { numVals = numVals == 0 ? size : numVals; numVals = std::min(numVals, size); + for(unsigned int i = 0; i < numVals; i++) { data[i] = value; } } + // share the buffer with another LUT, handy for same data but different clip flags + void share(const LUT &source, int flags = 0xfffffff) + { + if (owner && data) { + delete[] data; + } + + dirty = false; // Assumption + clip = flags; + data = source.data; + owner = 0; + size = source.getSize(); + upperBound = size - 1; + maxs = size - 2; + maxsf = (float)maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + maxsv = F2V( size - 2); + sizeiv = _mm_set1_epi32( (int)(size - 1) ); + sizev = F2V( size - 1 ); +#endif + } + }; diff --git a/rtengine/color.cc b/rtengine/color.cc index f5a8c86a3..db6824486 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -139,7 +139,6 @@ void Color::init () constexpr auto maxindex = 65536; cachef(maxindex, LUT_CLIP_BELOW); - gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); gammatab(maxindex, 0); gammatabThumb(maxindex, 0); @@ -185,11 +184,14 @@ void Color::init () #ifdef _OPENMP #pragma omp section #endif + { + for (int i = 0; i < maxindex; i++) + { + gammatab_srgb[i] = 65535.0 * gamma2(i / 65535.0); + } - for (int i = 0; i < maxindex; i++) { - gammatab_srgb[i] = gamma2curve[i] = 65535.0 * gamma2(i / 65535.0); // two lookup tables with same content but one clips and one does not clip + gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags } - #ifdef _OPENMP #pragma omp section #endif diff --git a/rtengine/curves.cc b/rtengine/curves.cc index e8a1bc88e..724ec7280 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -294,34 +294,20 @@ void CurveFactory::curveBW ( const std::vector& curvePointsbw, const std } // add curve Lab : C=f(L) -void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, const LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip) +void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, int skip) { bool needed = false; DiagonalCurve* dCurve = nullptr; - if (outBeforeCLurveHistogram) { - outBeforeCLurveHistogram.clear(); - } - - bool histNeededCL = false; - if (!clcurvePoints.empty() && clcurvePoints[0] != 0) { dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip); - if (outBeforeCLurveHistogram) { - histNeededCL = true; - } - if (dCurve && !dCurve->isIdentity()) { needed = true; clcutili = true; } } - if(histNeededCL) { - histogramcl.compressTo(outBeforeCLurveHistogram, 50000); - } - fillCurveArray(dCurve, clCurve, skip, needed); if (dCurve) { @@ -543,15 +529,15 @@ void CurveFactory::complexsgnCurve (float adjustr, bool & autili, bool & butili //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, - double shcompr, double br, double contr, - procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, - procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, - LUTu & histogram, LUTu & histogramCropped, - LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, - LUTu & outBeforeCCurveHistogram, - ToneCurve & customToneCurve1, - ToneCurve & customToneCurve2, - int skip) + double shcompr, double br, double contr, + procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, + procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, + LUTu & histogram, LUTu & histogramCropped, + LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, + LUTu & outBeforeCCurveHistogram, + ToneCurve & customToneCurve1, + ToneCurve & customToneCurve2, + int skip) { // the curve shapes are defined in sRGB gamma, but the output curves will operate on linear floating point data, @@ -621,34 +607,40 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double #ifdef __SSE2__ int i = shoulder + 1; - if(i&1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference + + if(i & 1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference // change to [0,1] range float val = (float)i - shoulder; float R = val * comp / (scalemshoulder); hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision i++; } + vdouble onev = _mm_set1_pd(1.0); - vdouble Rv = _mm_set_pd((i+1-shoulder) * (double)comp/ scalemshoulder,(i-shoulder) * (double)comp/ scalemshoulder); + vdouble Rv = _mm_set_pd((i + 1 - shoulder) * (double)comp / scalemshoulder, (i - shoulder) * (double)comp / scalemshoulder); vdouble incrementv = _mm_set1_pd(2.0 * comp / scalemshoulder); vdouble exp_scalev = _mm_set1_pd(exp_scale); - for (; i < 0x10000; i+=2) { + + for (; i < 0x10000; i += 2) { // change to [0,1] range vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv; vfloat resultfv = _mm_cvtpd_ps(resultv); _mm_store_ss(&hlCurve[i], resultfv); - resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1,1,1,1)); - _mm_store_ss(&hlCurve[i+1], resultfv); + resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1, 1, 1, 1)); + _mm_store_ss(&hlCurve[i + 1], resultfv); Rv += incrementv; } + #else float R = comp / scalemshoulder; float increment = R; + for (int i = shoulder + 1; i < 0x10000; i++) { // change to [0,1] range hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision R += increment; } + #endif } @@ -674,8 +666,9 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double // store result in a temporary array dcurve[0] = CLIPD(val); - - #pragma omp parallel for //schedule(dynamic,2048) +#ifdef _OPENMP + #pragma omp parallel for +#endif for (int i = 1; i < 0x10000; i++) { float val = i / 65535.f; @@ -792,17 +785,21 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double vfloat mulv = F2V(mul); vfloat addv = F2V(add); vfloat c65535v = F2V(65535.f); - for (int i = 0; i <= 0xffff; i+=4) { + + for (int i = 0; i <= 0xffff; i += 4) { vfloat valv = LVFU(dcurve[i]); valv = igamma (valv, gamma_v, startv, slopev, mulv, addv); - STVFU(outCurve[i],c65535v * valv); + STVFU(outCurve[i], c65535v * valv); } + #else + for (int i = 0; i <= 0xffff; i++) { float val = dcurve[i]; val = igamma (val, gamma_, start, slope, mul, add); outCurve[i] = (65535.f * val); } + #endif if (histNeeded) { @@ -827,7 +824,7 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePoints, - const LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, + const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili) { // curve without contrast @@ -962,7 +959,7 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePointsbw, const std::vector& curvePointsbw2, const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip); - static void curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, const LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip); + static void curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, int skip); static void curveWavContL ( bool & wavcontlutili, const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip); static void curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram); @@ -298,8 +298,7 @@ public: const std::vector& bcurvePoints, const std::vector& cccurvePoints, const std::vector& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, const LUTu & histogramC, const LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, ///for chroma int skip = 1); - static void complexLCurve (double br, double contr, const std::vector& curvePoints, const LUTu & histogram, LUTu & histogramCropped, - LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); + static void complexLCurve (double br, double contr, const std::vector& curvePoints, const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); static void curveLightBrightColor ( const std::vector& curvePoints, diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 77f0598b4..27104bde2 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -814,7 +814,7 @@ void Crop::update (int todo) LUTu dummy; int moderetinex; // parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1); - parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy); parent->ipf.vibrance (labnCrop); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ccee4328b..4e099dc5c 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -23,7 +23,9 @@ #include "../rtgui/ppversion.h" #include "colortemp.h" #include "improcfun.h" - +#ifdef _OPENMP +#include +#endif namespace rtengine { @@ -52,12 +54,11 @@ ImProcCoordinator::ImProcCoordinator () Noisecurve(65536, 0), NoiseCCcurve(65536, 0), vhist16(65536), vhist16bw(65536), - lhist16(65536), lhist16Cropped(65536), lhist16CAM(65536), lhist16CCAM(65536), lhist16RETI(65536), histCropped(65536), - lhist16Clad(65536), lhist16CLlad(65536), + lhist16Clad(65536), lhist16LClad(65536), lhist16LLClad(65536), histRed(256), histRedRaw(256), histGreen(256), histGreenRaw(256), @@ -67,7 +68,6 @@ ImProcCoordinator::ImProcCoordinator () histToneCurveBW(256), histLCurve(256), histCCurve(256), - histCLurve(256), histLLCurve(256), histLCAM(256), @@ -366,7 +366,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) */ imgsrc->convertColorSpace(orig_prev, params.icm, currWB); - ipf.firstAnalysis (orig_prev, ¶ms, vhist16); + ipf.firstAnalysis (orig_prev, params, vhist16); } readyphase++; @@ -450,28 +450,29 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); - // clToningcurve.dump("CLToning3"); CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); } - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); + } float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); @@ -559,31 +560,39 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } // compute L channel histogram - int x1, y1, x2, y2, pos; + int x1, y1, x2, y2; params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); - lhist16.clear(); - lhist16Cropped.clear(); - lhist16Clad.clear(); - lhist16CLlad.clear(); - lhist16LLClad.clear(); - - for (int x = 0; x < pH; x++) - for (int y = 0; y < pW; y++) { - pos = CLIP((int)(oprevl->L[x][y])); - lhist16[pos]++; - - if (y >= y1 && y < y2 && x >= x1 && x < x2) { - lhist16Cropped[pos]++; - } - } } readyphase++; - if ((todo & M_LUMACURVE) || (todo & M_CROP)) { + if (todo & (M_LUMACURVE | M_CROP)) { + LUTu lhist16(32768); + lhist16.clear(); +#ifdef _OPENMP + const int numThreads = min(max(pW * pH / (int)lhist16.getSize(), 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu lhist16thr(lhist16.getSize()); + lhist16thr.clear(); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int x = 0; x < pH; x++) + for (int y = 0; y < pW; y++) { + int pos = (int)(oprevl->L[x][y]); + lhist16thr[pos]++; + } + +#ifdef _OPENMP + #pragma omp critical +#endif + lhist16 += lhist16thr; + } utili = false; - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped, - lumacurve, histLCurve, scale == 1 ? 1 : 16, utili); + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale == 1 ? 1 : 16, utili); } if (todo & M_LUMACURVE) { @@ -593,7 +602,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) cclutili = false; clcutili = false; - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, lhist16CLlad, histCLurve, scale == 1 ? 1 : 16); + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, scale == 1 ? 1 : 16); float adjustr = 1.0f; @@ -605,6 +614,9 @@ 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;} */ + + lhist16LLClad.clear(); + lhist16Clad.clear(); 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); @@ -615,8 +627,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Applying Color Boost...", 100 * readyphase / numofphases); // ipf.MSR(nprevl, nprevl->W, nprevl->H, 1); - - ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histCLurve, histLLCurve, histLCurve); + ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLLCurve, histLCurve); ipf.vibrance(nprevl); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { @@ -678,7 +689,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) wavcontlutili = false; //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); - CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve , /*lhist16CLlad, histCLurve,*/ scale == 1 ? 1 : 16); + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16); if((params.wavelet.enabled)) { @@ -709,7 +720,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y])); lhist16CAM[pos]++; lhist16CCAM[posc]++; - } + } } CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3, @@ -1291,7 +1302,6 @@ void ImProcCoordinator::startProcessing(int changeCode) void ImProcCoordinator::process () { - if (plistener) { plistener->setProgressState (true); } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index e138de925..d394f942c 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -107,7 +107,6 @@ protected: LUTf NoiseCCcurve; LUTu vhist16, vhist16bw; - LUTu lhist16, lhist16Cropped; LUTu lhist16CAM; LUTu lhist16CCAM; LUTu lhist16RETI; @@ -116,7 +115,7 @@ protected: LUTu histRed, histRedRaw; LUTu histGreen, histGreenRaw; LUTu histBlue, histBlueRaw; - LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve; + LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve; LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI; LUTf CAMBrightCurveJ, CAMBrightCurveQ; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 74c750ccc..854b0b6b0 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -73,34 +73,6 @@ void ImProcFunctions::setScale (double iscale) scale = iscale; } -// Called from several threads -void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to) -{ - - TMatrix wprof = iccStore->workingSpaceMatrix (wprofile); - - lumimul[0] = wprof[1][0]; - lumimul[1] = wprof[1][1]; - lumimul[2] = wprof[1][2]; - - int W = original->width; - - for (int i = row_from; i < row_to; i++) { - for (int j = 0; j < W; j++) { - - int r = original->r(i, j); - int g = original->g(i, j); - int b = original->b(i, j); - - int y = CLIP((int)(lumimul[0] * r + lumimul[1] * g + lumimul[2] * b)) ; - - if (histogram) { - histogram[y]++; - } - } - } -} - void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) { // set up monitor transform @@ -148,59 +120,67 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con #endif } -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +void ImProcFunctions::firstAnalysis (const Imagefloat* const original, const ProcParams ¶ms, LUTu & histogram) { - Glib::ustring wprofile = params->icm.working; + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + + lumimul[0] = wprof[1][0]; + lumimul[1] = wprof[1][1]; + lumimul[2] = wprof[1][2]; + int W = original->width; + int H = original->height; + + float lumimulf[3] = {static_cast(lumimul[0]), static_cast(lumimul[1]), static_cast(lumimul[2])}; // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments - - int T = 1; -#ifdef _OPENMP - - if(multiThread) { - T = omp_get_max_threads(); - } - -#endif - - unsigned int** hist = new unsigned int* [T]; - - for (int i = 0; i < T; i++) { - hist[i] = new unsigned int[65536]; - memset (hist[i], 0, 65536 * sizeof(int)); - } - -#ifdef _OPENMP - #pragma omp parallel if (multiThread) - { - int H = original->height; - int tid = omp_get_thread_num(); - int nthreads = omp_get_num_threads(); - int blk = H / nthreads; - - if (tid < nthreads - 1) { - firstAnalysisThread (original, wprofile, hist[tid], tid * blk, (tid + 1)*blk); - } else { - firstAnalysisThread (original, wprofile, hist[tid], tid * blk, H); - } - } -#else - firstAnalysisThread (original, wprofile, hist[0], 0, original->height); -#endif - histogram.clear(); - for (int j = 0; j < T; j++) - for (int i = 0; i < 65536; i++) { - histogram[i] += hist[j][i]; + if(multiThread) { + +#ifdef _OPENMP + const int numThreads = min(max(W * H / (int)histogram.getSize(), 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu hist(histogram.getSize()); + hist.clear(); +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int i = 0; i < H; i++) + { + for (int j = 0; j < W; j++) { + + float r = original->r(i, j); + float g = original->g(i, j); + float b = original->b(i, j); + + int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b); + hist[y]++; + } + } + +#ifdef _OPENMP + #pragma omp critical +#endif + histogram += hist; + } + } else { + for (int i = 0; i < H; i++) { + for (int j = 0; j < W; j++) { - for (int i = 0; i < T; i++) { - delete [] hist[i]; + float r = original->r(i, j); + float g = original->g(i, j); + float b = original->b(i, j); + + int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b); + histogram[y]++; + } + } } - - delete [] hist; } // Copyright (c) 2012 Jacques Desmis @@ -1468,38 +1448,18 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int MyTime t1e, t2e; t1e.set(); #endif - LUTf dLcurve; - LUTu hist16JCAM; - float val; //preparate for histograms CIECAM - if(pW != 1) { //only with improccoordinator - dLcurve(65536, 0); - dLcurve.clear(); - hist16JCAM(65536); + LUTu hist16JCAM; + LUTu hist16_CCAM; + if(pW != 1 && params->colorappearance.datacie) { //only with improccoordinator + hist16JCAM(32768); hist16JCAM.clear(); - - for (int i = 0; i < 32768; i++) { //# 32768*1.414 approximation maxi for chroma - val = (double)i / 32767.0; - dLcurve[i] = CLIPD(val); - } - } - - LUTf dCcurve(65536, 0); - LUTu hist16_CCAM(65536); - bool chropC = false; - float valc; - - if(pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma - valc = (double)i / 47999.0; - dCcurve[i] = CLIPD(valc); - } - + hist16_CCAM(48000); hist16_CCAM.clear(); } - //end preparate histogram + //end preparate histogram int width = lab->W, height = lab->H; float minQ = 10000.f; float maxQ = -1000.f; @@ -1513,8 +1473,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int bool algepd = false; float sum = 0.f; - const bool ciedata = (params->colorappearance.datacie && pW != 1); - bool jp = ciedata; + const bool epdEnabled = params->epd.enabled; + bool ciedata = (params->colorappearance.datacie && pW != 1) && !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) + || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) + || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB @@ -1732,19 +1694,19 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int hist16Q.clear(); } - const int numThreads = min(max(width*height / 65536,1),omp_get_max_threads()); + const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); #pragma omp parallel num_threads(numThreads) if(numThreads>1) { LUTu hist16Jthr; LUTu hist16Qthr; if (needJ) { - hist16Jthr (32768); + hist16Jthr(hist16J.getSize()); hist16Jthr.clear(); } if (needQ) { - hist16Qthr(32768); + hist16Qthr(hist16Q.getSize()); hist16Qthr.clear(); } @@ -1802,11 +1764,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int #pragma omp critical { - if(needJ) + if(needJ) { hist16J += hist16Jthr; + } - if(needQ) + if(needQ) { hist16Q += hist16Qthr; + } } } @@ -1864,9 +1828,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } else { yb = 90.0f; } - } - - if(settings->viewinggreySc == 1) { + } else if(settings->viewinggreySc == 1) { yb = 18.0f; //fixed } @@ -1911,7 +1873,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int const float f_l = fl; const float coe = pow_F(fl, 0.25f); const float QproFactor = ( 0.4f / c ) * ( aw + 4.0f ) ; - const bool epdEnabled = params->epd.enabled; const bool LabPassOne = !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); @@ -2391,57 +2352,38 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled) { - if(ciedata) { + if(ciedata) { //only with improccoordinator // Data for J Q M s and C histograms int posl, posc; float brli = 327.f; float chsacol = 327.f; - int libr = 0; - int colch = 0; + float libr; + float colch; + //update histogram if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { brli = 70.0f; - libr = 1; - } else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { + libr = Q; //40.0 to 100.0 approximative factor for Q - 327 for J + } else /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ { brli = 327.f; - libr = 0; + libr = J; //327 for J } + posl = (int)(libr * brli); + hist16JCAM[posl]++; if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { chsacol = 327.f; - colch = 0; + colch = C; //450.0 approximative factor for s 320 for M } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { chsacol = 450.0f; - colch = 1; - } else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { + colch = s; + } else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ { chsacol = 327.0f; - colch = 2; + colch = M; } + posc = (int)(colch * chsacol); + hist16_CCAM[posc]++; - //update histogram - if(pW != 1) { //only with improccoordinator - if(libr == 1) { - posl = CLIP((int)(Q * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else if(libr == 0) { - posl = CLIP((int)(J * brli)); //327 for J - } - - hist16JCAM[posl]++; - } - - chropC = true; - - if(pW != 1) { //only with improccoordinator - if(colch == 0) { - posc = CLIP((int)(C * chsacol)); //450.0 approximative factor for s 320 for M - } else if(colch == 1) { - posc = CLIP((int)(s * chsacol)); - } else if(colch == 2) { - posc = CLIP((int)(M * chsacol)); - } - - hist16_CCAM[posc]++; - } } if(LabPassOne) { @@ -2582,25 +2524,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } // End of parallelization - if(!params->colorappearance.tonecie || !settings->autocielab) { //normal + if(!params->colorappearance.tonecie || !settings->autocielab) { //normal if(ciedata) { //update histogram J - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int)(255.0f * CLIPD(hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } - - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int)(255.0f * CLIPD(hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } + hist16JCAM.compressTo(histLCAM); + //update histogram C + hist16_CCAM.compressTo(histCCAM); } } @@ -2732,6 +2662,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)) { + ciedata = (params->colorappearance.datacie && pW != 1); if(epdEnabled && params->colorappearance.tonecie && algepd) { lab->deleteLab(); ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); @@ -2786,54 +2717,31 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int int posl, posc; float brli = 327.f; float chsacol = 327.f; - int libr = 0; - int colch = 0; - float sa_t; + float libr; + float colch; if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { brli = 70.0f; - libr = 1; - } else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { + libr = ncie->Q_p[i][j]; //40.0 to 100.0 approximative factor for Q - 327 for J + } else /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ { brli = 327.f; - libr = 0; + libr = ncie->J_p[i][j]; //327 for J } + posl = (int)(libr * brli); + hist16JCAM[posl]++; if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { chsacol = 327.f; - colch = 0; + colch = ncie_C_p; } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { chsacol = 450.0f; - colch = 1; - } else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { + colch = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]); + } else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ { chsacol = 327.0f; - colch = 2; - } - - //update histogram - if(pW != 1) { //only with improccoordinator - if(libr == 1) { - posl = CLIP((int)(ncie->Q_p[i][j] * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else if(libr == 0) { - posl = CLIP((int)(ncie->J_p[i][j] * brli)); //327 for J - } - - hist16JCAM[posl]++; - } - - chropC = true; - - if(pW != 1) { //only with improccoordinator - if(colch == 0) { - posc = CLIP((int)(ncie_C_p * chsacol)); //450.0 approximative factor for s 320 for M - } else if(colch == 1) { - sa_t = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]); //Q_p always > 0 - posc = CLIP((int)(sa_t * chsacol)); - } else if(colch == 2) { - posc = CLIP((int)(ncie->M_p[i][j] * chsacol)); - } - - hist16_CCAM[posc]++; + colch = ncie->M_p[i][j]; } + posc = (int)(colch * chsacol); + hist16_CCAM[posc]++; } //end histograms @@ -2959,24 +2867,12 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int //show CIECAM histograms if(ciedata) { //update histogram J and Q - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int)(255.0f * CLIPD(hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } + //update histogram J + hist16JCAM.compressTo(histLCAM); //update color histogram M,s,C - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int)(255.0f * CLIPD(hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } + hist16_CCAM.compressTo(histCCAM); } - } } } @@ -3215,7 +3111,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer ClutPtr colorLUT; bool clutAndWorkingProfilesAreSame = false; - TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work; + TMatrix xyz2clut, clut2xyz; if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) { colorLUT.set( clutStore.getClut( params->filmSimulation.clutFilename ) ); @@ -3224,9 +3120,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer clutAndWorkingProfilesAreSame = colorLUT->profile() == params->icm.working; if ( !clutAndWorkingProfilesAreSame ) { - work2xyz = iccStore->workingSpaceMatrix( params->icm.working ); xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() ); - xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working ); clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() ); } } @@ -4338,7 +4232,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (!clutAndWorkingProfilesAreSame) { //convert from working to clut profile float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, wprof ); Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); } @@ -4362,7 +4256,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer //convert from clut to working profile float x, y, z; Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, wiprof ); } } @@ -5517,9 +5411,8 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur -SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve, LUTf & lhskcurve, LUTf & clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLLCurve, LUTu &histLCurve) +SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve, LUTf & lhskcurve, LUTf & clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLLCurve, LUTu &histLCurve) { - int W = lold->W; int H = lold->H; // lhskcurve.dump("lh_curve"); @@ -5605,31 +5498,15 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } - LUTf dCcurve; - LUTf dLcurve; LUTu hist16Clad; LUTu hist16Llad; //preparate for histograms CIECAM if(pW != 1) { //only with improccoordinator - dCcurve(48000, 0); - dLcurve(65536, 0); hist16Clad(65536); - hist16Llad(65536); - float val; - - for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma - val = (double)i / 47999.0; - dCcurve[i] = CLIPD(val); - } - - for (int i = 0; i < 65535; i++) { // a - val = (double)i / 65534.0; - dLcurve[i] = CLIPD(val); - } - hist16Clad.clear(); + hist16Llad(65536); hist16Llad.clear(); } @@ -6125,7 +6002,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //update histogram C if(pW != 1) { //only with improccoordinator - int posp = CLIP((int)sqrt((atmp * atmp + btmp * btmp))); + int posp = (int)sqrt(atmp * atmp + btmp * btmp); hist16Clad[posp]++; } @@ -6181,7 +6058,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //update histo LC if(pW != 1) { //only with improccoordinator - int posl = CLIP((int(Lprov1 * 327.68f))); + int posl = Lprov1 * 327.68f; hist16Llad[posl]++; } @@ -6269,20 +6146,11 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu } } // end of parallelization - //update histogram C with data chromaticity and not with CC curve if(pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { //32768*1.414 + ... - float hval = dCcurve[i]; - int hi = (int)(255.0 * CLIPD(hval)); // - histCCurve[hi] += hist16Clad[i] ; - } - - //update histogram L with data luminance - for (int i = 0; i < 65535; i++) { - float hlval = dLcurve[i]; - int hli = (int)(255.0 * CLIPD(hlval)); - histLCurve[hli] += hist16Llad[i] ; - } + //update histogram C with data chromaticity and not with CC curve + hist16Clad.compressTo(histCCurve); + //update histogram L with data luminance + hist16Llad.compressTo(histLCurve); } #ifdef _DEBUG @@ -6683,15 +6551,15 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) #pragma omp parallel for // removed schedule(dynamic,10) #endif - for(int ii = 0; ii < N; ii++) - a[ii] *= s, - b[ii] *= s, - //L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL; - L[ii] = L[ii] * maxL * (1.f / gamm) + minL; + for(int ii = 0; ii < N; ii++) { + a[ii] *= s; + b[ii] *= s; + L[ii] = L[ii] * maxL * (1.f / gamm) + minL; + } } -void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, +void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh) { @@ -6704,12 +6572,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga float ave = 0.f, hidev = 0.f, lodev = 0.f; //find average luminance - for (int i = 0; i < imax; i++) { - sum += histogram[i]; - ave += histogram[i] * (float)i; - } - - ave /= (sum); + histogram.getSumAndAverage(sum, ave); //find median of luminance int median = 0, count = histogram[0]; @@ -6734,25 +6597,35 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga float octile[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}, ospread = 0.f; count = 0; - for (int i = 0; i < imax; i++) { + int i = 0; + for (; i < min((int)ave,imax); i++) { if (count < 8) { octile[count] += histogram[i]; if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { - octile[count] = log(1. + (float)i) / log(2.f); + octile[count] = xlog(1. + (float)i) / log(2.f); count++;// = min(count+1,7); } } - if (i < ave) { - //lodev += SQR(ave-i)*histogram[i]; - lodev += (log(ave + 1.f) - log((float)i + 1.)) * histogram[i]; - losum += histogram[i]; - } else { - //hidev += SQR(i-ave)*histogram[i]; - hidev += (log((float)i + 1.) - log(ave + 1.f)) * histogram[i]; - hisum += histogram[i]; + //lodev += SQR(ave-i)*histogram[i]; + lodev += (xlog(ave + 1.f) - xlog((float)i + 1.)) * histogram[i]; + losum += histogram[i]; + } + for (; i < imax; i++) { + if (count < 8) { + octile[count] += histogram[i]; + + if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { + octile[count] = xlog(1. + (float)i) / log(2.f); + count++;// = min(count+1,7); + } } + + //hidev += SQR(i-ave)*histogram[i]; + hidev += (xlog((float)i + 1.) - xlog(ave + 1.f)) * histogram[i]; + hisum += histogram[i]; + } if (losum == 0 || hisum == 0) { //probably the image is a blackframe @@ -6815,7 +6688,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga int clipped = 0; int rawmax = (imax) - 1; - while (rawmax > 1 && histogram[rawmax] + clipped <= 0) { + while (histogram[rawmax] + clipped <= 0 && rawmax > 1) { clipped += histogram[rawmax]; rawmax--; } @@ -6907,11 +6780,15 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga //take gamma into account double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0); - double gavg = 0.; + float gavg = 0.; - for (int i = 0; i<65536 >> histcompr; i++) { - gavg += histogram[i] * CurveFactory::gamma2((float)(corr * (i << histcompr) < 65535 ? corr * (i << histcompr) : 65535)) / sum; + float val = 0.f; + float increment = corr * (1 << histcompr); + for (int i = 0; i < 65536 >> histcompr; i++) { + gavg += histogram[i] * Color::gamma2curve[val]; + val += increment; } + gavg /= sum; if (black < gavg) { int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4 @@ -6981,6 +6858,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga } bright = max(-100, min(bright, 100)); + } @@ -7101,6 +6979,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, wipv[i][j] = F2V(wiprof[i][j]); } } + #endif #ifdef _OPENMP @@ -7110,9 +6989,10 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, for(int i = 0; i < H; i++) { int j = 0; #ifdef __SSE2__ + for(; j < W - 3; j += 4) { vfloat X, Y, Z; - vfloat R,G,B; + vfloat R, G, B; Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z); Color::xyz2rgb(X, Y, Z, R, G, B, wipv); STVFU(dst.r(i, j), R); @@ -7121,6 +7001,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, } #endif + for(; j < W; j++) { float X, Y, Z; Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 90a046149..ea64ce4ab 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -75,7 +75,6 @@ class ImProcFunctions void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, int W, int H, const SharpeningParams &sharpenParam); void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam); void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H); - void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to); void dcdamping (float** aI, float** aO, float damping, int W, int H); bool needsCA (); @@ -229,7 +228,7 @@ public: bool needsTransform (); bool needsPCVignetting (); - void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void firstAnalysis (const Imagefloat* const working, const ProcParams ¶ms, LUTu & vhist16); void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, @@ -255,7 +254,7 @@ public: void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, int scalecd, int rtt); - void chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve); + void chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve, LUTu &histLurve); void vibrance (LabImage* lab);//Jacques' vibrance void colorCurve (LabImage* lold, LabImage* lnew); void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam); @@ -377,7 +376,7 @@ public: bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); bool transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); - static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); + static void getAutoExp (const LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static double getAutoDistor (const Glib::ustring& fname, int thumb_size); double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL); void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5f09bb74a..15ceee77d 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -32,7 +32,6 @@ #include "rawimagesource.h" #include "stdimagesource.h" #include -#include #include "rawimage.h" #include "jpeg.h" #include "../rtgui/ppversion.h" @@ -54,7 +53,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, StdImageSource imgSrc; if (imgSrc.load(fname)) { - return NULL; + return nullptr; } ImageIO* img = imgSrc.getImageIO(); @@ -96,7 +95,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, // bilinear interpolation if (tpp->thumbImg) { delete tpp->thumbImg; - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; } if (inspectorMode) { @@ -161,7 +160,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL if( r ) { delete ri; - return NULL; + return nullptr; } rml.exifBase = ri->get_exifBase(); @@ -192,7 +191,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL printf("Could not extract thumb from %s\n", fname.data()); delete img; delete ri; - return NULL; + return nullptr; } Thumbnail* tpp = new Thumbnail (); @@ -220,7 +219,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL if (tpp->thumbImg) { delete tpp->thumbImg; - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; } if (inspectorMode) { @@ -289,7 +288,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati if( r ) { delete ri; - return NULL; + return nullptr; } int width = ri->get_width(); @@ -297,8 +296,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati rtengine::Thumbnail* tpp = new rtengine::Thumbnail; tpp->isRaw = true; - tpp->embProfile = NULL; - tpp->embProfileData = NULL; + tpp->embProfile = nullptr; + tpp->embProfileData = nullptr; tpp->embProfileLength = ri->get_profileLen(); if (ri->get_profileLen()) @@ -502,7 +501,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati delete tpp->thumbImg; } - tpp->thumbImg = NULL; + tpp->thumbImg = nullptr; tpp->thumbImg = resizeTo(w, h, TI_Bilinear, tmpImg); delete tmpImg; @@ -737,11 +736,11 @@ void Thumbnail::init () } Thumbnail::Thumbnail () : - camProfile(NULL), thumbImg(NULL), + camProfile(nullptr), thumbImg(nullptr), camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0), - embProfileLength(0), embProfileData(NULL), embProfile(NULL), + embProfileLength(0), embProfileData(nullptr), embProfile(nullptr), redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0), defGain(1.0), scaleForSave(8192), @@ -935,10 +934,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent); LUTu hist16 (65536); - LUTu hist16C (65536); double gamma = isRaw ? Color::sRGBGamma : 0; // usually in ImageSource, but we don't have that here - ipf.firstAnalysis (baseImg, ¶ms, hist16); + ipf.firstAnalysis (baseImg, params, hist16); // perform transform if (ipf.needsTransform()) { @@ -953,7 +951,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } // update blurmap - SHMap* shmap = NULL; + SHMap* shmap = nullptr; if (params.sh.enabled) { shmap = new SHMap (fw, fh, false); @@ -976,7 +974,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei int hlcomprthresh = params.toneCurve.hlcomprthresh; if (params.toneCurve.autoexp && aeHistogram) { ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); - //ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr); } LUTf curve1 (65536); @@ -989,17 +986,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei LUTf clcurve (65536); LUTf clToningcurve; LUTf cl2Toningcurve; - - LUTf rCurve (65536); - LUTf gCurve (65536); - LUTf bCurve (65536); - LUTu dummy; ToneCurve customToneCurve1, customToneCurve2; ColorGradientCurve ctColorCurve; OpacityCurve ctOpacityCurve; - // NoisCurve dnNoisCurve; ColorAppearance customColCurve1; ColorAppearance customColCurve2; @@ -1012,33 +1003,40 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei params.toneCurve.curveMode2, params.toneCurve.curve2, hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; + bool opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - //params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili); - if(params.colorToning.enabled) { - clToningcurve (65536); - cl2Toningcurve (65536); + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + clToningcurve (65536); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); + + cl2Toningcurve (65536); CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); } - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + } + double rrm, ggm, bbm; float autor, autog, autob; float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; @@ -1067,23 +1065,22 @@ 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); - DCPProfile *dcpProf = NULL; + DCPProfile *dcpProf = nullptr; if (isRaw) { cmsHPROFILE dummy; - RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, dummy); + RawImageSource::findInputProfile(params.icm.input, nullptr, camName, &dcpProf, dummy); - if (dcpProf != NULL) { + if (dcpProf) { dcpProf->setStep2ApplyState(params.icm.working, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset); } } - 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, dcpProf); + ipf.rgbProc (baseImg, labView, nullptr, 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, dcpProf); // freeing up some memory customToneCurve1.Reset(); customToneCurve2.Reset(); ctColorCurve.Reset(); ctOpacityCurve.Reset(); -// dnNoisCurve.Reset(); customToneCurvebw1.Reset(); customToneCurvebw2.Reset(); @@ -1092,36 +1089,34 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } // luminance histogram update - hist16.clear(); - hist16C.clear(); + if(params.labCurve.contrast != 0) { + hist16.clear(); + for (int i = 0; i < fh; i++) + for (int j = 0; j < fw; j++) { + hist16[(int)((labView->L[i][j]))]++; + } + } - for (int i = 0; i < fh; i++) - for (int j = 0; j < fw; j++) { - hist16[CLIP((int)((labView->L[i][j])))]++; - hist16C[CLIP((int)sqrt(labView->a[i][j]*labView->a[i][j] + labView->b[i][j]*labView->b[i][j]))]++; - } // luminance processing // ipf.EPDToneMap(labView,0,6); bool utili = false; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, + hist16, lumacurve, dummy, 16, utili); + + bool clcutili = false; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 16); + bool autili = false; bool butili = false; bool ccutili = false; bool cclutili = false; - bool clcutili = false; - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, - hist16, hist16, lumacurve, dummy, 16, utili); - - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 16); - CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, - hist16C, hist16C, dummy, dummy, + dummy, dummy, dummy, dummy, 16); - //ipf.luminanceCurve (labView, labView, curve); - - ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy); ipf.vibrance(labView); @@ -1129,16 +1124,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ipf.EPDToneMap(labView, 5, 6); } - //if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);} - - if(params.colorappearance.enabled) { CurveFactory::curveLightBrightColor ( params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3, hist16, dummy, - hist16C, dummy, + dummy, dummy, customColCurve1, customColCurve2, customColCurve3, @@ -1219,7 +1211,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio) { - if (thumbImg == NULL) { + if (!thumbImg) { return 0; // Can happen if thumb is just building and GUI comes in with resize wishes } @@ -1371,11 +1363,11 @@ void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty) unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) { if (!thumbImg) { - return NULL; + return nullptr; } if (thumbImg->width < trim_width) { - return NULL; + return nullptr; } // to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction @@ -1659,7 +1651,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname) if (thumbImg) { delete thumbImg; - thumbImg = NULL; + thumbImg = nullptr; } Glib::ustring fullFName = fname + ".rtti"; @@ -1872,8 +1864,8 @@ bool Thumbnail::readEmbProfile (const Glib::ustring& fname) FILE* f = g_fopen (fname.c_str (), "rb"); if (!f) { - embProfileData = NULL; - embProfile = NULL; + embProfileData = nullptr; + embProfile = nullptr; embProfileLength = 0; } else { fseek (f, 0, SEEK_END); @@ -1945,7 +1937,7 @@ unsigned char* Thumbnail::getImage8Data() return img8->data; } - return NULL; + return nullptr; } diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index b7d1f3b61..951d0e6cc 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -726,9 +726,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // perform first analysis LUTu hist16 (65536); - LUTu hist16C (65536); - ipf.firstAnalysis (baseImg, ¶ms, hist16); + ipf.firstAnalysis (baseImg, params, hist16); // perform transform (excepted resizing) if (ipf.needsTransform()) { @@ -777,9 +776,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf cl2Toningcurve; LUTf wavclCurve (65536, 0); - LUTf rCurve (65536, 0); - LUTf gCurve (65536, 0); - LUTf bCurve (65536, 0); + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; LUTu dummy; ToneCurve customToneCurve1, customToneCurve2; @@ -798,23 +797,22 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; bool opautili = false; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); clToningcurve (65536, 0); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1); cl2Toningcurve (65536, 0); @@ -822,8 +820,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } LabImage* labView = new LabImage (fw, fh); - - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); + } double rrm, ggm, bbm; float autor, autog, autob; float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; @@ -889,10 +888,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // start tile processing...??? - hist16.clear(); - hist16C.clear(); if(params.labCurve.contrast != 0) { //only use hist16 for contrast + hist16.clear(); #ifdef _OPENMP #pragma omp parallel @@ -918,21 +916,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } bool utili = false; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, lumacurve, dummy, 1, utili); + + bool clcutili = false; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1); + bool autili = false; bool butili = false; bool ccutili = false; bool cclutili = false; - bool clcutili = false; - - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, lumacurve, dummy, 1, utili); - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 1); - CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, - hist16C, hist16C, dummy, dummy, + dummy, dummy, dummy, dummy, 1); - ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); + ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy); if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { ipf.EPDToneMap(labView, 5, 1); @@ -1024,7 +1022,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p params.colorappearance.curve2, params.colorappearance.curve3, hist16, dummy, - hist16C, dummy, + dummy, dummy, customColCurve1, customColCurve2, customColCurve3,