Blame gegl/gegl-utils.c

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