66static inline float interp_pix_xtrans(
const int ratio_next,
const ssize_t offset_next,
const float clip0,
67 const float clip_next,
const float *
const in,
const float *
const ratios)
69 assert(ratio_next != 0);
73 const float clip_val = fmaxf(clip0, clip_next);
74 if(in[offset_next] >= clip_next - 1e-5f)
82 assert(ratio_next != 0);
84 return fminf(in[offset_next] / ratios[ratio_next], clip_val);
86 return fminf(in[offset_next] * ratios[-ratio_next], clip_val);
91 const dt_iop_roi_t *
const roi_out,
int dim,
int dir,
int other,
92 const float *
const clip,
const uint8_t (*
const xtrans)[6],
const int pass)
105 const int roff[3][3] = { { 0, -1, -2 }, { 1, 0, -3 }, { 2, 3, 0 } };
112 int i = (dim == 0) ? 0 : other;
113 int j = (dim == 0) ? other : 0;
114 const ssize_t offs = (ssize_t)(dim ? roi_out->
width : 1) * ((dir < 0) ? -1 : 1);
115 const ssize_t offl = offs - (dim ? 1 : roi_out->
width);
116 const ssize_t offr = offs + (dim ? 1 : roi_out->
width);
121 end = (dim == 0) ? roi_out->
width : roi_out->
height;
125 beg = ((dim == 0) ? roi_out->
width : roi_out->
height) - 1;
133 in = (
float *)ivoid + (
size_t)
i + (size_t)beg * roi_in->
width;
137 out = (
float *)
ovoid + (
size_t)beg + (size_t)j * roi_out->
width;
138 in = (
float *)ivoid + (
size_t)beg + (size_t)j * roi_in->
width;
141 for(
int k = beg;
k != end;
k += dir)
148 const uint8_t f0 =
FCxtrans(j,
i, roi_in, xtrans);
149 const uint8_t f1 =
FCxtrans(dim ? (j + dir) : j, dim ?
i : (
i + dir), roi_in, xtrans);
150 const uint8_t fl =
FCxtrans(dim ? (j + dir) : (j - 1), dim ? (
i - 1) : (
i + dir), roi_in, xtrans);
151 const uint8_t fr =
FCxtrans(dim ? (j + dir) : (j + 1), dim ? (
i + 1) : (
i + dir), roi_in, xtrans);
152 const float clip0 = clip[f0];
153 const float clip1 = clip[f1];
154 const float clipl = clip[fl];
155 const float clipr = clip[fr];
156 const float clip_max = fmaxf(fmaxf(clip[0], clip[1]), clip[2]);
158 if(
i == 0 ||
i == roi_out->
width - 1 || j == 0 || j == roi_out->
height - 1)
160 if(pass == 3)
out[0] = fminf(clip_max, in[0]);
166 if((f0 != f1) && (in[0] < clip0 && in[0] > 1e-5f) && (in[offs] < clip1 && in[offs] > 1e-5f))
168 const int r = roff[f0][f1];
171 ratios[
r] = (3.f * ratios[
r] + (in[offs] / in[0])) / 4.f;
173 ratios[-
r] = (3.f * ratios[-
r] + (in[0] / in[offs])) / 4.f;
176 if(in[0] >= clip0 - 1e-5f)
185 add = (fl != f0) ?
interp_pix_xtrans(roff[f0][fl], offl, clip0, clipl, in, ratios)
191 out[0] = fminf(clip_max, (
out[0] + add) / 4.0f);
198 if(pass == 3)
out[0] = in[0];
207 int dir,
int other,
const float *clip,
const uint32_t filters,
const int pass)
217 ssize_t offs = dim ? roi_out->
width : 1;
218 if(dir < 0) offs = -offs;
220 if(dim == 0 && dir == 1)
223 end = roi_out->
width;
225 else if(dim == 0 && dir == -1)
227 beg = roi_out->
width - 1;
230 else if(dim == 1 && dir == 1)
235 else if(dim == 1 && dir == -1)
237 beg = roi_out->
height - 1;
246 in = (
float *)ivoid +
i + (
size_t)beg * roi_out->
width;
251 in = (
float *)ivoid + beg + (
size_t)j * roi_out->
width;
253 for(
int k = beg;
k != end;
k += dir)
259 const float clip0 = clip[
FC(j,
i, filters)];
260 const float clip1 = clip[
FC(dim ? (j + 1) : j, dim ?
i : (
i + 1), filters)];
261 if(
i == 0 ||
i == roi_out->
width - 1 || j == 0 || j == roi_out->
height - 1)
263 if(pass == 3)
out[0] = in[0];
267 if(in[0] < clip0 && in[0] > 1e-5f)
269 if(in[offs] < clip1 && in[offs] > 1e-5f)
272 ratio = (3.0f * ratio + in[0] / in[offs]) / 4.0f;
274 ratio = (3.0f * ratio + in[offs] / in[0]) / 4.0f;
278 if(in[0] >= clip0 - 1e-5f)
281 if(in[offs] >= clip1 - 1e-5f)
282 add = fmaxf(clip0, clip1);
284 add = in[offs] * ratio;
286 add = in[offs] / ratio;
291 out[0] = (
out[0] + add) / 4.0f;
297 if(pass == 3)
out[0] = in[0];
322 for(
int j = 0; j < roi_out->
height; j++)
324 for(
int i = 0;
i < roi_out->
width;
i++)
326 float *
const out = (
float *)
ovoid + (
size_t)roi_out->
width * j +
i;
327 const float *
const in = (
float *)ivoid + (
size_t)roi_out->
width * j +
i;
332 out[0] =
MIN(clip, in[0]);
339 float R = 0.0f, Gmin = FLT_MAX, Gmax = -FLT_MAX,
B = 0.0f;
340 for(
int jj = 0; jj <= 1; jj++)
342 for(
int ii = 0; ii <= 1; ii++)
344 const float val = in[(size_t)jj * roi_out->
width + ii];
346 clipped = (clipped || (val > clip));
348 const int c =
FC(j + jj + roi_out->
y,
i + ii + roi_out->
x, filters);
355 Gmin =
MIN(Gmin, val);
356 Gmax =
MAX(Gmax, val);
367 const float Ro =
MIN(
R, clip);
368 const float Go =
MIN(Gmin, clip);
369 const float Bo =
MIN(
B, clip);
371 const float L = (
R + Gmax +
B) / 3.0f;
374 float H = 2.0f *
B - Gmax -
R;
376 const float Co =
SQRT3 * (Ro - Go);
377 const float Ho = 2.0f * Bo - Go - Ro;
379 if(
R != Gmax && Gmax !=
B)
381 const float ratio = sqrtf((Co * Co + Ho * Ho) / (
C *
C +
H *
H));
399 RGB[2] =
L +
H / 3.0f;
401 out[0] =
RGB[
FC(j + roi_out->
y,
i + roi_out->
x, filters)];
417 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])piece->
dsc_in.
xtrans;
419 for(
int j = 0; j < roi_out->
height; j++)
422 float *in = (
float *)ivoid + (
size_t)roi_in->
width * j;
429 for(
int i = 0;
i < roi_out->
width;
i++)
433 if(j >= 2 && j <= roi_out->
height - 3)
435 cl |= (in[-roi_in->
width] > clip) | (in[0] > clip) | (in[roi_in->
width] > clip);
438 if(i < 2 || i > roi_out->
width - 3 || j < 2 || j > roi_out->
height - 3)
441 out[0] =
MIN(clip, in[0]);
446 int clipped = (in[0] > clip);
460 for(
int offset_j = -2; offset_j <= 0; offset_j++)
462 for(
int offset_i = -2; offset_i <= 0; offset_i++)
467 for(
int jj = offset_j; jj <= offset_j + 2; jj++)
469 for(
int ii = offset_i; ii <= offset_i + 2; ii++)
471 const float val = in[(ssize_t)jj * roi_in->
width + ii];
472 clipped = (clipped || (val > clip));
485 int cnt[3] = { 0, 0, 0 };
487 for(
int jj = -1; jj <= 1; jj++)
489 for(
int ii = -1; ii <= 1; ii++)
491 const float val = in[(ssize_t)jj * roi_in->
width + ii];
492 const int c =
FCxtrans(j + jj,
i + ii, roi_in, xtrans);
495 RGBmax[c] =
MAX(RGBmax[c], val);
499 const float Ro =
MIN(mean[0] / cnt[0], clip);
500 const float Go =
MIN(mean[1] / cnt[1], clip);
501 const float Bo =
MIN(mean[2] / cnt[2], clip);
503 const float R = RGBmax[0];
504 const float G = RGBmax[1];
505 const float B = RGBmax[2];
507 const float L = (
R + G +
B) / 3.0f;
510 float H = 2.0f *
B - G -
R;
512 const float Co =
SQRT3 * (Ro - Go);
513 const float Ho = 2.0f * Bo - Go - Ro;
517 const float ratio = sqrtf((Co * Co + Ho * Ho) / (
C *
C +
H *
H));
526 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)