[gegl] operation: add GeglOperationAreaFilter::get_abyss_policy() vfunc
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operation: add GeglOperationAreaFilter::get_abyss_policy() vfunc
- Date: Thu, 26 Apr 2018 18:29:38 +0000 (UTC)
commit ad9790d6d28b0ac6ccf481260aca27f4dded74fe
Author: Ell <ell_se yahoo com>
Date: Thu Apr 26 14:09:40 2018 -0400
operation: add GeglOperationAreaFilter::get_abyss_policy() vfunc
Add a GeglOperationAreaFilter::get_abyss_policy() virtual function,
which subclasses can override to specify which abyss policy is used
when reading the input buffer.
Modify get_required_for_output() and get_invalidated_by_change() to
take the abyss policy into account. In particular, when using the
LOOP abyss policy, wrap the rectangle around the input bounds, so
that the correct input area is processed, and the correct output
area is invalidated.
gegl/operation/gegl-operation-area-filter.c | 89 +++++++++++++++++++++++++--
gegl/operation/gegl-operation-area-filter.h | 11 +++-
2 files changed, 92 insertions(+), 8 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-area-filter.c b/gegl/operation/gegl-operation-area-filter.c
index 4a9733b..dc9c33e 100644
--- a/gegl/operation/gegl-operation-area-filter.c
+++ b/gegl/operation/gegl-operation-area-filter.c
@@ -113,6 +113,40 @@ get_required_for_output (GeglOperation *operation,
rect.y -= area->top;
rect.width += area->left + area->right;
rect.height += area->top + area->bottom;
+
+ /* wrap rectangle around the input bounds, if using a LOOP abyss policy */
+ if (GEGL_OPERATION_AREA_FILTER_GET_CLASS (area)->get_abyss_policy &&
+ GEGL_OPERATION_AREA_FILTER_GET_CLASS (area)->get_abyss_policy (
+ operation, input_pad) == GEGL_ABYSS_LOOP)
+ {
+ GeglRectangle *in_rect;
+
+ in_rect = gegl_operation_source_get_bounding_box (operation,"input");
+ g_return_val_if_fail (in_rect != NULL, rect);
+
+ rect.x = in_rect->x + (rect.x - in_rect->x) % in_rect->width;
+ rect.y = in_rect->y + (rect.y - in_rect->y) % in_rect->height;
+ rect.width = rect.width;
+ rect.height = rect.height;
+
+ if (rect.x < in_rect->x)
+ rect.x += in_rect->width;
+
+ if (rect.y < in_rect->y)
+ rect.y += in_rect->height;
+
+ if (rect.x + rect.width > in_rect->x + in_rect->width)
+ {
+ rect.x = in_rect->x;
+ rect.width = in_rect->width;
+ }
+
+ if (rect.y + rect.height > in_rect->y + in_rect->height)
+ {
+ rect.y = in_rect->y;
+ rect.height = in_rect->height;
+ }
+ }
}
return rect;
@@ -123,13 +157,56 @@ get_invalidated_by_change (GeglOperation *operation,
const gchar *input_pad,
const GeglRectangle *input_region)
{
- GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
- GeglRectangle retval;
+ GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
+ GeglRectangle retval = *input_region;
+
+ /* wrap rectangle around the input bounds, if using a LOOP abyss policy */
+ if (GEGL_OPERATION_AREA_FILTER_GET_CLASS (area)->get_abyss_policy &&
+ GEGL_OPERATION_AREA_FILTER_GET_CLASS (area)->get_abyss_policy (
+ operation, input_pad) == GEGL_ABYSS_LOOP)
+ {
+ GeglRectangle *in_rect;
+
+ in_rect = gegl_operation_source_get_bounding_box (operation,"input");
+
+ if (in_rect)
+ {
+ if (input_region->x -
+ in_rect->x <
+ area->left + area->right)
+ {
+ retval.width = in_rect->width - (retval.x - in_rect->x);
+ }
+
+ if ((in_rect->x + in_rect->width) -
+ (input_region->x + input_region->width) <
+ area->right + area->left)
+ {
+ retval.width += retval.x - in_rect->x;
+ retval.x = in_rect->x;
+ }
+
+ if (input_region->y -
+ in_rect->y <
+ area->top + area->bottom)
+ {
+ retval.height = in_rect->height - (retval.y - in_rect->y);
+ }
+
+ if ((in_rect->y + in_rect->height) -
+ (input_region->y + input_region->height) <
+ area->bottom + area->top)
+ {
+ retval.height += retval.y - in_rect->y;
+ retval.y = in_rect->y;
+ }
+ }
+ }
- retval.x = input_region->x - area->right;
- retval.y = input_region->y - area->bottom;
- retval.width = input_region->width + area->right + area->left;
- retval.height = input_region->height + area->bottom + area->top;
+ retval.x -= area->right;
+ retval.y -= area->bottom;
+ retval.width += area->right + area->left;
+ retval.height += area->bottom + area->top;
return retval;
}
diff --git a/gegl/operation/gegl-operation-area-filter.h b/gegl/operation/gegl-operation-area-filter.h
index 789732d..38348f9 100644
--- a/gegl/operation/gegl-operation-area-filter.h
+++ b/gegl/operation/gegl-operation-area-filter.h
@@ -50,8 +50,15 @@ struct _GeglOperationAreaFilter
typedef struct _GeglOperationAreaFilterClass GeglOperationAreaFilterClass;
struct _GeglOperationAreaFilterClass
{
- GeglOperationFilterClass parent_class;
- gpointer pad[4];
+ GeglOperationFilterClass parent_class;
+
+ /* returns the abyss policy used when reading the input. if not overridden,
+ * GEGL_ABYSS_NONE is assumed.
+ */
+ GeglAbyssPolicy (* get_abyss_policy) (GeglOperation *operation,
+ const gchar *input_pad);
+
+ gpointer pad[3];
};
GType gegl_operation_area_filter_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]