int main(int argc, char *argv[]) { GeglRectangle expected_infinite_plane = gegl_rectangle_infinite_plane (); GeglRectangle infinite_plane = { INFINITE_PLANE }; int result = SUCCESS; int i = 0; /* Make sure our representation of an infinite plane GeglRectangle * is correct */ if (! gegl_rectangle_equal (&infinite_plane, &expected_infinite_plane)) { result = FAILURE; g_printerr("This test case and GEGL does not represent an infinite plane\n" "GeglRectangle in the same way, update this test case. Aborting.\n"); goto abort; } for (i = 0; i < G_N_ELEMENTS (tests); i++) { GeglRectangle result_rect; gboolean return_value; /* gegl_rectangle_bounding_box() */ gegl_rectangle_bounding_box (&result_rect, &tests[i].rect1, &tests[i].rect2); if (! gegl_rectangle_equal (&result_rect, &tests[i].bounding_box_result)) { result = FAILURE; g_printerr("The gegl_rectangle_bounding_box() test #%d failed. Aborting.\n", i + 1); goto abort; } /* gegl_rectangle_intersect() */ return_value = gegl_rectangle_intersect (&result_rect, &tests[i].rect1, &tests[i].rect2); if (! gegl_rectangle_equal (&result_rect, &tests[i].intersect_result) || return_value != tests[i].intersect_return_value) { result = FAILURE; g_printerr("The gegl_rectangle_intersect() test #%d failed. Aborting.\n", i + 1); goto abort; } /* gegl_rectangle_contains() */ return_value = gegl_rectangle_contains (&tests[i].rect1, &tests[i].rect2); if (return_value != tests[i].contains_return_value) { result = FAILURE; g_printerr("The gegl_rectangle_contains() test #%d failed. Aborting.\n", i + 1); goto abort; } } abort: return result; }
gboolean gegl_can_do_inplace_processing (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result) { if (!input) return FALSE; if (gegl_object_get_has_forked (G_OBJECT (input))) return FALSE; if (gegl_buffer_get_format (input) == gegl_operation_get_format (operation, "output") && gegl_rectangle_contains (gegl_buffer_get_extent (input), result)) return TRUE; return FALSE; }
static gboolean needs_indirect_read (GeglBufferIterator *iter, int index) { GeglBufferIteratorPriv *priv = iter->priv; SubIterState *sub = &priv->sub_iter[index]; if (sub->access_mode & GEGL_ITERATOR_INCOMPATIBLE) return TRUE; /* Needs abyss generation */ if (!gegl_rectangle_contains (&sub->buffer->abyss, &iter->roi[index])) return TRUE; return FALSE; }
static gboolean gimp_channel_combine_start (GimpChannel *mask, GimpChannelOps op, const GeglRectangle *rect, gboolean full_extent, gboolean full_value, GimpChannelCombineData *data) { GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); GeglRectangle extent; gboolean intersects; extent.x = 0; extent.y = 0; extent.width = gimp_item_get_width (GIMP_ITEM (mask)); extent.height = gimp_item_get_height (GIMP_ITEM (mask)); intersects = gegl_rectangle_intersect (&data->rect, rect, &extent); data->bounds_known = mask->bounds_known; data->empty = mask->empty; data->bounds.x = mask->x1; data->bounds.y = mask->y1; data->bounds.width = mask->x2 - mask->x1; data->bounds.height = mask->y2 - mask->y1; gegl_buffer_freeze_changed (buffer); /* Determine new boundary */ switch (op) { case GIMP_CHANNEL_OP_REPLACE: gimp_channel_combine_clear (mask, NULL); if (! intersects) { data->bounds_known = TRUE; data->empty = TRUE; return FALSE; } data->bounds_known = FALSE; if (full_extent) { data->bounds_known = TRUE; data->empty = FALSE; data->bounds = data->rect; } break; case GIMP_CHANNEL_OP_ADD: if (! intersects) return FALSE; data->bounds_known = FALSE; if (full_extent && (mask->bounds_known || gegl_rectangle_equal (&data->rect, &extent))) { data->bounds_known = TRUE; data->empty = FALSE; if (mask->bounds_known && ! mask->empty) { gegl_rectangle_bounding_box (&data->bounds, &data->bounds, &data->rect); } else { data->bounds = data->rect; } } break; case GIMP_CHANNEL_OP_SUBTRACT: if (intersects && mask->bounds_known) { if (mask->empty) { intersects = FALSE; } else { intersects = gegl_rectangle_intersect (&data->rect, &data->rect, &data->bounds); } } if (! intersects) return FALSE; if (full_value && gegl_rectangle_contains (&data->rect, mask->bounds_known ? &data->bounds : &extent)) { gimp_channel_combine_clear (mask, NULL); data->bounds_known = TRUE; data->empty = TRUE; return FALSE; } data->bounds_known = FALSE; gegl_buffer_set_abyss (buffer, &data->rect); break; case GIMP_CHANNEL_OP_INTERSECT: if (intersects && mask->bounds_known) { if (mask->empty) { intersects = FALSE; } else { intersects = gegl_rectangle_intersect (&data->rect, &data->rect, &data->bounds); } } if (! intersects) { gimp_channel_combine_clear (mask, NULL); data->bounds_known = TRUE; data->empty = TRUE; return FALSE; } if (full_value && mask->bounds_known && gegl_rectangle_contains (&data->rect, &data->bounds)) { return FALSE; } data->bounds_known = FALSE; gimp_channel_combine_clear_complement (mask, &data->rect); gegl_buffer_set_abyss (buffer, &data->rect); break; } return TRUE; }
GeglBuffer * gegl_operation_context_get_target (GeglOperationContext *context, const gchar *padname) { GeglBuffer *output; const GeglRectangle *result; const Babl *format; GeglNode *node; GeglOperation *operation; #if 0 g_return_val_if_fail (GEGL_IS_OPERATION_CONTEXT (context), NULL); #endif operation = context->operation; node = operation->node; /* <ick */ format = gegl_operation_get_format (operation, padname); if (format == NULL) { g_warning ("no format for %s presuming RGBA float\n", gegl_node_get_debug_name (node)); format = babl_format ("RGBA float"); } g_assert (format != NULL); g_assert (!strcmp (padname, "output")); result = &context->result_rect; if (result->width == 0 || result->height == 0) { output = g_object_ref (emptybuf()); } else if (node->dont_cache == FALSE && ! GEGL_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation))->no_cache) { GeglBuffer *cache; cache = GEGL_BUFFER (gegl_node_get_cache (node)); /* Only use the cache if the result is within the cache * extent. This is certainly not optimal. My gut feeling is that * the current caching mechanism needs to be redesigned */ if (gegl_rectangle_contains (gegl_buffer_get_extent (cache), result)) { output = g_object_ref (cache); } else { output = gegl_buffer_new_ram (result, format); } } else { output = gegl_buffer_new_ram (result, format); } gegl_operation_context_take_object (context, padname, G_OBJECT (output)); return output; }