diff --git a/rtengine/color.cc b/rtengine/color.cc index 3be412b6d..71fb097f6 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1747,15 +1747,41 @@ void Color::Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat & } #endif // __SSE2__ +inline float Color::computeXYZ2Lab(float f) +{ + if (f < 0.f) { + return 327.68 * ((kappa * f / MAXVALF + 16.0) / 116.0); + } else if (f > 65535.f) { + return (327.68f * xcbrtf(f / MAXVALF)); + } else { + return cachef[f]; + } +} + + +inline float Color::computeXYZ2LabY(float f) +{ + if (f < 0.f) { + return 327.68 * (kappa * f / MAXVALF); + } else if (f > 65535.f) { + return 327.68f * (116.f * xcbrtf(f / MAXVALF) - 16.f); + } else { + return cachefy[f]; + } +} + + void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, const float wp[3][3], int width) { #ifdef __SSE2__ + vfloat minvalfv = F2V(0.f); vfloat maxvalfv = F2V(MAXVALF); vfloat c500v = F2V(500.f); vfloat c200v = F2V(200.f); #endif int i = 0; + #ifdef __SSE2__ for(;i < width - 3; i+=4) { const vfloat rv = LVFU(R[i]); @@ -1766,17 +1792,18 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, const vfloat zv = F2V(wp[2][0]) * rv + F2V(wp[2][1]) * gv + F2V(wp[2][2]) * bv; vmask maxMask = vmaskf_gt(vmaxf(xv, vmaxf(yv, zv)), maxvalfv); - if (_mm_movemask_ps((vfloat)maxMask)) { + vmask minMask = vmaskf_lt(vminf(xv, vminf(yv, zv)), minvalfv); + if (_mm_movemask_ps((vfloat)maxMask) || _mm_movemask_ps((vfloat)minMask)) { // take slower code path for all 4 pixels if one of the values is > MAXVALF. Still faster than non SSE2 version for(int k = 0; k < 4; ++k) { float x = xv[k]; float y = yv[k]; float z = zv[k]; - float fx = (x <= 65535.f ? cachef[x] : (327.68f * xcbrtf(x / MAXVALF))); - float fy = (y <= 65535.f ? cachef[y] : (327.68f * xcbrtf(y / MAXVALF))); - float fz = (z <= 65535.f ? cachef[z] : (327.68f * xcbrtf(z / MAXVALF))); + float fx = computeXYZ2Lab(x); + float fy = computeXYZ2Lab(y); + float fz = computeXYZ2Lab(z); - L[i + k] = (y <= 65535.0f ? cachefy[y] : 327.68f * (116.f * xcbrtf(y / MAXVALF) - 16.f)); + L[i + k] = computeXYZ2LabY(y); a[i + k] = (500.f * (fx - fy) ); b[i + k] = (200.f * (fy - fz) ); } @@ -1800,11 +1827,11 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, float z = wp[2][0] * rv + wp[2][1] * gv + wp[2][2] * bv; float fx, fy, fz; - fx = (x <= 65535.0f ? cachef[x] : (327.68f * xcbrtf(x / MAXVALF))); - fy = (y <= 65535.0f ? cachef[y] : (327.68f * xcbrtf(y / MAXVALF))); - fz = (z <= 65535.0f ? cachef[z] : (327.68f * xcbrtf(z / MAXVALF))); + fx = computeXYZ2Lab(x); + fy = computeXYZ2Lab(y); + fz = computeXYZ2Lab(z); - L[i] = (y <= 65535.0f ? cachefy[y] : 327.68f * (116.f * xcbrtf(y / MAXVALF) - 16.f)); + L[i] = computeXYZ2LabY(y); a[i] = 500.0f * (fx - fy); b[i] = 200.0f * (fy - fz); } @@ -1818,11 +1845,11 @@ void Color::XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b) float y = Y; float fx, fy, fz; - fx = (x <= 65535.0f ? cachef[x] : (327.68f * xcbrtf(x / MAXVALF))); - fy = (y <= 65535.0f ? cachef[y] : (327.68f * xcbrtf(y / MAXVALF))); - fz = (z <= 65535.0f ? cachef[z] : (327.68f * xcbrtf(z / MAXVALF))); + fx = computeXYZ2Lab(x); + fy = computeXYZ2Lab(y); + fz = computeXYZ2Lab(z); - L = (y <= 65535.0f ? cachefy[y] : 327.68f * (116.f * xcbrtf(y / MAXVALF) - 16.f)); + L = computeXYZ2LabY(y); a = (500.0f * (fx - fy) ); b = (200.0f * (fy - fz) ); } @@ -1854,11 +1881,11 @@ void Color::Yuv2Lab(float Yin, float u, float v, float &L, float &a, float &b, c gamutmap(X, Y, Z, wp); - float fx = (X <= 65535.0 ? cachef[X] : (327.68 * std::cbrt(X / MAXVALF))); - float fy = (Y <= 65535.0 ? cachef[Y] : (327.68 * std::cbrt(Y / MAXVALF))); - float fz = (Z <= 65535.0 ? cachef[Z] : (327.68 * std::cbrt(Z / MAXVALF))); + float fx = computeXYZ2Lab(X); + float fy = computeXYZ2Lab(Y); + float fz = computeXYZ2Lab(Z); - L = (Y <= 65535.0f ? cachefy[Y] : 327.68f * (116.f * xcbrtf(Y / MAXVALF) - 16.f)); + L = computeXYZ2LabY(Y); a = (500.0 * (fx - fy) ); b = (200.0 * (fy - fz) ); } diff --git a/rtengine/color.h b/rtengine/color.h index 4b865f1d9..a0d8d93ee 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -97,6 +97,10 @@ private: #ifdef __SSE2__ static vfloat hue2rgb(vfloat p, vfloat q, vfloat t); #endif + + static float computeXYZ2Lab(float f); + static float computeXYZ2LabY(float f); + public: typedef enum Channel { diff --git a/rtengine/curves.h b/rtengine/curves.h index 01b17a02c..3762b3f1a 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -51,6 +51,9 @@ inline void setLutVal(const LUTf &lut, float &val) { if (!OOG(val)) { val = lut[std::max(val, 0.f)]; + } else if (val < 0.f) { + float m = lut[0.f]; + val += m; } else { float m = lut[MAXVALF]; val += (m - MAXVALF); @@ -61,8 +64,8 @@ inline void setLutVal(float &val, float lutval, float maxval) { if (!OOG(val)) { val = lutval; - } else { - val += (maxval - MAXVALF); + } else if (val > 0.f) { + val += maxval - MAXVALF; } } diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index e56e63dea..676213ef8 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -394,9 +394,9 @@ Imagefloat* ImProcFunctions::lab2rgbOut (LabImage* lab, int cx, int cy, int cw, Color::xyz2srgb(x_, y_, z_, R, G, B); - setUnlessOOG(image->r(i - cy, j - cx), Color::gamma2curve[CLIP(R)]); - setUnlessOOG(image->g(i - cy, j - cx), Color::gamma2curve[CLIP(G)]); - setUnlessOOG(image->b(i - cy, j - cx), Color::gamma2curve[CLIP(B)]); + image->r(i - cy, j - cx) = Color::gamma2curve[CLIP(R)]; + image->g(i - cy, j - cx) = Color::gamma2curve[CLIP(G)]; + image->b(i - cy, j - cx) = Color::gamma2curve[CLIP(B)]; } } } diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 1918439ef..a8c835a98 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -141,7 +141,7 @@ constexpr std::uint8_t uint16ToUint8Rounded(std::uint16_t i) template constexpr bool OOG(const T &val, const T &high=T(MAXVAL)) { - return (val > high); + return (val < T(0)) || (val > high); } template diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 2f88e0c11..60dd25e7e 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1979,10 +1979,6 @@ bool EditorPanel::saveImmediately (const Glib::ustring &filename, const SaveForm rtengine::procparams::ProcParams pparams; ipc->getParams (&pparams); - if (gimpPlugin) { - pparams.icm.gamma = "linear_g1.0"; - } - rtengine::ProcessingJob *job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); // save immediately