From 294f16c7415d3b9ae3c4305ec8e64c19ee022e87 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 25 Aug 2016 19:28:05 +0200 Subject: [PATCH 1/5] RGB Curves Luminosity mode: ~ 40% speedup --- rtengine/color.cc | 6 +-- rtengine/improcfun.cc | 106 ++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 69 deletions(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index c6f69d968..60d355b26 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -2137,7 +2137,7 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) #endif { - const float ClipLevel = 65535.0f; + constexpr float ClipLevel = 65535.0f; bool inGamut; #ifdef _DEBUG neg = false, more_rgb = false; @@ -2146,7 +2146,6 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr do { inGamut = true; - //Lprov1=LL; float aprov1 = Chprov1 * sincosval.y; float bprov1 = Chprov1 * sincosval.x; @@ -2156,9 +2155,8 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr float fz = fy - (0.005f * bprov1); float x_ = 65535.0f * f2xyz(fx) * D50x; - // float y_ = 65535.0f * f2xyz(fy); float z_ = 65535.0f * f2xyz(fz) * D50z; - float y_ = (Lprov1 > epskap) ? 65535.0 * fy * fy * fy : 65535.0 * Lprov1 / kappa; + float y_ = (Lprov1 > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * Lprov1 / kappa; xyz2rgb(x_, y_, z_, R, G, B, wip); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 9bbdb022f..112ef9826 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -40,7 +40,7 @@ #include "improccoordinator.h" #include "clutstore.h" #include "ciecam02.h" -//#define BENCHMARK +#define BENCHMARK #include "StopWatch.h" #include "../rtgui/ppversion.h" #include "../rtgui/guiutils.h" @@ -2977,19 +2977,19 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); - double toxyz[3][3] = { + float toxyz[3][3] = { { - ( wprof[0][0] / Color::D50x), - ( wprof[0][1] / Color::D50x), - ( wprof[0][2] / Color::D50x) + static_cast( wprof[0][0] / Color::D50x), + static_cast( wprof[0][1] / Color::D50x), + static_cast( wprof[0][2] / Color::D50x) }, { - ( wprof[1][0]), - ( wprof[1][1]), - ( wprof[1][2]) + static_cast( wprof[1][0]), + static_cast( wprof[1][1]), + static_cast( wprof[1][2]) }, { - ( wprof[2][0] / Color::D50z), - ( wprof[2][1] / Color::D50z), - ( wprof[2][2] / Color::D50z) + static_cast( wprof[2][0] / Color::D50z), + static_cast( wprof[2][1] / Color::D50z), + static_cast( wprof[2][2] / Color::D50z) } }; @@ -3628,60 +3628,48 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float r1, g1, b1, r2, g2, b2, L_1, L_2, Lfactor, a_1, b_1, x_, y_, z_, R, G, B ; - float y, fy, yy, fyy, x, z, fx, fz; - // rgb values before RGB curves - r1 = rtemp[ti * TS + tj] ; - g1 = gtemp[ti * TS + tj] ; - b1 = btemp[ti * TS + tj] ; + float r = rtemp[ti * TS + tj] ; + float g = gtemp[ti * TS + tj] ; + float b = btemp[ti * TS + tj] ; //convert to Lab to get a&b before RGB curves - x = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1; - y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; - z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; + float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF)); - fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF)); - fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF)); + float fx = x < 65535.0f ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF); + float fy = y < 65535.0f ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF); + float fz = z < 65535.0f ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF); - L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; - a_1 = (500.0f * (fx - fy) ); - b_1 = (200.0f * (fy - fz) ); + float a_1 = 500.0f * (fx - fy); + float b_1 = 200.0f * (fy - fz); // rgb values after RGB curves if (rCurve) { - r2 = rCurve[ rtemp[ti * TS + tj]]; - } else { - r2 = r1; + r = rCurve[r]; } if (gCurve) { - g2 = gCurve[ gtemp[ti * TS + tj]]; - } else { - g2 = g1; + g = gCurve[g]; } if (bCurve) { - b2 = bCurve[ btemp[ti * TS + tj]]; - } else { - b2 = b1; + b = bCurve[b]; } // Luminosity after // only Luminance in Lab - yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2; - fyy = (yy < 65535.0f ? Color::cachef[std::max(yy, 0.f)] : 327.68f * std::cbrt(yy / MAXVALF)); - L_2 = (116.0f * fyy - 5242.88f); + float newy = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float newfy = newy < 65535.0f ? Color::cachef[newy] : 327.68f * std::cbrt(newy / MAXVALF); + float L_2 = 116.0f * newfy - 5242.88f; //gamut control if(settings->rgbcurveslumamode_gamut) { - float RR, GG, BB; - float HH, Lpro, Chpro; - Lpro = L_2 / 327.68f; - Chpro = sqrt(SQR(a_1) + SQR(b_1)) / 327.68f; - HH = xatan2f(b_1, a_1); + float Lpro = L_2 / 327.68f; + float Chpro = sqrtf(SQR(a_1) + SQR(b_1)) / 327.68f; + float HH = xatan2f(b_1, a_1); // According to mathematical laws we can get the sin and cos of HH by simple operations - float2 sincosval; + float2 sincosval; if(Chpro == 0.0f) { sincosval.y = 1.0f; @@ -3695,30 +3683,18 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer bool neg = false; bool more_rgb = false; //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lpro, Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(HH, sincosval, Lpro, Chpro, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, Lpro, Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); + Color::gamutLchonly(HH, sincosval, Lpro, Chpro, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip, highlight, 0.15f, 0.96f); #endif - - //Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); - - - -// float2 sincosval = xsincosf(HH); - - L_2 = Lpro * 327.68f; - a_1 = 327.68f * Chpro * sincosval.y; - b_1 = 327.68f * Chpro * sincosval.x; - } //end of gamut control - - //calculate RGB with L_2 and old value of a and b - Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; - Color::xyz2rgb(x_, y_, z_, R, G, B, wip); - - rtemp[ti * TS + tj] = R; - gtemp[ti * TS + tj] = G; - btemp[ti * TS + tj] = B; + //end of gamut control + } else { + float x_, y_, z_; + //calculate RGB with L_2 and old value of a and b + Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; + Color::xyz2rgb(x_, y_, z_, rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], wip); + } } } } From 7a2dd888bb438fef1ba08b6c92911f08e1b2d0a4 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 26 Aug 2016 14:20:47 +0200 Subject: [PATCH 2/5] RGB Curves Luminosity mode, reduce number of atan2 calculations --- rtengine/color.cc | 7 ++++++- rtengine/improcfun.cc | 13 +++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index 60d355b26..872f47522 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -2142,7 +2142,7 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr #ifdef _DEBUG neg = false, more_rgb = false; #endif - + float ChprovSave = Chprov1; do { inGamut = true; @@ -2165,6 +2165,11 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr #ifdef _DEBUG neg = true; #endif + if (isnan(HH)) { + float atemp = ChprovSave * sincosval.y * 327.68; + float btemp = ChprovSave * sincosval.x * 327.68; + HH = xatan2f(btemp, atemp); + } if (Lprov1 < 0.1f) { Lprov1 = 0.1f; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 112ef9826..29ac45ca9 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -3637,9 +3637,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - float fx = x < 65535.0f ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF); - float fy = y < 65535.0f ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF); - float fz = z < 65535.0f ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF); + float fx = x < MAXVALF ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF); + float fy = y < MAXVALF ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF); + float fz = z < MAXVALF ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF); float a_1 = 500.0f * (fx - fy); float b_1 = 200.0f * (fy - fz); @@ -3660,15 +3660,16 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer // Luminosity after // only Luminance in Lab float newy = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; - float newfy = newy < 65535.0f ? Color::cachef[newy] : 327.68f * std::cbrt(newy / MAXVALF); + float newfy = newy < MAXVALF ? Color::cachef[newy] : 327.68f * std::cbrt(newy / MAXVALF); float L_2 = 116.0f * newfy - 5242.88f; //gamut control if(settings->rgbcurveslumamode_gamut) { float Lpro = L_2 / 327.68f; float Chpro = sqrtf(SQR(a_1) + SQR(b_1)) / 327.68f; - float HH = xatan2f(b_1, a_1); - // According to mathematical laws we can get the sin and cos of HH by simple operations + float HH = NAN; // we set HH to NAN, because then it will be calculated in Color::gamutLchonly only if needed +// float HH = xatan2f(b_1, a_1); + // According to mathematical laws we can get the sin and cos of HH by simple operations even if we don't calculate HH float2 sincosval; if(Chpro == 0.0f) { From 66054ca50dca6a3b868c62f8b896e34fd371131d Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 26 Aug 2016 16:38:14 +0200 Subject: [PATCH 3/5] RGB curves luminosity mode: Experimental patch to equalize the strength of R, G and B curve --- rtengine/improcfun.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 29ac45ca9..eb85e6577 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2992,6 +2992,10 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer static_cast( wprof[2][2] / Color::D50z) } }; + float maxFactorToxyz = max(toxyz[1][0],toxyz[1][1],toxyz[1][2]); + float equalR = maxFactorToxyz / toxyz[1][0]; + float equalG = maxFactorToxyz / toxyz[1][1]; + float equalB = maxFactorToxyz / toxyz[1][2]; //inverse matrix user select double wip[3][3] = { @@ -3646,15 +3650,18 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer // rgb values after RGB curves if (rCurve) { - r = rCurve[r]; + float rNew = rCurve[r]; + r += (rNew - r) * equalR; } if (gCurve) { - g = gCurve[g]; + float gNew = gCurve[g]; + g += (gNew - g) * equalG; } if (bCurve) { - b = bCurve[b]; + float bNew = bCurve[b]; + b += (bNew - b) * equalB; } // Luminosity after From 46334c046242405409f1644d81829751a34945c6 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 28 Aug 2016 19:59:46 +0200 Subject: [PATCH 4/5] Disables StopWatch --- rtengine/improcfun.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index eb85e6577..c9bc41d71 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -40,7 +40,7 @@ #include "improccoordinator.h" #include "clutstore.h" #include "ciecam02.h" -#define BENCHMARK +//#define BENCHMARK #include "StopWatch.h" #include "../rtgui/ppversion.h" #include "../rtgui/guiutils.h" From 2ba7e296d01fff8534ce8538d69f426f174dc5fd Mon Sep 17 00:00:00 2001 From: Hombre Date: Mon, 29 Aug 2016 01:35:19 +0200 Subject: [PATCH 5/5] Bugfix: Options::readFromFile should not reset the options values. They are initialy set in the constructor then should only be updated by each call to this method. --- rtgui/options.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index e723361be..ab887edfe 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -734,8 +734,6 @@ int Options::readFromFile (Glib::ustring fname) try { if (keyFile.load_from_file (fname)) { - setDefaults (); - // -------------------------------------------------------------------------------------------------------- if (keyFile.has_group ("General")) { @@ -1781,14 +1779,10 @@ int Options::readFromFile (Glib::ustring fname) if (options.rtSettings.verbose) { printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); } - - setDefaults (); } catch (...) { if (options.rtSettings.verbose) { printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); } - - setDefaults (); } return 1;