90#define INSET DT_PIXEL_APPLY_DPI(5)
97#define MAX_NUM_SCALES 8
100#define dt_atrous_show_upper_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), (.08 * height) - ink.height); \
104 pango_cairo_show_layout(cr, layout);
107#define dt_atrous_show_lower_label(cr, text, layout, ink) \
108 pango_layout_set_text(layout, text, -1); \
109 pango_layout_get_pixel_extents(layout, &ink, NULL); \
110 cairo_move_to(cr, .5 * (width - ink.width), (.98 * height) - ink.height); \
111 pango_cairo_show_layout(cr, layout);
172 return _(
"contrast equalizer");
177 return _(
"sharpness|acutance|local contrast");
183 _(
"corrective and creative"),
184 _(
"linear, Lab, scene-referred"),
185 _(
"frequential, RGB"),
186 _(
"linear, Lab, scene-referred"));
205 void *new_params,
const int new_version)
207 if(old_version == 1 && new_version == 2)
209 typedef struct dt_iop_atrous_params_v1_t
214 } dt_iop_atrous_params_v1_t;
216 dt_iop_atrous_params_v1_t *o = (dt_iop_atrous_params_v1_t *)old_params;
222 memcpy(
n, o,
sizeof(dt_iop_atrous_params_v1_t));
234 const float scale = roi_in->
scale;
237 const float i0 = dt_log2f((supp0 - 1.0f) * .5f);
242 const float supp = 2 * (2 <<
i) + 1;
244 const float supp_in = supp * (1.0f / scale);
245 const float i_in = dt_log2f((supp_in - 1) * .5f) - 1.0f;
246 t[
i] = 1.0f - (i_in + .5f) / i0;
247 if(
t[
i] < 0.0f)
break;
266 const float scale = roi_in->
scale;
271 const float i0 = dt_log2f((supp0 - 1.0f) * .5f);
276 const float supp = 2 * (2 <<
i) + 1;
278 const float supp_in = supp * (1.0f / scale);
279 const float i_in = dt_log2f((supp_in - 1) * .5f) - 1.0f;
281 const float t = 1.0f - (i_in + .5f) / i0;
284 for(
int k = 0;
k < 4;
k++) boost[
i][
k] *= boost[
i][
k];
285 thrs[
i][0] =
thrs[
i][3] = powf(2.0f, -7.0f * (1.0f -
t)) * 10.0f
287 thrs[
i][1] =
thrs[
i][2] = powf(2.0f, -7.0f * (1.0f -
t)) * 20.0f
296 const int max_scale_roi = (int)floorf(dt_log2f((
float)
MIN(roi_in->
width, roi_in->
height))) - 2;
297 return MIN(max_scale_roi,
i);
305 const dt_iop_roi_t *
const roi_out,
const eaw_decompose_t decompose,
306 const eaw_synthesize_t synthesize)
312 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
328 const int max_mult = 1u << (max_scale - 1);
346 float *
const restrict
out = (
float*)o;
347 float *restrict detail = NULL;
348 float *restrict tmp = NULL;
349 float *restrict tmp2 = NULL;
356 float *buf1 = (
float *)
i;
364 for(
int scale = 0; scale < max_scale; scale++)
366 decompose(buf2, buf1, detail, scale, sharp[scale],
width,
height);
368 if(scale == 0) buf1 = (
float *)tmp2;
408 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
421 const int devid = pipe->devid;
423 cl_mem dev_filter = NULL;
424 cl_mem dev_tmp = NULL;
425 cl_mem dev_tmp2 = NULL;
426 cl_mem dev_detail = NULL;
428 float m[] = { 0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f };
430 for(
int j = 0; j < 5; j++)
431 for(
int i = 0;
i < 5;
i++) mm[j][
i] =
m[
i] *
m[j];
447 const int width = roi_out->width;
448 const int height = roi_out->height;
454 if(err != CL_SUCCESS)
goto error;
458 void* dev_buf1 = &dev_in;
459 void* dev_buf2 = &dev_tmp;
462 for(
int s = 0; s < max_scale; s++)
477 if(err != CL_SUCCESS)
goto error;
495 if(err != CL_SUCCESS)
goto error;
498 if (scale == 0) dev_buf1 = dev_tmp2;
499 void* tmp = dev_buf2;
509 if(err != CL_SUCCESS)
goto error;
537 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
550 const int devid = pipe->
devid;
552 cl_mem dev_filter = NULL;
553 cl_mem dev_tmp = NULL;
554 cl_mem *dev_detail = calloc(max_scale,
sizeof(cl_mem));
556 float m[] = { 0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f };
558 for(
int j = 0; j < 5; j++)
559 for(
int i = 0;
i < 5;
i++)
560 mm[j][
i] =
m[
i] *
m[j];
572 for(
int k = 0;
k < max_scale;
k++)
575 if(dev_detail[
k] == NULL)
goto error;
581 size_t origin[] = { 0, 0, 0 };
586 if(err != CL_SUCCESS)
goto error;
589 for(
int s = 0; s < max_scale; s++)
611 if(err != CL_SUCCESS)
goto error;
615 for(
int scale = max_scale - 1; scale >= 0; scale--)
641 if(err != CL_SUCCESS)
goto error;
646 for(
int k = 0;
k < max_scale;
k++)
654 for(
int k = 0;
k < max_scale;
k++)
671 const int max_scale =
get_scales(
thrs, boost, sharp,
d, roi_in, piece);
672 const int max_filter_radius = 2 * (1 << max_scale);
675 tiling->factor_cl = 3.0f + max_scale;
679 tiling->overlap = max_filter_radius;
701 const int program = 1;
726 const int ch,
const int k,
728 const float px,
const float py,
float *
x,
float *y)
731 *
x = fminf(1.0f, fmaxf(0.0f, px + (
mix - 1.0f) * (px - dp->
x[
ch][
k])));
732 *y = fminf(1.0f, fmaxf(0.0f, py + (
mix - 1.0f) * (py - dp->
y[
ch][
k])));
742 printf(
"---------- atrous preset begin\n");
743 printf(
"p.octaves = %d; p.mix = %.2f\n",
p->octaves,
p->mix);
746 printf(
"p.x[%d][%d] = %f;\n",
ch,
k,
p->x[
ch][
k]);
747 printf(
"p.y[%d][%d] = %f;\n",
ch,
k,
p->y[
ch][
k]);
749 printf(
"---------- atrous preset end\n");
751 d->octaves =
p->octaves;
773 piece->
data = (
void *)
d;
810#define GAUSS(x, sigma) expf( -(1.0f - x) * (1.0f - x) / (sigma * sigma)) / (2.0 * sigma * powf(M_PI, 0.5f))
833 self->version(), &
p,
sizeof(
p), 1);
848 self->version(), &
p,
sizeof(
p), 1);
863 self->version(), &
p,
sizeof(
p), 1);
878 self->version(), &
p,
sizeof(
p), 1);
893 self->version(), &
p,
sizeof(
p), 1);
909 self->version(), &
p,
sizeof(
p), 1);
924 self->version(), &
p,
sizeof(
p), 1);
930 const float x =
k / (float)(
BANDS - 1);
934 const float coeff = 0.5f + (coarse + medium + fine) / 16.0f;
935 const float noise = (coarse + medium + fine) / 128.f;
944 self->version(), &
p,
sizeof(
p), 1);
948 const float x =
k / (float)(
BANDS - 1);
951 const float coeff = 0.5f + (medium + fine) / 16.0f;
952 const float noise = (medium + fine) / 128.f;
961 self->version(), &
p,
sizeof(
p), 1);
965 const float x =
k / (float)(
BANDS - 1);
967 const float coeff = 0.5f + fine / 16.f;
968 const float noise = fine / 128.f;
977 self->version(), &
p,
sizeof(
p), 1);
981 const float x =
k / (float)(
BANDS - 1);
985 const float coeff = 0.5f + (coarse + medium + fine) / 24.0f;
986 const float noise = (coarse + medium + fine) / 192.f;
995 self->version(), &
p,
sizeof(
p), 1);
999 const float x =
k / (float)(
BANDS - 1);
1002 const float coeff = 0.5f + (medium + fine) / 24.0f;
1003 const float noise = (medium + fine) / 192.f;
1012 self->version(), &
p,
sizeof(
p), 1);
1016 const float x =
k / (float)(
BANDS - 1);
1018 const float coeff = 0.5f + fine / 24.0f;
1019 const float noise = fine / 192.f;
1028 self->version(), &
p,
sizeof(
p), 1);
1032 const float x =
k / (float)(
BANDS - 1);
1036 const float coeff = 0.5f + (coarse + medium + fine) / 32.0f;
1037 const float noise = (coarse + medium + fine) / 128.f;
1046 self->version(), &
p,
sizeof(
p), 1);
1050 const float x =
k / (float)(
BANDS - 1);
1053 const float coeff = 0.5f + (medium + fine) / 32.0f;
1054 const float noise = (medium + fine) / 128.f;
1063 self->version(), &
p,
sizeof(
p), 1);
1067 const float x =
k / (float)(
BANDS - 1);
1069 const float coeff = 0.5f + fine / 32.f;
1070 const float noise = fine / 128.f;
1079 self->version(), &
p,
sizeof(
p), 1);
1088 c->drag_params = *
p;
1097 gtk_widget_queue_draw(self->
gui->
widget);
1107 if(!c->dragging) c->mouse_y = fabs(c->mouse_y);
1109 gtk_widget_queue_draw(widget);
1117 if(!c->dragging) c->mouse_y = -fabs(c->mouse_y);
1118 c->in_curve =
FALSE;
1119 gtk_widget_queue_draw(widget);
1129 const float f = expf(-(mouse_x -
p->x[
ch][
k]) * (mouse_x -
p->x[
ch][
k]) / (rad * rad));
1140 const float mix = c->in_curve ? 1.0f :
p.mix;
1144 const int ch2 = (int)c->channel2;
1150 const int inset =
INSET;
1151 GtkAllocation allocation;
1152 gtk_widget_get_allocation(widget, &allocation);
1153 int width = allocation.width,
height = allocation.height;
1155 cairo_t *cr = cairo_create(cst);
1157 GdkRGBA bright_bg_color, graph_bg;
1158 GtkStyleContext *context = gtk_widget_get_style_context(self->
gui->
expander);
1159 gboolean color_found = gtk_style_context_lookup_color (context,
"graph_overlay", &bright_bg_color);
1162 bright_bg_color.red = 1.0;
1163 bright_bg_color.green = 0.0;
1164 bright_bg_color.blue = 0.0;
1165 bright_bg_color.alpha = 1.0;
1168 color_found = gtk_style_context_lookup_color (context,
"graph_bg", &graph_bg);
1172 graph_bg.green = 0.0;
1173 graph_bg.blue = 0.0;
1174 graph_bg.alpha = 1.0;
1177 gdk_cairo_set_source_rgba(cr, &bright_bg_color);
1180 cairo_translate(cr, inset, inset);
1185 gdk_cairo_set_source_rgba(cr, &graph_bg);
1189 gdk_cairo_set_source_rgba(cr, &bright_bg_color);
1193 if(c->mouse_y > 0 || c->dragging)
1195 const int ch2 = (int)c->channel2;
1198 get_params(&
p, ch2, c->mouse_x, 1., c->mouse_radius);
1204 get_params(&
p, ch2, c->mouse_x, .0, c->mouse_radius);
1212 gdk_cairo_set_source_rgba(cr, &graph_bg);
1219 cairo_translate(cr, 0,
height);
1223 if(c->num_samples > 0)
1226 for(
int k = 1;
k < c->num_samples;
k += 2)
1228 cairo_set_source_rgba(cr, graph_bg.red, graph_bg.green, graph_bg.blue, .3);
1229 cairo_move_to(cr,
width * c->sample[
k - 1], 0.0f);
1232 cairo_line_to(cr,
width * c->sample[
k], 0.0f);
1235 if(c->num_samples & 1)
1237 cairo_move_to(cr,
width * c->sample[c->num_samples - 1], 0.0f);
1238 cairo_line_to(cr,
width * c->sample[c->num_samples - 1], -
height);
1239 cairo_line_to(cr, 0.0f, -
height);
1240 cairo_line_to(cr, 0.0f, 0.0f);
1249 cairo_set_source_rgba(cr, graph_bg.red, graph_bg.green, graph_bg.blue, .3);
1250 cairo_move_to(cr, 0, 0);
1251 for(
int k = 0;
k <
BANDS;
k++) cairo_line_to(cr,
k, c->band_hist[
k]);
1252 cairo_line_to(cr,
BANDS - 1.0, 0.);
1253 cairo_close_path(cr);
1260 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1265 int ch = ((int)c->channel +
i + 1) % (
atrous_s + 1);
1267 const float bgmul =
i <
atrous_s ? 0.5f : 1.0f;
1271 cairo_set_source_rgba(cr, .6, .6, .6, .3 * bgmul);
1275 cairo_set_source_rgba(cr, .4, .2, .0, .4 * bgmul);
1279 cairo_set_source_rgba(cr, .1, .2, .3, .4 * bgmul);
1285 if(c->channel2 == ch2)
1301 for(
int k =
RES - 2;
k >= 0;
k--)
1305 cairo_move_to(cr, 0, 0);
1313 for(
int k = 0;
k <
RES;
k++)
1316 cairo_line_to(cr,
width, 0);
1317 cairo_close_path(cr);
1318 cairo_stroke_preserve(cr);
1322 if(c->mouse_y > 0 || c->dragging)
1324 const int ch = (int)c->channel;
1325 const int ch2 = (int)c->channel2;
1330 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
1332 cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
1347 if(c->mouse_y > 0 || c->dragging)
1351 cairo_move_to(cr, 0, -
height * c->draw_min_ys[0]);
1352 for(
int k = 1;
k <
RES;
k++)
1353 cairo_line_to(cr,
k *
width / (
float)(
RES - 1), -
height * c->draw_min_ys[
k]);
1354 for(
int k =
RES - 1;
k >= 0;
k--)
1355 cairo_line_to(cr,
k *
width / (
float)(
RES - 1), -
height * c->draw_max_ys[
k]);
1356 cairo_close_path(cr);
1359 cairo_set_source_rgba(cr, .9, .9, .9, .5);
1360 const float pos =
RES * c->mouse_x;
1362 const float f =
k - pos;
1364 const float ht = -
height * (
f * c->draw_ys[
k] + (1 -
f) * c->draw_ys[
k + 1]);
1365 cairo_arc(cr, c->mouse_x *
width, ht, c->mouse_radius *
width, 0, 2. *
M_PI);
1369 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1373 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
1378 cairo_rel_line_to(cr, -arrw * .5f, 0);
1379 cairo_rel_line_to(cr, arrw * .5f, -arrw);
1380 cairo_rel_line_to(cr, arrw * .5f, arrw);
1381 cairo_close_path(cr);
1390 if(c->mouse_y > 0 || c->dragging)
1393 PangoLayout *layout;
1395 PangoFontDescription *desc = pango_font_description_copy_static(
dt_bauhaus_get_global()->pango_font_desc);
1396 pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
1397 pango_font_description_set_absolute_size(desc, (.06 *
height) * PANGO_SCALE);
1398 layout = pango_cairo_create_layout(cr);
1399 pango_layout_set_font_description(layout, desc);
1400 gdk_cairo_set_source_rgba(cr, &graph_bg);
1401 cairo_set_font_size(cr, .06 *
height);
1402 pango_layout_set_text(layout, _(
"coarse"), -1);
1403 pango_layout_get_pixel_extents(layout, &ink, NULL);
1404 cairo_move_to(cr, .02 *
width - ink.y, .14 *
height + ink.width);
1406 cairo_rotate(cr, -
M_PI * .5f);
1407 pango_cairo_show_layout(cr, layout);
1409 pango_layout_set_text(layout, _(
"fine"), -1);
1410 pango_layout_get_pixel_extents(layout, &ink, NULL);
1411 cairo_move_to(cr, .98 *
width - ink.height, .14 *
height + ink.width);
1413 cairo_rotate(cr, -
M_PI * .5f);
1414 pango_cairo_show_layout(cr, layout);
1434 pango_font_description_free(desc);
1435 g_object_unref(layout);
1440 cairo_set_source_surface(crf, cst, 0, 0);
1442 cairo_surface_destroy(cst);
1451 const int inset =
INSET;
1452 GtkAllocation allocation;
1453 gtk_widget_get_allocation(widget, &allocation);
1454 const int height = allocation.height - 2 * inset;
1455 const int width = allocation.width - 2 * inset;
1456 if(!c->dragging) c->mouse_x = CLAMP(event->x - inset, 0,
width) / (float)
width;
1457 c->mouse_y = 1.0 - CLAMP(event->y - inset, 0,
height) / (float)
height;
1459 int ch2 = c->channel;
1466 *
p = c->drag_params;
1469 const float mx = CLAMP(event->x - inset, 0,
width) / (float)
width;
1470 if(c->x_move > 0 && c->x_move <
BANDS - 1)
1472 const float minx =
p->x[c->channel][c->x_move - 1] + 0.001f;
1473 const float maxx =
p->x[c->channel][c->x_move + 1] - 0.001f;
1474 p->x[ch2][c->x_move] =
p->x[c->channel][c->x_move] = fminf(maxx, fmaxf(minx, mx));
1479 get_params(
p, c->channel2, c->mouse_x, c->mouse_y + c->mouse_pick, c->mouse_radius);
1481 gtk_widget_queue_draw(widget);
1484 else if(event->y >
height)
1488 float dist = fabs(
p->x[c->channel][0] - c->mouse_x);
1491 const float d2 = fabs(
p->x[c->channel][
k] - c->mouse_x);
1498 gtk_widget_queue_draw(widget);
1503 const int ch = c->channel;
1504 float dist = 1000000.0f;
1507 float d2 = fabs(
p->x[c->channel][
k] - c->mouse_x);
1510 if(fabs(c->mouse_y -
p->y[
ch][
k]) < fabs(c->mouse_y -
p->y[ch2][
k]))
1519 gtk_widget_queue_draw(widget);
1527 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
1536 p->x[c->channel2][
k] =
d->x[c->channel2][
k];
1537 p->y[c->channel2][
k] =
d->y[c->channel2][
k];
1539 gtk_widget_queue_draw(self->
gui->
widget);
1542 else if(event->button == 1)
1547 const int inset =
INSET;
1548 GtkAllocation allocation;
1549 gtk_widget_get_allocation(widget, &allocation);
1550 const int height = allocation.height - 2 * inset;
1551 const int width = allocation.width - 2 * inset;
1554 c->mouse_pick -= 1.0 - CLAMP(event->y - inset, 0,
height) / (float)
height;
1563 if(event->button == 1)
1582 c->mouse_radius = CLAMP(c->mouse_radius * (1.0 + 0.1 * delta_y), 0.25 /
BANDS, 1.0);
1583 gtk_widget_queue_draw(widget);
1594 gtk_widget_queue_draw(self->
gui->
widget);
1603 gtk_widget_queue_draw(self->
gui->
widget);
1614 c->channel = c->channel2 =
dt_conf_get_int(
"plugins/darkroom/atrous/gui_channel");
1615 int ch = (int)c->channel;
1619 c->mouse_x = c->mouse_y = c->mouse_pick = -1.0;
1623 c->mouse_radius = 1.0 /
BANDS;
1624 c->in_curve =
FALSE;
1629 dt_ui_notebook_page(c->channel_tabs, N_(
"luma"), _(
"change lightness at each feature size"));
1630 dt_ui_notebook_page(c->channel_tabs, N_(
"chroma"), _(
"change color saturation at each feature size"));
1631 dt_ui_notebook_page(c->channel_tabs, N_(
"edges"), _(
"change edge halos at each feature size\nonly changes results of luma and chroma tabs"));
1632 gtk_widget_show(gtk_notebook_get_nth_page(c->channel_tabs, c->channel));
1633 gtk_notebook_set_current_page(c->channel_tabs, c->channel);
1634 g_signal_connect(G_OBJECT(c->channel_tabs),
"switch_page", G_CALLBACK(
tab_switch), self);
1635 gtk_box_pack_start(GTK_BOX(self->
gui->
widget), GTK_WIDGET(c->channel_tabs),
FALSE,
FALSE, 0);
1638 c->area = GTK_DRAWING_AREA(gtk_drawing_area_new());
1639 gtk_widget_set_hexpand(GTK_WIDGET(c->area),
TRUE);
1640 gtk_box_pack_start(GTK_BOX(self->
gui->
widget),
1642 "plugins/darkroom/atrous/graphheight", 280, 100),
1645 gtk_widget_add_events(GTK_WIDGET(c->area),
1646 GDK_POINTER_MOTION_MASK
1647 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
1648 | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
1650 g_object_set_data(G_OBJECT(c->area),
"iop-instance", self);
1651 g_signal_connect(G_OBJECT(c->area),
"draw", G_CALLBACK(
area_draw), self);
1652 g_signal_connect(G_OBJECT(c->area),
"button-press-event", G_CALLBACK(
area_button_press), self);
1653 g_signal_connect(G_OBJECT(c->area),
"button-release-event", G_CALLBACK(
area_button_release), self);
1654 g_signal_connect(G_OBJECT(c->area),
"motion-notify-event", G_CALLBACK(
area_motion_notify), self);
1655 g_signal_connect(G_OBJECT(c->area),
"leave-notify-event", G_CALLBACK(
area_leave_notify), self);
1656 g_signal_connect(G_OBJECT(c->area),
"enter-notify-event", G_CALLBACK(
area_enter_notify), self);
1657 g_signal_connect(G_OBJECT(c->area),
"scroll-event", G_CALLBACK(
area_scrolled), self);
1661 gtk_widget_set_tooltip_text(c->mix, _(
"make effect stronger or weaker"));
1662 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)
const float *const const float coeff[3]
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
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)
Integer for name, clamped to the bounds declared in the XML.
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
#define dt_database_start_transaction()
#define dt_database_release_transaction()
#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)
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)
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_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
GtkWidget * dt_bauhaus_slider_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)
static float mix(const float a, const float b, const float t)
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
float *const restrict const size_t const size_t ch
#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.
GtkWidget * dt_ui_notebook_page(GtkNotebook *notebook, const char *text, const char *tooltip)
GtkNotebook * dt_ui_notebook_new()
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)
#define __OMP_SIMD__(...)
#define dt_pixelpipe_cache_free_align(mem)
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
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
dt_iop_global_data_t * data
dt_iop_params_t * default_params
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__