71#define DT_COLORRECONSTRUCT_BILATERAL_MAX_RES_S 500
72#define DT_COLORRECONSTRUCT_BILATERAL_MAX_RES_R 100
73#define DT_COLORRECONSTRUCT_SPATIAL_APPROX 100.0f
156 return _(
"color reconstruction");
163 _(
"linear or non-linear, Lab, display-referred"),
164 _(
"non-linear, Lab"),
165 _(
"non-linear, Lab, display-referred"));
186 void *new_params,
const int new_version)
188 if(old_version == 1 && new_version == 3)
194 new->range = old->
range;
199 else if(old_version == 2 && new_version == 3)
205 new->range = old->
range;
231 XYZ[0] = (
rgb[0] * 0.4360747f) + (
rgb[1] * 0.3850649f) + (
rgb[2] * 0.1430804f);
232 XYZ[1] = (
rgb[0] * 0.2225045f) + (
rgb[1] * 0.7168786f) + (
rgb[2] * 0.0606169f);
233 XYZ[2] = (
rgb[0] * 0.0139322f) + (
rgb[1] * 0.0971045f) + (
rgb[2] * 0.7141733f);
238 float LCH_hue = atan2f(
Lab[2],
Lab[1]);
247 *
x =
CLAMPS(
i / b->sigma_s, 0, b->size_x - 1);
248 *y =
CLAMPS(j / b->sigma_s, 0, b->size_y - 1);
249 *z =
CLAMPS(
L / b->sigma_r, 0, b->size_z - 1);
253 const float scale,
float *px,
float *py)
255 *px = (roi->
x +
i) * scale - b->x;
256 *py = (roi->
y + j) * scale - b->y;
281 fprintf(stderr,
"[color reconstruction] not able to allocate buffer (a)\n");
286 float _z = roundf(100.0f /
sigma_r);
290 b->width = roi->
width;
295 b->sigma_s =
MAX(roi->
height / (b->size_y - 1.0f), roi->
width / (b->size_x - 1.0f));
296 b->sigma_r = 100.0f / (b->size_z - 1.0f);
302 fprintf(stderr,
"[color reconstruction] not able to allocate buffer (b)\n");
303 dt_iop_colorreconstruct_bilateral_free(b);
309 fprintf(stderr,
"[bilateral] created grid [%d %d %d]"
310 " with sigma (%f %f) (%f %f)\n", b->size_x, b->size_y, b->size_z,
323 fprintf(stderr,
"[color reconstruction] not able to allocate buffer (c)\n");
330 bf->
width = b->width;
334 bf->
scale = b->scale;
340 if(bf->
buf && b->buf)
346 fprintf(stderr,
"[color reconstruction] not able to allocate buffer (d)\n");
347 dt_iop_colorreconstruct_bilateral_dump(bf);
363 for(
int j = 0; j < b->height; j++)
365 size_t index = (size_t)4 * j * b->width;
366 for(
int i = 0;
i < b->width;
i++, index += 4)
369 const float Lin = in[index];
370 const float ain = in[index + 1];
371 const float bin = in[index + 2];
378 weight = sqrtf(ain * ain + bin * bin);
382 m = atan2f(bin, ain) - params[0];
397 const int xi =
CLAMPS((
int)round(
x), 0, b->size_x - 1);
398 const int yi =
CLAMPS((
int)round(y), 0, b->size_y - 1);
399 const int zi =
CLAMPS((
int)round(z), 0, b->size_z - 1);
400 const size_t grid_index = xi + b->size_x * (yi + b->size_y * zi);
405 b->buf[grid_index].L += Lin *
weight;
410 b->buf[grid_index].a += ain *
weight;
415 b->buf[grid_index].b += bin *
weight;
420 b->buf[grid_index].weight +=
weight;
428 const int size2,
const int size3)
432 const float w0 = 6.f / 16.f;
433 const float w1 = 4.f / 16.f;
434 const float w2 = 1.f / 16.f;
436 for(
int k = 0;
k < size1;
k++)
438 size_t index = (size_t)
k * offset1;
439 for(
int j = 0; j < size2; j++)
442 buf[index].
L = buf[index].
L * w0 +
w1 * buf[index + offset3].
L +
w2 * buf[index + 2 * offset3].
L;
443 buf[index].
a = buf[index].
a * w0 +
w1 * buf[index + offset3].
a +
w2 * buf[index + 2 * offset3].
a;
444 buf[index].
b = buf[index].
b * w0 +
w1 * buf[index + offset3].
b +
w2 * buf[index + 2 * offset3].
b;
448 buf[index].
L = buf[index].
L * w0 +
w1 * (buf[index + offset3].
L + tmp1.
L) +
w2 * buf[index + 2 * offset3].
L;
449 buf[index].
a = buf[index].
a * w0 +
w1 * (buf[index + offset3].
a + tmp1.
a) +
w2 * buf[index + 2 * offset3].a;
450 buf[index].
b = buf[index].
b * w0 +
w1 * (buf[index + offset3].
b + tmp1.
b) +
w2 * buf[index + 2 * offset3].b;
453 for(
int i = 2;
i < size3 - 2;
i++)
456 buf[index].
L = buf[index].
L * w0 +
w1 * (buf[index + offset3].
L + tmp2.
L)
457 +
w2 * (buf[index + 2 * offset3].
L + tmp1.
L);
458 buf[index].
a = buf[index].
a * w0 +
w1 * (buf[index + offset3].
a + tmp2.
a)
459 +
w2 * (buf[index + 2 * offset3].a + tmp1.
a);
460 buf[index].
b = buf[index].
b * w0 +
w1 * (buf[index + offset3].
b + tmp2.
b)
461 +
w2 * (buf[index + 2 * offset3].b + tmp1.
b);
470 buf[index].
L = buf[index].
L * w0 +
w1 * (buf[index + offset3].
L + tmp2.
L) +
w2 * tmp1.
L;
471 buf[index].
a = buf[index].
a * w0 +
w1 * (buf[index + offset3].
a + tmp2.
a) +
w2 * tmp1.
a;
472 buf[index].
b = buf[index].
b * w0 +
w1 * (buf[index + offset3].
b + tmp2.
b) +
w2 * tmp1.
b;
475 buf[index].
L = buf[index].
L * w0 +
w1 * tmp3.
L +
w2 * tmp2.
L;
476 buf[index].
a = buf[index].
a * w0 +
w1 * tmp3.
a +
w2 * tmp2.
a;
477 buf[index].
b = buf[index].
b * w0 +
w1 * tmp3.
b +
w2 * tmp2.
b;
480 index += offset2 - offset3 * size3;
491 blur_line(
b->buf,
b->size_x *
b->size_y,
b->size_x, 1,
b->size_z,
b->size_y,
b->size_x);
493 blur_line(
b->buf,
b->size_x *
b->size_y, 1,
b->size_x,
b->size_z,
b->size_x,
b->size_y);
495 blur_line(
b->buf, 1,
b->size_x,
b->size_x *
b->size_y,
b->size_x,
b->size_y,
b->size_z);
500 const float *
const in,
float *
const out,
506 const float rescale =
iscale / (roi->
scale * b->scale);
508 const int oy = b->size_x;
509 const int oz = b->size_y * b->size_x;
511 for(
int j = 0; j < roi->
height; j++)
513 size_t index = (size_t)4 * j * roi->
width;
514 for(
int i = 0;
i < roi->
width;
i++, index += 4)
518 const float Lin =
out[index + 0] = in[index + 0];
519 const float ain =
out[index + 1] = in[index + 1];
520 const float bin =
out[index + 2] = in[index + 2];
521 out[index + 3] = in[index + 3];
522 const float blend =
CLAMPS(20.0f /
threshold * Lin - 19.0f, 0.0f, 1.0f);
523 if (blend == 0.0f)
continue;
527 const int xi =
MIN((
int)
x, b->size_x - 2);
528 const int yi =
MIN((
int)y, b->size_y - 2);
529 const int zi =
MIN((
int)z, b->size_z - 2);
530 const float xf =
x - xi;
531 const float yf = y - yi;
532 const float zf = z - zi;
533 const size_t gi = xi + b->size_x * (yi + b->size_y * zi);
535 const float Lout = b->buf[gi].L * (1.0f - xf) * (1.0f - yf) * (1.0f - zf)
536 + b->buf[gi + ox].L * (xf) * (1.0f - yf) * (1.0f - zf)
537 + b->buf[gi + oy].L * (1.0f - xf) * (yf) * (1.0f - zf)
538 + b->buf[gi + ox + oy].L * (xf) * (yf) * (1.0f - zf)
539 + b->buf[gi + oz].L * (1.0f - xf) * (1.0f - yf) * (zf)
540 + b->buf[gi + ox + oz].L * (xf) * (1.0f - yf) * (zf)
541 + b->buf[gi + oy + oz].L * (1.0f - xf) * (yf) * (zf)
542 + b->buf[gi + ox + oy + oz].L * (xf) * (yf) * (zf);
544 const float aout = b->buf[gi].a * (1.0f - xf) * (1.0f - yf) * (1.0f - zf)
545 + b->buf[gi + ox].a * (xf) * (1.0f - yf) * (1.0f - zf)
546 + b->buf[gi + oy].a * (1.0f - xf) * (yf) * (1.0f - zf)
547 + b->buf[gi + ox + oy].a * (xf) * (yf) * (1.0f - zf)
548 + b->buf[gi + oz].a * (1.0f - xf) * (1.0f - yf) * (zf)
549 + b->buf[gi + ox + oz].a * (xf) * (1.0f - yf) * (zf)
550 + b->buf[gi + oy + oz].a * (1.0f - xf) * (yf) * (zf)
551 + b->buf[gi + ox + oy + oz].a * (xf) * (yf) * (zf);
554 const float bout = b->buf[gi].b * (1.0f - xf) * (1.0f - yf) * (1.0f - zf)
555 + b->buf[gi + ox].b * (xf) * (1.0f - yf) * (1.0f - zf)
556 + b->buf[gi + oy].b * (1.0f - xf) * (yf) * (1.0f - zf)
557 + b->buf[gi + ox + oy].b * (xf) * (yf) * (1.0f - zf)
558 + b->buf[gi + oz].b * (1.0f - xf) * (1.0f - yf) * (zf)
559 + b->buf[gi + ox + oz].b * (xf) * (1.0f - yf) * (zf)
560 + b->buf[gi + oy + oz].b * (1.0f - xf) * (yf) * (zf)
561 + b->buf[gi + ox + oy + oz].b * (xf) * (yf) * (zf);
563 const float weight = b->buf[gi].weight * (1.0f - xf) * (1.0f - yf) * (1.0f - zf)
564 + b->buf[gi + ox].weight * (xf) * (1.0f - yf) * (1.0f - zf)
565 + b->buf[gi + oy].weight * (1.0f - xf) * (yf) * (1.0f - zf)
566 + b->buf[gi + ox + oy].weight * (xf) * (yf) * (1.0f - zf)
567 + b->buf[gi + oz].weight * (1.0f - xf) * (1.0f - yf) * (zf)
568 + b->buf[gi + ox + oz].weight * (xf) * (1.0f - yf) * (zf)
569 + b->buf[gi + oy + oz].weight * (1.0f - xf) * (yf) * (zf)
570 + b->buf[gi + ox + oy + oz].weight * (xf) * (yf) * (zf);
572 const float lout = fmax(Lout, 0.01f);
573 out[index + 1] = (
weight > 0.0f) ? ain * (1.0f - blend) + aout * Lin/lout * blend : ain;
574 out[index + 2] = (
weight > 0.0f) ? bin * (1.0f - blend) + bout * Lin/lout * blend : bin;
587 float *in = (
float *)ivoid;
602 dt_iop_colorreconstruct_bilateral_blur(b);
612 dt_iop_colorreconstruct_bilateral_dump(
g->can);
619 dt_iop_colorreconstruct_bilateral_free(b);
625 dt_iop_colorreconstruct_bilateral_free(b);
661 int blocksizex, blocksizey;
665 .cellsize = 4 *
sizeof(float) +
sizeof(
int), .overhead = 0,
666 .sizex = 1 << 6, .sizey = 1 << 6 };
670 blocksizex = locopt.
sizex;
671 blocksizey = locopt.
sizey;
674 blocksizex = blocksizey = 1;
676 if(blocksizex * blocksizey < 16 * 16)
679 "[opencl_colorreconstruction] device %d does not offer sufficient resources to run bilateral grid\n",
693 float _z = roundf(100.0f /
sigma_r);
697 b->width = roi->
width;
702 b->blocksizex = blocksizex;
703 b->blocksizey = blocksizey;
704 b->sigma_s =
MAX(roi->
height / (b->size_y - 1.0f), roi->
width / (b->size_x - 1.0f));
705 b->sigma_r = 100.0f / (b->size_z - 1.0f);
709 b->dev_grid_tmp = NULL;
732 int wd = 4 * b->size_x, ht = b->size_y * b->size_z;
734 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_zero, 0,
sizeof(cl_mem), (
void *)&b->dev_grid);
739 if(err != CL_SUCCESS)
741 dt_print(
DT_DEBUG_OPENCL,
"[opencl_colorreconstruction] error running kernel colorreconstruct_zero: %d\n", err);
747 fprintf(stderr,
"[bilateral] created grid [%d %d %d]"
748 " with sigma (%f %f) (%f %f)\n", b->size_x, b->size_y, b->size_z,
768 bf->
width = b->width;
772 bf->
scale = b->scale;
778 if(bf->
buf && b->dev_grid)
783 if(err != CL_SUCCESS)
786 "[opencl_colorreconstruction] can not read bilateral grid from device %d\n", b->devid);
787 dt_iop_colorreconstruct_bilateral_dump(bf);
794 dt_iop_colorreconstruct_bilateral_dump(bf);
807 int pref = precedence;
808 size_t sizes[] = {
ROUNDUP(b->width, b->blocksizex),
ROUNDUP(b->height, b->blocksizey), 1 };
809 size_t local[] = { b->blocksizex, b->blocksizey, 1 };
811 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_splat, 1,
sizeof(cl_mem), (
void *)&b->dev_grid);
817 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_splat, 7,
sizeof(
float), (
void *)&b->sigma_s);
818 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_splat, 8,
sizeof(
float), (
void *)&b->sigma_r);
822 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_splat, 12, b->blocksizex * b->blocksizey *
sizeof(
int),
825 b->blocksizex * b->blocksizey * 4 *
sizeof(
float), NULL);
834 size_t sizes[3] = { 0, 0, 1 };
837 b->size_x * b->size_y * b->size_z * 4 *
sizeof(
float));
838 if(err != CL_SUCCESS)
return err;
842 int stride1, stride2, stride3;
843 stride1 = b->size_x * b->size_y;
846 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 0,
sizeof(cl_mem), (
void *)&b->dev_grid_tmp);
847 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 1,
sizeof(cl_mem), (
void *)&b->dev_grid);
851 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 5,
sizeof(
int), (
void *)&b->size_z);
852 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 6,
sizeof(
int), (
void *)&b->size_y);
853 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 7,
sizeof(
int), (
void *)&b->size_x);
855 if(err != CL_SUCCESS)
return err;
857 stride1 = b->size_x * b->size_y;
862 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 0,
sizeof(cl_mem), (
void *)&b->dev_grid);
863 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 1,
sizeof(cl_mem), (
void *)&b->dev_grid_tmp);
867 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 5,
sizeof(
int), (
void *)&b->size_z);
868 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 6,
sizeof(
int), (
void *)&b->size_x);
869 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 7,
sizeof(
int), (
void *)&b->size_y);
871 if(err != CL_SUCCESS)
return err;
875 stride3 = b->size_x * b->size_y;
879 (
void *)&b->dev_grid_tmp);
880 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 1,
sizeof(cl_mem), (
void *)&b->dev_grid);
884 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 5,
sizeof(
int), (
void *)&b->size_x);
885 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 6,
sizeof(
int), (
void *)&b->size_y);
886 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_blur_line, 7,
sizeof(
int), (
void *)&b->size_z);
896 const int bxy[2] = { b->x, b->y };
897 const int roixy[2] = { roi->
x, roi->
y };
898 const float rescale =
iscale / (roi->
scale * b->scale);
903 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_slice, 2,
sizeof(cl_mem), (
void *)&b->dev_grid);
909 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_slice, 8,
sizeof(
float), (
void *)&b->sigma_s);
910 dt_opencl_set_kernel_arg(b->devid, b->global->kernel_colorreconstruct_slice, 9,
sizeof(
float), (
void *)&b->sigma_r);
928 const float sigma_r = fmax(
d->range, 0.1f);
929 const float sigma_s = fmax(
d->spatial, 1.0f) / scale;
932 const float params[4] = { hue,
M_PI*
M_PI/8, 0.0f, 0.0f };
941 if(err != CL_SUCCESS)
goto error;
943 if(err != CL_SUCCESS)
goto error;
946 if(err != CL_SUCCESS)
goto error;
952 dt_iop_colorreconstruct_bilateral_dump(
g->can);
958 err = CL_MEM_OBJECT_ALLOCATION_FAILURE;
981 float _z = roundf(100.0f /
sigma_r);
997 float _z = roundf(100.0f /
sigma_r);
1010 const float sigma_r = fmax(
d->range, 0.1f);
1011 const float sigma_s = fmax(
d->spatial, 1.0f) / scale;
1017 const size_t basebuffer =
sizeof(float) * channels *
width *
height;
1034 if(w ==
g->precedence)
1046 d->threshold =
p->threshold;
1047 d->spatial =
p->spatial;
1048 d->range =
p->range;
1049 d->precedence =
p->precedence;
1060 piece->
data = (
void *)
d;
1077 gtk_stack_set_visible_child_name(GTK_STACK(self->
gui->
widget), !monochrome ?
"default" :
"monochrome");
1082 dt_iop_colorreconstruct_bilateral_dump(
g->can);
1093 const int program = 13;
1136 gtk_widget_show_all(
g->hue);
1137 gtk_widget_set_no_show_all(
g->hue,
TRUE);
1139 gtk_widget_set_tooltip_text(
g->threshold, _(
"pixels with lightness values above this threshold are corrected"));
1140 gtk_widget_set_tooltip_text(
g->spatial, _(
"how far to look for replacement colors in spatial dimensions"));
1141 gtk_widget_set_tooltip_text(
g->range, _(
"how far to look for replacement colors in the luminance dimension"));
1142 gtk_widget_set_tooltip_text(
g->precedence, _(
"if and how to give precedence to specific replacement colors"));
1143 gtk_widget_set_tooltip_text(
g->hue, _(
"the hue tone which should be given precedence over other hue tones"));
1146 gtk_widget_set_tooltip_text(monochromes, _(
"no highlights reconstruction for monochrome images"));
1150 gtk_stack_add_named(GTK_STACK(self->
gui->
widget), monochromes,
"monochrome");
1151 gtk_stack_add_named(GTK_STACK(self->
gui->
widget), box_enabled,
"default");
1157 dt_iop_colorreconstruct_bilateral_dump(
g->can);
static void error(char *msg)
void dt_bauhaus_slider_set_stop(GtkWidget *widget, float stop, float r, float g, float b)
void dt_bauhaus_slider_set_feedback(GtkWidget *widget, int feedback)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
void dt_bauhaus_slider_set_factor(GtkWidget *widget, float factor)
static dt_iop_colorreconstruct_bilateral_frozen_t * dt_iop_colorreconstruct_bilateral_freeze_cl(dt_iop_colorreconstruct_bilateral_cl_t *b)
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
#define DT_COLORRECONSTRUCT_BILATERAL_MAX_RES_R
static __DT_CLONE_TARGETS__ void dt_iop_colorreconstruct_bilateral_splat(dt_iop_colorreconstruct_bilateral_t *b, const float *const in, const float threshold, dt_iop_colorreconstruct_precedence_t precedence, const float *params)
const char ** description(struct dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ void blur_line(dt_iop_colorreconstruct_Lab_t *buf, const int offset1, const int offset2, const int offset3, const int size1, const int size2, const int size3)
static void image_to_grid(const dt_iop_colorreconstruct_bilateral_t *const b, const float i, const float j, const float L, float *x, float *y, float *z)
static void grid_rescale(const dt_iop_colorreconstruct_bilateral_t *const b, const int i, const int j, const dt_iop_roi_t *roi, const float scale, float *px, float *py)
static cl_int dt_iop_colorreconstruct_bilateral_blur_cl(dt_iop_colorreconstruct_bilateral_cl_t *b)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static size_t dt_iop_colorreconstruct_bilateral_memory_use(const int width, const int height, const float sigma_s, const float sigma_r)
static dt_iop_colorreconstruct_bilateral_t * dt_iop_colorreconstruct_bilateral_init(const dt_iop_roi_t *roi, const float iscale, const float sigma_s, const float sigma_r)
static cl_int dt_iop_colorreconstruct_bilateral_splat_cl(dt_iop_colorreconstruct_bilateral_cl_t *b, cl_mem in, const float threshold, dt_iop_colorreconstruct_precedence_t precedence, const float *params)
void gui_update(struct dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ void dt_iop_colorreconstruct_bilateral_slice(const dt_iop_colorreconstruct_bilateral_t *const b, const float *const in, float *const out, const float threshold, const dt_iop_roi_t *const roi, const float iscale)
#define DT_COLORRECONSTRUCT_BILATERAL_MAX_RES_S
void gui_init(struct dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
void cleanup_global(dt_iop_module_so_t *module)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static size_t dt_iop_colorreconstruct_bilateral_singlebuffer_size(const int width, const int height, const float sigma_s, const float sigma_r)
void gui_cleanup(struct dt_iop_module_t *self)
dt_iop_colorreconstruct_precedence_t
@ COLORRECONSTRUCT_PRECEDENCE_NONE
@ COLORRECONSTRUCT_PRECEDENCE_HUE
@ COLORRECONSTRUCT_PRECEDENCE_CHROMA
int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
static float hue_conversion(const float HSL_Hue)
static dt_iop_colorreconstruct_bilateral_frozen_t * dt_iop_colorreconstruct_bilateral_freeze(dt_iop_colorreconstruct_bilateral_t *b)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static dt_iop_colorreconstruct_bilateral_cl_t * dt_iop_colorreconstruct_bilateral_init_cl(const int devid, dt_iop_colorreconstruct_global_data_t *global, const dt_iop_roi_t *roi, const float iscale, const float sigma_s, const float sigma_r)
void init_global(dt_iop_module_so_t *module)
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
static void dt_iop_colorreconstruct_bilateral_free_cl(dt_iop_colorreconstruct_bilateral_cl_t *b)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
static cl_int dt_iop_colorreconstruct_bilateral_slice_cl(dt_iop_colorreconstruct_bilateral_cl_t *b, cl_mem in, cl_mem out, const float threshold, const dt_iop_roi_t *roi, const float iscale)
void hsl2rgb(dt_aligned_pixel_t rgb, float h, float s, float l)
Convert HSL back to RGB. Common helper used by iop modules.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static dt_aligned_pixel_t rgb
static dt_aligned_pixel_t XYZ
static dt_aligned_pixel_t Lab
const dt_colormatrix_t dt_aligned_pixel_t out
gboolean dt_image_is_monochrome(const dt_image_t *img)
void dt_control_log(const char *msg,...)
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module)
Release what dt_iop_gui_enter_critical_section() took. Also a no-op headless.
@ IOP_FLAGS_INCLUDE_IN_STYLES
@ IOP_FLAGS_SUPPORTS_BLENDING
void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module)
Take the module's GUI lock, serialising access to its dt_iop_gui_data_t.
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
static dt_iop_gui_data_t * dt_iop_gui_data(const struct dt_iop_module_t *m)
The module's GUI data blob, NULL-safe for headless callers: IOP process() implementations read it for...
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_ui_label_new(const gchar *str)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_local_buffer_opt(const int devid, const int kernel, dt_opencl_local_buffer_t *factors)
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
int dt_opencl_create_kernel(const int prog, const char *name)
int dt_opencl_read_buffer_from_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
int dt_opencl_enqueue_copy_buffer_to_buffer(const int devid, cl_mem src_buffer, cl_mem dst_buffer, size_t srcoffset, size_t dstoffset, size_t size)
void dt_opencl_release_mem_object(cl_mem mem)
int dt_opencl_avoid_atomics(const int devid)
#define __OMP_PARALLEL_FOR__(...)
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
unsigned __int64 uint64_t
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_iop_colorreconstruct_global_data_t * global
dt_iop_colorreconstruct_Lab_t * buf
dt_iop_colorreconstruct_Lab_t * buf
dt_iop_colorreconstruct_precedence_t precedence
int kernel_colorreconstruct_slice
int kernel_colorreconstruct_splat
int kernel_colorreconstruct_zero
int kernel_colorreconstruct_blur_line
dt_iop_colorreconstruct_bilateral_frozen_t * can
dt_iop_colorreconstruct_precedence_t precedence
dt_iop_colorreconstruct_precedence_t precedence
dt_iop_global_data_t * data
int32_t hide_enable_button
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
dt_iop_global_data_t * global_data
Region of interest passed through the pixelpipe.
#define __DT_CLONE_TARGETS__
Telling the user something happened.