186 return _(
"_Vignetting");
193 _(
"non-linear, RGB, display-referred"),
194 _(
"non-linear, RGB"),
195 _(
"non-linear, RGB, display-referred"));
215 void *new_params,
const int new_version)
217 if(old_version == 1 && new_version == 4)
229 new->autoratio =
TRUE;
233 new->unbound =
FALSE;
236 if(old_version == 2 && new_version == 4)
248 new->shape = old->
shape;
250 new->unbound =
FALSE;
253 if(old_version == 3 && new_version == 4)
265 new->shape = old->
shape;
267 new->unbound =
FALSE;
281 const float radius_sq = radius[0] * radius[0];
283 if((pointerx - startx) * (pointerx - startx) + pointery * pointery <= radius_sq)
return 2;
284 if(pointerx * pointerx + (pointery - starty) * (pointery - starty) <= radius_sq)
return 4;
285 if(pointerx * pointerx + pointery * pointery <= radius_sq)
return 1;
286 if((pointerx - endx) * (pointerx - endx) + pointery * pointery <= radius_sq)
return 8;
287 if(pointerx * pointerx + (pointery - endy) * (pointery - endy) <= radius_sq)
return 16;
292static void draw_overlay(cairo_t *cr,
float x,
float y,
float fx,
float fy,
int grab,
float zoom_scale)
299 cairo_move_to(cr, -crosshair_w, 0.0);
300 cairo_line_to(cr, crosshair_w, 0.0);
301 cairo_move_to(cr, 0.0, -crosshair_h);
302 cairo_line_to(cr, 0.0, crosshair_h);
309 cairo_scale(cr,
x / y, 1.0);
310 cairo_arc(cr, 0.0, 0.0, y, 0.0,
M_PI * 2.0);
314 cairo_scale(cr, 1.0, y /
x);
315 cairo_arc(cr, 0.0, 0.0,
x, 0.0,
M_PI * 2.0);
324 cairo_scale(cr,
fx / fy, 1.0);
325 cairo_arc(cr, 0.0, 0.0, fy, 0.0,
M_PI * 2.0);
329 cairo_scale(cr, 1.0, fy /
fx);
330 cairo_arc(cr, 0.0, 0.0,
fx, 0.0,
M_PI * 2.0);
339 cairo_arc(cr, 0.0, 0.0, radius_sel, 0.0,
M_PI * 2.0);
341 cairo_arc(cr, 0.0, 0.0, radius_reg, 0.0,
M_PI * 2.0);
344 cairo_arc(cr,
x, 0.0, radius_sel, 0.0,
M_PI * 2.0);
346 cairo_arc(cr,
x, 0.0, radius_reg, 0.0,
M_PI * 2.0);
349 cairo_arc(cr, 0.0, -y, radius_sel, 0.0,
M_PI * 2.0);
351 cairo_arc(cr, 0.0, -y, radius_reg, 0.0,
M_PI * 2.0);
354 cairo_arc(cr,
fx, 0.0, radius_sel, 0.0,
M_PI * 2.0);
356 cairo_arc(cr,
fx, 0.0, radius_reg, 0.0,
M_PI * 2.0);
359 cairo_arc(cr, 0.0, -fy, radius_sel, 0.0,
M_PI * 2.0);
361 cairo_arc(cr, 0.0, -fy, radius_reg, 0.0,
M_PI * 2.0);
368 int32_t pointerx, int32_t pointery)
377 float bigger_side, smaller_side;
389 float pzxpy[2] = { (float)pointerx, (
float)pointery };
391 const float pzx = pzxpy[0];
392 const float pzy = pzxpy[1];
395 float vignette_x = (
p->center.x + 1.0) * 0.5 * wd;
396 float vignette_y = (
p->center.y + 1.0) * 0.5 * ht;
398 cairo_translate(cr, vignette_x, vignette_y);
400 float vignette_w =
p->scale * 0.01 * 0.5 * wd;
401 float vignette_h =
p->scale * 0.01 * 0.5 * ht;
402 float vignette_fx = vignette_w +
p->falloff_scale * 0.01 * 0.5 * wd;
403 float vignette_fy = vignette_h +
p->falloff_scale * 0.01 * 0.5 * ht;
407 float factor1 = bigger_side / smaller_side;
410 float factor2 = (2.0 -
p->whratio) * factor1;
414 vignette_h *= factor1;
415 vignette_w *=
p->whratio;
416 vignette_fx *=
p->whratio;
417 vignette_fy *= factor1;
421 vignette_h *= factor2;
422 vignette_fy *= factor2;
427 float factor2 = (
p->whratio) * factor1;
431 vignette_w *= factor2;
432 vignette_fx *= factor2;
436 vignette_w *= factor1;
437 vignette_h *= (2.0 -
p->whratio);
438 vignette_fx *= factor1;
439 vignette_fy *= (2.0 -
p->whratio);
444 int grab =
get_grab(self, pzx * wd - vignette_x, pzy * ht - vignette_y, vignette_w, -vignette_h, vignette_fx,
445 -vignette_fy, zoom_scale);
446 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
449 draw_overlay(cr, vignette_w, vignette_h, vignette_fx, vignette_fy, grab, zoom_scale);
452 draw_overlay(cr, vignette_w, vignette_h, vignette_fx, vignette_fy, grab, zoom_scale);
464 float bigger_side, smaller_side;
477 float pzxpy[2] = { (float)
x, (
float)y };
479 const float pzx = pzxpy[0];
480 const float pzy = pzxpy[1];
481 static int old_grab = -1;
484 float vignette_x = (
p->center.x + 1.0) * 0.5 * wd;
485 float vignette_y = (
p->center.y + 1.0) * 0.5 * ht;
487 float vignette_w =
p->scale * 0.01 * 0.5 * wd;
488 float vignette_h =
p->scale * 0.01 * 0.5 * ht;
489 float vignette_fx = vignette_w +
p->falloff_scale * 0.01 * 0.5 * wd;
490 float vignette_fy = vignette_h +
p->falloff_scale * 0.01 * 0.5 * ht;
494 float factor1 = bigger_side / smaller_side;
497 float factor2 = (2.0 -
p->whratio) * factor1;
501 vignette_h *= factor1;
502 vignette_w *=
p->whratio;
503 vignette_fx *=
p->whratio;
504 vignette_fy *= factor1;
508 vignette_h *= factor2;
509 vignette_fy *= factor2;
514 float factor2 = (
p->whratio) * factor1;
518 vignette_w *= factor2;
519 vignette_fx *= factor2;
523 vignette_w *= factor1;
524 vignette_h *= (2.0 -
p->whratio);
525 vignette_fx *= factor1;
526 vignette_fy *= (2.0 -
p->whratio);
533 grab =
get_grab(self, pzx * wd - vignette_x, pzy * ht - vignette_y, vignette_w, -vignette_h, vignette_fx,
534 -vignette_fy, zoom_scale);
551 const float max = 0.5 * ((
p->whratio <= 1.0) ? bigger_side *
p->whratio : bigger_side);
552 const float new_vignette_w =
MIN(bigger_side,
MAX(0.1, pzx * wd - vignette_x));
553 const float ratio = new_vignette_w / vignette_h;
554 const float new_scale = 100.0 * new_vignette_w /
max;
575 float new_whratio = 2.0 - 1.0 / ratio;
582 const float new_vignette_h =
MIN(bigger_side,
MAX(0.1, vignette_y - pzy * ht));
583 const float ratio = new_vignette_h / vignette_w;
584 const float max = 0.5 * ((ratio <= 1.0) ? bigger_side * (2.0 -
p->whratio) : bigger_side);
592 const float new_scale = 100.0 * new_vignette_h /
max;
602 const float new_scale = 100.0 * new_vignette_h /
max;
607 const float new_whratio = 1.0 / ratio;
614 const float new_vignette_fx = pzx * wd - vignette_x;
615 const float max = 0.5 * ((
p->whratio <= 1.0) ? bigger_side *
p->whratio : bigger_side);
616 const float delta_x =
MIN(2.0f *
max,
MAX(0.0, new_vignette_fx - vignette_w));
617 const float new_falloff = 100.0 * delta_x /
max;
622 const float new_vignette_fy = vignette_y - pzy * ht;
623 const float max = 0.5 * ((
p->whratio > 1.0) ? bigger_side * (2.0 -
p->whratio) : bigger_side);
624 const float delta_y =
MIN(2.0f *
max,
MAX(0.0, new_vignette_fy - vignette_h));
625 const float new_falloff = 100.0 * delta_y /
max;
656 if(which == 1)
return 1;
662 if(which == 1)
return 1;
675 const gboolean unbound = data->
unbound;
684 = { vignette_center.
x * roi_in->
scale - roi_in->
x, vignette_center.
y * roi_in->
scale - roi_in->
y };
691 xscale = 2.0 / (buf_in->
width * roi_out->
scale);
701 xscale = yscale / data->
whratio;
708 yscale = xscale / (2.0 - data->
whratio);
711 const float dscale = data->
scale / 100.0;
713 const float min_falloff = 100.0 /
MIN(buf_in->
width, buf_in->
height);
715 const float shape =
MAX(data->
shape, 0.001);
716 const float exp1 = 2.0 / shape;
717 const float exp2 = shape / 2.0;
729 dither = 1.0f / 65536;
738 for(
int j = 0; j < roi_out->
height; j++)
740 const size_t k = (size_t)
ch * roi_out->
width * j;
741 const float *in = (
const float *)ivoid +
k;
744 tea_state[0] = j * roi_out->
height;
749 = { fabsf(
i * xscale - roi_center_scaled.
x), fabsf(j * yscale - roi_center_scaled.
y) };
752 const float cplen = powf(powf(pv.
x, exp1) + powf(pv.
y, exp1), exp2);
758 weight = ((cplen - dscale) / fscale);
763 else if(dither == 0.0f)
772 dith = dither *
tpdf(tea_state[0]);
777 float col0 = in[0], col1 = in[1], col2 = in[2], col3 = in[3];
783 col0 = data->
brightness < 0 ? col0 * falloff + dith : col0 + falloff + dith;
784 col1 = data->
brightness < 0 ? col1 * falloff + dith : col1 + falloff + dith;
785 col2 = data->
brightness < 0 ? col2 * falloff + dith : col2 + falloff + dith;
787 col0 = unbound ? col0 :
CLIP(col0);
788 col1 = unbound ? col1 :
CLIP(col1);
789 col2 = unbound ? col2 :
CLIP(col2);
792 float mv = (col0 + col1 + col2) / 3.0f;
794 col0 = col0 - ((mv - col0) * wss);
795 col1 = col1 - ((mv - col1) * wss);
796 col2 = col2 - ((mv - col2) * wss);
798 col0 = unbound ? col0 :
CLIP(col0);
799 col1 = unbound ? col1 :
CLIP(col1);
800 col2 = unbound ? col2 :
CLIP(col2);
824 const int devid = pipe->
devid;
837 = { vignette_center.
x * roi_in->
scale - roi_in->
x, vignette_center.
y * roi_in->
scale - roi_in->
y };
844 xscale = 2.0 / (buf_in->
width * roi_out->
scale);
854 xscale = yscale / data->
whratio;
861 yscale = xscale / (2.0 - data->
whratio);
864 const float dscale = data->
scale / 100.0;
866 const float min_falloff = 100.0 /
MIN(buf_in->
width, buf_in->
height);
868 const float shape =
MAX(data->
shape, 0.001);
869 const float exp1 = 2.0 / shape;
870 const float exp2 = shape / 2.0;
882 dither = 1.0f / 65536;
889 float scale[2] = { xscale, yscale };
890 float roi_center_scaled_f[2] = { roi_center_scaled.
x, roi_center_scaled.
y };
891 float expt[2] = { exp1, exp2 };
894 const int unbound = data->
unbound;
912 if(err != CL_SUCCESS)
goto error;
925 const int program = 8;
947 gtk_widget_set_sensitive(GTK_WIDGET(
g->whratio), !
p->autoratio);
956 d->falloff_scale =
p->falloff_scale;
957 d->brightness =
p->brightness;
958 d->saturation =
p->saturation;
959 d->center =
p->center;
960 d->autoratio =
p->autoratio;
961 d->whratio =
p->whratio;
963 d->dithering =
p->dithering;
964 d->unbound =
p->unbound;
972 p.falloff_scale = 100.0f;
973 p.brightness = -1.0f;
1004 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->autoratio),
p->autoratio);
1005 gtk_widget_set_sensitive(GTK_WIDGET(
g->whratio), !
p->autoratio);
1017 gtk_box_pack_start(GTK_BOX(self->
widget),
1036 gtk_widget_set_tooltip_text(
g->scale, _(
"the radii scale of vignette for start of fall-off"));
1037 gtk_widget_set_tooltip_text(
g->falloff_scale, _(
"the radii scale of vignette for end of fall-off"));
1038 gtk_widget_set_tooltip_text(
g->brightness, _(
"strength of effect on brightness"));
1039 gtk_widget_set_tooltip_text(
g->saturation, _(
"strength of effect on saturation"));
1040 gtk_widget_set_tooltip_text(
g->center_x, _(
"horizontal offset of center of the effect"));
1041 gtk_widget_set_tooltip_text(
g->center_y, _(
"vertical offset of center of the effect"));
1042 gtk_widget_set_tooltip_text(
g->shape, _(
"shape factor\n0 produces a rectangle\n1 produces a circle or ellipse\n"
1043 "2 produces a diamond"));
1044 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->autoratio), _(
"enable to have the ratio automatically follow the image size"));
1045 gtk_widget_set_tooltip_text(
g->whratio, _(
"width-to-height ratio"));
1046 gtk_widget_set_tooltip_text(
g->dithering, _(
"add some level of random noise to prevent banding"));
static void error(char *msg)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
@ DEVELOP_BLEND_CS_RGB_DISPLAY
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
#define dt_control_queue_cursor(cursor)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
static int dt_get_thread_num()
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define __DT_CLONE_TARGETS__
#define __OMP_PARALLEL_FOR__(...)
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
#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)
void dt_dev_coordinates_image_abs_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
float dt_dev_get_overlay_scale(dt_develop_t *dev)
Get the overlay scale factor in GUI logical coordinates.
void dt_dev_coordinates_image_norm_to_preview_abs(dt_develop_t *dev, float *points, size_t num_points)
gboolean dt_dev_rescale_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit within given width/height, centered.
void dt_dev_coordinates_widget_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
Coordinate conversion helpers between widget, normalized image, and absolute image spaces.
static void dt_draw_set_color_overlay(cairo_t *cr, gboolean bright, double alpha)
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
#define DT_GUI_MOUSE_EFFECT_RADIUS
static GtkWidget * dt_ui_section_label_new(const gchar *str)
#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)
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
@ IOP_FLAGS_TILING_FULL_ROI
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
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)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
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)
struct _GtkWidget GtkWidget
const float uint32_t state[4]
int32_t num_openmp_threads
const struct dt_database_t * db
struct dt_control_t * control
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
struct dt_develop_t::@17 roi
GModule *dt_dev_operation_t op
dt_iop_global_data_t * data
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.
dt_iop_vector_2d_t center
GtkWidget * falloff_scale
dt_iop_dvector_2d_t center
gboolean invert_saturation
dt_iop_vector_2d_t center
dt_iop_vector_2d_t center
dt_iop_dither_t dithering
dt_iop_vector_2d_t center
static float tpdf(unsigned int urandom)
static unsigned int * get_tea_state(unsigned int *const states, int threadnum)
static void free_tea_states(unsigned int *states)
static unsigned int * alloc_tea_states(size_t numthreads)
static void encrypt_tea(unsigned int *arg)
static int get_grab(dt_iop_module_t *self, float pointerx, float pointery, float startx, float starty, float endx, float endy, float zoom_scale)
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)
__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 ivoid, void *const ovoid)
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)
Refresh GUI controls from current params and configuration.
void gui_init(struct dt_iop_module_t *self)
int button_pressed(struct dt_iop_module_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state)
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)
void gui_post_expose(struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
void init_presets(dt_iop_module_so_t *self)
struct dt_iop_fvector_2d_t dt_iop_vector_2d_t
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)
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)
int mouse_moved(struct dt_iop_module_t *self, double x, double y, double pressure, int which)
static void draw_overlay(cairo_t *cr, float x, float y, float fx, float fy, int grab, float zoom_scale)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)