53 if(group_entry) *group_entry = entry;
72 double pressure,
int which,
int type, uint32_t
state,
89 gboolean return_value =
FALSE;
144 for(GList *fpts = form->
points; fpts; fpts = g_list_next(fpts))
159 float **buffer,
int *
width,
int *
height,
int *posx,
int *posy)
162 const int wt = piece->
iwidth;
168 const int posx_ = *posx;
169 const int posy_ = *posy;
170 const int width_ = *
width;
171 const int height_ = *
height;
172 const float *
const src = *buffer;
174 for(
int yy = 0; yy <
MIN(posy_, ht); yy++)
176 float *
const row = buf + (size_t)yy * wt;
177 for(
int xx = 0; xx < wt; xx++)
row[xx] = 1.0f;
180 for(
int yy =
MAX(posy_, 0); yy <
MIN(ht, posy_ + height_); yy++)
182 float *
const row = buf + (size_t)yy * wt;
183 for(
int xx = 0; xx <
MIN(posx_, wt); xx++)
row[xx] = 1.0f;
184 const int xstart =
MAX(posx_, 0);
185 const int xend =
MIN(wt, posx_ + width_);
186 const float *
const src_row = src + (size_t)(yy - posy_) * width_;
187 for(
int xx = xstart; xx < xend; xx++)
188 row[xx] = 1.0f - src_row[xx - posx_];
189 for(
int xx =
MAX(posx_ + width_, 0); xx < wt; xx++)
row[xx] = 1.0f;
192 for(
int yy =
MAX(posy_ + height_, 0); yy < ht; yy++)
194 float *
const row = buf + (size_t)yy * wt;
195 for(
int xx = 0; xx < wt; xx++)
row[xx] = 1.0f;
212 float **buffer,
int *
width,
int *
height,
int *posx,
int *posy)
215 const guint nb = g_list_length(form->
points);
222 float **bufs = calloc(nb,
sizeof(
float *));
223 int *w = malloc(
sizeof(
int) * nb);
224 int *h = malloc(
sizeof(
int) * nb);
225 int *px = malloc(
sizeof(
int) * nb);
226 int *py = malloc(
sizeof(
int) * nb);
227 int *states = malloc(
sizeof(
int) * nb);
228 float *op = malloc(
sizeof(
float) * nb);
245 for(GList *fpts = form->
points; fpts; fpts = g_list_next(fpts))
251 if(
dt_masks_get_mask(module, pipe, piece, sel, &bufs[pos], &w[pos], &h[pos], &px[pos], &py[pos]) != 0)
259 if(
_inverse_mask(module, piece, sel, &bufs[pos], &w[pos], &h[pos], &px[pos], &py[pos]) != 0)
268 states[pos] = fpt->
state;
282 int l = INT_MAX,
r = INT_MIN,
t = INT_MAX, b = INT_MIN;
283 for(
int i = 0;
i < nb;
i++)
288 b =
MAX(b, py[
i] + h[
i]);
304 const int dst_w =
r - l;
305 const int dst_h = b -
t;
306 float *
const dst = *buffer;
307 for(
int i = 0;
i < nb;
i++)
312 const int ox = px[
i] - l;
313 const int oy = py[
i] -
t;
315 const float *
const src = bufs[
i];
319 for(
int y = 0; y < hi; y++)
321 float *
const dst_row = dst + (size_t)(oy + y) * dst_w + ox;
322 const float *
const src_row = src + (size_t)y * wi;
323 for(
int x = 0;
x < wi;
x++)
326 if(
v > dst_row[
x]) dst_row[
x] =
v;
332 const int x0 =
MAX(px[
i], l);
333 const int y0 =
MAX(py[
i],
t);
334 const int x1 =
MIN(px[
i] + wi,
r);
335 const int y1 =
MIN(py[
i] + hi, b);
336 if(x0 >= x1 || y0 >= y1)
338 memset(dst, 0, (
size_t)dst_w * dst_h *
sizeof(
float));
342 const int row_start = y0 -
t;
343 const int row_end = y1 -
t;
344 const int col_start = x0 - l;
345 const int col_end = x1 - l;
346 const int src_x_offset = x0 - px[
i];
347 const int src_y_offset =
t - py[
i];
349 for(
int y = 0; y < dst_h; y++)
351 float *
const dst_row = dst + (size_t)y * dst_w;
352 if(y < row_start || y >= row_end)
354 memset(dst_row, 0, (
size_t)dst_w *
sizeof(
float));
358 const int src_y = y + src_y_offset;
359 const float *
const src_row = src + (size_t)src_y * wi + src_x_offset;
360 float *
const dst_mid = dst_row + col_start;
361 const int mid_w = col_end - col_start;
362 for(
int x = 0;
x < mid_w;
x++)
364 const float b1 = dst_mid[
x];
365 const float b2 = src_row[
x];
366 if(b1 > 0.0f && b2 > 0.0f)
367 dst_mid[
x] = fminf(b1, b2 *
opacity);
372 if(col_start > 0) memset(dst_row, 0, (
size_t)col_start *
sizeof(
float));
373 if(col_end < dst_w) memset(dst_row + col_end, 0, (
size_t)(dst_w - col_end) *
sizeof(
float));
380 for(
int y = 0; y < hi; y++)
382 float *
const dst_row = dst + (size_t)(oy + y) * dst_w + ox;
383 const float *
const src_row = src + (size_t)y * wi;
384 for(
int x = 0;
x < wi;
x++)
386 const float b1 = dst_row[
x];
387 const float b2 = src_row[
x] *
opacity;
388 if(b1 > 0.0f && b2 > 0.0f) dst_row[
x] = b1 * (1.0f - b2);
395 for(
int y = 0; y < hi; y++)
397 float *
const dst_row = dst + (size_t)(oy + y) * dst_w + ox;
398 const float *
const src_row = src + (size_t)y * wi;
399 for(
int x = 0;
x < wi;
x++)
401 const float b1 = dst_row[
x];
402 const float b2 = src_row[
x] *
opacity;
403 if(b1 > 0.0f && b2 > 0.0f)
404 dst_row[
x] = fmaxf((1.0f - b1) * b2, b1 * (1.0f - b2));
406 dst_row[
x] = fmaxf(dst_row[
x], b2);
412 const int x0 =
MAX(px[
i], l);
413 const int y0 =
MAX(py[
i],
t);
414 const int x1 =
MIN(px[
i] + wi,
r);
415 const int y1 =
MIN(py[
i] + hi, b);
416 if(x0 >= x1 || y0 >= y1)
418 memset(dst, 0, (
size_t)dst_w * dst_h *
sizeof(
float));
422 const int row_start = y0 -
t;
423 const int row_end = y1 -
t;
424 const int col_start = x0 - l;
425 const int col_end = x1 - l;
426 const int src_x_offset = x0 - px[
i];
427 const int src_y_offset =
t - py[
i];
429 for(
int y = 0; y < dst_h; y++)
431 float *
const dst_row = dst + (size_t)y * dst_w;
432 if(y < row_start || y >= row_end)
434 memset(dst_row, 0, (
size_t)dst_w *
sizeof(
float));
438 const int src_y = y + src_y_offset;
439 const float *
const src_row = src + (size_t)src_y * wi + src_x_offset;
440 float *
const dst_mid = dst_row + col_start;
441 const int mid_w = col_end - col_start;
442 for(
int x = 0;
x < mid_w;
x++)
447 if(col_start > 0) memset(dst_row, 0, (
size_t)col_start *
sizeof(
float));
448 if(col_end < dst_w) memset(dst_row + col_end, 0, (
size_t)(dst_w - col_end) *
sizeof(
float));
469static void _combine_masks_union(
float *
const restrict dest,
float *
const restrict newmask,
const size_t npixels,
470 const float opacity,
const int inverted)
475 for(
int index = 0; index < npixels; index++)
477 const float mask =
opacity * (1.0f - newmask[index]);
478 dest[index] =
MAX(dest[index], mask);
484 for(
int index = 0; index < npixels; index++)
486 const float mask =
opacity * newmask[index];
487 dest[index] =
MAX(dest[index], mask);
493 const float opacity,
const int inverted)
498 for(
int index = 0; index < npixels; index++)
500 const float mask =
opacity * (1.0f - newmask[index]);
501 dest[index] =
MIN(
MAX(dest[index], 0.0f),
MAX(mask, 0.0f));
507 for(
int index = 0; index < npixels; index++)
509 const float mask =
opacity * newmask[index];
510 dest[index] =
MIN(
MAX(dest[index], 0.0f),
MAX(mask, 0.0f));
519 return (val1 > 0.0f) && (val2 > 0.0f);
523 const float opacity,
const int inverted)
528 for(
int index = 0; index < npixels; index++)
530 const float mask =
opacity * (1.0f - newmask[index]);
531 dest[index] *= (1.0f - mask *
both_positive(dest[index],mask));
538 for(
int index = 0; index < npixels; index++)
540 const float mask =
opacity * newmask[index];
541 dest[index] *= (1.0f - mask *
both_positive(dest[index],mask));
547 const float opacity,
const int inverted)
553 for(
int index = 0; index < npixels; index++)
555 const float mask =
opacity * (1.0f - newmask[index]);
557 const float neg = (1.0f - pos);
558 const float b1 = dest[index];
559 dest[index] = pos *
MAX((1.0f - b1) * mask, b1 * (1.0f - mask)) + neg *
MAX(b1, mask);
565 for(
int index = 0; index < npixels; index++)
567 const float mask =
opacity * newmask[index];
569 const float neg = (1.0f - pos);
570 const float b1 = dest[index];
571 dest[index] = pos *
MAX((1.0f - b1) * mask, b1 * (1.0f - mask)) + neg *
MAX(b1, mask);
579 float *
const restrict buffer)
596 for(GList *fpts = form->
points; fpts; fpts = g_list_next(fpts))
604 memset(bufs, 0, npixels*
sizeof(
float));
609 const int state = (
i == 0) ? no_op_state : fpt->
state;
639 for(
int index = 0; index < npixels; index++)
641 buffer[index] = op * (inverted ? (1.0f - bufs[index]) : bufs[index]);
658 memset(buffer, 0, npixels *
sizeof(
float));
680 for(GList *pts = base->
points; pts; pts = g_list_next(pts))
702 for(
const GList *l = form->
points; l; l = g_list_next(l))
709 float child_center[2] = { 0.0f, 0.0f };
710 float child_area = 0.0f;
713 const float w = (child_area > 0.0f) ? child_area : 1.0f;
714 sum_x += child_center[0] * w;
715 sum_y += child_center[1] * w;
730 center[0] = sum_x / (float)count;
731 center[1] = sum_y / (float)count;
736 center[0] = sum_x / sum_w;
737 center[1] = sum_y / sum_w;
747 .sanitize_config = NULL,
748 .set_form_name = NULL,
749 .set_hint_message = NULL,
751 .initial_source_pos = NULL,
752 .get_distance = NULL,
754 .get_points_border = NULL,
758 .get_source_area = NULL,
760 .get_interaction_value = NULL,
761 .set_interaction_value = NULL,
762 .update_hover = NULL,
void cleanup(dt_imageio_module_format_t *self)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
#define __OMP_DECLARE_SIMD__(...)
#define dt_pixelpipe_cache_free_align(mem)
#define __OMP_PARALLEL_FOR__(...)
static double dt_get_wtime(void)
#define __OMP_FOR_SIMD__(...)
#define __OMP_PARALLEL_FOR_SIMD__(...)
#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 guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
static int _group_events_mouse_moved(struct dt_iop_module_t *module, double x, double y, double pressure, int which, dt_masks_form_t *form, int unused1, dt_masks_form_gui_t *gui, int unused2)
static dt_masks_form_t * _group_get_child_at(dt_masks_form_t *form, const int group_index, dt_masks_form_group_t **group_entry)
int dt_masks_group_render_roi(dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, const dt_iop_roi_t *roi, float *buffer)
static int _group_events_key_pressed(struct dt_iop_module_t *module, GdkEventKey *event, dt_masks_form_t *form, int parentid, dt_masks_form_gui_t *gui, int index)
static int _group_events_button_released(struct dt_iop_module_t *module, double x, double y, int which, uint32_t state, dt_masks_form_t *form, int unused1, dt_masks_form_gui_t *gui, int unused2)
static void _group_duplicate_points(dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)
static gboolean _group_get_gravity_center(const dt_masks_form_t *form, float center[2], float *area)
const dt_masks_functions_t dt_masks_functions_group
static void _group_events_post_expose_draw(cairo_t *cr, float zoom_scale, dt_masks_form_t *form, dt_masks_form_gui_t *gui, int pos)
static void _combine_masks_union(float *const restrict dest, float *const restrict newmask, const size_t npixels, const float opacity, const int inverted)
static void _combine_masks_exclusion(float *const restrict dest, float *const restrict newmask, const size_t npixels, const float opacity, const int inverted)
static gboolean _group_events_button_pressed(struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state, dt_masks_form_t *form, int unused1, dt_masks_form_gui_t *gui, int unused2)
static int _group_get_mask_roi(const dt_iop_module_t *const restrict module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const restrict piece, dt_masks_form_t *const form, const dt_iop_roi_t *const roi, float *const restrict buffer)
static void _combine_masks_difference(float *const restrict dest, float *const restrict newmask, const size_t npixels, const float opacity, const int inverted)
static int _inverse_mask(const dt_iop_module_t *const module, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, float **buffer, int *width, int *height, int *posx, int *posy)
static int both_positive(const float val1, const float val2)
static dt_masks_form_t * _group_get_selected_child(dt_masks_form_t *form, dt_masks_form_gui_t *gui, dt_masks_form_group_t **group_entry)
static int _group_get_mask(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, float **buffer, int *width, int *height, int *posx, int *posy)
void dt_group_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_t *form, dt_masks_form_gui_t *gui)
static void _combine_masks_intersect(float *const restrict dest, float *const restrict newmask, const size_t npixels, const float opacity, const int inverted)
static int _group_events_mouse_scrolled(struct dt_iop_module_t *module, double x, double y, int up, const int flow, uint32_t state, dt_masks_form_t *form, int unused1, dt_masks_form_gui_t *gui, int unused, dt_masks_interaction_t interaction)
gboolean dt_masks_gui_remove(struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui, const int parentid)
remove a mask shape or node form from the GUI. This function is used with a popupmenu "Delete" action...
@ DT_MASKS_STATE_DIFFERENCE
@ DT_MASKS_STATE_INTERSECTION
@ DT_MASKS_STATE_IS_COMBINE_OP
@ DT_MASKS_STATE_EXCLUSION
gboolean dt_masks_form_exit_creation(dt_iop_module_t *module, dt_masks_form_gui_t *gui)
dt_masks_form_t * dt_masks_get_from_id(dt_develop_t *dev, int id)
static int dt_masks_get_mask(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, float **buffer, int *width, int *height, int *posx, int *posy)
static int dt_masks_get_mask_roi(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const form, const dt_iop_roi_t *roi, float *buffer)
int dt_masks_form_duplicate(dt_develop_t *dev, int formid)
gboolean dt_masks_form_get_gravity_center(const struct dt_masks_form_t *form, float center[2], float *area)
const float uint32_t state[4]
struct dt_develop_t * develop
struct dt_develop_t * dev
Region of interest passed through the pixelpipe.
void(* post_expose)(cairo_t *cr, float zoom_scale, struct dt_masks_form_gui_t *gui, int index, int num_points)