diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 7854dfb81..d9b4f1ca1 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -815,37 +815,13 @@ void Crop::update(int todo) const Glib::ustring profile = params.icm.workingProfile; if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") { - int cw = baseCrop->getWidth(); - int ch = baseCrop->getHeight(); + const int cw = baseCrop->getWidth(); + const int ch = baseCrop->getHeight(); workingCrop = new Imagefloat(cw, ch); - baseCrop->copyData(workingCrop); //first put gamma TRC to 1 - Imagefloat* readyImg0 = parent->ipf.workingtrc(workingCrop, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - workingCrop->r(row, col) = (float)readyImg0->r(row, col); - workingCrop->g(row, col) = (float)readyImg0->g(row, col); - workingCrop->b(row, col) = (float)readyImg0->b(row, col); - } - } - - delete readyImg0; - + parent->ipf.workingtrc(baseCrop, workingCrop, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310, true, false); //adjust gamma TRC - Imagefloat* readyImg = parent->ipf.workingtrc(workingCrop, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - workingCrop->r(row, col) = (float)readyImg->r(row, col); - workingCrop->g(row, col) = (float)readyImg->g(row, col); - workingCrop->b(row, col) = (float)readyImg->b(row, col); - } - } - - delete readyImg; + parent->ipf.workingtrc(workingCrop, workingCrop, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, false, true); } } double rrm, ggm, bbm; diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 63c521040..2dae72793 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -475,7 +475,7 @@ void Imagefloat::calcCroppedHistogram(const ProcParams ¶ms, float scale, LUT } // Parallelized transformation; create transform with cmsFLAGS_NOCACHE! -void Imagefloat::ExecCMSTransform2(cmsHTRANSFORM hTransform) +void Imagefloat::ExecCMSTransform2(cmsHTRANSFORM hTransform, bool normalizeIn) { // LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation @@ -487,18 +487,25 @@ void Imagefloat::ExecCMSTransform2(cmsHTRANSFORM hTransform) AlignedBuffer pBuf(width * 3); #ifdef _OPENMP - #pragma omp for schedule(static) + #pragma omp for schedule(dynamic, 16) #endif for (int y = 0; y < height; y++) { float *p = pBuf.data, *pR = r(y), *pG = g(y), *pB = b(y); - for (int x = 0; x < width; x++) { - *(p++) = *(pR++)/ 65535.f; - *(p++) = *(pG++)/ 65535.f; - *(p++) = *(pB++)/ 65535.f; - + if (normalizeIn) { + for (int x = 0; x < width; x++) { + *(p++) = *(pR++)/ 65535.f; + *(p++) = *(pG++)/ 65535.f; + *(p++) = *(pB++)/ 65535.f; + } + } else { + for (int x = 0; x < width; x++) { + *(p++) = *(pR++); + *(p++) = *(pG++); + *(p++) = *(pB++); + } } cmsDoTransform (hTransform, pBuf.data, pBuf.data, width); diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index 9d7c69aef..921f86b59 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -222,7 +222,7 @@ public: void normalizeFloatTo1(); void normalizeFloatTo65535(); void calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist); - void ExecCMSTransform2(cmsHTRANSFORM hTransform); + void ExecCMSTransform2(cmsHTRANSFORM hTransform, bool normalizeIn = true); void ExecCMSTransform(cmsHTRANSFORM hTransform); void ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index d76ccda27..bbadbf0a7 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -28,7 +28,6 @@ #include #include #include "color.h" - #ifdef _OPENMP #include #endif @@ -511,38 +510,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) orig_prev->copyData(oprevi); } - Glib::ustring profile = params.icm.workingProfile; + const Glib::ustring profile = params.icm.workingProfile; if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") { - int cw = oprevi->getWidth(); - int ch = oprevi->getHeight(); + const int cw = oprevi->getWidth(); + const int ch = oprevi->getHeight(); // put gamma TRC to 1 - Imagefloat* readyImg0 = ipf.workingtrc(oprevi, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - oprevi->r(row, col) = (float)readyImg0->r(row, col); - oprevi->g(row, col) = (float)readyImg0->g(row, col); - oprevi->b(row, col) = (float)readyImg0->b(row, col); - } - } - - delete readyImg0; + ipf.workingtrc(oprevi, oprevi, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310, true, false); //adjust TRC - Imagefloat* readyImg = ipf.workingtrc(oprevi, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - oprevi->r(row, col) = (float)readyImg->r(row, col); - oprevi->g(row, col) = (float)readyImg->g(row, col); - oprevi->b(row, col) = (float)readyImg->b(row, col); - } - } - - delete readyImg; - + ipf.workingtrc(oprevi, oprevi, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, false, true); } } } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c3e17a050..470922508 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -350,7 +350,7 @@ public: Image8* lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true); Imagefloat* lab2rgbOut(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); // CieImage *ciec; - Imagefloat* workingtrc(Imagefloat* working, int cw, int ch, int mul, Glib::ustring profile, double gampos, double slpos); + void workingtrc(Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring profile, double gampos, double slpos, bool normalizeIn = true, bool normalizeOut = true); 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 LensCorrection *pLCPMap = nullptr); bool transCoord(int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index da8e687ed..437144600 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -432,7 +432,7 @@ Imagefloat* ImProcFunctions::lab2rgbOut(LabImage* lab, int cx, int cy, int cw, i } -Imagefloat* ImProcFunctions::workingtrc(Imagefloat* working, int cw, int ch, int mul, Glib::ustring profile, double gampos, double slpos) +void ImProcFunctions::workingtrc(Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring profile, double gampos, double slpos, bool normalizeIn, bool normalizeOut) { TMatrix wprof; @@ -445,22 +445,20 @@ Imagefloat* ImProcFunctions::workingtrc(Imagefloat* working, int cw, int ch, int } double toxyz[3][3] = { { - (wprof[0][0] / dx), //I have suppressed / Color::D50x - (wprof[0][1] / dx), - (wprof[0][2] / dx) + (wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x + (wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))), + (wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0))) }, { - (wprof[1][0]), - (wprof[1][1]), - (wprof[1][2]) + (wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)), + (wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)), + (wprof[1][2] / (normalizeIn ? 65535.0 : 1.0)) }, { - (wprof[2][0] / dz), //I have suppressed / Color::D50z - (wprof[2][1] / dz), - (wprof[2][2] / dz) + (wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z + (wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))), + (wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0))) } }; - Imagefloat* image = new Imagefloat(cw, ch); - double pwr; double ts; ts = slpos; @@ -618,27 +616,22 @@ Imagefloat* ImProcFunctions::workingtrc(Imagefloat* working, int cw, int ch, int #pragma omp parallel for if (multiThread) for (int i = 0; i < ch; i++) { - float* rr = working->r(i); - float* rg = working->g(i); - float* rb = working->b(i); + float* rr = src->r(i); + float* rg = src->g(i); + float* rb = src->b(i); - float* xa = (float*)image->r(i); - float* ya = (float*)image->g(i); - float* za = (float*)image->b(i); + float* xa = (float*)dst->r(i); + float* ya = (float*)dst->g(i); + float* za = (float*)dst->b(i); for (int j = 0; j < cw; j++) { float r1 = rr[j]; float g1 = rg[j]; float b1 = rb[j]; - float x_ = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; - float y_ = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; - float z_ = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; - - xa[j] = ( x_) ; - ya[j] = ( y_); - za[j] = ( z_); - + xa[j] = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; + ya[j] = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; + za[j] = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; } } @@ -651,16 +644,14 @@ Imagefloat* ImProcFunctions::workingtrc(Imagefloat* working, int cw, int ch, int cmsHTRANSFORM hTransform = cmsCreateTransform(iprof, TYPE_RGB_FLT, oprofdef, TYPE_RGB_FLT, params->icm.outputIntent, flags); lcmsMutex->unlock(); - image->ExecCMSTransform2(hTransform); + dst->ExecCMSTransform2(hTransform, false); cmsDeleteTransform(hTransform); - image->normalizeFloatTo65535(); + if (normalizeOut) { + dst->normalizeFloatTo65535(); + } } - - - return image; - } diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index bdb3ced19..e09d2fe3a 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -893,39 +893,15 @@ private: //gamma TRC working if (params.icm.workingTRC == "Custom") { //exec TRC IN free - Glib::ustring profile; - profile = params.icm.workingProfile; + const Glib::ustring profile = params.icm.workingProfile; if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") { - int cw = baseImg->getWidth(); - int ch = baseImg->getHeight(); + const int cw = baseImg->getWidth(); + const int ch = baseImg->getHeight(); // put gamma TRC to 1 - Imagefloat* readyImg0 = ipf.workingtrc(baseImg, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - baseImg->r(row, col) = (float)readyImg0->r(row, col); - baseImg->g(row, col) = (float)readyImg0->g(row, col); - baseImg->b(row, col) = (float)readyImg0->b(row, col); - } - } - - delete readyImg0; - + ipf.workingtrc(baseImg, baseImg, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310, true, false); //adjust TRC - Imagefloat* readyImg = ipf.workingtrc(baseImg, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope); - #pragma omp parallel for - - for (int row = 0; row < ch; row++) { - for (int col = 0; col < cw; col++) { - baseImg->r(row, col) = (float)readyImg->r(row, col); - baseImg->g(row, col) = (float)readyImg->g(row, col); - baseImg->b(row, col) = (float)readyImg->b(row, col); - } - } - - delete readyImg; + ipf.workingtrc(baseImg, baseImg, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, false, true); } }