53#define DT_GUI_CURVE_EDITOR_INSET DT_PIXEL_APPLY_DPI(5)
57#define RGBLEVELS_MIN 0.f
58#define RGBLEVELS_MID 0.5f
59#define RGBLEVELS_MAX 1.f
137 _(
"corrective and creative"),
138 _(
"linear, RGB, display-referred"),
139 _(
"non-linear, RGB"),
140 _(
"non-linear, RGB, display-referred"));
148 g->button_down =
g->draw_selected_region = 0;
149 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->bt_select_region),
g->draw_selected_region);
169 if(
g->call_auto_levels == 2)
171 g->call_auto_levels = -1;
180 g->call_auto_levels = 0;
203 const float delta = (
d->params.levels[c][2] -
d->params.levels[c][0]) / 2.0f;
204 const float mid =
d->params.levels[c][0] +
delta;
205 const float tmp = (
d->params.levels[c][1] - mid) /
delta;
206 d->inv_gamma[0] =
d->inv_gamma[1] =
d->inv_gamma[2] = pow(10, tmp);
208 for(
unsigned int i = 0;
i < 0x10000;
i++)
210 float percentage = (float)
i / (
float)0x10000ul;
211 d->lut[0][
i] =
d->lut[1][
i] =
d->lut[2][
i] = pow(percentage,
d->inv_gamma[c]);
216 for(
int c = 0; c < 3; c++)
218 const float delta = (
d->params.levels[c][2] -
d->params.levels[c][0]) / 2.0f;
219 const float mid =
d->params.levels[c][0] +
delta;
220 const float tmp = (
d->params.levels[c][1] - mid) /
delta;
221 d->inv_gamma[c] = pow(10, tmp);
223 for(
unsigned int i = 0;
i < 0x10000;
i++)
225 float percentage = (float)
i / (
float)0x10000ul;
226 d->lut[c][
i] = pow(percentage,
d->inv_gamma[c]);
237 gtk_notebook_set_show_tabs(
g->channel_tabs,
TRUE);
240 gtk_notebook_set_show_tabs(
g->channel_tabs,
FALSE);
245 gtk_widget_set_visible(
g->cmb_preserve_colors,
TRUE);
247 gtk_widget_set_visible(
g->cmb_preserve_colors,
FALSE);
253 c->mouse_x = c->mouse_y = -1.0;
254 gtk_widget_queue_draw(widget);
264 GtkAllocation allocation;
265 gtk_widget_get_allocation(GTK_WIDGET(c->area), &allocation);
266 int width = allocation.width,
height = allocation.height;
268 cairo_t *cr = cairo_create(cst);
271 cairo_set_source_rgb(cr, .2, .2, .2);
274 cairo_translate(cr, inset, inset);
279 cairo_set_source_rgb(cr, .1, .1, .1);
283 cairo_set_source_rgb(cr, .3, .3, .3);
289 cairo_set_source_rgb(cr, .1, .1, .1);
295 for(
int k = 0;
k < 3;
k++)
297 if(
k == c->handle_move && c->mouse_x > 0)
298 cairo_set_source_rgb(cr, 1, 1, 1);
300 cairo_set_source_rgb(cr, .7, .7, .7);
303 cairo_rel_line_to(cr, 0, -
height);
310 for(
int k = 0;
k < 3;
k++)
315 cairo_set_source_rgb(cr, 0, 0, 0);
319 cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
323 cairo_set_source_rgb(cr, 1, 1, 1);
327 cairo_move_to(cr,
width *
p->levels[c->channel][
k],
height + inset - 1);
328 cairo_rel_line_to(cr, -arrw * .5f, 0);
329 cairo_rel_line_to(cr, arrw * .5f, -arrw);
330 cairo_rel_line_to(cr, arrw * .5f, arrw);
331 cairo_close_path(cr);
332 if(c->handle_move ==
k && c->mouse_x > 0)
338 cairo_translate(cr, 0,
height);
344 const int ch = c->channel;
346 const gboolean is_linear =
FALSE;
355 hist_max = logf(1.0 + hist_max);
359 cairo_push_group_with_content(cr, CAIRO_CONTENT_COLOR);
364 cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
377 cairo_pop_group_to_source(cr);
378 cairo_paint_with_alpha(cr, 0.2);
384 cairo_set_source_surface(crf, cst, 0, 0);
386 cairo_surface_destroy(cst);
391 const float drag_start_percentage)
397 if((handle_move < 0) || handle_move > 2)
return;
405 max_x = fminf(
levels[2] - (0.05 / drag_start_percentage), 1);
406 max_x = fminf((
levels[2] * (1 - drag_start_percentage) - 0.05) / (1 - drag_start_percentage), max_x);
415 min_x = fmaxf((0.05 / drag_start_percentage) +
levels[0], 0);
416 min_x = fmaxf((
levels[0] * (1 - drag_start_percentage) + 0.05) / (1 - drag_start_percentage), min_x);
420 levels[handle_move] = fminf(max_x, fmaxf(min_x, new_pos));
424 c->last_picked_color = -1;
428 gtk_widget_queue_draw(GTK_WIDGET(c->area));
436 GtkAllocation allocation;
437 gtk_widget_get_allocation(widget, &allocation);
438 int height = allocation.height - 2 * inset,
width = allocation.width - 2 * inset;
441 c->mouse_x = CLAMP(event->x - inset, 0,
width);
442 c->drag_start_percentage = (
p->levels[c->channel][1] -
p->levels[c->channel][0]) / (
p->levels[c->channel][2] -
p->levels[c->channel][0]);
444 c->mouse_y = CLAMP(event->y - inset, 0,
height);
448 if(c->handle_move >= 0 && c->handle_move < 3)
450 const float mx = (CLAMP(event->x - inset, 0,
width)) / (
float)
width;
458 const float mx = CLAMP(event->x - inset, 0,
width) / (float)
width;
459 float dist = fabsf(
p->levels[c->channel][0] - mx);
460 for(
int k = 1;
k < 3;
k++)
462 float d2 = fabsf(
p->levels[c->channel][
k] - mx);
470 gtk_widget_queue_draw(widget);
479 if(event->button == 1)
483 if(event->type == GDK_2BUTTON_PRESS)
492 for(
int i = 0;
i < 3;
i++)
493 p->levels[c->channel][
i] = default_params->
levels[c->channel][
i];
497 c->drag_start_percentage = 0.5;
499 gtk_widget_queue_draw(self->
widget);
515 if(event->button == 1)
540 const float interval = 0.002;
543 const float new_position =
p->levels[c->channel][c->handle_move] - interval * delta_y;
560 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off), 1);
567 if(
g->call_auto_levels == 0)
569 g->box_cood[0] =
g->box_cood[1] =
g->box_cood[2] =
g->box_cood[3] = 0.f;
570 g->call_auto_levels = 1;
586 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off), 1);
594 if(gtk_toggle_button_get_active(togglebutton))
596 g->draw_selected_region = 1;
599 g->draw_selected_region = 0;
601 g->posx_from =
g->posx_to =
g->posy_from =
g->posy_to = 0;
613 if(w ==
g->cmb_autoscale)
616 gtk_notebook_set_current_page(GTK_NOTEBOOK(
g->channel_tabs),
g->channel);
629 gtk_widget_queue_draw(self->
widget);
651 if(mean_picked_color != c->last_picked_color)
654 previous_color[0] =
p->levels[channel][0];
655 previous_color[1] =
p->levels[channel][1];
656 previous_color[2] =
p->levels[channel][2];
658 c->last_picked_color = mean_picked_color;
660 if(picker == c->blackpick)
662 if(mean_picked_color >
p->levels[channel][1])
664 p->levels[channel][0] =
p->levels[channel][1] - FLT_EPSILON;
668 p->levels[channel][0] = mean_picked_color;
671 else if(picker == c->greypick)
673 if(mean_picked_color < p->
levels[channel][0] || mean_picked_color >
p->levels[channel][2])
675 p->levels[channel][1] =
p->levels[channel][1];
679 p->levels[channel][1] = mean_picked_color;
682 else if(picker == c->whitepick)
684 if(mean_picked_color < p->
levels[channel][1])
686 p->levels[channel][2] =
p->levels[channel][1] + FLT_EPSILON;
690 p->levels[channel][2] = mean_picked_color;
694 if(previous_color[0] !=
p->levels[channel][0]
695 || previous_color[1] !=
p->levels[channel][1]
696 || previous_color[2] !=
p->levels[channel][2])
719 for(
int c = 0; c < 3; c++)
722 d->params.levels[
i][c] =
p->levels[0][c];
724 d->params.levels[
i][c] =
p->levels[
i][c];
751 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->bt_select_region),
g->draw_selected_region);
754 gtk_widget_queue_draw(self->
widget);
770 gtk_widget_queue_draw(self->
widget);
794 g->call_auto_levels = 0;
795 g->draw_selected_region = 0;
796 g->posx_from =
g->posx_to =
g->posy_from =
g->posy_to = 0.f;
797 g->box_cood[0] =
g->box_cood[1] =
g->box_cood[2] =
g->box_cood[3] = 0.f;
807 c->mouse_x = c->mouse_y = -1.0;
809 c->last_picked_color = -1;
812 gtk_widget_set_tooltip_text(c->cmb_autoscale, _(
"choose between linked and independent channels."));
814 c->channel_tabs = GTK_NOTEBOOK(gtk_notebook_new());
818 g_signal_connect(G_OBJECT(c->channel_tabs),
"switch_page", G_CALLBACK(
_tab_switch_callback), self);
819 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(c->channel_tabs),
FALSE,
FALSE, 0);
821 c->area = GTK_DRAWING_AREA(gtk_drawing_area_new());
822 gtk_widget_set_hexpand(GTK_WIDGET(c->area),
TRUE);
824 gtk_box_pack_start(GTK_BOX(self->
widget),
826 "plugins/darkroom/rgblevels/graphheight", 280, 100),
829 g_object_set_data(G_OBJECT(c->area),
"iop-instance", self);
831 gtk_widget_set_tooltip_text(GTK_WIDGET(c->area),_(
"drag handles to set black, gray, and white points. "
832 "operates on L channel."));
834 gtk_widget_add_events(GTK_WIDGET(c->area), GDK_POINTER_MOTION_MASK
835 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
836 | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
846 gtk_widget_set_tooltip_text(c->blackpick, _(
"pick black point from image"));
847 gtk_widget_set_name(GTK_WIDGET(c->blackpick),
"picker-black");
851 gtk_widget_set_tooltip_text(c->greypick, _(
"pick medium gray point from image"));
852 gtk_widget_set_name(GTK_WIDGET(c->greypick),
"picker-grey");
856 gtk_widget_set_tooltip_text(c->whitepick, _(
"pick white point from image"));
857 gtk_widget_set_name(GTK_WIDGET(c->whitepick),
"picker-white");
861 gtk_box_pack_start(GTK_BOX(pick_hbox), GTK_WIDGET(c->blackpick),
TRUE,
TRUE, 0);
862 gtk_box_pack_start(GTK_BOX(pick_hbox), GTK_WIDGET(c->greypick ),
TRUE,
TRUE, 0);
863 gtk_box_pack_start(GTK_BOX(pick_hbox), GTK_WIDGET(c->whitepick),
TRUE,
TRUE, 0);
865 gtk_box_pack_start(GTK_BOX(self->
widget), pick_hbox,
TRUE,
TRUE, 0);
867 c->bt_auto_levels = gtk_button_new_with_label(_(
"auto"));
868 gtk_widget_set_tooltip_text(c->bt_auto_levels, _(
"apply auto levels"));
872 gtk_widget_set_tooltip_text(c->bt_select_region,
873 _(
"apply auto levels based on a region defined by the user\n"
874 "click and drag to draw the area\n"
875 "right click to cancel"));
878 gtk_box_pack_start(GTK_BOX(autolevels_box), c->bt_auto_levels,
TRUE,
TRUE, 0);
879 gtk_box_pack_start(GTK_BOX(autolevels_box), c->bt_select_region,
TRUE,
TRUE, 0);
881 gtk_box_pack_start(GTK_BOX(self->
widget), autolevels_box,
TRUE,
TRUE, 0);
887 gtk_widget_set_tooltip_text(c->cmb_preserve_colors, _(
"method to preserve colors when applying contrast"));
906 box_out[0] = box_out[1] = box_out[2] = box_out[3] = 0;
914 box_cood[0] *= pipe->
iwidth;
916 box_cood[2] *= pipe->
iwidth;
922 box_cood[0] *= roi_in->
scale;
923 box_cood[1] *= roi_in->
scale;
924 box_cood[2] *= roi_in->
scale;
925 box_cood[3] *= roi_in->
scale;
927 box_cood[0] -= roi_in->
x;
928 box_cood[1] -= roi_in->
y;
929 box_cood[2] -= roi_in->
x;
930 box_cood[3] -= roi_in->
y;
935 box[0] = fminf(box_cood[0], box_cood[2]);
936 box[1] = fminf(box_cood[1], box_cood[3]);
937 box[2] = fmaxf(box_cood[0], box_cood[2]);
938 box[3] = fmaxf(box_cood[1], box_cood[3]);
941 if(!(box[0] >=
width || box[1] >=
height || box[2] < 0 || box[3] < 0))
948 if(!(box[2] - box[0] < 1 || box[3] - box[1] < 1))
963 int y_from, y_to, x_from, x_to;
966 if(box_area[2] > box_area[0] && box_area[3] > box_area[1])
968 y_from = box_area[1];
970 x_from = box_area[0];
981 float max = -INFINITY;
982 float min = INFINITY;
984 for(
int y = y_from; y <= y_to; y++)
986 const float *
const in = img +
ch *
width * y;
987 for(
int x = x_from;
x <= x_to;
x++)
989 const float *
const pixel = in +
x *
ch;
995 if(pixel[channel] >= 0.f)
997 max = fmaxf(
max, pixel[channel]);
998 min = fminf(
min, pixel[channel]);
1003 for(
int c = 0; c < 3; c++)
1007 max = fmaxf(
max, pixel[c]);
1008 min = fminf(
min, pixel[c]);
1015 const float lum =
dt_rgb_norm(pixel,
p->preserve_colors, work_profile);
1025 p->levels[channel][0] = CLAMP(
min, 0.f, 1.f);
1026 p->levels[channel][2] = CLAMP(
max, 0.f, 1.f);
1027 p->levels[channel][1] = (
p->levels[channel][2] +
p->levels[channel][0]) / 2.f;
1032 const void *
const ivoid,
void *
const ovoid)
1048 g->call_auto_levels = -1;
1059 g->call_auto_levels = 2;
1069 1.f / (
d->params.levels[1][2] -
d->params.levels[1][0]),
1070 1.f / (
d->params.levels[2][2] -
d->params.levels[2][0]) };
1072 const size_t npixels = (size_t)roi_out->
width * roi_out->
height;
1073 const float *
const restrict in = (
const float*)ivoid;
1074 float *
const restrict
out = (
float*)
ovoid;
1078 for(
int k = 0;
k < 4U*npixels;
k += 4)
1080 for(
int c = 0; c < 3; c++)
1082 const float L_in = in[
k+c];
1084 if(L_in <= d->params.levels[c][0])
1089 else if(L_in >=
d->params.levels[c][2])
1091 const float percentage = (L_in -
d->params.levels[c][0]) * mult[c];
1092 out[
k+c] = powf(percentage,
d->inv_gamma[c]);
1097 const float percentage = (L_in -
d->params.levels[c][0]) * mult[c];
1098 out[
k+c] =
d->lut[c][CLAMP((
int)(percentage * 0x10000ul), 0, 0xffff)];
1106 const int ch_levels = 0;
1107 const float mult_ch = mult[ch_levels];
1108 const float *
const restrict
levels =
d->params.levels[ch_levels];
1110 for(
int k = 0;
k < 4U*npixels;
k += 4)
1112 const float lum =
dt_rgb_norm(in+
k,
d->params.preserve_colors, work_profile);
1116 const float percentage = (lum -
levels[0]) * mult_ch;
1119 curve_lum = powf(percentage,
d->inv_gamma[ch_levels]);
1124 curve_lum =
d->lut[ch_levels][CLAMP((
int)(percentage * 0x10000ul), 0, 0xffff)];
1127 const float ratio = curve_lum / lum;
1131 out[
k+c] = (ratio * in[
k+c]);
static double dist(double x1, double y1, double x2, double y2)
int levels(struct dt_imageio_module_data_t *data)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
static void set_color(cairo_t *cr, GdkRGBA color)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
static const float const float const float min
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define for_each_channel(_var,...)
float dt_boundingbox_t[4]
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define __DT_CLONE_TARGETS__
#define __OMP_PARALLEL_FOR__(...)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static float dt_rgb_norm(const float4 in, const int norm, const int work_profile, constant dt_colorspaces_iccprofile_info_cl_t *profile_info, read_only image2d_t lut)
#define dt_dev_add_history_item(dev, module, enable, redraw)
#define dt_dev_pixelpipe_update_history_all(dev)
int dt_dev_distort_transform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
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_TRANSFORM_DIR_BACK_INCL
static void dt_draw_vertical_lines(cairo_t *cr, const int num, const int left, const int top, const int right, const int bottom)
static void dt_draw_histogram_8(cairo_t *cr, const uint32_t *hist, int32_t channels, int32_t channel, const gboolean linear)
void dtgtk_cairo_paint_colorpicker(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
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)
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_iop_default_init(dt_iop_module_t *module)
void dt_iop_request_focus(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)
static void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module) ACQUIRE(&module -> gui_lock)
@ IOP_FLAGS_SUPPORTS_BLENDING
static void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module) RELEASE(&module -> gui_lock)
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_work_profile_info(const struct dt_dev_pixelpipe_t *pipe)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
float dt_aligned_pixel_t[4]
static gboolean _area_draw_callback(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self)
dt_iop_rgblevels_autoscale_t
@ DT_IOP_RGBLEVELS_LINKED_CHANNELS
@ DT_IOP_RGBLEVELS_INDEPENDENT_CHANNELS
const char ** description(struct dt_iop_module_t *self)
static void _auto_levels_callback(GtkButton *button, dt_iop_module_t *self)
static gboolean _area_button_release_callback(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ void _auto_levels(const float *const img, const int width, const int height, int *box_area, dt_iop_rgblevels_params_t *p, const int _channel, const dt_iop_order_iccprofile_info_t *const work_profile)
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
__DT_CLONE_TARGETS__ int process(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)
#define DT_GUI_CURVE_EDITOR_INSET
static gboolean _area_leave_notify_callback(GtkWidget *widget, GdkEventCrossing *event, dt_iop_module_t *self)
void gui_focus(struct dt_iop_module_t *self, gboolean in)
static void _compute_lut(const dt_dev_pixelpipe_iop_t *piece)
void gui_reset(struct dt_iop_module_t *self)
static void _rgblevels_move_handle(dt_iop_module_t *self, const int handle_move, const float new_pos, float *levels, const float drag_start_percentage)
void gui_init(dt_iop_module_t *self)
void change_image(struct dt_iop_module_t *self)
static void _select_region_toggled_callback(GtkToggleButton *togglebutton, dt_iop_module_t *self)
static void _develop_ui_pipe_finished_callback(gpointer instance, dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
static gboolean _area_scroll_callback(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self)
static void _turn_selregion_picker_off(struct dt_iop_module_t *self)
void commit_params(dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void gui_cleanup(dt_iop_module_t *self)
static void _tab_switch_callback(GtkNotebook *notebook, GtkWidget *page, guint page_num, dt_iop_module_t *self)
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static void _turn_select_region_off(struct dt_iop_module_t *self)
static gboolean _area_button_press_callback(GtkWidget *widget, GdkEventButton *event, dt_iop_module_t *self)
void init(dt_iop_module_t *self)
static void _color_picker_callback(GtkWidget *button, dt_iop_module_t *self)
static void _rgblevels_show_hide_controls(dt_iop_rgblevels_params_t *p, dt_iop_rgblevels_gui_data_t *g)
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static __DT_CLONE_TARGETS__ void _get_selected_area(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, dt_iop_rgblevels_gui_data_t *g, const dt_iop_roi_t *const roi_in, int *box_out)
static gboolean _area_motion_notify_callback(GtkWidget *widget, GdkEventMotion *event, dt_iop_module_t *self)
dt_iop_rgblevels_channel_t
@ DT_IOP_RGBLEVELS_MAX_CHANNELS
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_bauhaus_t * bauhaus
struct dt_develop_t * develop
dt_dev_request_flags_t request_histogram
struct dt_iop_module_t *void * data
struct dt_iop_module_t * gui_module
GtkDarktableToggleButton * off
dt_iop_params_t * default_params
struct dt_develop_t * dev
dt_iop_gui_data_t * gui_data
dt_dev_request_flags_t request_histogram
uint32_t histogram_max[4]
dt_aligned_pixel_t picked_color
float inv_gamma[DT_IOP_RGBLEVELS_MAX_CHANNELS]
float lut[DT_IOP_RGBLEVELS_MAX_CHANNELS][0x10000]
dt_iop_rgblevels_params_t params
GtkWidget * cmb_preserve_colors
GtkWidget * bt_select_region
GtkNotebook * channel_tabs
float drag_start_percentage
dt_iop_rgblevels_params_t params
dt_iop_rgblevels_channel_t channel
dt_boundingbox_t box_cood
GtkWidget * bt_auto_levels
GtkWidget * cmb_autoscale
dt_iop_rgb_norms_t preserve_colors
float levels[DT_IOP_RGBLEVELS_MAX_CHANNELS][3]
dt_iop_rgblevels_autoscale_t autoscale
Region of interest passed through the pixelpipe.