From 5f97c4f15be2b35cb6de584121cde9f4032994b2 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 16 Sep 2015 00:14:58 +0200 Subject: [PATCH] Simpler interface for gaussian blur, speedup for double precision gaussian blur and speedup for retinex transmission curve --- rtengine/PF_correct_RT.cc | 36 +--- rtengine/bilateral2.h | 4 +- rtengine/gauss.h | 403 +++++++++---------------------------- rtengine/helpersse2.h | 3 + rtengine/impulse_denoise.h | 9 +- rtengine/ipretinex.cc | 66 ++---- rtengine/ipsharpen.cc | 37 +--- rtengine/shmap.cc | 5 +- 8 files changed, 132 insertions(+), 431 deletions(-) diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index 130a683d8..c56ce168d 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -65,11 +65,8 @@ SSEFUNCTION void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, #pragma omp parallel #endif { - AlignedBufferMP buffer(max(src->W, src->H)); - gaussHorizontal (src->a, tmp1->a, buffer, src->W, src->H, radius); - gaussHorizontal (src->b, tmp1->b, buffer, src->W, src->H, radius); - gaussVertical (tmp1->a, tmp1->a, buffer, src->W, src->H, radius); - gaussVertical (tmp1->b, tmp1->b, buffer, src->W, src->H, radius); + gaussianBlur (src->a, tmp1->a, src->W, src->H, radius); + gaussianBlur (src->b, tmp1->b, src->W, src->H, radius); } float chromave = 0.0f; @@ -395,11 +392,8 @@ SSEFUNCTION void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * ds #pragma omp parallel #endif { - AlignedBufferMP buffer(max(src->W, src->H)); - gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); - gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); - gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); - gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + gaussianBlur (sraa, tmaa, src->W, src->H, radius); + gaussianBlur (srbb, tmbb, src->W, src->H, radius); } float chromave = 0.0f; @@ -773,19 +767,14 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d #pragma omp parallel #endif { - AlignedBufferMP buffer(max(src->W, src->H)); - //chroma a and b if(mode == 2) { //choice of gaussian blur - gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); - gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); - gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); - gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + gaussianBlur (sraa, tmaa, src->W, src->H, radius); + gaussianBlur (srbb, tmbb, src->W, src->H, radius); } //luma sh_p - gaussHorizontal (src->sh_p, tmL, buffer, src->W, src->H, 2.0);//low value to avoid artifacts - gaussVertical (tmL, tmL, buffer, src->W, src->H, 2.0); + gaussianBlur (src->sh_p, tmL, src->W, src->H, 2.0);//low value to avoid artifacts } if(mode == 1) { //choice of median @@ -1386,19 +1375,14 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d #pragma omp parallel #endif { - AlignedBufferMP buffer(max(src->W, src->H)); - //chroma a and b if(mode >= 2) { //choice of gaussian blur - gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); - gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); - gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); - gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + gaussianBlur (sraa, tmaa, src->W, src->H, radius); + gaussianBlur (srbb, tmbb, src->W, src->H, radius); } //luma sh_p - gaussHorizontal (src->L, tmL, buffer, src->W, src->H, 2.0);//low value to avoid artifacts - gaussVertical (tmL, tmL, buffer, src->W, src->H, 2.0); + gaussianBlur (src->L, tmL, src->W, src->H, 2.0);//low value to avoid artifacts } if(mode == 1) { //choice of median diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h index 925414fd4..7a919546f 100644 --- a/rtengine/bilateral2.h +++ b/rtengine/bilateral2.h @@ -26,9 +26,7 @@ #include "rtengine.h" #include "rt_math.h" -#include "alignedbuffer.h" #include "mytime.h" -#include "gauss.h" #include "array2D.h" #ifdef _OPENMP @@ -147,7 +145,7 @@ using namespace rtengine; a31*SULY(3,-5) + a32*SULY(3,-4) + a33*SULY(3,-3) + a34*SULY(3,-2) + a35*SULY(3,-1) + a36*SULY(3,0) + a35*SULY(3,1) + a34*SULY(3,2) + a33*SULY(3,3) + a32*SULY(3,4) + a31*SULY(3,5) + \ a21*SULY(4,-5) + a22*SULY(4,-4) + a23*SULY(4,-3) + a24*SULY(4,-2) + a25*SULY(4,-1) + a26*SULY(4,0) + a25*SULY(4,1) + a24*SULY(4,2) + a23*SULY(4,3) + a22*SULY(4,4) + a21*SULY(4,5) + \ a11*SULY(5,-5) + a12*SULY(5,-4) + a13*SULY(5,-3) + a14*SULY(5,-2) + a15*SULY(5,-1) + a16*SULY(5,0) + a15*SULY(5,1) + a14*SULY(5,2) + a13*SULY(5,3) + a12*SULY(5,4) + a11*SULY(5,5); \ - + // sigma = 0.5 template void bilateral05 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) diff --git a/rtengine/gauss.h b/rtengine/gauss.h index b8ec0008f..61e5e2fe4 100644 --- a/rtengine/gauss.h +++ b/rtengine/gauss.h @@ -22,15 +22,11 @@ #include #include #include -#include "alignedbuffer.h" -#ifdef _OPENMP -#include -#endif #include "opthelper.h" // classical filtering if the support window is small: -template void gaussHorizontal3 (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, const float c0, const float c1) +template void gaussHorizontal3 (T** src, T** dst, int W, int H, const float c0, const float c1) { #ifdef _OPENMP @@ -38,8 +34,7 @@ template void gaussHorizontal3 (T** src, T** dst, AlignedBufferMP* pBuf = buffer.acquire(); - T* temp = (T*)pBuf->data; + T temp[W] ALIGNED16; for (int j = 1; j < W - 1; j++) { temp[j] = (T)(c1 * (src[i][j - 1] + src[i][j + 1]) + c0 * src[i][j]); @@ -48,13 +43,11 @@ template void gaussHorizontal3 (T** src, T** dst, AlignedBufferMP void gaussVertical3 (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, const float c0, const float c1) +template void gaussVertical3 (T** src, T** dst, int W, int H, const float c0, const float c1) { #ifdef _OPENMP @@ -62,8 +55,7 @@ template void gaussVertical3 (T** src, T** dst, AlignedBufferMP #endif for (int i = 0; i < W; i++) { - AlignedBuffer* pBuf = buffer.acquire(); - T* temp = (T*)pBuf->data; + T temp[H] ALIGNED16; for (int j = 1; j < H - 1; j++) { temp[j] = (T)(c1 * (src[j - 1][i] + src[j + 1][i]) + c0 * src[j][i]); @@ -75,39 +67,37 @@ template void gaussVertical3 (T** src, T** dst, AlignedBufferMP dst[j][i] = temp[j]; } - buffer.release(pBuf); - dst[H - 1][i] = src[H - 1][i]; } } -#ifdef __SSE__ +#ifdef __SSE2__ template SSEFUNCTION void gaussVertical3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { __m128 Tv, Tm1v, Tp1v; __m128 c0v, c1v; - c0v = _mm_set1_ps(c0); - c1v = _mm_set1_ps(c1); + c0v = F2V(c0); + c1v = F2V(c1); #ifdef _OPENMP #pragma omp for #endif for (int i = 0; i < W - 3; i += 4) { - Tm1v = _mm_loadu_ps( &src[0][i] ); - _mm_storeu_ps( &dst[0][i], Tm1v); + Tm1v = LVFU( src[0][i] ); + STVFU( dst[0][i], Tm1v); if (H > 1) { - Tv = _mm_loadu_ps( &src[1][i]); + Tv = LVFU( src[1][i]); } for (int j = 1; j < H - 1; j++) { - Tp1v = _mm_loadu_ps( &src[j + 1][i]); - _mm_storeu_ps( &dst[j][i], c1v * (Tp1v + Tm1v) + Tv * c0v); + Tp1v = LVFU( src[j + 1][i]); + STVFU( dst[j][i], c1v * (Tp1v + Tm1v) + Tv * c0v); Tm1v = Tv; Tv = Tp1v; } - _mm_storeu_ps( &dst[H - 1][i], _mm_loadu_ps( &src[H - 1][i])); + STVFU( dst[H - 1][i], LVFU( src[H - 1][i])); } // Borders are done without SSE @@ -129,12 +119,12 @@ template SSEFUNCTION void gaussVertical3Sse (T** src, T** dst, int W, i template SSEFUNCTION void gaussHorizontal3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { - float tmp[W][4] __attribute__ ((aligned (16))); + float tmp[W][4] ALIGNED16; __m128 Tv, Tm1v, Tp1v; __m128 c0v, c1v; - c0v = _mm_set1_ps(c0); - c1v = _mm_set1_ps(c1); + c0v = F2V(c0); + c1v = F2V(c1); #ifdef _OPENMP #pragma omp for #endif @@ -152,7 +142,7 @@ template SSEFUNCTION void gaussHorizontal3Sse (T** src, T** dst, int W, for (int j = 1; j < W - 1; j++) { Tp1v = _mm_set_ps( src[i][j + 1], src[i + 1][j + 1], src[i + 2][j + 1], src[i + 3][j + 1] ); - _mm_store_ps( &tmp[j][0], c1v * (Tp1v + Tm1v) + Tv * c0v); + STVF( tmp[j][0], c1v * (Tp1v + Tm1v) + Tv * c0v); Tm1v = Tv; Tv = Tp1v; } @@ -250,16 +240,16 @@ template SSEFUNCTION void gaussHorizontalSse (T** src, T** dst, int W, M[i][j] /= (1.0 + b1 - b2 + b3) * (1.0 - b1 - b2 - b3); } - float tmp[W][4] __attribute__ ((aligned (16))); - float tmpV[4] __attribute__ ((aligned (16))); + float tmp[W][4] ALIGNED16; + float tmpV[4] ALIGNED16; __m128 Rv; __m128 Tv, Tm2v, Tm3v; __m128 Bv, b1v, b2v, b3v; __m128 temp2W, temp2Wp1; - Bv = _mm_set1_ps(B); - b1v = _mm_set1_ps(b1); - b2v = _mm_set1_ps(b2); - b3v = _mm_set1_ps(b3); + Bv = F2V(B); + b1v = F2V(b1); + b2v = F2V(b2); + b3v = F2V(b3); #ifdef _OPENMP #pragma omp for @@ -270,47 +260,47 @@ template SSEFUNCTION void gaussHorizontalSse (T** src, T** dst, int W, tmpV[1] = src[i + 2][0]; tmpV[2] = src[i + 1][0]; tmpV[3] = src[i][0]; - Tv = _mm_load_ps(tmpV); + Tv = LVF(tmpV[0]); Rv = Tv * (Bv + b1v + b2v + b3v); Tm3v = Rv; - _mm_store_ps( &tmp[0][0], Rv ); + STVF( tmp[0][0], Rv ); tmpV[0] = src[i + 3][1]; tmpV[1] = src[i + 2][1]; tmpV[2] = src[i + 1][1]; tmpV[3] = src[i][1]; - Rv = _mm_load_ps(tmpV) * Bv + Rv * b1v + Tv * (b2v + b3v); + Rv = LVF(tmpV[0]) * Bv + Rv * b1v + Tv * (b2v + b3v); Tm2v = Rv; - _mm_store_ps( &tmp[1][0], Rv ); + STVF( tmp[1][0], Rv ); tmpV[0] = src[i + 3][2]; tmpV[1] = src[i + 2][2]; tmpV[2] = src[i + 1][2]; tmpV[3] = src[i][2]; - Rv = _mm_load_ps(tmpV) * Bv + Rv * b1v + Tm3v * b2v + Tv * b3v; - _mm_store_ps( &tmp[2][0], Rv ); + Rv = LVF(tmpV[0]) * Bv + Rv * b1v + Tm3v * b2v + Tv * b3v; + STVF( tmp[2][0], Rv ); for (int j = 3; j < W; j++) { Tv = Rv; Rv = _mm_set_ps(src[i][j], src[i + 1][j], src[i + 2][j], src[i + 3][j]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; - _mm_store_ps( &tmp[j][0], Rv ); + STVF( tmp[j][0], Rv ); Tm3v = Tm2v; Tm2v = Tv; } Tv = _mm_set_ps(src[i][W - 1], src[i + 1][W - 1], src[i + 2][W - 1], src[i + 3][W - 1]); - temp2Wp1 = Tv + _mm_set1_ps(M[2][0]) * (Rv - Tv) + _mm_set1_ps(M[2][1]) * ( Tm2v - Tv ) + _mm_set1_ps(M[2][2]) * (Tm3v - Tv); - temp2W = Tv + _mm_set1_ps(M[1][0]) * (Rv - Tv) + _mm_set1_ps(M[1][1]) * (Tm2v - Tv) + _mm_set1_ps(M[1][2]) * (Tm3v - Tv); + temp2Wp1 = Tv + F2V(M[2][0]) * (Rv - Tv) + F2V(M[2][1]) * ( Tm2v - Tv ) + F2V(M[2][2]) * (Tm3v - Tv); + temp2W = Tv + F2V(M[1][0]) * (Rv - Tv) + F2V(M[1][1]) * (Tm2v - Tv) + F2V(M[1][2]) * (Tm3v - Tv); - Rv = Tv + _mm_set1_ps(M[0][0]) * (Rv - Tv) + _mm_set1_ps(M[0][1]) * (Tm2v - Tv) + _mm_set1_ps(M[0][2]) * (Tm3v - Tv); - _mm_store_ps( &tmp[W - 1][0], Rv ); + Rv = Tv + F2V(M[0][0]) * (Rv - Tv) + F2V(M[0][1]) * (Tm2v - Tv) + F2V(M[0][2]) * (Tm3v - Tv); + STVF( tmp[W - 1][0], Rv ); Tm2v = Bv * Tm2v + b1v * Rv + b2v * temp2W + b3v * temp2Wp1; - _mm_store_ps( &tmp[W - 2][0], Tm2v ); + STVF( tmp[W - 2][0], Tm2v ); Tm3v = Bv * Tm3v + b1v * Tm2v + b2v * Rv + b3v * temp2W; - _mm_store_ps( &tmp[W - 3][0], Tm3v ); + STVF( tmp[W - 3][0], Tm3v ); Tv = Rv; Rv = Tm3v; @@ -318,8 +308,8 @@ template SSEFUNCTION void gaussHorizontalSse (T** src, T** dst, int W, for (int j = W - 4; j >= 0; j--) { Tv = Rv; - Rv = _mm_load_ps(&tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; - _mm_store_ps( &tmp[j][0], Rv ); + Rv = LVF(tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; + STVF( tmp[j][0], Rv ); Tm3v = Tm2v; Tm2v = Tv; } @@ -370,10 +360,10 @@ template SSEFUNCTION void gaussHorizontalSse (T** src, T** dst, int W, // fast gaussian approximation if the support window is large -template void gaussHorizontal (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) +template void gaussHorizontal (T** src, T** dst, int W, int H, double sigma) { -#ifdef __SSE__ +#ifdef __SSE2__ if (sigma < 70) { // bigger sigma only with double precision gaussHorizontalSse (src, dst, W, H, sigma); @@ -401,7 +391,7 @@ template void gaussHorizontal (T** src, T** dst, AlignedBufferMP (src, dst, buffer, W, H, c0, c1); + gaussHorizontal3 (src, dst, W, H, c0, c1); return; } @@ -439,13 +429,13 @@ template void gaussHorizontal (T** src, T** dst, AlignedBufferMP* pBuf = buffer.acquire(); - double* temp2 = pBuf->data; temp2[0] = B * src[i][0] + b1 * src[i][0] + b2 * src[i][0] + b3 * src[i][0]; temp2[1] = B * src[i][1] + b1 * temp2[0] + b2 * src[i][0] + b3 * src[i][0]; @@ -471,11 +461,10 @@ template void gaussHorizontal (T** src, T** dst, AlignedBufferMP SSEFUNCTION void gaussVerticalSse (T** src, T** dst, int W, int H, float sigma) { @@ -537,15 +526,15 @@ template SSEFUNCTION void gaussVerticalSse (T** src, T** dst, int W, in M[i][j] /= (1.0 + b1 - b2 + b3) * (1.0 - b1 - b2 - b3); } - float tmp[H][4] __attribute__ ((aligned (16))); + float tmp[H][4] ALIGNED16; __m128 Rv; __m128 Tv, Tm2v, Tm3v; __m128 Bv, b1v, b2v, b3v; __m128 temp2W, temp2Wp1; - Bv = _mm_set1_ps(B); - b1v = _mm_set1_ps(b1); - b2v = _mm_set1_ps(b2); - b3v = _mm_set1_ps(b3); + Bv = F2V(B); + b1v = F2V(b1); + b2v = F2V(b2); + b3v = F2V(b3); #ifdef _OPENMP @@ -553,39 +542,39 @@ template SSEFUNCTION void gaussVerticalSse (T** src, T** dst, int W, in #endif for (int i = 0; i < W - 3; i += 4) { - Tv = _mm_loadu_ps( &src[0][i]); + Tv = LVFU( src[0][i]); Rv = Tv * (Bv + b1v + b2v + b3v); Tm3v = Rv; - _mm_store_ps( &tmp[0][0], Rv ); + STVF( tmp[0][0], Rv ); - Rv = _mm_loadu_ps(&src[1][i]) * Bv + Rv * b1v + Tv * (b2v + b3v); + Rv = LVFU(src[1][i]) * Bv + Rv * b1v + Tv * (b2v + b3v); Tm2v = Rv; - _mm_store_ps( &tmp[1][0], Rv ); + STVF( tmp[1][0], Rv ); - Rv = _mm_loadu_ps(&src[2][i]) * Bv + Rv * b1v + Tm3v * b2v + Tv * b3v; - _mm_store_ps( &tmp[2][0], Rv ); + Rv = LVFU(src[2][i]) * Bv + Rv * b1v + Tm3v * b2v + Tv * b3v; + STVF( tmp[2][0], Rv ); for (int j = 3; j < H; j++) { Tv = Rv; - Rv = _mm_loadu_ps(&src[j][i]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; - _mm_store_ps( &tmp[j][0], Rv ); + Rv = LVFU(src[j][i]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; + STVF( tmp[j][0], Rv ); Tm3v = Tm2v; Tm2v = Tv; } - Tv = _mm_loadu_ps(&src[H - 1][i]); + Tv = LVFU(src[H - 1][i]); - temp2Wp1 = Tv + _mm_set1_ps(M[2][0]) * (Rv - Tv) + _mm_set1_ps(M[2][1]) * (Tm2v - Tv) + _mm_set1_ps(M[2][2]) * (Tm3v - Tv); - temp2W = Tv + _mm_set1_ps(M[1][0]) * (Rv - Tv) + _mm_set1_ps(M[1][1]) * (Tm2v - Tv) + _mm_set1_ps(M[1][2]) * (Tm3v - Tv); + temp2Wp1 = Tv + F2V(M[2][0]) * (Rv - Tv) + F2V(M[2][1]) * (Tm2v - Tv) + F2V(M[2][2]) * (Tm3v - Tv); + temp2W = Tv + F2V(M[1][0]) * (Rv - Tv) + F2V(M[1][1]) * (Tm2v - Tv) + F2V(M[1][2]) * (Tm3v - Tv); - Rv = Tv + _mm_set1_ps(M[0][0]) * (Rv - Tv) + _mm_set1_ps(M[0][1]) * (Tm2v - Tv) + _mm_set1_ps(M[0][2]) * (Tm3v - Tv); - _mm_storeu_ps( &dst[H - 1][i], Rv ); + Rv = Tv + F2V(M[0][0]) * (Rv - Tv) + F2V(M[0][1]) * (Tm2v - Tv) + F2V(M[0][2]) * (Tm3v - Tv); + STVFU( dst[H - 1][i], Rv ); Tm2v = Bv * Tm2v + b1v * Rv + b2v * temp2W + b3v * temp2Wp1; - _mm_storeu_ps( &dst[H - 2][i], Tm2v ); + STVFU( dst[H - 2][i], Tm2v ); Tm3v = Bv * Tm3v + b1v * Tm2v + b2v * Rv + b3v * temp2W; - _mm_storeu_ps( &dst[H - 3][i], Tm3v ); + STVFU( dst[H - 3][i], Tm3v ); Tv = Rv; Rv = Tm3v; @@ -593,8 +582,8 @@ template SSEFUNCTION void gaussVerticalSse (T** src, T** dst, int W, in for (int j = H - 4; j >= 0; j--) { Tv = Rv; - Rv = _mm_load_ps(&tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; - _mm_storeu_ps( &dst[j][i], Rv ); + Rv = LVF(tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; + STVFU( dst[j][i], Rv ); Tm3v = Tm2v; Tm2v = Tv; } @@ -635,10 +624,10 @@ template SSEFUNCTION void gaussVerticalSse (T** src, T** dst, int W, in #endif -template void gaussVertical (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) +template void gaussVertical (T** src, T** dst, int W, int H, double sigma) { -#ifdef __SSE__ +#ifdef __SSE2__ if (sigma < 70) { // bigger sigma only with double precision gaussVerticalSse (src, dst, W, H, sigma); @@ -666,7 +655,7 @@ template void gaussVertical (T** src, T** dst, AlignedBufferMP double csum = 2.0 * c1 + 1.0; c1 /= csum; double c0 = 1.0 / csum; - gaussVertical3 (src, dst, buffer, W, H, c0, c1); + gaussVertical3 (src, dst, W, H, c0, c1); return; } @@ -705,7 +694,7 @@ template void gaussVertical (T** src, T** dst, AlignedBufferMP } // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) - static const int numcols = 4; + static const int numcols = 8; double temp2[H][numcols] ALIGNED16; double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; #ifdef _OPENMP @@ -732,20 +721,14 @@ template void gaussVertical (T** src, T** dst, AlignedBufferMP } for (int k = 0; k < numcols; k++) { - temp2[H - 1][k] = temp2Hm1[k]; - temp2[H - 2][k] = B * temp2[H - 2][k] + b1 * temp2[H - 1][k] + b2 * temp2H[k] + b3 * temp2Hp1[k]; - temp2[H - 3][k] = B * temp2[H - 3][k] + b1 * temp2[H - 2][k] + b2 * temp2[H - 1][k] + b3 * temp2H[k]; + dst[H - 1][i + k] = temp2[H - 1][k] = temp2Hm1[k]; + dst[H - 2][i + k] = temp2[H - 2][k] = B * temp2[H - 2][k] + b1 * temp2[H - 1][k] + b2 * temp2H[k] + b3 * temp2Hp1[k]; + dst[H - 3][i + k] = temp2[H - 3][k] = B * temp2[H - 3][k] + b1 * temp2[H - 2][k] + b2 * temp2[H - 1][k] + b3 * temp2H[k]; } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - temp2[j][k] = B * temp2[j][k] + b1 * temp2[j + 1][k] + b2 * temp2[j + 2][k] + b3 * temp2[j + 3][k]; - } - } - - for (int j = 0; j < H; j++) { - for (int k = 0; k < numcols; k++) { - dst[j][i + k] = (T)temp2[j][k]; + dst[j][i + k] = temp2[j][k] = B * temp2[j][k] + b1 * temp2[j + 1][k] + b2 * temp2[j + 2][k] + b3 * temp2[j + 3][k]; } } } @@ -768,241 +751,35 @@ template void gaussVertical (T** src, T** dst, AlignedBufferMP double temp2H = src[H - 1][i] + M[1][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[1][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[1][2] * (temp2[H - 3][0] - src[H - 1][i]); double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[2][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[2][2] * (temp2[H - 3][0] - src[H - 1][i]); - temp2[H - 1][0] = temp2Hm1; - temp2[H - 2][0] = B * temp2[H - 2][0] + b1 * temp2[H - 1][0] + b2 * temp2H + b3 * temp2Hp1; - temp2[H - 3][0] = B * temp2[H - 3][0] + b1 * temp2[H - 2][0] + b2 * temp2[H - 1][0] + b3 * temp2H; + dst[H - 1][i] = temp2[H - 1][0] = temp2Hm1; + dst[H - 2][i] = temp2[H - 2][0] = B * temp2[H - 2][0] + b1 * temp2[H - 1][0] + b2 * temp2H + b3 * temp2Hp1; + dst[H - 3][i] = temp2[H - 3][0] = B * temp2[H - 3][0] + b1 * temp2[H - 2][0] + b2 * temp2[H - 1][0] + b3 * temp2H; for (int j = H - 4; j >= 0; j--) { - temp2[j][0] = B * temp2[j][0] + b1 * temp2[j + 1][0] + b2 * temp2[j + 2][0] + b3 * temp2[j + 3][0]; - } - - for (int j = 0; j < H; j++) { - dst[j][i] = (T)temp2[j][0]; + dst[j][i] = temp2[j][0] = B * temp2[j][0] + b1 * temp2[j + 1][0] + b2 * temp2[j + 2][0] + b3 * temp2[j + 3][0]; } } } - - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -template void gaussDerivH (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) +template void gaussianBlur(T** src, T** dst, const int W, const int H, const double sigma, bool forceLowSigma = false) { + double newSigma = sigma; + if(forceLowSigma) { + newSigma /= sqrt(2.0); - if (sigma < 0.6) { - // apply symmetric derivative -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H; i++) { - AlignedBuffer* pBuf = buffer.acquire(); - T* temp = (T*)pBuf->data; - - // double* temp = buffer->data;// replaced by 2 lines above - for (int j = 1; j < W - 1; j++) { - temp[j] = (0.5 * (src[i][j + 1] - src[i][j - 1]) ); - } - - dst[i][0] = (src[i][1] - src[i][0]); - - //memcpy (dst[i]+1, temp+1, (W-2)*sizeof(T)); - for (int j = 1; j < W - 1; j++) { - dst[i][j] = temp[j]; - } - - buffer.release(pBuf); - dst[i][W - 1] = (src[i][W - 1] - src[i][W - 2]); + if(newSigma < 0.6) { // barrier to avoid using simple gauss version for higher radius + newSigma = sigma; + forceLowSigma = false; } - - return; } - // coefficient calculation - double q = 0.98711 * sigma - 0.96330; + gaussHorizontal (src, dst, W, H, newSigma); + gaussVertical (dst, dst, W, H, newSigma); - if (sigma < 2.5) { - q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); - } - - double b0 = 1.57825 + 2.44413 * q + 1.4281 * q * q + 0.422205 * q * q * q; - double b1 = 2.44413 * q + 2.85619 * q * q + 1.26661 * q * q * q; - double b2 = -1.4281 * q * q - 1.26661 * q * q * q; - double b3 = 0.422205 * q * q * q; - double B = 1.0 - (b1 + b2 + b3) / b0; - - b1 /= b0; - b2 /= b0; - b3 /= b0; - - // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering - double M[3][3]; - M[0][0] = -b3 * b1 + 1.0 - b3 * b3 - b2; - M[0][1] = (b3 + b1) * (b2 + b3 * b1); - M[0][2] = b3 * (b1 + b3 * b2); - M[1][0] = b1 + b3 * b2; - M[1][1] = -(b2 - 1.0) * (b2 + b3 * b1); - M[1][2] = -(b3 * b1 + b3 * b3 + b2 - 1.0) * b3; - M[2][0] = b3 * b1 + b2 + b1 * b1 - b2 * b2; - M[2][1] = b1 * b2 + b3 * b2 * b2 - b1 * b3 * b3 - b3 * b3 * b3 - b3 * b2 + b3; - M[2][2] = b3 * (b1 + b3 * b2); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) { - M[i][j] /= (1.0 + b1 - b2 + b3) * (1.0 + b2 + (b1 - b3) * b3); - } - - #pragma omp for - - for (int i = 0; i < H; i++) { - AlignedBuffer* pBuf = buffer.acquire(); - T* temp2 = (T*)pBuf->data; - // double* temp2 = buffer->data;// replaced by 2 lines above - - double src0 = (src[i][1] - src[i][0]); - - temp2[0] = B * src0 + b1 * src0 + b2 * src0 + b3 * src0; - temp2[1] = B * 0.5 * (src[i][2] - src[i][0]) + b1 * temp2[0] + b2 * src0 + b3 * src0; - temp2[2] = B * 0.5 * (src[i][3] - src[i][1]) + b1 * temp2[1] + b2 * temp2[0] + b3 * src0; - - for (int j = 3; j < W - 1; j++) { - temp2[j] = B * 0.5 * (src[i][j + 1] - src[i][j - 1]) + b1 * temp2[j - 1] + b2 * temp2[j - 2] + b3 * temp2[j - 3]; - } - - double srcWm1 = (src[i][W - 1] - src[i][W - 2]); - - temp2[W - 1] = B * srcWm1 + b1 * temp2[W - 2] + b2 * temp2[W - 3] + b3 * temp2[W - 4]; - - double temp2Wm1 = srcWm1 + M[0][0] * (temp2[W - 1] - srcWm1) + M[0][1] * (temp2[W - 2] - srcWm1) + M[0][2] * (temp2[W - 3] - srcWm1); - double temp2W = srcWm1 + M[1][0] * (temp2[W - 1] - srcWm1) + M[1][1] * (temp2[W - 2] - srcWm1) + M[1][2] * (temp2[W - 3] - srcWm1); - double temp2Wp1 = srcWm1 + M[2][0] * (temp2[W - 1] - srcWm1) + M[2][1] * (temp2[W - 2] - srcWm1) + M[2][2] * (temp2[W - 3] - srcWm1); - - temp2[W - 1] = temp2Wm1; - temp2[W - 2] = B * temp2[W - 2] + b1 * temp2[W - 1] + b2 * temp2W + b3 * temp2Wp1; - temp2[W - 3] = B * temp2[W - 3] + b1 * temp2[W - 2] + b2 * temp2[W - 1] + b3 * temp2W; - - for (int j = W - 4; j >= 0; j--) { - temp2[j] = B * temp2[j] + b1 * temp2[j + 1] + b2 * temp2[j + 2] + b3 * temp2[j + 3]; - } - - for (int j = 0; j < W; j++) { - dst[i][j] = (T)temp2[j]; - } - - buffer.release(pBuf); - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -template void gaussDerivV (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) -{ - - if (sigma < 0.6) { - // apply symmetric derivative -#ifdef _OPENMP - #pragma omp for -#endif - - for (int j = 0; j < W; j++) { - AlignedBuffer* pBuf = buffer.acquire(); - T* temp = (T*)pBuf->data; - - // double* temp = buffer->data;// replaced by 2 lines above - for (int i = 1; i < H - 1; i++) { - temp[i] = (0.5 * (src[i + 1][j] - src[i - 1][j]) ); - } - - dst[0][j] = (src[1][j] - src[0][j]); - - for (int i = 1; i < H - 1; i++) { - dst[i][j] = temp[i]; - } - - buffer.release(pBuf); - - dst[H - 1][j] = (src[H - 1][j] - src[H - 2][j]); - } - - return; - } - - // coefficient calculation - double q = 0.98711 * sigma - 0.96330; - - if (sigma < 2.5) { - q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); - } - - double b0 = 1.57825 + 2.44413 * q + 1.4281 * q * q + 0.422205 * q * q * q; - double b1 = 2.44413 * q + 2.85619 * q * q + 1.26661 * q * q * q; - double b2 = -1.4281 * q * q - 1.26661 * q * q * q; - double b3 = 0.422205 * q * q * q; - double B = 1.0 - (b1 + b2 + b3) / b0; - - b1 /= b0; - b2 /= b0; - b3 /= b0; - - // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering - double M[3][3]; - M[0][0] = -b3 * b1 + 1.0 - b3 * b3 - b2; - M[0][1] = (b3 + b1) * (b2 + b3 * b1); - M[0][2] = b3 * (b1 + b3 * b2); - M[1][0] = b1 + b3 * b2; - M[1][1] = -(b2 - 1.0) * (b2 + b3 * b1); - M[1][2] = -(b3 * b1 + b3 * b3 + b2 - 1.0) * b3; - M[2][0] = b3 * b1 + b2 + b1 * b1 - b2 * b2; - M[2][1] = b1 * b2 + b3 * b2 * b2 - b1 * b3 * b3 - b3 * b3 * b3 - b3 * b2 + b3; - M[2][2] = b3 * (b1 + b3 * b2); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) { - M[i][j] /= (1.0 + b1 - b2 + b3) * (1.0 + b2 + (b1 - b3) * b3); - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < W; i++) { - AlignedBuffer* pBuf = buffer.acquire(); - T* temp2 = (T*)pBuf->data; - // double* temp2 = buffer->data;// replaced by 2 lines above - - double src0 = 0.5 * (src[1][i] - src[0][i]); - - temp2[0] = B * src0 + b1 * src0 + b2 * src0 + b3 * src0; - temp2[1] = B * 0.5 * (src[2][i] - src[0][i]) + b1 * temp2[0] + b2 * src0 + b3 * src0; - temp2[2] = B * 0.5 * (src[3][i] - src[1][i]) + b1 * temp2[1] + b2 * temp2[0] + b3 * src0; - - for (int j = 3; j < H - 1; j++) { - temp2[j] = B * 0.5 * (src[j + 1][i] - src[j - 1][i]) + b1 * temp2[j - 1] + b2 * temp2[j - 2] + b3 * temp2[j - 3]; - } - - double srcHm1 = 0.5 * (src[H - 1][i] - src[H - 2][i]); - - temp2[H - 1] = B * srcHm1 + b1 * temp2[H - 2] + b2 * temp2[H - 3] + b3 * temp2[H - 4]; - - double temp2Hm1 = srcHm1 + M[0][0] * (temp2[H - 1] - srcHm1) + M[0][1] * (temp2[H - 2] - srcHm1) + M[0][2] * (temp2[H - 3] - srcHm1); - double temp2H = srcHm1 + M[1][0] * (temp2[H - 1] - srcHm1) + M[1][1] * (temp2[H - 2] - srcHm1) + M[1][2] * (temp2[H - 3] - srcHm1); - double temp2Hp1 = srcHm1 + M[2][0] * (temp2[H - 1] - srcHm1) + M[2][1] * (temp2[H - 2] - srcHm1) + M[2][2] * (temp2[H - 3] - srcHm1); - - temp2[H - 1] = temp2Hm1; - temp2[H - 2] = B * temp2[H - 2] + b1 * temp2[H - 1] + b2 * temp2H + b3 * temp2Hp1; - temp2[H - 3] = B * temp2[H - 3] + b1 * temp2[H - 2] + b2 * temp2[H - 1] + b3 * temp2H; - - for (int j = H - 4; j >= 0; j--) { - temp2[j] = B * temp2[j] + b1 * temp2[j + 1] + b2 * temp2[j + 2] + b3 * temp2[j + 3]; - } - - for (int j = 0; j < H; j++) { - dst[j][i] = (T)temp2[j]; - } - - buffer.release(pBuf); + if(forceLowSigma) { + gaussHorizontal (dst, dst, W, H, newSigma); + gaussVertical (dst, dst, W, H, newSigma); } } diff --git a/rtengine/helpersse2.h b/rtengine/helpersse2.h index c7dce8806..6aee552b8 100644 --- a/rtengine/helpersse2.h +++ b/rtengine/helpersse2.h @@ -26,15 +26,18 @@ typedef __m128i vint2; #define LVF(x) _mm_load_ps(&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) + #define STVFU(x,y) _mm_storeu_ps(&x,y) #else // there is a bug in gcc 4.7.x when using openmp and aligned memory and -O3 #define LVF(x) _mm_loadu_ps(&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_storeu_ps(&x,y) + #define STVFU(x,y) _mm_storeu_ps(&x,y) #endif #else #define LVF(x) _mm_load_ps(&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) + #define STVFU(x,y) _mm_storeu_ps(&x,y) #endif // Load 8 floats from a and combine a[0],a[2],a[4] and a[6] into a vector of 4 floats diff --git a/rtengine/impulse_denoise.h b/rtengine/impulse_denoise.h index 1c89021e7..0e3fefd97 100644 --- a/rtengine/impulse_denoise.h +++ b/rtengine/impulse_denoise.h @@ -65,10 +65,7 @@ SSEFUNCTION void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) #pragma omp parallel #endif { - AlignedBufferMP buffer(max(width, height)); - - gaussHorizontal (lab->L, lpf, buffer, width, height, max(2.0, thresh - 1.0)); - gaussVertical (lpf, lpf, buffer, width, height, max(2.0, thresh - 1.0)); + gaussianBlur (lab->L, lpf, width, height, max(2.0, thresh - 1.0)); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -320,9 +317,7 @@ SSEFUNCTION void ImProcFunctions::impulse_nrcam (CieImage* ncie, double thresh, #pragma omp parallel #endif { - AlignedBufferMP buffer(max(width, height)); - gaussHorizontal (ncie->sh_p, lpf, buffer, width, height, max(2.0, thresh - 1.0)); - gaussVertical (lpf, lpf, buffer, width, height, max(2.0, thresh - 1.0)); + gaussianBlur (ncie->sh_p, lpf, width, height, max(2.0, thresh - 1.0)); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 29456cddd..ae5b78961 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -220,7 +220,6 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width limD *= useHslLin ? 10.f : 1.f; float ilimD = 1.f / limD; int moderetinex = 2; // default to 2 ( deh.retinexMethod == "high" ) - bool execcur = false; if (deh.retinexMethod == "uni") { moderetinex = 0; @@ -259,32 +258,18 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width out[i] = &outBuffer[i * W_L]; } - float logBetaGain = xlogf(16384.f); - float pond = logBetaGain / (float) scal; + const float logBetaGain = xlogf(16384.f); + const float pond = logBetaGain / (float) scal; #ifdef _OPENMP #pragma omp parallel #endif { - AlignedBufferMP* pBuffer = new AlignedBufferMP (max(W_L, H_L)); - for ( int scale = scal - 1; scale >= 0; scale-- ) { - float ** source; - float sigma; if(scale == scal - 1) { // probably large sigma. Use double gauss with sigma divided by sqrt(2.0) - sigma = RetinexScales[scale] / sqrt(2.0); - source = src; + gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], true); } else { // reuse result of last iteration - sigma = sqrtf((RetinexScales[scale] * RetinexScales[scale]) - (RetinexScales[scale + 1] * RetinexScales[scale + 1])); - source = out; - } - - gaussHorizontal (source, out, *pBuffer, W_L, H_L, sigma); - gaussVertical (out, out, *pBuffer, W_L, H_L, sigma); - - if(scale == scal - 1) { // probably large sigma. Use double gauss with sigma divided by sqrt(2.0) - gaussHorizontal (out, out, *pBuffer, W_L, H_L, sigma); - gaussVertical (out, out, *pBuffer, W_L, H_L, sigma); + gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1]))); } #ifdef __SSE2__ @@ -324,18 +309,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width } } } - - delete pBuffer; } delete [] outBuffer; delete [] srcBuffer; - - if (dehatransmissionCurve) { - execcur = true; - } - mean = 0.f; stddv = 0.f; // I call mean_stddv2 instead of mean_stddv ==> logBetaGain @@ -344,18 +322,20 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width // printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); // mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr); - if (execcur && mean != 0.f && stddv != 0.f) { //if curve + if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve float asig = 0.166666f / stddv; float bsig = 0.5f - asig * mean; - //float insigma = 0.66666f; //SD - float amean = 0.5f / mean; - float asign = 0.166666f / stddv; - float bsign = 0.5f - asign * mean; float amax = 0.333333f / (maxtr - mean - stddv); float bmax = 1.f - amax * maxtr; float amin = 0.333333f / (mean - stddv - mintr); float bmin = -amin * mintr; + asig *= 500.f; + bsig *= 500.f; + amax *= 500.f; + bmax *= 500.f; + amin *= 500.f; + bmin *= 500.f; #ifdef _OPENMP #pragma omp parallel #endif @@ -367,20 +347,15 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width for (int i = 0; i < H_L; i++ ) for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission - if (luminance[i][j] >= mean && luminance[i][j] < mean + stddv) { - absciss = asig * luminance[i][j] + bsig; - } else if (luminance[i][j] >= mean + stddv) { - absciss = amax * luminance[i][j] + bmax; - } else if (/*luminance[i][j] < mean && */luminance[i][j] > mean - stddv) { - absciss = asign * luminance[i][j] + bsign; + if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { + absciss = asig * luminance[i][j] + bsig; + } else if (luminance[i][j] >= mean) { + absciss = amax * luminance[i][j] + bmax; } else { /*if(luminance[i][j] <= mean - stddv)*/ - absciss = amin * luminance[i][j] + bmin; + absciss = amin * luminance[i][j] + bmin; } - float kmul = 2.5f; - float kinterm = 1.f + kmul * (dehatransmissionCurve[absciss * 500.f] - 0.5f); //new transmission - luminance[i][j] *= kinterm; -// luminance[i][j] *= 1.000001f; + luminance[i][j] *= (-0.25f + 2.5f * dehatransmissionCurve[absciss]); //new transmission } } @@ -396,13 +371,6 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width tmL[i] = &tmLBuffer[i * wid]; } - /* - for(int i = borderL; i < hei - borderL; i++ ) { - for(int j = borderL; j < wid - borderL; j++) { - tmL[i][j] = luminance[i][j]; - } - } - */ #ifdef _OPENMP #pragma omp parallel for #endif diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 302c07655..928ffe5bd 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -140,16 +140,13 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2, SharpeningPar #pragma omp parallel #endif { - AlignedBufferMP buffer(max(W, H)); - float damping = sharpenParam.deconvdamping / 5.0; bool needdamp = sharpenParam.deconvdamping > 0; for (int k = 0; k < sharpenParam.deconviter; k++) { // apply blur function (gaussian blur) - gaussHorizontal (tmpI, tmp, buffer, W, H, sharpenParam.deconvradius / scale); - gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + gaussianBlur (tmpI, tmp, W, H, sharpenParam.deconvradius / scale); if (!needdamp) { #ifdef _OPENMP @@ -165,8 +162,7 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2, SharpeningPar dcdamping (tmp, lab->L, damping, W, H); } - gaussHorizontal (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); - gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + gaussianBlur (tmp, tmp, W, H, sharpenParam.deconvradius / scale); #ifdef _OPENMP #pragma omp for @@ -238,17 +234,11 @@ void ImProcFunctions::sharpening (LabImage* lab, float** b2, SharpeningParams &s #endif { - - AlignedBufferMP buffer(max(W, H)); - if (sharpenParam.edgesonly == false) { - - gaussHorizontal (lab->L, b2, buffer, W, H, sharpenParam.radius / scale); - gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale); + gaussianBlur (lab->L, b2, W, H, sharpenParam.radius / scale); } else { bilateral (lab->L, (float**)b3, b2, W, H, sharpenParam.edges_radius / scale, sharpenParam.edges_tolerance, multiThread); - gaussHorizontal (b3, b2, buffer, W, H, sharpenParam.radius / scale); - gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale); + gaussianBlur (b3, b2, W, H, sharpenParam.radius / scale); } float** base = lab->L; @@ -1390,17 +1380,13 @@ void ImProcFunctions::deconvsharpeningcam (CieImage* ncie, float** b2) #pragma omp parallel #endif { - AlignedBufferMP buffer(max(W, H)); - - float damping = params->sharpening.deconvdamping / 5.0; bool needdamp = params->sharpening.deconvdamping > 0; for (int k = 0; k < params->sharpening.deconviter; k++) { // apply blur function (gaussian blur) - gaussHorizontal (tmpI, tmp, buffer, W, H, params->sharpening.deconvradius / scale); - gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + gaussianBlur (tmpI, tmp, W, H, params->sharpening.deconvradius / scale); if (!needdamp) { #ifdef _OPENMP @@ -1416,8 +1402,7 @@ void ImProcFunctions::deconvsharpeningcam (CieImage* ncie, float** b2) dcdamping (tmp, ncie->sh_p, damping, W, H); } - gaussHorizontal (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); - gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + gaussianBlur (tmp, tmp, W, H, params->sharpening.deconvradius / scale); #ifdef _OPENMP @@ -1493,17 +1478,11 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2) #endif { - - AlignedBufferMP buffer(max(W, H)); - if (params->sharpening.edgesonly == false) { - - gaussHorizontal (ncie->sh_p, b2, buffer, W, H, params->sharpening.radius / scale); - gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale); + gaussianBlur (ncie->sh_p, b2, W, H, params->sharpening.radius / scale); } else { bilateral (ncie->sh_p, (float**)b3, b2, W, H, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance, multiThread); - gaussHorizontal (b3, b2, buffer, W, H, params->sharpening.radius / scale); - gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale); + gaussianBlur (b3, b2, W, H, params->sharpening.radius / scale); } float** base = ncie->sh_p; diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index cb2a2a332..34fadd5e7 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -74,10 +74,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int #pragma omp parallel #endif { - AlignedBufferMP* pBuffer = new AlignedBufferMP (max(W, H)); - gaussHorizontal (map, map, *pBuffer, W, H, radius); - gaussVertical (map, map, *pBuffer, W, H, radius); - delete pBuffer; + gaussianBlur (map, map, W, H, radius); } }