diff --git a/rtengine/color.cc b/rtengine/color.cc index 706d0f36d..ee63720aa 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -553,44 +553,6 @@ void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l) } } -void Color::rgb2hslfloat(float r, float g, float b, float &h, float &s, float &l) -{ - - float m = min(r, g, b); - float M = max(r, g, b); - float C = M - m; - - l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) - - if (fabsf(C) < 0.65535f) { // 0.00001f * 65535.f - h = 0.f; - s = 0.f; - } else { - - if (l <= 0.5f) { - s = (M - m) / (M + m); - } else { - s = (M - m) / (131070.f - M - m); // 131070.f = 2.f * 65535.f - } - - if ( r == M ) { - h = (g - b); - } else if ( g == M ) { - h = (2.f * C) + (b - r); - } else { - h = (4.f * C) + (r - g); - } - - h /= (6.f * C); - - if ( h < 0.f ) { - h += 1.f; - } else if ( h > 1.f ) { - h -= 1.f; - } - } -} - #ifdef __SSE2__ void Color::rgb2hsl(vfloat r, vfloat g, vfloat b, vfloat &h, vfloat &s, vfloat &l) { @@ -609,9 +571,8 @@ void Color::rgb2hsl(vfloat r, vfloat g, vfloat b, vfloat &h, vfloat &s, vfloat & h /= (F2V(6.f) * C); vfloat onev = F2V(1.f); h = vself(vmaskf_lt(h, ZEROV), h + onev, h); - h = vself(vmaskf_gt(h, onev), h - onev, h); - vmask zeromask = vmaskf_lt(vabsf(C), F2V(0.65535f)); + vmask zeromask = vmaskf_lt(C, F2V(0.65535f)); h = vself(zeromask, ZEROV, h); s = vself(zeromask, ZEROV, s); } @@ -697,28 +658,6 @@ void Color::hsl2rgb (float h, float s, float l, float &r, float &g, float &b) } } -void Color::hsl2rgbfloat (float h, float s, float l, float &r, float &g, float &b) -{ - - if (s == 0.f) { - r = g = b = 65535.f * l; // achromatic - } else { - float m2; - - if (l <= 0.5f) { - m2 = l * (1.f + s); - } else { - m2 = l + s - l * s; - } - - float m1 = 2.f * l - m2; - - r = 65535.f * hue2rgbfloat (m1, m2, h * 6.f + 2.f); - g = 65535.f * hue2rgbfloat (m1, m2, h * 6.f); - b = 65535.f * hue2rgbfloat (m1, m2, h * 6.f - 2.f); - } -} - #ifdef __SSE2__ void Color::hsl2rgb (vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b) { diff --git a/rtengine/color.h b/rtengine/color.h index 2b6d40174..d56b30e52 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -205,7 +205,64 @@ public: * @param l luminance channel [0; 1] (return value) */ static void rgb2hsl (float r, float g, float b, float &h, float &s, float &l); - static void rgb2hslfloat (float r, float g, float b, float &h, float &s, float &l); + + static inline void rgb2slfloat(float r, float g, float b, float &s, float &l) + { + + float m = min(r, g, b); + float M = max(r, g, b); + float C = M - m; + + l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + + if (C < 0.65535f) { // 0.00001f * 65535.f + s = 0.f; + } else { + + if (l <= 0.5f) { + s = C / (M + m); + } else { + s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + } + } + } + + static inline void rgb2hslfloat(float r, float g, float b, float &h, float &s, float &l) + { + + float m = min(r, g, b); + float M = max(r, g, b); + float C = M - m; + + l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + + if (C < 0.65535f) { // 0.00001f * 65535.f + h = 0.f; + s = 0.f; + } else { + + if (l <= 0.5f) { + s = C / (M + m); + } else { + s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + } + + if ( r == M ) { + h = (g - b); + } else if ( g == M ) { + h = (2.f * C) + (b - r); + } else { + h = (4.f * C) + (r - g); + } + + h /= (6.f * C); + + if ( h < 0.f ) { + h += 1.f; + } + } + } + #ifdef __SSE2__ static void rgb2hsl (vfloat r, vfloat g, vfloat b, vfloat &h, vfloat &s, vfloat &l); #endif @@ -220,7 +277,29 @@ public: * @param b blue channel [0 ; 65535] (return value) */ static void hsl2rgb (float h, float s, float l, float &r, float &g, float &b); - static void hsl2rgbfloat (float h, float s, float l, float &r, float &g, float &b); + + static inline void hsl2rgbfloat (float h, float s, float l, float &r, float &g, float &b) + { + + if (s == 0.f) { + r = g = b = 65535.f * l; // achromatic + } else { + float m2; + + if (l <= 0.5f) { + m2 = l * (1.f + s); + } else { + m2 = l + s - l * s; + } + + float m1 = 2.f * l - m2; + + r = 65535.f * hue2rgbfloat (m1, m2, h * 6.f + 2.f); + g = 65535.f * hue2rgbfloat (m1, m2, h * 6.f); + b = 65535.f * hue2rgbfloat (m1, m2, h * 6.f - 2.f); + } + } + #ifdef __SSE2__ static void hsl2rgb (vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b); #endif @@ -254,11 +333,7 @@ public: float var_Max = max(r, g, b); float del_Max = var_Max - var_Min; - if (del_Max < 0.00001f) { - return 0.f; - } else { - return del_Max / var_Max; - } + return del_Max / (var_Max == 0.f ? 1.f : var_Max); } static inline bool rgb2hsvdcp(float r, float g, float b, float &h, float &s, float &v) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 7505bccec..89eb9cfbf 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4168,29 +4168,25 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer // Luminance = (0.299f*r + 0.587f*g + 0.114f*b) - float h, s, l; - Color::rgb2hsl (r, g, b, h, s, l); + float s, l; + Color::rgb2slfloat (r, g, b, s, l); - float l_ = Color::gamma_srgb (l * 65535.f) / 65535.f; + float l_ = Color::gammatab_srgb1[l * 65535.f]; // get the opacity and tweak it to preserve saturated colors - float opacity; + float opacity = 0.f; if (ctOpacityCurve) { opacity = (1.f - min (s / satLimit, 1.f) * (1.f - satLimitOpacity)) * ctOpacityCurve.lutOpacityCurve[l_ * 500.f]; } - if (!ctOpacityCurve) { - opacity = 0.f; - } - float r2, g2, b2; ctColorCurve.getVal (l_, r2, g2, b2); // get the color from the color curve float h2, s2, l2; - Color::rgb2hsl (r2, g2, b2, h2, s2, l2); // transform this new color to hsl + Color::rgb2hslfloat (r2, g2, b2, h2, s2, l2); // transform this new color to hsl - Color::hsl2rgb (h2, s + ((1.f - s) * (1.f - l) * 0.7f), l, r2, g2, b2); + Color::hsl2rgbfloat (h2, s + ((1.f - s) * (1.f - l) * 0.7f), l, r2, g2, b2); rtemp[ti * TS + tj] = r + (r2 - r) * opacity; // merge the color to the old color, depending on the opacity gtemp[ti * TS + tj] = g + (g2 - g) * opacity; @@ -4869,31 +4865,31 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { for (int j = 0; j < tW; j++) { - float r = tmpImage->r (i, j); - float g = tmpImage->g (i, j); - float b = tmpImage->b (i, j); + float r = tmpImage->r(i, j); + float g = tmpImage->g(i, j); + float b = tmpImage->b(i, j); // Luminance = (0.299f*r + 0.587f*g + 0.114f*b) - float h, s, l; - Color::rgb2hsl (r, g, b, h, s, l); + float s, l; + Color::rgb2slfloat(r, g, b, s, l); - float l_ = Color::gamma_srgb (l * 65535.f) / 65535.f; + float l_ = Color::gammatab_srgb1[l * 65535.f]; - // get the opacity and tweak it to preserve saturated colors + // get the opacity and tweak it to preserve saturated colours float opacity = ctOpacityCurve.lutOpacityCurve[l_ * 500.f] / 4.f; float r2, g2, b2; - ctColorCurve.getVal (l_, r2, g2, b2); // get the color from the color curve + ctColorCurve.getVal(l_, r2, g2, b2); // get the colour from the colour curve float h2, s2, l2; - Color::rgb2hsl (r2, g2, b2, h2, s2, l2); // transform this new color to hsl + Color::rgb2hslfloat(r2, g2, b2, h2, s2, l2); // transform this new colour to hsl - Color::hsl2rgb (h2, s2, l, r2, g2, b2); + Color::hsl2rgbfloat(h2, s2, l, r2, g2, b2); - tmpImage->r (i, j) = r + (r2 - r) * opacity; - tmpImage->g (i, j) = g + (g2 - g) * opacity; - tmpImage->b (i, j) = b + (b2 - b) * opacity; + tmpImage->r(i, j) = intp(opacity, r2, r); + tmpImage->g(i, j) = intp(opacity, g2, g); + tmpImage->b(i, j) = intp(opacity, b2, b); } } }