74#define DT_COLORCORRECTION_INSET DT_PIXEL_APPLY_DPI(5)
75#define DT_COLORCORRECTION_MAX 40.
104 return _(
"color correction");
110 _(
"corrective or creative"),
111 _(
"non-linear, Lab, display-referred"),
112 _(
"non-linear, Lab"),
113 _(
"non-linear, Lab, display-referred"));
141 self->version(), &
p,
sizeof(
p), 1);
149 self->version(), &
p,
sizeof(
p), 1);
157 self->version(), &
p,
sizeof(
p), 1);
171 const float saturation =
d->saturation;
172 const float a_scale =
d->a_scale;
173 const float a_base =
d->a_base;
174 const float b_scale =
d->b_scale;
175 const float b_base =
d->b_base;
177 for(
size_t k = 0;
k < (size_t)4 * roi_out->
width * roi_out->
height;
k += 4)
180 out[
k+1] = saturation * (in[
k+1] + in[
k+0] * a_scale + a_base);
181 out[
k+2] = saturation * (in[
k+2] + in[
k+0] * b_scale + b_base);
196 const int devid = pipe->
devid;
212 if(err != CL_SUCCESS)
goto error;
225 const int program = 2;
246 d->a_scale = (
p->hia -
p->loa) / 100.0;
248 d->b_scale = (
p->hib -
p->lob) / 100.0;
250 d->saturation =
p->saturation;
270 gtk_widget_queue_draw(self->
gui->
widget);
292 g_object_set_data(G_OBJECT(
g->area),
"iop-instance", self);
294 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->area), _(
"drag the line for split-toning. "
295 "bright means highlights, dark means shadows. "
296 "use mouse wheel to change saturation."));
299 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
300 | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
301 gtk_widget_set_can_focus(GTK_WIDGET(
g->area),
TRUE);
313 gtk_widget_set_tooltip_text(
g->slider, _(
"set the global saturation"));
317 g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);
323 cmsDeleteTransform(
g->xform);
335 GtkAllocation allocation;
336 gtk_widget_get_allocation(widget, &allocation);
337 int width = allocation.width,
height = allocation.height;
339 cairo_t *cr = cairo_create(cst);
341 cairo_set_source_rgb(cr, .2, .2, .2);
344 cairo_translate(cr, inset, inset);
345 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
349 cairo_translate(cr, 0,
height);
350 cairo_scale(cr, 1., -1.);
352 for(
int j = 0; j < cells; j++)
353 for(
int i = 0;
i < cells;
i++)
355 double rgb[3] = { 0.5, 0.5, 0.5 };
363 cmsDoTransform(
g->xform, &
Lab,
rgb, 1);
365 cairo_set_source_rgb(cr,
rgb[0],
rgb[1],
rgb[2]);
366 cairo_rectangle(cr,
width *
i / (
float)cells,
height * j / (
float)cells,
371 cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
372 float loa, hia, lob, hib;
378 cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
379 cairo_move_to(cr, loa, lob);
380 cairo_line_to(cr, hia, hib);
383 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
390 cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
398 cairo_set_source_surface(crf, cst, 0, 0);
400 cairo_surface_destroy(cst);
411 GtkAllocation allocation;
412 gtk_widget_get_allocation(widget, &allocation);
413 int width = allocation.width - 2 * inset,
height = allocation.height - 2 * inset;
414 const float mouse_x = CLAMP(event->x - inset, 0,
width);
415 const float mouse_y = CLAMP(
height - 1 - event->y + inset, 0,
height);
418 if(event->state & GDK_BUTTON1_MASK)
426 else if(
g->selected == 2)
437 const float distlo = (
p->loa - ma) * (
p->loa - ma) + (
p->lob - mb) * (
p->lob - mb);
438 const float disthi = (
p->hia - ma) * (
p->hia - ma) + (
p->hib - mb) * (
p->hib - mb);
439 if(distlo <
thrs *
thrs && distlo < disthi)
441 else if(disthi <
thrs *
thrs && disthi <= distlo)
444 if(
g->selected > 0) gtk_widget_grab_focus(widget);
445 gtk_widget_queue_draw(self->
gui->
widget);
452 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
461 p->loa =
p->lob = 0.0;
465 p->hia =
p->hib = 0.0;
471 memcpy(
p,
d,
sizeof(*
p));
484 gtk_widget_queue_draw(self->
gui->
widget);
497 p->saturation = CLAMP(
p->saturation - 0.1 * delta_y, -3.0, 3.0);
499 gtk_widget_queue_draw(widget);
505#define COLORCORRECTION_DEFAULT_STEP (0.5f)
512 if(
g->selected < 1)
return FALSE;
516 float dx = 0.0f, dy = 0.0f;
517 if(
key == GDK_KEY_Up)
522 else if(
key == GDK_KEY_Down)
527 else if(
key == GDK_KEY_Right)
532 else if(
key == GDK_KEY_Left)
538 if(!handled)
return FALSE;
553 gtk_widget_queue_draw(widget);
static void error(char *msg)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
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)
const char ** description(struct dt_iop_module_t *self)
static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
static gboolean dt_iop_colorcorrection_leave_notify(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
static gboolean dt_iop_colorcorrection_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
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)
static gboolean dt_iop_colorcorrection_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
void gui_init(struct dt_iop_module_t *self)
#define DT_COLORCORRECTION_INSET
void cleanup_global(dt_iop_module_so_t *module)
#define COLORCORRECTION_DEFAULT_STEP
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
void gui_cleanup(struct dt_iop_module_t *self)
static gboolean dt_iop_colorcorrection_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
void init_presets(dt_iop_module_so_t *self)
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const i, void *const o)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void init_global(dt_iop_module_so_t *module)
static gboolean dt_iop_colorcorrection_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
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)
#define DT_COLORCORRECTION_MAX
const dt_colorspaces_color_profile_t * dt_colorspaces_get_profile(dt_colorspaces_color_profile_type_t type, const char *filename, dt_colorspaces_profile_role_t role)
Resolve a profile identity to its registered entry.
The colour-profile module's API: which profiles exist, and how to apply one.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static dt_aligned_pixel_t rgb
static dt_aligned_pixel_t Lab
const dt_colormatrix_t dt_aligned_pixel_t out
#define dt_dev_add_history_item(dev, module, enable, redraw)
GtkWidget * dtgtk_drawing_area_new_with_aspect_ratio(double aspect)
static guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
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 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_INCLUDE_IN_STYLES
@ 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)
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 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_IS_ALIGNED(x)
Promise the compiler that x is already cacheline-aligned, and return it.
#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_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
int dt_opencl_create_kernel(const int prog, const char *name)
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)
#define __OMP_PARALLEL_FOR__(...)
@ DT_COLORSPACE_SRGB
sRGB – registered TWICE, and the two entries are not interchangeable.
@ DT_PROFILE_ROLE_INPUT
Listed in the input-profile combo (colorin).
@ DT_PROFILE_ROLE_ANY
All four roles, in registration order.
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
cmsHPROFILE profile
the actual profile; NULL for the three category entries
struct dt_iop_module_t *void * data
int kernel_colorcorrection
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__