83#define INSET DT_PIXEL_APPLY_DPI(5)
90#define MAX_NUM_SCALES 8
93#define dt_atrous_show_upper_label(cr, text, layout, ink) \
94 pango_layout_set_text(layout, text, -1); \
95 pango_layout_get_pixel_extents(layout, &ink, NULL); \
96 cairo_move_to(cr, .5 * (width - ink.width), (.08 * height) - ink.height); \
97 pango_cairo_show_layout(cr, layout);
100#define dt_atrous_show_lower_label(cr, text, layout, ink) \
101 pango_layout_set_text(layout, text, -1); \
102 pango_layout_get_pixel_extents(layout, &ink, NULL); \
103 cairo_move_to(cr, .5 * (width - ink.width), (.98 * height) - ink.height); \
104 pango_cairo_show_layout(cr, layout);
165 return _(
"contrast equalizer");
170 return _(
"sharpness|acutance|local contrast");
176 _(
"corrective and creative"),
177 _(
"linear, Lab, scene-referred"),
178 _(
"frequential, RGB"),
179 _(
"linear, Lab, scene-referred"));
198 void *new_params,
const int new_version)
200 if(old_version == 1 && new_version == 2)
202 typedef struct dt_iop_atrous_params_v1_t
207 } dt_iop_atrous_params_v1_t;
209 dt_iop_atrous_params_v1_t *o = (dt_iop_atrous_params_v1_t *)old_params;
215 memcpy(
n, o,
sizeof(dt_iop_atrous_params_v1_t));
227 const float scale = roi_in->
scale;
230 const float i0 = dt_log2f((supp0 - 1.0f) * .5f);
235 const float supp = 2 * (2 <<
i) + 1;
237 const float supp_in = supp * (1.0f / scale);
238 const float i_in = dt_log2f((supp_in - 1) * .5f) - 1.0f;
239 t[
i] = 1.0f - (i_in + .5f) / i0;
240 if(
t[
i] < 0.0f)
break;
259 const float scale = roi_in->
scale;
264 const float i0 = dt_log2f((supp0 - 1.0f) * .5f);
269 const float supp = 2 * (2 <<
i) + 1;
271 const float supp_in = supp * (1.0f / scale);
272 const float i_in = dt_log2f((supp_in - 1) * .5f) - 1.0f;
274 const float t = 1.0f - (i_in + .5f) / i0;
277 for(
int k = 0;
k < 4;
k++) boost[
i][
k] *= boost[
i][
k];
278 thrs[
i][0] =
thrs[
i][3] = powf(2.0f, -7.0f * (1.0f -
t)) * 10.0f
280 thrs[
i][1] =
thrs[
i][2] = powf(2.0f, -7.0f * (1.0f -
t)) * 20.0f
289 const int max_scale_roi = (int)floorf(dt_log2f((
float)
MIN(roi_in->
width, roi_in->
height))) - 2;
290 return MIN(max_scale_roi,
i);
298 const dt_iop_roi_t *
const roi_out,
const eaw_decompose_t decompose,
299 const eaw_synthesize_t synthesize)
305 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
306 const int max_mult = 1u << (max_scale - 1);
327 float *
const restrict
out = (
float*)o;
328 float *restrict detail = NULL;
329 float *restrict tmp = NULL;
330 float *restrict tmp2 = NULL;
337 float *buf1 = (
float *)
i;
345 for(
int scale = 0; scale < max_scale; scale++)
347 decompose(buf2, buf1, detail, scale, sharp[scale],
width,
height);
349 if(scale == 0) buf1 = (
float *)tmp2;
389 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
402 const int devid = pipe->devid;
404 cl_mem dev_filter = NULL;
405 cl_mem dev_tmp = NULL;
406 cl_mem dev_tmp2 = NULL;
407 cl_mem dev_detail = NULL;
409 float m[] = { 0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f };
411 for(
int j = 0; j < 5; j++)
412 for(
int i = 0;
i < 5;
i++) mm[j][
i] =
m[
i] *
m[j];
428 const int width = roi_out->width;
429 const int height = roi_out->height;
435 if(err != CL_SUCCESS)
goto error;
439 void* dev_buf1 = &dev_in;
440 void* dev_buf2 = &dev_tmp;
443 for(
int s = 0; s < max_scale; s++)
458 if(err != CL_SUCCESS)
goto error;
476 if(err != CL_SUCCESS)
goto error;
479 if (scale == 0) dev_buf1 = dev_tmp2;
480 void* tmp = dev_buf2;
490 if(err != CL_SUCCESS)
goto error;
518 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
531 const int devid = pipe->
devid;
533 cl_mem dev_filter = NULL;
534 cl_mem dev_tmp = NULL;
535 cl_mem *dev_detail = calloc(max_scale,
sizeof(cl_mem));
537 float m[] = { 0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f };
539 for(
int j = 0; j < 5; j++)
540 for(
int i = 0;
i < 5;
i++)
541 mm[j][
i] =
m[
i] *
m[j];
553 for(
int k = 0;
k < max_scale;
k++)
556 if(dev_detail[
k] == NULL)
goto error;
562 size_t origin[] = { 0, 0, 0 };
567 if(err != CL_SUCCESS)
goto error;
570 for(
int s = 0; s < max_scale; s++)
592 if(err != CL_SUCCESS)
goto error;
596 for(
int scale = max_scale - 1; scale >= 0; scale--)
622 if(err != CL_SUCCESS)
goto error;
627 for(
int k = 0;
k < max_scale;
k++)
635 for(
int k = 0;
k < max_scale;
k++)
652 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
653 const int max_filter_radius = 2 * (1 << max_scale);
656 tiling->factor_cl = 3.0f + max_scale;
660 tiling->overlap = max_filter_radius;
682 const int program = 1;
707 const int ch,
const int k,
709 const float px,
const float py,
float *
x,
float *y)
712 *
x = fminf(1.0f, fmaxf(0.0f, px + (
mix - 1.0f) * (px - dp->
x[
ch][
k])));
713 *y = fminf(1.0f, fmaxf(0.0f, py + (
mix - 1.0f) * (py - dp->
y[
ch][
k])));
723 printf(
"---------- atrous preset begin\n");
724 printf(
"p.octaves = %d; p.mix = %.2f\n",
p->octaves,
p->mix);
727 printf(
"p.x[%d][%d] = %f;\n",
ch,
k,
p->x[
ch][
k]);
728 printf(
"p.y[%d][%d] = %f;\n",
ch,
k,
p->y[
ch][
k]);
730 printf(
"---------- atrous preset end\n");
732 d->octaves =
p->octaves;
751 piece->
data = (
void *)
d;
773#define GAUSS(x, sigma) expf( -(1.0f - x) * (1.0f - x) / (sigma * sigma)) / (2.0 * sigma * powf(M_PI, 0.5f))
893 const float x =
k / (float)(
BANDS - 1);
897 const float coeff = 0.5f + (coarse + medium + fine) / 16.0f;
898 const float noise = (coarse + medium + fine) / 128.f;
911 const float x =
k / (float)(
BANDS - 1);
914 const float coeff = 0.5f + (medium + fine) / 16.0f;
915 const float noise = (medium + fine) / 128.f;
928 const float x =
k / (float)(
BANDS - 1);
930 const float coeff = 0.5f + fine / 16.f;
931 const float noise = fine / 128.f;
944 const float x =
k / (float)(
BANDS - 1);
948 const float coeff = 0.5f + (coarse + medium + fine) / 24.0f;
949 const float noise = (coarse + medium + fine) / 192.f;
962 const float x =
k / (float)(
BANDS - 1);
965 const float coeff = 0.5f + (medium + fine) / 24.0f;
966 const float noise = (medium + fine) / 192.f;
979 const float x =
k / (float)(
BANDS - 1);
981 const float coeff = 0.5f + fine / 24.0f;
982 const float noise = fine / 192.f;
995 const float x =
k / (float)(
BANDS - 1);
999 const float coeff = 0.5f + (coarse + medium + fine) / 32.0f;
1000 const float noise = (coarse + medium + fine) / 128.f;
1013 const float x =
k / (float)(
BANDS - 1);
1016 const float coeff = 0.5f + (medium + fine) / 32.0f;
1017 const float noise = (medium + fine) / 128.f;
1030 const float x =
k / (float)(
BANDS - 1);
1032 const float coeff = 0.5f + fine / 32.f;
1033 const float noise = fine / 128.f;
1051 c->drag_params = *
p;
1061 gtk_widget_queue_draw(self->
widget);
1071 if(!c->dragging) c->mouse_y = fabs(c->mouse_y);
1073 gtk_widget_queue_draw(widget);
1081 if(!c->dragging) c->mouse_y = -fabs(c->mouse_y);
1082 c->in_curve =
FALSE;
1083 gtk_widget_queue_draw(widget);
1093 const float f = expf(-(mouse_x -
p->x[
ch][
k]) * (mouse_x -
p->x[
ch][
k]) / (rad * rad));
1104 const float mix = c->in_curve ? 1.0f :
p.mix;
1108 const int ch2 = (int)c->channel2;
1114 const int inset =
INSET;
1115 GtkAllocation allocation;
1116 gtk_widget_get_allocation(widget, &allocation);
1117 int width = allocation.width,
height = allocation.height;
1119 cairo_t *cr = cairo_create(cst);
1121 GdkRGBA bright_bg_color, graph_bg;
1122 GtkStyleContext *context = gtk_widget_get_style_context(self->
expander);
1123 gboolean color_found = gtk_style_context_lookup_color (context,
"graph_overlay", &bright_bg_color);
1126 bright_bg_color.red = 1.0;
1127 bright_bg_color.green = 0.0;
1128 bright_bg_color.blue = 0.0;
1129 bright_bg_color.alpha = 1.0;
1132 color_found = gtk_style_context_lookup_color (context,
"graph_bg", &graph_bg);
1136 graph_bg.green = 0.0;
1137 graph_bg.blue = 0.0;
1138 graph_bg.alpha = 1.0;
1141 gdk_cairo_set_source_rgba(cr, &bright_bg_color);
1144 cairo_translate(cr, inset, inset);
1149 gdk_cairo_set_source_rgba(cr, &graph_bg);
1153 gdk_cairo_set_source_rgba(cr, &bright_bg_color);
1157 if(c->mouse_y > 0 || c->dragging)
1159 const int ch2 = (int)c->channel2;
1162 get_params(&
p, ch2, c->mouse_x, 1., c->mouse_radius);
1168 get_params(&
p, ch2, c->mouse_x, .0, c->mouse_radius);
1176 gdk_cairo_set_source_rgba(cr, &graph_bg);
1183 cairo_translate(cr, 0,
height);
1187 if(c->num_samples > 0)
1190 for(
int k = 1;
k < c->num_samples;
k += 2)
1192 cairo_set_source_rgba(cr, graph_bg.red, graph_bg.green, graph_bg.blue, .3);
1193 cairo_move_to(cr,
width * c->sample[
k - 1], 0.0f);
1196 cairo_line_to(cr,
width * c->sample[
k], 0.0f);
1199 if(c->num_samples & 1)
1201 cairo_move_to(cr,
width * c->sample[c->num_samples - 1], 0.0f);
1202 cairo_line_to(cr,
width * c->sample[c->num_samples - 1], -
height);
1203 cairo_line_to(cr, 0.0f, -
height);
1204 cairo_line_to(cr, 0.0f, 0.0f);
1213 cairo_set_source_rgba(cr, graph_bg.red, graph_bg.green, graph_bg.blue, .3);
1214 cairo_move_to(cr, 0, 0);
1215 for(
int k = 0;
k <
BANDS;
k++) cairo_line_to(cr,
k, c->band_hist[
k]);
1216 cairo_line_to(cr,
BANDS - 1.0, 0.);
1217 cairo_close_path(cr);
1224 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1229 int ch = ((int)c->channel +
i + 1) % (
atrous_s + 1);
1231 const float bgmul =
i <
atrous_s ? 0.5f : 1.0f;
1235 cairo_set_source_rgba(cr, .6, .6, .6, .3 * bgmul);
1239 cairo_set_source_rgba(cr, .4, .2, .0, .4 * bgmul);
1243 cairo_set_source_rgba(cr, .1, .2, .3, .4 * bgmul);
1249 if(c->channel2 == ch2)
1265 for(
int k =
RES - 2;
k >= 0;
k--)
1269 cairo_move_to(cr, 0, 0);
1277 for(
int k = 0;
k <
RES;
k++)
1280 cairo_line_to(cr,
width, 0);
1281 cairo_close_path(cr);
1282 cairo_stroke_preserve(cr);
1286 if(c->mouse_y > 0 || c->dragging)
1288 const int ch = (int)c->channel;
1289 const int ch2 = (int)c->channel2;
1294 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
1296 cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
1311 if(c->mouse_y > 0 || c->dragging)
1315 cairo_move_to(cr, 0, -
height * c->draw_min_ys[0]);
1316 for(
int k = 1;
k <
RES;
k++)
1317 cairo_line_to(cr,
k *
width / (
float)(
RES - 1), -
height * c->draw_min_ys[
k]);
1318 for(
int k =
RES - 1;
k >= 0;
k--)
1319 cairo_line_to(cr,
k *
width / (
float)(
RES - 1), -
height * c->draw_max_ys[
k]);
1320 cairo_close_path(cr);
1323 cairo_set_source_rgba(cr, .9, .9, .9, .5);
1324 const float pos =
RES * c->mouse_x;
1326 const float f =
k - pos;
1328 const float ht = -
height * (
f * c->draw_ys[
k] + (1 -
f) * c->draw_ys[
k + 1]);
1329 cairo_arc(cr, c->mouse_x *
width, ht, c->mouse_radius *
width, 0, 2. *
M_PI);
1333 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1337 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
1342 cairo_rel_line_to(cr, -arrw * .5f, 0);
1343 cairo_rel_line_to(cr, arrw * .5f, -arrw);
1344 cairo_rel_line_to(cr, arrw * .5f, arrw);
1345 cairo_close_path(cr);
1354 if(c->mouse_y > 0 || c->dragging)
1357 PangoLayout *layout;
1360 pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
1361 pango_font_description_set_absolute_size(desc, (.06 *
height) * PANGO_SCALE);
1362 layout = pango_cairo_create_layout(cr);
1363 pango_layout_set_font_description(layout, desc);
1364 gdk_cairo_set_source_rgba(cr, &graph_bg);
1365 cairo_set_font_size(cr, .06 *
height);
1366 pango_layout_set_text(layout, _(
"coarse"), -1);
1367 pango_layout_get_pixel_extents(layout, &ink, NULL);
1368 cairo_move_to(cr, .02 *
width - ink.y, .14 *
height + ink.width);
1370 cairo_rotate(cr, -
M_PI * .5f);
1371 pango_cairo_show_layout(cr, layout);
1373 pango_layout_set_text(layout, _(
"fine"), -1);
1374 pango_layout_get_pixel_extents(layout, &ink, NULL);
1375 cairo_move_to(cr, .98 *
width - ink.height, .14 *
height + ink.width);
1377 cairo_rotate(cr, -
M_PI * .5f);
1378 pango_cairo_show_layout(cr, layout);
1398 pango_font_description_free(desc);
1399 g_object_unref(layout);
1404 cairo_set_source_surface(crf, cst, 0, 0);
1406 cairo_surface_destroy(cst);
1415 const int inset =
INSET;
1416 GtkAllocation allocation;
1417 gtk_widget_get_allocation(widget, &allocation);
1418 const int height = allocation.height - 2 * inset;
1419 const int width = allocation.width - 2 * inset;
1420 if(!c->dragging) c->mouse_x = CLAMP(event->x - inset, 0,
width) / (float)
width;
1421 c->mouse_y = 1.0 - CLAMP(event->y - inset, 0,
height) / (float)
height;
1423 int ch2 = c->channel;
1430 *
p = c->drag_params;
1433 const float mx = CLAMP(event->x - inset, 0,
width) / (float)
width;
1434 if(c->x_move > 0 && c->x_move <
BANDS - 1)
1436 const float minx =
p->x[c->channel][c->x_move - 1] + 0.001f;
1437 const float maxx =
p->x[c->channel][c->x_move + 1] - 0.001f;
1438 p->x[ch2][c->x_move] =
p->x[c->channel][c->x_move] = fminf(maxx, fmaxf(minx, mx));
1443 get_params(
p, c->channel2, c->mouse_x, c->mouse_y + c->mouse_pick, c->mouse_radius);
1445 gtk_widget_queue_draw(widget);
1448 else if(event->y >
height)
1452 float dist = fabs(
p->x[c->channel][0] - c->mouse_x);
1455 const float d2 = fabs(
p->x[c->channel][
k] - c->mouse_x);
1462 gtk_widget_queue_draw(widget);
1467 const int ch = c->channel;
1468 float dist = 1000000.0f;
1471 float d2 = fabs(
p->x[c->channel][
k] - c->mouse_x);
1474 if(fabs(c->mouse_y -
p->y[
ch][
k]) < fabs(c->mouse_y -
p->y[ch2][
k]))
1483 gtk_widget_queue_draw(widget);
1491 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
1500 p->x[c->channel2][
k] =
d->x[c->channel2][
k];
1501 p->y[c->channel2][
k] =
d->y[c->channel2][
k];
1503 gtk_widget_queue_draw(self->
widget);
1506 else if(event->button == 1)
1511 const int inset =
INSET;
1512 GtkAllocation allocation;
1513 gtk_widget_get_allocation(widget, &allocation);
1514 const int height = allocation.height - 2 * inset;
1515 const int width = allocation.width - 2 * inset;
1518 c->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0,
height) / (float)
height;
1527 if(event->button == 1)
1546 c->mouse_radius = CLAMP(c->mouse_radius * (1.0 + 0.1 * delta_y), 0.25 /
BANDS, 1.0);
1547 gtk_widget_queue_draw(widget);
1558 gtk_widget_queue_draw(self->
widget);
1567 gtk_widget_queue_draw(self->
widget);
1578 c->channel = c->channel2 =
dt_conf_get_int(
"plugins/darkroom/atrous/gui_channel");
1579 int ch = (int)c->channel;
1583 c->mouse_x = c->mouse_y = c->mouse_pick = -1.0;
1587 c->mouse_radius = 1.0 /
BANDS;
1588 c->in_curve =
FALSE;
1593 dt_ui_notebook_page(c->channel_tabs, N_(
"luma"), _(
"change lightness at each feature size"));
1594 dt_ui_notebook_page(c->channel_tabs, N_(
"chroma"), _(
"change color saturation at each feature size"));
1595 dt_ui_notebook_page(c->channel_tabs, N_(
"edges"), _(
"change edge halos at each feature size\nonly changes results of luma and chroma tabs"));
1596 gtk_widget_show(gtk_notebook_get_nth_page(c->channel_tabs, c->channel));
1597 gtk_notebook_set_current_page(c->channel_tabs, c->channel);
1598 g_signal_connect(G_OBJECT(c->channel_tabs),
"switch_page", G_CALLBACK(
tab_switch), self);
1599 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(c->channel_tabs),
FALSE,
FALSE, 0);
1602 c->area = GTK_DRAWING_AREA(gtk_drawing_area_new());
1603 gtk_widget_set_hexpand(GTK_WIDGET(c->area),
TRUE);
1604 gtk_box_pack_start(GTK_BOX(self->
widget),
1606 "plugins/darkroom/atrous/graphheight", 280, 100),
1609 gtk_widget_add_events(GTK_WIDGET(c->area),
1610 GDK_POINTER_MOTION_MASK
1611 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
1612 | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
1614 g_object_set_data(G_OBJECT(c->area),
"iop-instance", self);
1615 g_signal_connect(G_OBJECT(c->area),
"draw", G_CALLBACK(
area_draw), self);
1616 g_signal_connect(G_OBJECT(c->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
1617 g_signal_connect(G_OBJECT(c->area),
"button-release-event", G_CALLBACK(
area_button_release), self);
1618 g_signal_connect(G_OBJECT(c->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
1619 g_signal_connect(G_OBJECT(c->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
1620 g_signal_connect(G_OBJECT(c->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
1621 g_signal_connect(G_OBJECT(c->area),
"scroll-event", G_CALLBACK(
area_scrolled), self);
1625 gtk_widget_set_tooltip_text(c->mix, _(
"make effect stronger or weaker"));
1626 g_signal_connect(G_OBJECT(c->mix),
"value-changed", G_CALLBACK(
mix_callback), self);
static double dist(double x1, double y1, double x2, double y2)
static void error(char *msg)
void init(dt_iop_module_t *module)
static gboolean area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
const char ** description(struct dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ int get_scales(float(*thrs)[4], float(*boost)[4], float *sharp, const dt_iop_atrous_data_t *const d, const dt_iop_roi_t *roi_in, const dt_dev_pixelpipe_iop_t *const piece)
static gboolean area_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
static void reset_mix(dt_iop_module_t *self)
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void gui_update(struct dt_iop_module_t *self)
void gui_init(struct dt_iop_module_t *self)
static void mix_callback(GtkWidget *slider, gpointer user_data)
static void _apply_mix(dt_iop_module_t *self, const int ch, const int k, const float mix, const float px, const float py, float *x, float *y)
#define dt_atrous_show_lower_label(cr, text, layout, ink)
static __DT_CLONE_TARGETS__ int process_wavelets(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const eaw_decompose_t decompose, const eaw_synthesize_t synthesize)
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)
static void get_params(dt_iop_atrous_params_t *p, const int ch, const double mouse_x, const double mouse_y, const float rad)
static gboolean area_enter_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
static gboolean area_button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static gboolean area_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
static gboolean area_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
void gui_cleanup(struct dt_iop_module_t *self)
void init_presets(dt_iop_module_so_t *self)
static __DT_CLONE_TARGETS__ int get_samples(float *t, const dt_iop_atrous_data_t *const d, const dt_iop_roi_t *roi_in, const dt_dev_pixelpipe_iop_t *const piece)
static gboolean area_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int process(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o)
void init_global(dt_iop_module_so_t *module)
#define dt_atrous_show_upper_label(cr, text, layout, ink)
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 tab_switch(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
float dt_bauhaus_slider_get(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
@ DEVELOP_BLEND_CS_RGB_DISPLAY
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define __OMP_SIMD__(...)
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define dt_pixelpipe_cache_free_align(mem)
#define __DT_CLONE_TARGETS__
#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_database_start_transaction(db)
#define dt_database_release_transaction(db)
#define dt_dev_add_history_item(dev, module, enable, redraw)
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
static void dt_draw_curve_calc_values(dt_draw_curve_t *c, const float min, const float max, const int res, float *x, float *y)
static void dt_draw_grid(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
static float dt_draw_curve_calc_value(dt_draw_curve_t *c, const float x)
static void dt_draw_curve_destroy(dt_draw_curve_t *c)
static void dt_draw_curve_set_point(dt_draw_curve_t *c, const int num, const float x, const float y)
static int dt_draw_curve_add_point(dt_draw_curve_t *c, const float x, const float y)
static dt_draw_curve_t * dt_draw_curve_new(const float min, const float max, unsigned int type)
void eaw_decompose(float *const restrict out, const float *const restrict in, float *const restrict detail, const int scale, const float sharpen, const int32_t width, const int32_t height)
void eaw_synthesize(float *const out, const float *const in, const float *const restrict detail, const float *const restrict threshold, const float *const restrict boost, const int32_t width, const int32_t height)
gboolean dt_gui_get_scroll_unit_deltas(const GdkEventScroll *event, int *delta_x, int *delta_y)
GtkWidget * dt_ui_resizable_drawing_area(GtkWidget *area, char *config_str, int default_height, int min_height)
Make a self-drawing widget (typically a GtkDrawingArea graph or scope) vertically resizable.
GtkWidget * dt_ui_notebook_page(GtkNotebook *notebook, const char *text, const char *tooltip)
GtkNotebook * dt_ui_notebook_new()
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
void dt_gui_presets_add_generic(const char *name, dt_dev_operation_t op, const int32_t version, const void *params, const int32_t params_size, const int32_t enabled, const dt_develop_blend_colorspace_t blend_cst)
void dt_gui_throttle_cancel(gpointer source)
void dt_gui_throttle_queue(gpointer source, dt_gui_throttle_callback_t callback, gpointer user_data)
int dt_iop_alloc_image_buffers(struct dt_iop_module_t *const module, const struct dt_iop_roi_t *const roi_in, const struct dt_iop_roi_t *const roi_out,...)
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)
void dt_iop_throttled_history_update(gpointer data)
void dt_iop_default_init(dt_iop_module_t *module)
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)
@ IOP_FLAGS_SUPPORTS_BLENDING
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
const float *const const float coeff[3]
static float mix(const float a, const float b, const float t)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
float dt_aligned_pixel_t[4]
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
int dt_opencl_create_kernel(const int prog, const char *name)
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
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)
void dt_opencl_release_mem_object(cl_mem mem)
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
const struct dt_database_t * db
struct dt_bauhaus_t * bauhaus
struct dt_develop_t * develop
PangoFontDescription * pango_font_desc
struct dt_iop_module_t *void * data
gboolean cache_output_on_ram
dt_draw_curve_t * curve[atrous_none]
atrous_channel_t channel2
dt_iop_atrous_params_t drag_params
GtkNotebook * channel_tabs
dt_draw_curve_t * minmax_curve
GModule *dt_dev_operation_t op
dt_iop_global_data_t * data
dt_iop_params_t * default_params
struct dt_develop_t * dev
dt_iop_gui_data_t * gui_data
dt_iop_global_data_t * global_data
Region of interest passed through the pixelpipe.