/* This file is part of GEGL * * GEGL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * GEGL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with GEGL; if not, see . * * Copyright 2003-2007 Calvin Williamson, Øyvind Kolås. */ #include "config.h" #include #include "gegl.h" #include "gegl-types-internal.h" #include "gegl-utils.h" #include "gegl-types-internal.h" inline gint _gegl_float_epsilon_zero (float value) { return value > -GEGL_FLOAT_EPSILON && value < GEGL_FLOAT_EPSILON; } gint _gegl_float_epsilon_equal (float v1, float v2) { register float diff = v1 - v2; return diff > -GEGL_FLOAT_EPSILON && diff < GEGL_FLOAT_EPSILON; } void gegl_rectangle_set (GeglRectangle *r, gint x, gint y, guint w, guint h) { r->x = x; r->y = y; r->width = w; r->height = h; } void gegl_rectangle_bounding_box (GeglRectangle *dest, const GeglRectangle *src1, const GeglRectangle *src2) { gboolean s1_has_area = src1->width && src1->height; gboolean s2_has_area = src2->width && src2->height; if (!s1_has_area && !s2_has_area) gegl_rectangle_set (dest, 0, 0, 0, 0); else if (!s1_has_area) gegl_rectangle_copy (dest, src2); else if (!s2_has_area) gegl_rectangle_copy (dest, src1); else { gint x1 = MIN (src1->x, src2->x); gint x2 = MAX (src1->x + src1->width, src2->x + src2->width); gint y1 = MIN (src1->y, src2->y); gint y2 = MAX (src1->y + src1->height, src2->y + src2->height); dest->x = x1; dest->y = y1; dest->width = x2 - x1; dest->height = y2 - y1; } } gboolean gegl_rectangle_intersect (GeglRectangle *dest, const GeglRectangle *src1, const GeglRectangle *src2) { gint x1, x2, y1, y2; x1 = MAX (src1->x, src2->x); x2 = MIN (src1->x + src1->width, src2->x + src2->width); if (x2 <= x1) { if (dest) gegl_rectangle_set (dest, 0, 0, 0, 0); return FALSE; } y1 = MAX (src1->y, src2->y); y2 = MIN (src1->y + src1->height, src2->y + src2->height); if (y2 <= y1) { if (dest) gegl_rectangle_set (dest, 0, 0, 0, 0); return FALSE; } if (dest) gegl_rectangle_set (dest, x1, y1, x2 - x1, y2 - y1); return TRUE; } void gegl_rectangle_copy (GeglRectangle *to, const GeglRectangle *from) { to->x = from->x; to->y = from->y; to->width = from->width; to->height = from->height; } gboolean gegl_rectangle_contains (const GeglRectangle *r, const GeglRectangle *s) { g_return_val_if_fail (r && s, FALSE); if (s->x >= r->x && s->y >= r->y && (s->x + s->width) <= (r->x + r->width) && (s->y + s->height) <= (r->y + r->height)) return TRUE; else return FALSE; } gboolean gegl_rectangle_equal (const GeglRectangle *r, const GeglRectangle *s) { g_return_val_if_fail (r && s, FALSE); if (r->x == s->x && r->y == s->y && r->width == s->width && r->height == s->height) return TRUE; else return FALSE; } gboolean gegl_rectangle_equal_coords (const GeglRectangle *r, gint x, gint y, gint w, gint h) { g_return_val_if_fail (r, FALSE); if (r->x == x && r->y == y && r->width == w && r->height == h) return TRUE; else return FALSE; } gboolean gegl_rectangle_is_empty (const GeglRectangle *r) { g_return_val_if_fail (r != NULL, FALSE); return r->width == 0 && r->height == 0; } static GeglRectangle * gegl_rectangle_dup (const GeglRectangle *rectangle) { GeglRectangle *result = g_new (GeglRectangle, 1); *result = *rectangle; return result; } GeglRectangle gegl_rectangle_infinite_plane (void) { GeglRectangle infinite_plane_rect = {G_MININT / 2, G_MININT / 2, G_MAXINT, G_MAXINT}; return infinite_plane_rect; } gboolean gegl_rectangle_is_infinite_plane (const GeglRectangle *rectangle) { return (rectangle->x == G_MININT / 2 && rectangle->y == G_MININT / 2 && rectangle->width == G_MAXINT && rectangle->height == G_MAXINT); } void gegl_rectangle_dump (const GeglRectangle *rectangle) { g_print ("%d, %d, %d×%d\n", rectangle->x, rectangle->y, rectangle->width, rectangle->height); } GType gegl_rectangle_get_type (void) { static GType our_type = 0; if (our_type == 0) our_type = g_boxed_type_register_static (g_intern_static_string ("GeglRectangle"), (GBoxedCopyFunc) gegl_rectangle_dup, (GBoxedFreeFunc) g_free); return our_type; } #define GEGL_ALIGN 16 gpointer gegl_malloc (gsize size); /* utility call that makes sure allocations are 16 byte aligned. * making RGBA float buffers have aligned access for pixels. */ gpointer gegl_malloc (gsize size) { gchar *mem; gchar *ret; gint offset; mem = g_malloc (size + GEGL_ALIGN + sizeof(gpointer)); offset = GEGL_ALIGN - (GPOINTER_TO_UINT(mem) + sizeof(gpointer)) % GEGL_ALIGN; ret = (gpointer)(mem + sizeof(gpointer) + offset); /* store the real malloc one pointer in front of this malloc */ *(gpointer*)(ret-sizeof(gpointer))=mem; return (gpointer) ret; } void gegl_free (gpointer buf); void gegl_free (gpointer buf) { g_assert (buf); g_free (*((gpointer*)buf -1)); }