From 41e5899f97bd7055f6ba957c490aeb8d2005c5a0 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 22:54:32 +0200 Subject: [PATCH] Moved film negative thumbnail processing to own compilation unit --- rtengine/CMakeLists.txt | 1 + rtengine/filmnegativethumb.cc | 139 ++++++++++++++++++++++++++++++++++ rtengine/rtthumbnail.cc | 91 +--------------------- rtengine/rtthumbnail.h | 2 + 4 files changed, 143 insertions(+), 90 deletions(-) create mode 100644 rtengine/filmnegativethumb.cc diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 9ac09fbcc..c5c8afa82 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -62,6 +62,7 @@ set(RTENGINESOURCEFILES fast_demo.cc ffmanager.cc filmnegativeproc.cc + filmnegativethumb.cc flatcurves.cc gauss.cc green_equil_RT.cc diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc new file mode 100644 index 000000000..8889915e6 --- /dev/null +++ b/rtengine/filmnegativethumb.cc @@ -0,0 +1,139 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include + +#ifdef _OPENMP +#include +#endif + +#include "rtengine.h" +#include "rtthumbnail.h" + +#include "mytime.h" +#include "opthelper.h" +#include "procparams.h" +#include "rt_algo.h" +#include "rtengine.h" +#include "settings.h" +#include "procparams.h" +#define BENCHMARK +#include "StopWatch.h" + +namespace rtengine +{ + +extern const Settings* settings; + +} + +void rtengine::Thumbnail::processFilmNegative( + const procparams::ProcParams ¶ms, + const Imagefloat* baseImg, + const int rwidth, const int rheight, + float &rmi, float &gmi, float &bmi +) { + StopWatch stop1("Thumbnail film negative", true); + + // Channel exponents + const float rexp = -params.filmNegative.redExp; + const float gexp = -params.filmNegative.greenExp; + const float bexp = -params.filmNegative.blueExp; + + // Need to calculate channel averages, to fake the same conditions + // found in rawimagesource, where get_ColorsCoeff is called with + // forceAutoWB=true. + float rsum = 0.f, gsum = 0.f, bsum = 0.f; + + // Channel vectors to calculate medians + std::vector rv, gv, bv; + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + const float r = baseImg->r(i, j); + const float g = baseImg->g(i, j); + const float b = baseImg->b(i, j); + + rsum += r; + gsum += g; + bsum += b; + + rv.push_back(r); + gv.push_back(g); + bv.push_back(b); + } + } + + const float ravg = rsum / (rheight*rwidth); + const float gavg = gsum / (rheight*rwidth); + const float bavg = bsum / (rheight*rwidth); + + // Shifting current WB multipliers, based on channel averages. + rmi /= (gavg/ravg); + // gmi /= (gAvg/gAvg); green chosen as reference channel + bmi /= (gavg/bavg); + + float rmed, gmed, bmed; + findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); + findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); + findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); + + rmed = powf(rmed, rexp); + gmed = powf(gmed, gexp); + bmed = powf(bmed, bexp); + + const float MAX_OUT_VALUE = 65000.f; + const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; + const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; + const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; + + if (settings->verbose) { + printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); + printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); + } + +#ifdef __SSE2__ + const vfloat clipv = F2V(MAXVALF); + const vfloat rexpv = F2V(rexp); + const vfloat gexpv = F2V(gexp); + const vfloat bexpv = F2V(bexp); + const vfloat rmultv = F2V(rmult); + const vfloat gmultv = F2V(gmult); + const vfloat bmultv = F2V(bmult); +#endif + + for (int i = 0; i < rheight; i++) { + float *rline = baseImg->r(i); + float *gline = baseImg->g(i); + float *bline = baseImg->b(i); + int j = 0; +#ifdef __SSE2__ + for (; j < rwidth - 3; j +=4) { + STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); + STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); + STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); + } +#endif + for (; j < rwidth; ++j) { + rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); + gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); + bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); + } + } +} \ No newline at end of file diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 60052f783..4b0baa685 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -39,12 +39,9 @@ #include "settings.h" #include "procparams.h" #include -#define BENCHMARK #include "StopWatch.h" #include "median.h" -#include "rt_algo.h" - namespace { @@ -1171,93 +1168,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); if(isRaw && params.filmNegative.enabled) { - StopWatch stop1("Thumbnail film negative", true); - - // Channel exponents - const float rexp = -params.filmNegative.redExp; - const float gexp = -params.filmNegative.greenExp; - const float bexp = -params.filmNegative.blueExp; - - // Need to calculate channel averages, to fake the same conditions - // found in rawimagesource, where get_ColorsCoeff is called with - // forceAutoWB=true. - float rsum = 0.f, gsum = 0.f, bsum = 0.f; - - // Channel vectors to calculate medians - std::vector rv, gv, bv; - - for (int i = 0; i < rheight; i++) { - for (int j = 0; j < rwidth; j++) { - const float r = baseImg->r(i, j); - const float g = baseImg->g(i, j); - const float b = baseImg->b(i, j); - - rsum += r; - gsum += g; - bsum += b; - - rv.push_back(r); - gv.push_back(g); - bv.push_back(b); - } - } - - const float ravg = rsum / (rheight*rwidth); - const float gavg = gsum / (rheight*rwidth); - const float bavg = bsum / (rheight*rwidth); - - // Shifting current WB multipliers, based on channel averages. - rmi /= (gavg/ravg); - // gmi /= (gAvg/gAvg); green chosen as reference channel - bmi /= (gavg/bavg); - - float rmed, gmed, bmed; - findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); - findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); - findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); - - rmed = powf(rmed, rexp); - gmed = powf(gmed, gexp); - bmed = powf(bmed, bexp); - - const float MAX_OUT_VALUE = 65000.f; - const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; - const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; - const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; - - if (settings->verbose) { - printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); - printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); - } - -#ifdef __SSE2__ - const vfloat clipv = F2V(MAXVALF); - const vfloat rexpv = F2V(rexp); - const vfloat gexpv = F2V(gexp); - const vfloat bexpv = F2V(bexp); - const vfloat rmultv = F2V(rmult); - const vfloat gmultv = F2V(gmult); - const vfloat bmultv = F2V(bmult); -#endif - - for (int i = 0; i < rheight; i++) { - float *rline = baseImg->r(i); - float *gline = baseImg->g(i); - float *bline = baseImg->b(i); - int j = 0; -#ifdef __SSE2__ - for (; j < rwidth - 3; j +=4) { - STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); - STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); - STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); - } -#endif - for (; j < rwidth; ++j) { - rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); - gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); - bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); - } - } + processFilmNegative(params, baseImg, rwidth, rheight, rmi, gmi, bmi); } if (params.coarse.rotate) { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index df33b892d..09a0510eb 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -68,6 +68,8 @@ class Thumbnail bool gammaCorrected; double colorMatrix[3][3]; + void processFilmNegative(const procparams::ProcParams& params, const Imagefloat* baseImg, int rwidth, int rheight, float &rmi, float &gmi, float &bmi); + public: bool isRaw;