diff --git a/rtengine/color.h b/rtengine/color.h index 789bf27c6..d36a7db8e 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1804,84 +1804,6 @@ public: return (hr); } - static inline void RGB2YCbCr(float* R, float* G, float* B, float* Y, float* Cb, float *Cr, float gamma, int W) { - gamma = 1.f / gamma; - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.2627f); - const vfloat c2v = F2V(0.6780f); - const vfloat c3v = F2V(0.0593f); - const vfloat c4v = F2V(1.f - 0.0593f); - const vfloat c5v = F2V(1.f - 0.2627f); - for (; i < W - 3; i += 4) { - const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); - const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); - const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); - STVFU(Cb[i], c4v * Bv - (c1v * Rv + c2v * Gv)); - STVFU(Cr[i], c5v * Rv - (c2v * Gv + c3v * Bv)); - } -#endif - for (; i < W; ++i) { - const float r = std::max(R[i], 0.f); - const float g = std::max(G[i], 0.f); - const float b = std::max(B[i], 0.f); - Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); - Cb[i] = (1.f - 0.0593f) * b - (0.2627f * r + 0.6780f * g); - Cr[i] = (1.f - 0.2627f) * r - (0.6780f * g + 0.0593f * b); - } - } - - static inline void YCbCr2RGB(float* Y, float* Cb, float* Cr, float* R, float* G, float* B, float gamma, int W) { - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.0593f / 0.6780f); - const vfloat c2v = F2V(0.2627f / 0.6780f); - - for (; i < W - 3; i += 4) { - const vfloat Yv = pow_F(LVFU(Y[i]), gammav); - const vfloat Crv = LVFU(Cr[i]); - const vfloat Cbv = LVFU(Cb[i]); - STVFU(R[i], vmaxf(Yv + Crv, ZEROV)); - STVFU(G[i], vmaxf(Yv - c1v * Cbv - c2v * Crv, ZEROV)); - STVFU(B[i], vmaxf(Yv + Cbv, ZEROV)); - } -#endif - for (; i < W; ++i) { - const float y = pow_F(Y[i], gamma); - const float cr = Cr[i]; - const float cb = Cb[i]; - R[i] = std::max(y + cr, 0.f); - G[i] = std::max(y - (0.0593f / 0.6780f) * cb - (0.2627f / 0.6780f) * cr, 0.f); - B[i] = std::max(y + cb, 0.f); - } - } - - static inline void RGB2Y(float* R, float* G, float* B, float* Y, float gamma, int W) { - gamma = 1.f / gamma; - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.2627f); - const vfloat c2v = F2V(0.6780f); - const vfloat c3v = F2V(0.0593f); - for (; i < W - 3; i += 4) { - const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); - const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); - const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); - } -#endif - for (; i < W; ++i) { - const float r = std::max(R[i], 0.f); - const float g = std::max(G[i], 0.f); - const float b = std::max(B[i], 0.f); - Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); - } - } - static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) { gamma = 1.f / gamma; int i = 0; diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index 5665394cc..dfb7cb225 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -272,52 +272,16 @@ template void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** REST dst[i][0] = dst[i][1] = dst[i][2] = 1.f; // I tried hand written SSE code but gcc vectorizes better for (int j = 3; j < W - 3; ++j) { - float val = src[i - 3][j - 1] * c31; - val += src[i - 3][j - 0] * c30; - val += src[i - 3][j + 1] * c31; + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; - val += src[i - 2][j - 2] * c22; - val += src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - val += src[i - 2][j + 2] * c22; - - val += src[i - 1][j - 3] * c31; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - val += src[i - 1][j + 3] * c31; - - val += src[i][j - 3] * c30; - val += src[i][j - 2] * c20; - val += src[i][j - 1] * c10; - val += src[i][j - 0] * c00; - val += src[i][j + 1] * c10; - val += src[i][j + 2] * c20; - val += src[i][j + 3] * c30; - - val += src[i + 1][j - 3] * c31; - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - val += src[i + 1][j + 3] * c31; - - val += src[i + 2][j - 2] * c22; - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - val += src[i + 2][j + 2] * c22; - - val += src[i + 3][j - 1] * c31; - val += src[i + 3][j - 0] * c30; - val += src[i + 3][j + 1] * c31; - - val = val > 0.f ? val : 1.f; - dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -360,34 +324,13 @@ template void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** REST dst[i][0] = dst[i][1] = 1.f; // I tried hand written SSE code but gcc vectorizes better for (int j = 2; j < W - 2; ++j) { - float val = src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - - val += src[i - 0][j - 2] * c20; - val += src[i - 0][j - 1] * c10; - val += src[i - 0][j - 0] * c00; - val += src[i - 0][j + 1] * c10; - val += src[i - 0][j + 2] * c20; - - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - - val = val > 0.f ? val : 1.f; - dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -431,49 +374,14 @@ template void gauss7x7mult (T** RESTRICT src, T** RESTRICT dst, const i for (int i = 3; i < H - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better for (int j = 3; j < W - 3; ++j) { - float val = src[i - 3][j - 1] * c31; - val += src[i - 3][j - 0] * c30; - val += src[i - 3][j + 1] * c31; - - val += src[i - 2][j - 2] * c22; - val += src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - val += src[i - 2][j + 2] * c22; - - val += src[i - 1][j - 3] * c31; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - val += src[i - 1][j + 3] * c31; - - val += src[i][j - 3] * c30; - val += src[i][j - 2] * c20; - val += src[i][j - 1] * c10; - val += src[i][j - 0] * c00; - val += src[i][j + 1] * c10; - val += src[i][j + 2] * c20; - val += src[i][j + 3] * c30; - - val += src[i + 1][j - 3] * c31; - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - val += src[i + 1][j + 3] * c31; - - val += src[i + 2][j - 2] * c22; - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - val += src[i + 2][j + 2] * c22; - - val += src[i + 3][j - 1] * c31; - val += src[i + 3][j - 0] * c30; - val += src[i + 3][j + 1] * c31; + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; dst[i][j] *= val; } @@ -499,31 +407,11 @@ template void gauss5x5mult (T** RESTRICT src, T** RESTRICT dst, const i for (int i = 2; i < H - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better for (int j = 2; j < W - 2; ++j) { - float val = src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - - val += src[i - 0][j - 2] * c20; - val += src[i - 0][j - 1] * c10; - val += src[i - 0][j - 0] * c00; - val += src[i - 0][j + 1] * c10; - val += src[i - 0][j + 2] * c20; - - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; dst[i][j] *= val; }