69 const uint32_t filters,
const size_t width,
const size_t height)
87 for(
size_t j = 0; j <
width; j++)
89 const size_t c =
FC(
i, j, filters);
90 const size_t i_center =
i *
width;
91 const float center = input[i_center + j];
109 const size_t i_prev = ((
i == 0) ? 1 :
i - 1) *
width;
111 const size_t j_prev = (j == 0) ? 1 : j - 1;
112 const size_t j_next = (j ==
width - 1) ?
width - 2 : j + 1;
114 const float north = input[i_prev + j];
115 const float south = input[i_next + j];
116 const float west = input[i_center + j_prev];
117 const float east = input[i_center + j_next];
119 const float north_east = input[i_prev + j_next];
120 const float north_west = input[i_prev + j_prev];
121 const float south_east = input[i_next + j_next];
122 const float south_west = input[i_next + j_prev];
127 G_clipped = (center > clips[
GREEN]);
133 G = (north + south + east + west) / 4.f;
136 G_clipped = (north > clips[
GREEN] || south > clips[
GREEN] || east > clips[
GREEN] || west > clips[
GREEN]);
142 R_clipped = (center > clips[
RED]);
146 if(
FC(
i + 1, j, filters) ==
RED)
150 R = (north + south) / 2.f;
151 R_clipped = (north > clips[
RED] || south > clips[
RED]);
153 else if(
FC(
i, j + 1, filters) ==
RED)
157 R = (west + east) / 2.f;
158 R_clipped = (west > clips[
RED] || east > clips[
RED]);
164 R = (north_west + north_east + south_east + south_west) / 4.f;
165 R_clipped = (north_west > clips[
RED] || north_east > clips[
RED] || south_west > clips[
RED]
166 || south_east > clips[
RED]);
173 B_clipped = (center > clips[
BLUE]);
177 if(
FC(
i + 1, j, filters) ==
BLUE)
181 B = (north + south) / 2.f;
182 B_clipped = (north > clips[
BLUE] || south > clips[
BLUE]);
184 else if(
FC(
i, j + 1, filters) ==
BLUE)
188 B = (west + east) / 2.f;
189 B_clipped = (west > clips[
BLUE] || east > clips[
BLUE]);
195 B = (north_west + north_east + south_east + south_west) / 4.f;
197 B_clipped = (north_west > clips[
BLUE] || north_east > clips[
BLUE] || south_west > clips[
BLUE]
198 || south_east > clips[
BLUE]);
206 dt_aligned_pixel_t clipped = { R_clipped, G_clipped, B_clipped, (R_clipped || G_clipped || B_clipped) };
210 const size_t idx = (
i *
width + j) * 4 +
k;
215 interpolated[idx] = fmaxf(
RGB[
k] / white_balance[
k], 0.f);
216 clipping_mask[idx] = clipped[
k];
223 const uint32_t filters,
const uint8_t (*
const xtrans)[6],
234 const float n_pixels = roi_in->
height * roi_in->
width;
236 for(
size_t i = 0;
i < roi_in->
height;
i++)
237 for(
size_t j = 0; j < roi_in->
width; j++)
239 const int c = (filters == 9u) ?
FCxtrans((
int)
i, (int)j, roi_in, xtrans) :
FC(
i, j, filters);
240 if(c < 0 || c > 2)
continue;
242 const float value = input[
i * roi_in->
width + j] / n_pixels;
251 normalization[
RED] = sum_R;
252 normalization[
GREEN] = sum_G;
253 normalization[
BLUE] = sum_B;
254 normalization[
ALPHA] = 1.f;
259 const uint8_t (*
const xtrans)[6])
263 for(
int col = 0; col < 6; col++)
271 for(
int y = -1; y <= 1; y++)
272 for(
int x = -1;
x <= 1;
x++)
277 const int weight = 1 << ((y == 0) + (
x == 0));
278 const int color =
FCxtrans(
row + y, col +
x, roi_in, xtrans);
279 if(color ==
f)
continue;
280 *ip++ = (y << 16) | (
x & 0xffffu);
287 for(
int c = 0; c < 3; c++)
301 const int32_t
lookup[6][6][32],
const uint8_t (*
const xtrans)[6],
309 for(
size_t j = 0; j <
width; j++)
311 const size_t idx =
i *
width + j;
312 const float center = input[idx];
320 int count[3] = { 0 };
321 int used_clipped[3] = { 0 };
322 const int f =
FCxtrans((
int)
i, (
int)j, roi_in, xtrans);
326 for(
int y =
MAX((
int)
i - 1, 0); y <=
MIN((
int)
i + 1, (
int)
height - 1); y++)
327 for(
int x =
MAX((
int)j - 1, 0);
x <=
MIN((
int)j + 1, (
int)
width - 1);
x++)
329 const int color =
FCxtrans(y,
x, roi_in, xtrans);
333 used_clipped[color] |= (
value > clips[color]);
336 for(
int c = 0; c < 3; c++)
338 const int has_samples = (count[c] > 0);
342 RGB[c] = (c ==
f || !has_samples) ? center : sum[c] / count[c];
343 clipped[c] = (c ==
f || !has_samples) ? (center > clips[c]) : used_clipped[c];
348 const int32_t *ip = &(
lookup[
i % 6][j % 6][0]);
350 int used_clipped[3] = { 0 };
351 const int neighbours = *ip++;
355 for(
int k = 0;
k < neighbours;
k++, ip += 3)
357 const int32_t offset = ip[0];
358 const int x = (int16_t)(offset & 0xffffu);
359 const int y = (int16_t)(offset >> 16);
360 const size_t neighbour = ((size_t)((
int)
i + y) *
width + (
size_t)((int)j +
x));
361 const int color = ip[2];
362 const float value = input[neighbour];
363 sum[color] +=
value * ip[1];
364 used_clipped[color] |= (
value > clips[color]);
370 for(
int k = 0;
k < 2;
k++, ip += 2)
372 const int color = ip[0];
373 const int total = ip[1];
374 RGB[color] = (total > 0) ? sum[color] / total : center;
375 clipped[color] = used_clipped[color];
380 clipped[
f] = (center > clips[
f]);
395 const size_t index = idx * 4 +
k;
398 interpolated[index] = fmaxf(
RGB[
k] / white_balance[
k], 0.f);
399 clipping_mask[index] = clipped[
k];
406 const float *
const restrict interpolated,
const float *
const restrict clipping_mask,
420 for(
size_t j = 0; j <
width; j++)
422 const size_t c =
FC(
i, j, filters);
423 const size_t idx =
i *
width + j;
424 const size_t index = idx * 4;
425 const float opacity = clipping_mask[index +
ALPHA];
428 const float reconstructed = fmaxf(interpolated[index + c] * white_balance[c], 0.f);
429 float base = input[idx];
430 if(clip_is_floor && input_raw[idx] >= clips[c]) base = fmaxf(base, reconstructed);
431 output[idx] = opacity * reconstructed + (1.f - opacity) * base;
437 const float *
const restrict interpolated,
438 const float *
const restrict clipping_mask,
float *
const restrict output,
440 const int clip_is_floor,
const dt_iop_roi_t *
const roi_in,
441 const uint8_t (*
const xtrans)[6],
const size_t width,
const size_t height)
447 for(
size_t j = 0; j <
width; j++)
449 const size_t idx =
i *
width + j;
450 const size_t index = idx * 4;
451 const int c =
FCxtrans((
int)
i, (
int)j, roi_in, xtrans);
452 const float opacity = clipping_mask[index +
ALPHA];
454 const float reconstructed = fmaxf(interpolated[index + c] * white_balance[c], 0.f);
455 float base = input[idx];
456 if(clip_is_floor && input_raw[idx] >= clips[c]) base = fmaxf(base, reconstructed);
457 output[idx] = opacity * reconstructed + (1.f - opacity) * base;
static float lookup(read_only image2d_t lut, const float x)
const dt_aligned_pixel_t f
static dt_aligned_pixel_t RGB
#define for_each_channel(_var,...)
#define __DT_CLONE_TARGETS__
#define for_four_channels(_var,...)
#define __OMP_PARALLEL_FOR__(...)
static const dt_aligned_pixel_simd_t value
static int FCxtrans(const int row, const int col, global const unsigned char(*const xtrans)[6])
static int FC(const int row, const int col, const unsigned int filters)
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
__DT_CLONE_TARGETS__ void _compute_laplacian_normalization(const float *const restrict input, const dt_iop_roi_t *const roi_in, const uint32_t filters, const uint8_t(*const xtrans)[6], dt_aligned_pixel_t normalization)
__DT_CLONE_TARGETS__ void _remosaic_and_replace_xtrans(const float *const restrict input, const float *const restrict input_raw, const float *const restrict interpolated, const float *const restrict clipping_mask, float *const restrict output, const dt_aligned_pixel_t white_balance, const dt_aligned_pixel_t clips, const int clip_is_floor, const dt_iop_roi_t *const roi_in, const uint8_t(*const xtrans)[6], const size_t width, const size_t height)
__DT_CLONE_TARGETS__ void _interpolate_and_mask(const float *const restrict input, float *const restrict interpolated, float *const restrict clipping_mask, const dt_aligned_pixel_t clips_in, const dt_aligned_pixel_t det_scale, const dt_aligned_pixel_t white_balance, const uint32_t filters, const size_t width, const size_t height)
__DT_CLONE_TARGETS__ void _remosaic_and_replace(const float *const restrict input, const float *const restrict input_raw, const float *const restrict interpolated, const float *const restrict clipping_mask, float *const restrict output, const dt_aligned_pixel_t white_balance, const dt_aligned_pixel_t clips, const int clip_is_floor, const uint32_t filters, const size_t width, const size_t height)
__DT_CLONE_TARGETS__ void _interpolate_and_mask_xtrans(const float *const restrict input, float *const restrict interpolated, float *const restrict clipping_mask, const dt_aligned_pixel_t clips, const dt_aligned_pixel_t white_balance, const dt_iop_roi_t *const roi_in, const int32_t lookup[6][6][32], const uint8_t(*const xtrans)[6], const size_t width, const size_t height)
__DT_CLONE_TARGETS__ void _build_xtrans_bilinear_lookup(int32_t lookup[6][6][32], const dt_iop_roi_t *const roi_in, const uint8_t(*const xtrans)[6])
float *const restrict const size_t k
float dt_aligned_pixel_t[4]
Region of interest passed through the pixelpipe.