70 const uint32_t filters,
const size_t width,
const size_t height)
88 for(
size_t j = 0; j <
width; j++)
90 const size_t c =
FC(
i, j, filters);
91 const size_t i_center =
i *
width;
92 const float center = input[i_center + j];
110 const size_t i_prev = ((
i == 0) ? 1 :
i - 1) *
width;
112 const size_t j_prev = (j == 0) ? 1 : j - 1;
113 const size_t j_next = (j ==
width - 1) ?
width - 2 : j + 1;
115 const float north = input[i_prev + j];
116 const float south = input[i_next + j];
117 const float west = input[i_center + j_prev];
118 const float east = input[i_center + j_next];
120 const float north_east = input[i_prev + j_next];
121 const float north_west = input[i_prev + j_prev];
122 const float south_east = input[i_next + j_next];
123 const float south_west = input[i_next + j_prev];
128 G_clipped = (center > clips[
GREEN]);
134 G = (north + south + east + west) / 4.f;
137 G_clipped = (north > clips[
GREEN] || south > clips[
GREEN] || east > clips[
GREEN] || west > clips[
GREEN]);
143 R_clipped = (center > clips[
RED]);
147 if(
FC(
i + 1, j, filters) ==
RED)
151 R = (north + south) / 2.f;
152 R_clipped = (north > clips[
RED] || south > clips[
RED]);
154 else if(
FC(
i, j + 1, filters) ==
RED)
158 R = (west + east) / 2.f;
159 R_clipped = (west > clips[
RED] || east > clips[
RED]);
165 R = (north_west + north_east + south_east + south_west) / 4.f;
166 R_clipped = (north_west > clips[
RED] || north_east > clips[
RED] || south_west > clips[
RED]
167 || south_east > clips[
RED]);
174 B_clipped = (center > clips[
BLUE]);
178 if(
FC(
i + 1, j, filters) ==
BLUE)
182 B = (north + south) / 2.f;
183 B_clipped = (north > clips[
BLUE] || south > clips[
BLUE]);
185 else if(
FC(
i, j + 1, filters) ==
BLUE)
189 B = (west + east) / 2.f;
190 B_clipped = (west > clips[
BLUE] || east > clips[
BLUE]);
196 B = (north_west + north_east + south_east + south_west) / 4.f;
198 B_clipped = (north_west > clips[
BLUE] || north_east > clips[
BLUE] || south_west > clips[
BLUE]
199 || south_east > clips[
BLUE]);
207 dt_aligned_pixel_t clipped = { R_clipped, G_clipped, B_clipped, (R_clipped || G_clipped || B_clipped) };
211 const size_t idx = (
i *
width + j) * 4 +
k;
216 interpolated[idx] = fmaxf(
RGB[
k] / white_balance[
k], 0.f);
217 clipping_mask[idx] = clipped[
k];
224 const uint32_t filters,
const uint8_t (*
const xtrans)[6],
235 const float n_pixels = roi_in->
height * roi_in->
width;
242 for(
size_t i = 0;
i < roi_in->
height;
i++)
243 for(
size_t j = 0; j < roi_in->
width; j++)
245 const size_t idx = (
i * roi_in->
width + j) * 4;
246 sum_R += input[idx +
RED] / n_pixels;
247 sum_G += input[idx +
GREEN] / n_pixels;
248 sum_B += input[idx +
BLUE] / n_pixels;
254 for(
size_t i = 0;
i < roi_in->
height;
i++)
255 for(
size_t j = 0; j < roi_in->
width; j++)
257 const int c = (filters == 9u) ?
FCxtrans((
int)
i, (int)j, roi_in, xtrans) :
FC(
i, j, filters);
258 if(c < 0 || c > 2)
continue;
260 const float value = input[
i * roi_in->
width + j] / n_pixels;
270 normalization[
RED] = sum_R;
271 normalization[
GREEN] = sum_G;
272 normalization[
BLUE] = sum_B;
273 normalization[
ALPHA] = 1.f;
278 const uint8_t (*
const xtrans)[6])
282 for(
int col = 0; col < 6; col++)
290 for(
int y = -1; y <= 1; y++)
291 for(
int x = -1;
x <= 1;
x++)
296 const int weight = 1 << ((y == 0) + (
x == 0));
299 *ip++ = (y << 16) | (
x & 0xffffu);
306 for(
int c = 0; c < 3; c++)
320 const int32_t
lookup[6][6][32],
const uint8_t (*
const xtrans)[6],
328 for(
size_t j = 0; j <
width; j++)
330 const size_t idx =
i *
width + j;
331 const float center = input[idx];
339 int count[3] = { 0 };
340 int used_clipped[3] = { 0 };
341 const int f =
FCxtrans((
int)
i, (
int)j, roi_in, xtrans);
345 for(
int y =
MAX((
int)
i - 1, 0); y <=
MIN((
int)
i + 1, (
int)
height - 1); y++)
346 for(
int x =
MAX((
int)j - 1, 0);
x <=
MIN((
int)j + 1, (
int)
width - 1);
x++)
355 for(
int c = 0; c < 3; c++)
357 const int has_samples = (count[c] > 0);
361 RGB[c] = (c ==
f || !has_samples) ? center : sum[c] / count[c];
362 clipped[c] = (c ==
f || !has_samples) ? (center > clips[c]) : used_clipped[c];
367 const int32_t *ip = &(
lookup[
i % 6][j % 6][0]);
369 int used_clipped[3] = { 0 };
370 const int neighbours = *ip++;
374 for(
int k = 0;
k < neighbours;
k++, ip += 3)
376 const int32_t offset = ip[0];
377 const int x = (int16_t)(offset & 0xffffu);
378 const int y = (int16_t)(offset >> 16);
379 const size_t neighbour = ((size_t)((
int)
i + y) *
width + (
size_t)((int)j +
x));
380 const int color = ip[2];
381 const float value = input[neighbour];
389 for(
int k = 0;
k < 2;
k++, ip += 2)
391 const int color = ip[0];
392 const int total = ip[1];
399 clipped[
f] = (center > clips[
f]);
414 const size_t index = idx * 4 +
k;
417 interpolated[index] = fmaxf(
RGB[
k] / white_balance[
k], 0.f);
418 clipping_mask[index] = clipped[
k];
435 for(
size_t j = 0; j <
width; j++)
437 const size_t idx = (
i *
width + j) * 4;
438 const float R = input[idx +
RED];
439 const float G = input[idx +
GREEN];
440 const float B = input[idx +
BLUE];
441 const int R_clipped = (
R > clips[
RED]);
442 const int G_clipped = (G > clips[
GREEN]);
443 const int B_clipped = (
B > clips[
BLUE]);
446 const dt_aligned_pixel_t clipped = { R_clipped, G_clipped, B_clipped, (R_clipped || G_clipped || B_clipped) };
450 interpolated[idx +
k] = fmaxf(
RGB[
k] / white_balance[
k], 0.f);
451 clipping_mask[idx +
k] = clipped[
k];
458 const float *
const restrict interpolated,
const float *
const restrict clipping_mask,
472 for(
size_t j = 0; j <
width; j++)
474 const size_t c =
FC(
i, j, filters);
475 const size_t idx =
i *
width + j;
476 const size_t index = idx * 4;
477 const float opacity = clipping_mask[index +
ALPHA];
480 const float reconstructed = fmaxf(interpolated[index + c] * white_balance[c], 0.f);
481 float base = input[idx];
482 if(clip_is_floor && input_raw[idx] >= clips[c]) base = fmaxf(base, reconstructed);
483 output[idx] = opacity * reconstructed + (1.f - opacity) * base;
489 const float *
const restrict interpolated,
490 const float *
const restrict clipping_mask,
float *
const restrict output,
492 const int clip_is_floor,
const dt_iop_roi_t *
const roi_in,
493 const uint8_t (*
const xtrans)[6],
const size_t width,
const size_t height)
499 for(
size_t j = 0; j <
width; j++)
501 const size_t idx =
i *
width + j;
502 const size_t index = idx * 4;
503 const int c =
FCxtrans((
int)
i, (
int)j, roi_in, xtrans);
504 const float opacity = clipping_mask[index +
ALPHA];
506 const float reconstructed = fmaxf(interpolated[index + c] * white_balance[c], 0.f);
507 float base = input[idx];
508 if(clip_is_floor && input_raw[idx] >= clips[c]) base = fmaxf(base, reconstructed);
509 output[idx] = opacity * reconstructed + (1.f - opacity) * base;
515 const float *
const restrict interpolated,
516 const float *
const restrict clipping_mask,
float *
const restrict output,
518 const int clip_is_floor,
const size_t width,
const size_t height)
527 for(
size_t j = 0; j <
width; j++)
529 const size_t idx = (
i *
width + j) * 4;
530 for_each_channel(c, aligned(input, input_raw, interpolated, clipping_mask, output, white_balance))
532 const float opacity = clipping_mask[idx + c];
534 const float reconstructed = fmaxf(interpolated[idx + c] * white_balance[c], 0.f);
535 float base = input[idx + c];
536 if(clip_is_floor && input_raw[idx + c] >= clips[c]) base = fmaxf(base, reconstructed);
537 output[idx + c] = opacity * reconstructed + (1.f - opacity) * base;
static float lookup(read_only image2d_t lut, const float x)
static dt_aligned_pixel_t RGB
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 _interpolate_and_mask_passthrough(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 size_t width, const size_t height)
__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])
__DT_CLONE_TARGETS__ void _remosaic_and_replace_passthrough(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 size_t width, const size_t height)
float *const restrict const size_t k
#define __OMP_PARALLEL_FOR__(...)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
#define for_each_channel(_var,...)
#define for_four_channels(_var,...)
static const dt_aligned_pixel_simd_t value
Region of interest passed through the pixelpipe.
#define __DT_CLONE_TARGETS__