35 const float wl = dt_fast_expf(-sharpen * square[0]);
36 const float wc = dt_fast_expf(-sharpen * (square[1] + square[2]));
45#define SUM_PIXEL_CONTRIBUTION(ii, jj) \
48 const float f = filter[(ii)] * filter[(jj)]; \
49 dt_aligned_pixel_t wp; \
50 weight(px, px2, sharpen, wp); \
51 dt_aligned_pixel_t w; \
52 dt_aligned_pixel_t pd; \
53 for_four_channels(c,aligned(px2)) \
57 pd[c] = w[c] * px2[c]; \
62#define SUM_PIXEL_PROLOGUE \
63 dt_aligned_pixel_t sum = { 0.0f, 0.0f, 0.0f, 0.0f }; \
64 dt_aligned_pixel_t wgt = { 0.0f, 0.0f, 0.0f, 0.0f };
66#define SUM_PIXEL_EPILOGUE \
70 pcoarse[c] = sum[c]; \
71 const float det = (px[c] - sum[c]); \
79void eaw_decompose(
float *
const restrict
out,
const float *
const restrict in,
float *
const restrict detail,
80 const int scale,
const float sharpen,
const int32_t
width,
const int32_t
height)
82 const int mult = 1 << scale;
83 static const float filter[5] = { 1.0f / 16.0f, 4.0f / 16.0f, 6.0f / 16.0f, 4.0f / 16.0f, 1.0f / 16.0f };
84 const int boundary = 2 * mult;
86 for(
int rowid = 0; rowid <
height; rowid++)
89 const float *px = ((
float *)in) + (size_t)4 * j *
width;
91 float *pdetail = detail + (size_t)4 * j *
width;
92 float *pcoarse =
out + (size_t)4 * j *
width;
96 const int lbound = (j < boundary || j >=
height - boundary) ?
width-boundary : boundary;
101 for(
i = 0;
i < lbound;
i++)
104 for(
int jj = 0; jj < 5; jj++)
106 const int y = j + mult * (jj-2);
107 const int clamp_y = CLAMP(y,0,
height-1);
108 for(
int ii = 0; ii < 5; ii++)
110 int x =
i + mult * ((ii)-2);
112 px2 = ((
float *)in) + 4 *
x + (size_t)4 * clamp_y *
width;
120 for( ;
i <
width - boundary;
i++)
123 px2 = ((
float *)in) + (size_t)4 * (
i - 2 * mult + (
size_t)(j - 2 * mult) *
width);
124 for(
int jj = 0; jj < 5; jj++)
126 for(
int ii = 0; ii < 5; ii++)
129 px2 += (size_t)4 * mult;
131 px2 += (size_t)4 * (
width - 5) * mult;
140 for(
int jj = 0; jj < 5; jj++)
142 const int y = j + mult * (jj-2);
143 const int clamp_y = CLAMP(y,0,
height-1);
144 for(
int ii = 0; ii < 5; ii++)
146 int x =
i + mult * ((ii)-2);
148 px2 = ((
float *)in) + 4 *
x + (size_t)4 * clamp_y *
width;
158 const float *
const restrict
threshold,
const float *
const restrict boost,
165 for(
size_t c = 0; c < 4; c++)
172 out[4*
k + c] = in[4*
k + c] + (boost[c] * amount);
181static inline float dn_weight(
const float *
c1,
const float *
c2,
const float inv_sigma2)
187 const float diff =
c1[c] -
c2[c];
188 sqr[c] = diff * diff;
190 const float dot = (sqr[0] + sqr[1] + sqr[2]) * inv_sigma2;
193 const float off2 = 9.0f;
208#pragma omp declare reduction(vsum:_aligned_pixel:omp_out=add_float4(omp_out,omp_in)) \
209 initializer(omp_priv = { .v = { 0.0f, 0.0f, 0.0f, 0.0f } })
212#undef SUM_PIXEL_CONTRIBUTION
213#define SUM_PIXEL_CONTRIBUTION(ii, jj) \
216 const float f = filter[(ii)] * filter[(jj)]; \
217 const float wp = dn_weight(px, px2, inv_sigma2); \
218 const float w = f * wp; \
219 dt_aligned_pixel_t pd; \
220 for_each_channel(c,aligned(px2)) \
222 pd[c] = w * px2[c]; \
228#undef SUM_PIXEL_EPILOGUE
229#define SUM_PIXEL_EPILOGUE \
230 for_each_channel(c) \
233 pcoarse[c] = sum[c]; \
234 const float det = (px[c] - sum[c]); \
236 sum_sq.v[c] += (det*det); \
242void eaw_dn_decompose(
float *
const restrict
out,
const float *
const restrict in,
float *
const restrict detail,
246 const int mult = 1u << scale;
247 static const float filter[5] = { 1.0f / 16.0f, 4.0f / 16.0f, 6.0f / 16.0f, 4.0f / 16.0f, 1.0f / 16.0f };
248 const int boundary = 2 * mult;
252#if !(defined(__apple_build_version__) && __apple_build_version__ < 11030000)
255 for(
int rowid = 0; rowid <
height; rowid++)
258 const float *px = ((
float *)in) + (size_t)4 * j *
width;
260 float *pdetail = detail + (size_t)4 * j *
width;
261 float *pcoarse =
out + (size_t)4 * j *
width;
265 const int lbound = (j < boundary || j >=
height - boundary) ?
width-boundary : boundary;
270 for(
i = 0;
i < lbound;
i++)
273 for(
int jj = 0; jj < 5; jj++)
275 const int y = j + mult * (jj-2);
276 const int clamp_y = CLAMP(y,0,
height-1);
277 for(
int ii = 0; ii < 5; ii++)
279 int x =
i + mult * ((ii)-2);
281 px2 = ((
float *)in) + 4 *
x + (size_t)4 * clamp_y *
width;
289 for( ;
i <
width - boundary;
i++)
292 px2 = ((
float *)in) + (size_t)4 * (
i - 2 * mult + (
size_t)(j - 2 * mult) *
width);
293 for(
int jj = 0; jj < 5; jj++)
295 for(
int ii = 0; ii < 5; ii++)
298 px2 += (size_t)4 * mult;
300 px2 += (size_t)4 * (
width - 5) * mult;
309 for(
int jj = 0; jj < 5; jj++)
311 const int y = j + mult * (jj-2);
312 const int clamp_y = CLAMP(y,0,
height-1);
313 for(
int ii = 0; ii < 5; ii++)
315 int x =
i + mult * ((ii)-2);
317 px2 = ((
float *)in) + 4 *
x + (size_t)4 * clamp_y *
width;
325 sum_squared[c] = sum_sq.
v[c];
328#undef SUM_PIXEL_CONTRIBUTION
329#undef SUM_PIXEL_PROLOGUE
330#undef SUM_PIXEL_EPILOGUE
const dt_colormatrix_t dt_aligned_pixel_t out
static int dwt_interleave_rows(const int rowid, const int height, const int stride)
#define SUM_PIXEL_CONTRIBUTION(ii, jj)
#define SUM_PIXEL_PROLOGUE
void eaw_decompose(float *const restrict out, const float *const restrict in, float *const restrict detail, const int scale, const float sharpen, const int32_t width, const int32_t height)
#define SUM_PIXEL_EPILOGUE
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
struct _aligned_pixel _aligned_pixel
static float dn_weight(const float *c1, const float *c2, const float inv_sigma2)
void eaw_dn_decompose(float *const restrict out, const float *const restrict in, float *const restrict detail, dt_aligned_pixel_t sum_squared, const int scale, const float inv_sigma2, const int32_t width, const int32_t height)
void eaw_synthesize(float *const out, const float *const in, const float *const restrict detail, const float *const restrict threshold, const float *const restrict boost, const int32_t width, const int32_t height)
float *const restrict const size_t k
static float fast_mexp2f(const float x)
#define __OMP_SIMD__(...)
#define __OMP_PARALLEL_FOR__(...)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
#define for_each_channel(_var,...)
#define for_four_channels(_var,...)