63static inline float interp_pix_xtrans(
const int ratio_next,
const ssize_t offset_next,
const float clip0,
64 const float clip_next,
const float *
const in,
const float *
const ratios)
66 assert(ratio_next != 0);
70 const float clip_val = fmaxf(clip0, clip_next);
71 if(in[offset_next] >= clip_next - 1e-5f)
79 assert(ratio_next != 0);
81 return fminf(in[offset_next] / ratios[ratio_next], clip_val);
83 return fminf(in[offset_next] * ratios[-ratio_next], clip_val);
88 const dt_iop_roi_t *
const roi_out,
int dim,
int dir,
int other,
89 const float *
const clip,
const uint8_t (*
const xtrans)[6],
const int pass)
102 const int roff[3][3] = { { 0, -1, -2 }, { 1, 0, -3 }, { 2, 3, 0 } };
109 int i = (dim == 0) ? 0 : other;
110 int j = (dim == 0) ? other : 0;
111 const ssize_t offs = (ssize_t)(dim ? roi_out->
width : 1) * ((dir < 0) ? -1 : 1);
112 const ssize_t offl = offs - (dim ? 1 : roi_out->
width);
113 const ssize_t offr = offs + (dim ? 1 : roi_out->
width);
118 end = (dim == 0) ? roi_out->
width : roi_out->
height;
122 beg = ((dim == 0) ? roi_out->
width : roi_out->
height) - 1;
130 in = (
float *)ivoid + (
size_t)
i + (size_t)beg * roi_in->
width;
134 out = (
float *)
ovoid + (
size_t)beg + (size_t)j * roi_out->
width;
135 in = (
float *)ivoid + (
size_t)beg + (size_t)j * roi_in->
width;
138 for(
int k = beg;
k != end;
k += dir)
145 const uint8_t f0 =
FCxtrans(j,
i, roi_in, xtrans);
146 const uint8_t f1 =
FCxtrans(dim ? (j + dir) : j, dim ?
i : (
i + dir), roi_in, xtrans);
147 const uint8_t fl =
FCxtrans(dim ? (j + dir) : (j - 1), dim ? (
i - 1) : (
i + dir), roi_in, xtrans);
148 const uint8_t fr =
FCxtrans(dim ? (j + dir) : (j + 1), dim ? (
i + 1) : (
i + dir), roi_in, xtrans);
149 const float clip0 = clip[f0];
150 const float clip1 = clip[f1];
151 const float clipl = clip[fl];
152 const float clipr = clip[fr];
153 const float clip_max = fmaxf(fmaxf(clip[0], clip[1]), clip[2]);
155 if(
i == 0 ||
i == roi_out->
width - 1 || j == 0 || j == roi_out->
height - 1)
157 if(pass == 3)
out[0] = fminf(clip_max, in[0]);
163 if((f0 != f1) && (in[0] < clip0 && in[0] > 1e-5f) && (in[offs] < clip1 && in[offs] > 1e-5f))
165 const int r = roff[f0][f1];
168 ratios[
r] = (3.f * ratios[
r] + (in[offs] / in[0])) / 4.f;
170 ratios[-
r] = (3.f * ratios[-
r] + (in[0] / in[offs])) / 4.f;
173 if(in[0] >= clip0 - 1e-5f)
182 add = (fl != f0) ?
interp_pix_xtrans(roff[f0][fl], offl, clip0, clipl, in, ratios)
188 out[0] = fminf(clip_max, (
out[0] + add) / 4.0f);
195 if(pass == 3)
out[0] = in[0];
204 int dir,
int other,
const float *clip,
const uint32_t filters,
const int pass)
214 ssize_t offs = dim ? roi_out->
width : 1;
215 if(dir < 0) offs = -offs;
217 if(dim == 0 && dir == 1)
220 end = roi_out->
width;
222 else if(dim == 0 && dir == -1)
224 beg = roi_out->
width - 1;
227 else if(dim == 1 && dir == 1)
232 else if(dim == 1 && dir == -1)
234 beg = roi_out->
height - 1;
243 in = (
float *)ivoid +
i + (
size_t)beg * roi_out->
width;
248 in = (
float *)ivoid + beg + (
size_t)j * roi_out->
width;
250 for(
int k = beg;
k != end;
k += dir)
256 const float clip0 = clip[
FC(j,
i, filters)];
257 const float clip1 = clip[
FC(dim ? (j + 1) : j, dim ?
i : (
i + 1), filters)];
258 if(
i == 0 ||
i == roi_out->
width - 1 || j == 0 || j == roi_out->
height - 1)
260 if(pass == 3)
out[0] = in[0];
264 if(in[0] < clip0 && in[0] > 1e-5f)
266 if(in[offs] < clip1 && in[offs] > 1e-5f)
269 ratio = (3.0f * ratio + in[0] / in[offs]) / 4.0f;
271 ratio = (3.0f * ratio + in[offs] / in[0]) / 4.0f;
275 if(in[0] >= clip0 - 1e-5f)
278 if(in[offs] >= clip1 - 1e-5f)
279 add = fmaxf(clip0, clip1);
281 add = in[offs] * ratio;
283 add = in[offs] / ratio;
288 out[0] = (
out[0] + add) / 4.0f;
294 if(pass == 3)
out[0] = in[0];
319 for(
int j = 0; j < roi_out->
height; j++)
321 for(
int i = 0;
i < roi_out->
width;
i++)
323 float *
const out = (
float *)
ovoid + (
size_t)roi_out->
width * j +
i;
324 const float *
const in = (
float *)ivoid + (
size_t)roi_out->
width * j +
i;
329 out[0] =
MIN(clip, in[0]);
336 float R = 0.0f, Gmin = FLT_MAX, Gmax = -FLT_MAX,
B = 0.0f;
337 for(
int jj = 0; jj <= 1; jj++)
339 for(
int ii = 0; ii <= 1; ii++)
341 const float val = in[(size_t)jj * roi_out->
width + ii];
343 clipped = (clipped || (val > clip));
345 const int c =
FC(j + jj + roi_out->
y,
i + ii + roi_out->
x, filters);
352 Gmin =
MIN(Gmin, val);
353 Gmax =
MAX(Gmax, val);
364 const float Ro =
MIN(
R, clip);
365 const float Go =
MIN(Gmin, clip);
366 const float Bo =
MIN(
B, clip);
368 const float L = (
R + Gmax +
B) / 3.0f;
371 float H = 2.0f *
B - Gmax -
R;
373 const float Co =
SQRT3 * (Ro - Go);
374 const float Ho = 2.0f * Bo - Go - Ro;
376 if(
R != Gmax && Gmax !=
B)
378 const float ratio = sqrtf((Co * Co + Ho * Ho) / (
C *
C +
H *
H));
396 RGB[2] =
L +
H / 3.0f;
398 out[0] =
RGB[
FC(j + roi_out->
y,
i + roi_out->
x, filters)];
414 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])piece->
dsc_in.
xtrans;
416 for(
int j = 0; j < roi_out->
height; j++)
419 float *in = (
float *)ivoid + (
size_t)roi_in->
width * j;
426 for(
int i = 0;
i < roi_out->
width;
i++)
430 if(j >= 2 && j <= roi_out->
height - 3)
432 cl |= (in[-roi_in->
width] > clip) | (in[0] > clip) | (in[roi_in->
width] > clip);
435 if(i < 2 || i > roi_out->
width - 3 || j < 2 || j > roi_out->
height - 3)
438 out[0] =
MIN(clip, in[0]);
443 int clipped = (in[0] > clip);
457 for(
int offset_j = -2; offset_j <= 0; offset_j++)
459 for(
int offset_i = -2; offset_i <= 0; offset_i++)
464 for(
int jj = offset_j; jj <= offset_j + 2; jj++)
466 for(
int ii = offset_i; ii <= offset_i + 2; ii++)
468 const float val = in[(ssize_t)jj * roi_in->
width + ii];
469 clipped = (clipped || (val > clip));
482 int cnt[3] = { 0, 0, 0 };
484 for(
int jj = -1; jj <= 1; jj++)
486 for(
int ii = -1; ii <= 1; ii++)
488 const float val = in[(ssize_t)jj * roi_in->
width + ii];
489 const int c =
FCxtrans(j + jj,
i + ii, roi_in, xtrans);
492 RGBmax[c] =
MAX(RGBmax[c], val);
496 const float Ro =
MIN(mean[0] / cnt[0], clip);
497 const float Go =
MIN(mean[1] / cnt[1], clip);
498 const float Bo =
MIN(mean[2] / cnt[2], clip);
500 const float R = RGBmax[0];
501 const float G = RGBmax[1];
502 const float B = RGBmax[2];
504 const float L = (
R + G +
B) / 3.0f;
507 float H = 2.0f *
B - G -
R;
509 const float Co =
SQRT3 * (Ro - Go);
510 const float Ho = 2.0f * Bo - Go - Ro;
514 const float ratio = sqrtf((Co * Co + Ho * Ho) / (
C *
C +
H *
H));
523 RGB[2] =
L +
H / 3.0f;
__DT_CLONE_TARGETS__ void process_lch_bayer(dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const float clip)
void interpolate_color(const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_out, int dim, int dir, int other, const float *clip, const uint32_t filters, const int pass)
__DT_CLONE_TARGETS__ void process_lch_xtrans(dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const float clip)
static float interp_pix_xtrans(const int ratio_next, const ssize_t offset_next, const float clip0, const float clip_next, const float *const in, const float *const ratios)
void interpolate_color_xtrans(const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, int dim, int dir, int other, const float *const clip, const uint8_t(*const xtrans)[6], const int pass)