Blame gegl/buffer/gegl-sampler.c

Packit bc1512
/* This file is part of GEGL
Packit bc1512
 *
Packit bc1512
 * GEGL is free software; you can redistribute it and/or modify it
Packit bc1512
 * under the terms of the GNU Lesser General Public License as
Packit bc1512
 * published by the Free Software Foundation; either version 3 of the
Packit bc1512
 * License, or (at your option) any later version.
Packit bc1512
 *
Packit bc1512
 * GEGL is distributed in the hope that it will be useful, but WITHOUT
Packit bc1512
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit bc1512
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
Packit bc1512
 * Public License for more details.
Packit bc1512
 *
Packit bc1512
 * You should have received a copy of the GNU Lesser General Public
Packit bc1512
 * License along with GEGL; if not, see
Packit bc1512
 * <http://www.gnu.org/licenses/>.
Packit bc1512
 *
Packit bc1512
 * 2007 © Øyvind Kolås
Packit bc1512
 * 2009 © Nicolas Robidoux
Packit bc1512
 * 2011 © Adam Turcotte
Packit bc1512
 */
Packit bc1512
#include "config.h"
Packit bc1512
Packit bc1512
#include <glib-object.h>
Packit bc1512
#include <string.h>
Packit bc1512
#include <math.h>
Packit bc1512
Packit bc1512
#include "gegl.h"
Packit bc1512
#include "gegl-types-internal.h"
Packit bc1512
#include "gegl-buffer.h"
Packit bc1512
#include "gegl-utils.h"
Packit bc1512
#include "gegl-buffer-private.h"
Packit bc1512
Packit bc1512
#include "gegl-sampler-nearest.h"
Packit bc1512
#include "gegl-sampler-linear.h"
Packit bc1512
#include "gegl-sampler-cubic.h"
Packit bc1512
#include "gegl-sampler-lohalo.h"
Packit bc1512
Packit bc1512
enum
Packit bc1512
{
Packit bc1512
  PROP_0,
Packit bc1512
  PROP_BUFFER,
Packit bc1512
  PROP_FORMAT,
Packit bc1512
  PROP_CONTEXT_RECT,
Packit bc1512
  PROP_LAST
Packit bc1512
};
Packit bc1512
Packit bc1512
static void gegl_sampler_class_init (GeglSamplerClass *klass);
Packit bc1512
Packit bc1512
static void gegl_sampler_init (GeglSampler *self);
Packit bc1512
Packit bc1512
static void finalize (GObject *gobject);
Packit bc1512
Packit bc1512
static void dispose (GObject *gobject);
Packit bc1512
Packit bc1512
static void get_property (GObject    *gobject,
Packit bc1512
                          guint       property_id,
Packit bc1512
                          GValue     *value,
Packit bc1512
                          GParamSpec *pspec);
Packit bc1512
Packit bc1512
static void set_property (      GObject      *gobject,
Packit bc1512
                                guint         property_id,
Packit bc1512
                          const GValue *value,
Packit bc1512
                                GParamSpec   *pspec);
Packit bc1512
Packit bc1512
static void set_buffer (GeglSampler  *self,
Packit bc1512
                        GeglBuffer   *buffer);
Packit bc1512
Packit bc1512
G_DEFINE_TYPE (GeglSampler, gegl_sampler, G_TYPE_OBJECT)
Packit bc1512
Packit bc1512
static void
Packit bc1512
gegl_sampler_class_init (GeglSamplerClass *klass)
Packit bc1512
{
Packit bc1512
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit bc1512
Packit bc1512
  object_class->finalize = finalize;
Packit bc1512
  object_class->dispose = dispose;
Packit bc1512
Packit bc1512
  klass->prepare = NULL;
Packit bc1512
  klass->get     = NULL;
Packit bc1512
  klass->set_buffer   = set_buffer;
Packit bc1512
Packit bc1512
  object_class->set_property = set_property;
Packit bc1512
  object_class->get_property = get_property;
Packit bc1512
Packit bc1512
  g_object_class_install_property (
Packit bc1512
                 object_class,
Packit bc1512
                 PROP_FORMAT,
Packit bc1512
                 g_param_spec_pointer ("format",
Packit bc1512
                                       "format",
Packit bc1512
                                       "babl format",
Packit bc1512
                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
Packit bc1512
Packit bc1512
  g_object_class_install_property (
Packit bc1512
                   object_class,
Packit bc1512
                   PROP_BUFFER,
Packit bc1512
                   g_param_spec_object ("buffer",
Packit bc1512
                                        "Buffer",
Packit bc1512
                                        "Input pad, for image buffer input.",
Packit bc1512
                                        GEGL_TYPE_BUFFER,
Packit bc1512
                                        G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
gegl_sampler_init (GeglSampler *self)
Packit bc1512
{
Packit bc1512
  int i;
Packit bc1512
  self->buffer = NULL;
Packit bc1512
  for (i=0; i
Packit bc1512
    GeglRectangle context_rect = {0,0,1,1};
Packit bc1512
    GeglRectangle sampler_rectangle = {0,0,0,0};
Packit bc1512
    self->sampler_buffer[i] = NULL;
Packit bc1512
    self->context_rect[i] = context_rect;
Packit bc1512
    self->sampler_rectangle[i] = sampler_rectangle;
Packit bc1512
  }
Packit bc1512
}
Packit bc1512
Packit bc1512
void
Packit bc1512
gegl_sampler_get (GeglSampler   *self,
Packit bc1512
                  gdouble        x,
Packit bc1512
                  gdouble        y,
Packit bc1512
                  GeglMatrix2   *scale,
Packit bc1512
                  void          *output,
Packit bc1512
                  GeglAbyssPolicy repeat_mode)
Packit bc1512
{
Packit bc1512
  self->get (self, x, y, scale, output);
Packit bc1512
}
Packit bc1512
Packit bc1512
void
Packit bc1512
gegl_sampler_prepare (GeglSampler *self)
Packit bc1512
{
Packit bc1512
  GeglSamplerClass *klass;
Packit bc1512
Packit bc1512
  g_return_if_fail (GEGL_IS_SAMPLER (self));
Packit bc1512
Packit bc1512
  klass = GEGL_SAMPLER_GET_CLASS (self);
Packit bc1512
Packit bc1512
  if (klass->prepare)
Packit bc1512
    klass->prepare (self);
Packit bc1512
Packit bc1512
Packit bc1512
  self->fish = babl_fish (self->interpolate_format, self->format);
Packit bc1512
Packit bc1512
  /*
Packit bc1512
   * This makes the cache rect invalid, in case the data in the buffer
Packit bc1512
   * has changed:
Packit bc1512
   */
Packit bc1512
  self->sampler_rectangle[0].width = 0;
Packit bc1512
  self->sampler_rectangle[0].height = 0;
Packit bc1512
Packit bc1512
#if 0
Packit bc1512
  if (self->cache_buffer) /* Force a regetting of the region, even
Packit bc1512
                             though the cached getter may be valid. */
Packit bc1512
    {
Packit bc1512
      g_free (self->cache_buffer);
Packit bc1512
      self->cache_buffer = NULL;
Packit bc1512
    }
Packit bc1512
#endif
Packit bc1512
  self->get = klass->get; /* cache the sampler in the instance */
Packit bc1512
}
Packit bc1512
Packit bc1512
void
Packit bc1512
gegl_sampler_set_buffer (GeglSampler *self, GeglBuffer *buffer)
Packit bc1512
{
Packit bc1512
  GeglSamplerClass *klass;
Packit bc1512
Packit bc1512
  g_return_if_fail (GEGL_IS_SAMPLER (self));
Packit bc1512
Packit bc1512
  klass = GEGL_SAMPLER_GET_CLASS (self);
Packit bc1512
Packit bc1512
  if (klass->set_buffer)
Packit bc1512
    klass->set_buffer (self, buffer);
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
finalize (GObject *gobject)
Packit bc1512
{
Packit bc1512
  int i;
Packit bc1512
  GeglSampler *sampler = GEGL_SAMPLER (gobject);
Packit bc1512
  for (i=0; i
Packit bc1512
    {
Packit bc1512
      if (sampler->sampler_buffer[i])
Packit bc1512
        {
Packit bc1512
          g_free (sampler->sampler_buffer[i]);
Packit bc1512
          sampler->sampler_buffer[i] = NULL;
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
  G_OBJECT_CLASS (gegl_sampler_parent_class)->finalize (gobject);
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
dispose (GObject *gobject)
Packit bc1512
{
Packit bc1512
  GeglSampler *sampler = GEGL_SAMPLER (gobject);
Packit bc1512
  if (sampler->buffer)
Packit bc1512
    {
Packit bc1512
      g_object_unref (sampler->buffer);
Packit bc1512
      sampler->buffer = NULL;
Packit bc1512
    }
Packit bc1512
  G_OBJECT_CLASS (gegl_sampler_parent_class)->dispose (gobject);
Packit bc1512
}
Packit bc1512
Packit bc1512
/*
Packit bc1512
 * Gets a pointer to the center pixel, within a buffer that has a
Packit bc1512
 * rowstride of 64px * 16bpp:
Packit bc1512
 */
Packit bc1512
gfloat *
Packit bc1512
gegl_sampler_get_ptr (GeglSampler *const sampler,
Packit bc1512
                      const gint         x,
Packit bc1512
                      const gint         y)
Packit bc1512
{
Packit bc1512
  guchar *buffer_ptr;
Packit bc1512
  gint    dx;
Packit bc1512
  gint    dy;
Packit bc1512
  gint    sof;
Packit bc1512
Packit bc1512
  const gint bpp =
Packit bc1512
    babl_format_get_bytes_per_pixel (sampler->interpolate_format);
Packit bc1512
Packit bc1512
  /*
Packit bc1512
   * maximum_width_and_height is the largest number of pixels which
Packit bc1512
   * can be be requested in the horizontal or vertical directions (64
Packit bc1512
   * in GEGL).
Packit bc1512
   */
Packit bc1512
  const gint maximum_width_and_height = 64;
Packit bc1512
  g_assert (sampler->context_rect[0].width  <= maximum_width_and_height);
Packit bc1512
  g_assert (sampler->context_rect[0].height <= maximum_width_and_height);
Packit bc1512
Packit bc1512
  if (( sampler->sampler_buffer[0] == NULL )
Packit bc1512
      ||
Packit bc1512
      ( x + sampler->context_rect[0].x < sampler->sampler_rectangle[0].x )
Packit bc1512
      ||
Packit bc1512
      ( y + sampler->context_rect[0].y < sampler->sampler_rectangle[0].y )
Packit bc1512
      ||
Packit bc1512
      ( x + sampler->context_rect[0].x + sampler->context_rect[0].width
Packit bc1512
        > sampler->sampler_rectangle[0].x + sampler->sampler_rectangle[0].width )
Packit bc1512
      ||
Packit bc1512
      ( y + sampler->context_rect[0].y + sampler->context_rect[0].height
Packit bc1512
        > sampler->sampler_rectangle[0].y + sampler->sampler_rectangle[0].height ))
Packit bc1512
    {
Packit bc1512
      /*
Packit bc1512
       * fetch_rectangle will become the value of
Packit bc1512
       * sampler->sampler_rectangle[0]:
Packit bc1512
       */
Packit bc1512
      GeglRectangle fetch_rectangle;
Packit bc1512
Packit bc1512
      /*
Packit bc1512
       * Override the fetch rectangle needed by the sampler, hoping
Packit bc1512
       * that the extra pixels are useful for subsequent requests,
Packit bc1512
       * assuming that it is more likely that further access is to the
Packit bc1512
       * right or down of our currently requested
Packit bc1512
       * position. Consequently, we move the top left corner of the
Packit bc1512
       * context_rect by about one fourth of the maximal distance we
Packit bc1512
       * can (one fourth of one half = one eight). Given that the
Packit bc1512
       * maximum width and height of the fetch_rectangle is 64, so
Packit bc1512
       * that half of it is 32, one fourth of the elbow room is at
Packit bc1512
       * most 8. If context_rect is large, the corner is not moved
Packit bc1512
       * much if at all, as should be.
Packit bc1512
       */
Packit bc1512
      fetch_rectangle.x =
Packit bc1512
        x + sampler->context_rect[0].x
Packit bc1512
        - ( maximum_width_and_height - sampler->context_rect[0].width  ) / 8;
Packit bc1512
      fetch_rectangle.y =
Packit bc1512
        y + sampler->context_rect[0].y
Packit bc1512
        - ( maximum_width_and_height - sampler->context_rect[0].height ) / 8;
Packit bc1512
Packit bc1512
      fetch_rectangle.width  = maximum_width_and_height;
Packit bc1512
      fetch_rectangle.height = maximum_width_and_height;
Packit bc1512
Packit bc1512
      if (sampler->sampler_buffer[0] == NULL)
Packit bc1512
        {
Packit bc1512
          /*
Packit bc1512
           * Always request the same amount of pixels:
Packit bc1512
           */
Packit bc1512
          sampler->sampler_buffer[0] =
Packit bc1512
            g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
Packit bc1512
                       * bpp);
Packit bc1512
        }
Packit bc1512
Packit bc1512
      gegl_buffer_get (sampler->buffer,
Packit bc1512
                       &fetch_rectangle,
Packit bc1512
                       1.0,
Packit bc1512
                       sampler->interpolate_format,
Packit bc1512
                       sampler->sampler_buffer[0],
Packit bc1512
                       GEGL_AUTO_ROWSTRIDE,
Packit bc1512
                       GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
      sampler->sampler_rectangle[0] = fetch_rectangle;
Packit bc1512
    }
Packit bc1512
Packit bc1512
  dx = x - sampler->sampler_rectangle[0].x;
Packit bc1512
  dy = y - sampler->sampler_rectangle[0].y;
Packit bc1512
  buffer_ptr = (guchar *)sampler->sampler_buffer[0];
Packit bc1512
  sof = ( dx + dy * sampler->sampler_rectangle[0].width ) * bpp;
Packit bc1512
Packit bc1512
  return (gfloat*)(buffer_ptr+sof);
Packit bc1512
}
Packit bc1512
Packit bc1512
gfloat *
Packit bc1512
gegl_sampler_get_from_buffer (GeglSampler *const sampler,
Packit bc1512
                              const gint         x,
Packit bc1512
                              const gint         y)
Packit bc1512
{
Packit bc1512
  guchar *buffer_ptr;
Packit bc1512
  gint    dx;
Packit bc1512
  gint    dy;
Packit bc1512
  gint    sof;
Packit bc1512
Packit bc1512
  const gint bpp =
Packit bc1512
    babl_format_get_bytes_per_pixel (sampler->interpolate_format);
Packit bc1512
Packit bc1512
  /*
Packit bc1512
   * maximum_width_and_height is the largest number of pixels which
Packit bc1512
   * can be be requested in the horizontal or vertical directions (64
Packit bc1512
   * in GEGL).
Packit bc1512
   */
Packit bc1512
  const gint maximum_width_and_height = 64;
Packit bc1512
  g_assert (sampler->context_rect[0].width  <= maximum_width_and_height);
Packit bc1512
  g_assert (sampler->context_rect[0].height <= maximum_width_and_height);
Packit bc1512
Packit bc1512
  if (( sampler->sampler_buffer[0] == NULL )
Packit bc1512
      ||
Packit bc1512
      ( x < sampler->sampler_rectangle[0].x )
Packit bc1512
      ||
Packit bc1512
      ( y < sampler->sampler_rectangle[0].y )
Packit bc1512
      ||
Packit bc1512
      ( x >= sampler->sampler_rectangle[0].x + sampler->sampler_rectangle[0].width )
Packit bc1512
      ||
Packit bc1512
      ( y >= sampler->sampler_rectangle[0].y + sampler->sampler_rectangle[0].height ))
Packit bc1512
    {
Packit bc1512
      /*
Packit bc1512
       * fetch_rectangle will become the value of
Packit bc1512
       * sampler->sampler_rectangle:
Packit bc1512
       */
Packit bc1512
      GeglRectangle fetch_rectangle;
Packit bc1512
Packit bc1512
      fetch_rectangle.x =
Packit bc1512
        x - ( maximum_width_and_height - sampler->context_rect[0].width  ) / 8;
Packit bc1512
      fetch_rectangle.y =
Packit bc1512
        y - ( maximum_width_and_height - sampler->context_rect[0].height ) / 8;
Packit bc1512
Packit bc1512
      fetch_rectangle.width  = maximum_width_and_height;
Packit bc1512
      fetch_rectangle.height = maximum_width_and_height;
Packit bc1512
Packit bc1512
      if (sampler->sampler_buffer[0] == NULL)
Packit bc1512
        {
Packit bc1512
          /*
Packit bc1512
           * Always request the same amount of pixels:
Packit bc1512
           */
Packit bc1512
          sampler->sampler_buffer[0] =
Packit bc1512
            g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
Packit bc1512
                       * bpp);
Packit bc1512
        }
Packit bc1512
Packit bc1512
      gegl_buffer_get (sampler->buffer,
Packit bc1512
                       &fetch_rectangle,
Packit bc1512
                       1.0,
Packit bc1512
                       sampler->interpolate_format,
Packit bc1512
                       sampler->sampler_buffer[0],
Packit bc1512
                       GEGL_AUTO_ROWSTRIDE,
Packit bc1512
                       GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
      sampler->sampler_rectangle[0] = fetch_rectangle;
Packit bc1512
    }
Packit bc1512
Packit bc1512
  dx = x - sampler->sampler_rectangle[0].x;
Packit bc1512
  dy = y - sampler->sampler_rectangle[0].y;
Packit bc1512
  buffer_ptr = (guchar *)sampler->sampler_buffer[0];
Packit bc1512
  sof = ( dx + dy * sampler->sampler_rectangle[0].width ) * bpp;
Packit bc1512
Packit bc1512
  return (gfloat*)(buffer_ptr+sof);
Packit bc1512
}
Packit bc1512
Packit bc1512
gfloat *
Packit bc1512
gegl_sampler_get_from_mipmap (GeglSampler *const sampler,
Packit bc1512
                              const gint         x,
Packit bc1512
                              const gint         y,
Packit bc1512
                              const gint         level)
Packit bc1512
{
Packit bc1512
  guchar *buffer_ptr;
Packit bc1512
  gint    dx;
Packit bc1512
  gint    dy;
Packit bc1512
  gint    sof;
Packit bc1512
Packit bc1512
  const gdouble scale = 1. / ( (gdouble) (1<
Packit bc1512
Packit bc1512
  const gint bpp =
Packit bc1512
    babl_format_get_bytes_per_pixel (sampler->interpolate_format);
Packit bc1512
Packit bc1512
  /*
Packit bc1512
   * maximum_width_and_height is the largest number of pixels which
Packit bc1512
   * can be be requested in the horizontal or vertical directions (64
Packit bc1512
   * in GEGL).
Packit bc1512
   */
Packit bc1512
  const gint maximum_width_and_height = 64;
Packit bc1512
  g_assert (sampler->context_rect[level].width  <= maximum_width_and_height);
Packit bc1512
  g_assert (sampler->context_rect[level].height <= maximum_width_and_height);
Packit bc1512
  g_assert (level >= 0 && level < GEGL_SAMPLER_MIPMAP_LEVELS);
Packit bc1512
Packit bc1512
  if (( sampler->sampler_buffer[level] == NULL )
Packit bc1512
      ||
Packit bc1512
      ( x + sampler->context_rect[level].x < sampler->sampler_rectangle[level].x )
Packit bc1512
      ||
Packit bc1512
      ( y + sampler->context_rect[level].y < sampler->sampler_rectangle[level].y )
Packit bc1512
      ||
Packit bc1512
      ( x + sampler->context_rect[level].x + sampler->context_rect[level].width
Packit bc1512
        > sampler->sampler_rectangle[level].x + sampler->sampler_rectangle[level].width )
Packit bc1512
      ||
Packit bc1512
      ( y + sampler->context_rect[level].y + sampler->context_rect[level].height
Packit bc1512
        > sampler->sampler_rectangle[level].y + sampler->sampler_rectangle[level].height ))
Packit bc1512
    {
Packit bc1512
      /*
Packit bc1512
       * fetch_rectangle will become the value of
Packit bc1512
       * sampler->sampler_rectangle[level]:
Packit bc1512
       */
Packit bc1512
      GeglRectangle fetch_rectangle;
Packit bc1512
Packit bc1512
      /*
Packit bc1512
       * Override the fetch rectangle needed by the sampler, hoping
Packit bc1512
       * that the extra pixels are useful for subsequent requests,
Packit bc1512
       * assuming that it is more likely that further access is to the
Packit bc1512
       * right or down of our currently requested
Packit bc1512
       * position. Consequently, we move the top left corner of the
Packit bc1512
       * context_rect by about one fourth of the maximal distance we
Packit bc1512
       * can (one fourth of one half = one eight). Given that the
Packit bc1512
       * maximum width and height of the fetch_rectangle is 64, so
Packit bc1512
       * that half of it is 32, one fourth of the elbow room is at
Packit bc1512
       * most 8. If context_rect is large, the corner is not moved
Packit bc1512
       * much if at all, as should be.
Packit bc1512
       */
Packit bc1512
      fetch_rectangle.x =
Packit bc1512
        x + sampler->context_rect[level].x
Packit bc1512
        - ( maximum_width_and_height - sampler->context_rect[level].width  ) / 8;
Packit bc1512
      fetch_rectangle.y =
Packit bc1512
        y + sampler->context_rect[level].y
Packit bc1512
        - ( maximum_width_and_height - sampler->context_rect[level].height ) / 8;
Packit bc1512
Packit bc1512
      fetch_rectangle.width  = maximum_width_and_height;
Packit bc1512
      fetch_rectangle.height = maximum_width_and_height;
Packit bc1512
Packit bc1512
      if (sampler->sampler_buffer[level] == NULL)
Packit bc1512
        {
Packit bc1512
          /*
Packit bc1512
           * Always request the same amount of pixels:
Packit bc1512
           */
Packit bc1512
          sampler->sampler_buffer[level] =
Packit bc1512
            g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
Packit bc1512
                       * bpp);
Packit bc1512
        }
Packit bc1512
Packit bc1512
      gegl_buffer_get (sampler->buffer,
Packit bc1512
                       &fetch_rectangle,
Packit bc1512
                       scale,
Packit bc1512
                       sampler->interpolate_format,
Packit bc1512
                       sampler->sampler_buffer[level],
Packit bc1512
                       GEGL_AUTO_ROWSTRIDE,
Packit bc1512
                       GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
      sampler->sampler_rectangle[level] = fetch_rectangle;
Packit bc1512
    }
Packit bc1512
Packit bc1512
  dx = x - sampler->sampler_rectangle[level].x;
Packit bc1512
  dy = y - sampler->sampler_rectangle[level].y;
Packit bc1512
  buffer_ptr = (guchar *)sampler->sampler_buffer[level];
Packit bc1512
  sof = ( dx + dy * sampler->sampler_rectangle[level].width ) * bpp;
Packit bc1512
Packit bc1512
  return (gfloat*)(buffer_ptr+sof);
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
get_property (GObject    *object,
Packit bc1512
              guint       property_id,
Packit bc1512
              GValue     *value,
Packit bc1512
              GParamSpec *pspec)
Packit bc1512
{
Packit bc1512
  GeglSampler *self = GEGL_SAMPLER (object);
Packit bc1512
Packit bc1512
  switch (property_id)
Packit bc1512
    {
Packit bc1512
      case PROP_BUFFER:
Packit bc1512
        g_value_set_object (value, self->buffer);
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      case PROP_FORMAT:
Packit bc1512
        g_value_set_pointer (value, (void*)self->format);
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      default:
Packit bc1512
        break;
Packit bc1512
    }
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
set_property (GObject      *object,
Packit bc1512
              guint         property_id,
Packit bc1512
              const GValue *value,
Packit bc1512
              GParamSpec   *pspec)
Packit bc1512
{
Packit bc1512
  GeglSampler *self = GEGL_SAMPLER (object);
Packit bc1512
Packit bc1512
  switch (property_id)
Packit bc1512
    {
Packit bc1512
      case PROP_BUFFER:
Packit bc1512
        self->buffer = GEGL_BUFFER (g_value_dup_object (value));
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      case PROP_FORMAT:
Packit bc1512
        self->format = g_value_get_pointer (value);
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      default:
Packit bc1512
        break;
Packit bc1512
    }
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
set_buffer (GeglSampler *self, GeglBuffer *buffer)
Packit bc1512
{
Packit bc1512
   if (self->buffer != buffer)
Packit bc1512
     {
Packit bc1512
       if (GEGL_IS_BUFFER(self->buffer))
Packit bc1512
         g_object_unref(self->buffer);
Packit bc1512
       if (GEGL_IS_BUFFER (buffer))
Packit bc1512
         self->buffer = gegl_buffer_dup (buffer);
Packit bc1512
       else
Packit bc1512
         self->buffer = NULL;
Packit bc1512
     }
Packit bc1512
}
Packit bc1512
Packit bc1512
GeglSamplerType
Packit bc1512
gegl_sampler_type_from_string (const gchar *string)
Packit bc1512
{
Packit bc1512
  if (g_str_equal (string, "nearest") ||
Packit bc1512
      g_str_equal (string, "none"))
Packit bc1512
    return GEGL_SAMPLER_NEAREST;
Packit bc1512
Packit bc1512
  if (g_str_equal (string, "linear") ||
Packit bc1512
      g_str_equal (string, "bilinear"))
Packit bc1512
    return GEGL_SAMPLER_LINEAR;
Packit bc1512
Packit bc1512
  if (g_str_equal (string, "cubic") ||
Packit bc1512
      g_str_equal (string, "bicubic"))
Packit bc1512
    return GEGL_SAMPLER_CUBIC;
Packit bc1512
Packit bc1512
  if (g_str_equal (string, "lohalo"))
Packit bc1512
    return GEGL_SAMPLER_LOHALO;
Packit bc1512
Packit bc1512
  return GEGL_SAMPLER_NEAREST;
Packit bc1512
}
Packit bc1512
Packit bc1512
GType
Packit bc1512
gegl_sampler_gtype_from_enum (GeglSamplerType sampler_type);
Packit bc1512
GType
Packit bc1512
gegl_sampler_gtype_from_enum (GeglSamplerType sampler_type)
Packit bc1512
{
Packit bc1512
  switch (sampler_type)
Packit bc1512
    {
Packit bc1512
      case GEGL_SAMPLER_NEAREST:
Packit bc1512
        return GEGL_TYPE_SAMPLER_NEAREST;
Packit bc1512
      case GEGL_SAMPLER_LINEAR:
Packit bc1512
        return GEGL_TYPE_SAMPLER_LINEAR;
Packit bc1512
      case GEGL_SAMPLER_CUBIC:
Packit bc1512
        return GEGL_TYPE_SAMPLER_CUBIC;
Packit bc1512
      case GEGL_SAMPLER_LOHALO:
Packit bc1512
        return GEGL_TYPE_SAMPLER_LOHALO;
Packit bc1512
      default:
Packit bc1512
        return GEGL_TYPE_SAMPLER_LINEAR;
Packit bc1512
    }
Packit bc1512
}
Packit bc1512
Packit bc1512
GeglSampler *
Packit bc1512
gegl_buffer_sampler_new (GeglBuffer       *buffer,
Packit bc1512
                         const Babl       *format,
Packit bc1512
                         GeglSamplerType   sampler_type)
Packit bc1512
{
Packit bc1512
  GeglSampler          *sampler;
Packit bc1512
  GType                 desired_type;
Packit bc1512
  if (format == NULL)
Packit bc1512
    format = babl_format ("RaGaBaA float");
Packit bc1512
  desired_type = gegl_sampler_gtype_from_enum (sampler_type);
Packit bc1512
  sampler = g_object_new (desired_type,
Packit bc1512
                          "buffer", buffer,
Packit bc1512
                          "format", format,
Packit bc1512
                          NULL);
Packit bc1512
  gegl_sampler_prepare (sampler);
Packit bc1512
  return sampler;
Packit bc1512
}
Packit bc1512
Packit bc1512
const GeglRectangle*
Packit bc1512
gegl_sampler_get_context_rect (GeglSampler *sampler)
Packit bc1512
{
Packit bc1512
  return &(sampler->context_rect[0]);
Packit bc1512
}