gegl r2442 - in trunk: . gegl/buffer operations/affine



Author: ok
Date: Sat Jun 14 13:25:17 2008
New Revision: 2442
URL: http://svn.gnome.org/viewvc/gegl?rev=2442&view=rev

Log:
Applied patch from Bug #360888 - Adapt cubic and lanczos samplers for
new framework.
The patch isn't closed yet, but the code for nearest and linear is
stable now and the rest of the code delta is quite large. The patch
has been adapted to not introduce new API and the cubic and lanczos
filters are disabled due to artifacts.
* gegl/buffer/gegl-buffer-access.c:
* gegl/buffer/gegl-buffer-types.h:
* gegl/buffer/gegl-buffer.c:
* gegl/buffer/gegl-buffer.h:
* gegl/buffer/gegl-sampler-cubic.c:
* gegl/buffer/gegl-sampler-lanczos.c:
* gegl/buffer/gegl-sampler-linear.c:
* gegl/buffer/gegl-sampler-nearest.c:
* gegl/buffer/gegl-sampler.c:
* gegl/buffer/gegl-sampler.h:
* operations/affine/affine.c:
* operations/affine/affine.h:


Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/gegl-buffer-access.c
   trunk/gegl/buffer/gegl-buffer-types.h
   trunk/gegl/buffer/gegl-buffer.c
   trunk/gegl/buffer/gegl-buffer.h
   trunk/gegl/buffer/gegl-sampler-cubic.c
   trunk/gegl/buffer/gegl-sampler-lanczos.c
   trunk/gegl/buffer/gegl-sampler-linear.c
   trunk/gegl/buffer/gegl-sampler-nearest.c
   trunk/gegl/buffer/gegl-sampler.c
   trunk/gegl/buffer/gegl-sampler.h
   trunk/operations/affine/affine.c
   trunk/operations/affine/affine.h

Modified: trunk/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-access.c	(original)
+++ trunk/gegl/buffer/gegl-buffer-access.c	Sat Jun 14 13:25:17 2008
@@ -35,6 +35,7 @@
 #include "gegl-sampler-nearest.h"
 #include "gegl-sampler-linear.h"
 #include "gegl-sampler-cubic.h"
+#include "gegl-sampler-lanczos.h"
 #include "gegl-buffer-index.h"
 #include "gegl-tile-backend.h"
 #include "gegl-buffer-iterator.h"
@@ -300,7 +301,7 @@
       buffer->hot_tile = NULL;
     }
   if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))
-    {   
+    {
       ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))->x =buffer->extent.x;
       ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))->y =buffer->extent.y;
       ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))->width =buffer->extent.width;
@@ -1087,6 +1088,7 @@
                     const Babl       *format,
                     GeglInterpolation interpolation)
 {
+  GType desired_type;
   g_return_if_fail (GEGL_IS_BUFFER (buffer));
 
 /*#define USE_WORKING_SHORTCUT*/
@@ -1099,26 +1101,19 @@
   g_static_rec_mutex_lock (&mutex);
 #endif
 
+  desired_type = gegl_sampler_type_from_interpolation (interpolation);
+
+  if (buffer->sampler != NULL &&
+      !G_TYPE_CHECK_INSTANCE_TYPE (buffer->sampler, desired_type))
+    {
+      g_object_unref(buffer->sampler);
+      buffer->sampler = NULL;
+    }
+
   /* look up appropriate sampler,. */
   if (buffer->sampler == NULL)
     {
-      /* FIXME: should probably check if the desired form of interpolation
-       * changes from the currently cached sampler.
-       */
-      GType interpolation_type = 0;
-
-      switch (interpolation)
-        {
-          case GEGL_INTERPOLATION_NEAREST:
-            interpolation_type=GEGL_TYPE_SAMPLER_NEAREST;
-            break;
-          case GEGL_INTERPOLATION_LINEAR:
-            interpolation_type=GEGL_TYPE_SAMPLER_LINEAR;
-            break;
-          default:
-            g_warning ("unimplemented interpolation type %i", interpolation);
-        }
-      buffer->sampler = g_object_new (interpolation_type,
+      buffer->sampler = g_object_new (desired_type,
                                       "buffer", buffer,
                                       "format", format,
                                       NULL);
@@ -1220,12 +1215,36 @@
 GeglBuffer *
 gegl_buffer_dup (GeglBuffer *buffer)
 {
-  GeglBuffer *new;
+  GeglBuffer *new_buffer;
 
   g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
 
-  new = gegl_buffer_new (gegl_buffer_get_extent (buffer), buffer->format);
+  new_buffer = gegl_buffer_new (gegl_buffer_get_extent (buffer), buffer->format);
   gegl_buffer_copy (buffer, gegl_buffer_get_extent (buffer),
-                    new, gegl_buffer_get_extent (buffer));
-  return new;
+                    new_buffer, gegl_buffer_get_extent (buffer));
+  return new_buffer;
+}
+
+void
+gegl_buffer_sampler (GeglBuffer       *buffer,
+                    gdouble           x,
+                    gdouble           y,
+                    gdouble           scale,
+                    gpointer          dest,
+                    const Babl       *format,
+                    gpointer          sampler2)
+{
+  GeglSampler *sampler = sampler2;
+  g_return_if_fail (GEGL_IS_BUFFER (buffer));
+  g_return_if_fail (GEGL_IS_SAMPLER (sampler));
+
+#if ENABLE_MP
+  g_static_rec_mutex_lock (&mutex);
+#endif
+
+  gegl_sampler_get (sampler, x, y, dest);
+
+#if ENABLE_MP
+  g_static_rec_mutex_unlock (&mutex);
+#endif
 }

Modified: trunk/gegl/buffer/gegl-buffer-types.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-types.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-types.h	Sat Jun 14 13:25:17 2008
@@ -19,7 +19,7 @@
 #ifndef __GEGL_BUFFER_TYPES_H__
 #define __GEGL_BUFFER_TYPES_H__
 
-typedef struct _GeglSampler               GeglSampler;
+
 
 typedef struct _GeglTile                  GeglTile;
 typedef struct _GeglTileClass             GeglTileClass;

Modified: trunk/gegl/buffer/gegl-buffer.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.c	(original)
+++ trunk/gegl/buffer/gegl-buffer.c	Sat Jun 14 13:25:17 2008
@@ -61,6 +61,7 @@
 #include "gegl-sampler-nearest.h"
 #include "gegl-sampler-linear.h"
 #include "gegl-sampler-cubic.h"
+#include "gegl-sampler-lanczos.h"
 #include "gegl-types.h"
 #include "gegl-utils.h"
 #include "gegl-id-pool.h"
@@ -294,7 +295,7 @@
    (*(GeglRectangle*)gegl_buffer_get_extent (buffer))=*extent;
 
   if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))
-    {   
+    {
       GeglBufferHeader *header = ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header));
       header->x = buffer->extent.x;
       header->y = buffer->extent.x;
@@ -464,7 +465,7 @@
             }
 
           source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
-                                                   
+
           /* after construction,. x and y should be set to reflect
            * the top level behavior exhibited by this buffer object.
            */
@@ -607,7 +608,7 @@
       buffer->abyss.height = self.height;
     }
 
-  /* compute our own total shift <- this should probably happen 
+  /* compute our own total shift <- this should probably happen
    * approximatly first */
   if (GEGL_IS_BUFFER (source))
     {
@@ -637,7 +638,7 @@
   GeglTile    *tile   = NULL;
   source = handler->source;
 
-  if (source) 
+  if (source)
     tile = gegl_tile_source_get_tile (source, x, y, z);
   else
     g_assert (0);
@@ -890,19 +891,6 @@
   g_object_unref (buffer);
 }
 
-GeglInterpolation
-gegl_buffer_interpolation_from_string (const gchar *string)
-{
-  if (g_str_equal (string, "nearest") ||
-      g_str_equal (string, "none"))
-    return GEGL_INTERPOLATION_NEAREST;
-
-  if (g_str_equal (string, "linear") ||
-      g_str_equal (string, "bilinear"))
-    return GEGL_INTERPOLATION_LINEAR;
-
- return GEGL_INTERPOLATION_NEAREST;
-}
 
 
 

Modified: trunk/gegl/buffer/gegl-buffer.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.h	(original)
+++ trunk/gegl/buffer/gegl-buffer.h	Sat Jun 14 13:25:17 2008
@@ -41,7 +41,7 @@
  */
 GType           gegl_buffer_get_type          (void) G_GNUC_CONST;
 
-/** 
+/**
  * gegl_buffer_new:
  * @extent: the geometry of the buffer (origin, width and height) a
  * GeglRectangle.
@@ -105,7 +105,7 @@
 void            gegl_buffer_flush             (GeglBuffer          *buffer);
 
 
-/** 
+/**
  * gegl_buffer_create_sub_buffer:
  * @buffer: parent buffer.
  * @extent: coordinates of new buffer.
@@ -273,7 +273,7 @@
                                                const GeglRectangle *dst_rect);
 
 
-/** 
+/**
  * gegl_buffer_dup:
  * @buffer: the GeglBuffer to duplicate.
  *
@@ -286,6 +286,8 @@
 typedef enum {
   GEGL_INTERPOLATION_NEAREST = 0,
   GEGL_INTERPOLATION_LINEAR,
+  GEGL_INTERPOLATION_CUBIC,
+  GEGL_INTERPOLATION_LANCZOS,
 } GeglInterpolation;
 
 /**
@@ -298,7 +300,9 @@
  * @format: the format to store the sampled color in.
  * @interpolation: the interpolation behavior to use, currently only nearest
  * neighbour is implemented for this API, bilinear, bicubic and lanczos needs
- * to be ported from working code. Valid values: GEGL_INTERPOLATION_NEAREST
+ * to be ported from working code. Valid values: GEGL_INTERPOLATION_NEAREST and
+ * GEGL_INTERPOLATION_LINEAR, CUBIC and LANCZOS will become available for now they
+ * fall back to linear.
  *
  * Resample the buffer at some given coordinates using a specified format. For
  * some operations this might be sufficient, but it might be considered
@@ -313,6 +317,7 @@
                                                const Babl       *format,
                                                GeglInterpolation interpolation);
 
+
 /**
  * gegl_buffer_sample_cleanup:
  * @buffer: the GeglBuffer to sample from
@@ -321,7 +326,7 @@
  * automatically later when the buffer is destroyed, for long lived buffers
  * cleaning up the sampling infrastructure when it has been used for its
  * purpose will sometimes be more efficient).
- */ 
+ */
 void            gegl_buffer_sample_cleanup    (GeglBuffer *buffer);
 
 /**
@@ -333,6 +338,7 @@
  */
 GeglInterpolation gegl_buffer_interpolation_from_string (const gchar *string);
 
+
 /**
  */
 #endif

Modified: trunk/gegl/buffer/gegl-sampler-cubic.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-cubic.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-cubic.c	Sat Jun 14 13:25:17 2008
@@ -13,39 +13,40 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  */
+
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <glib/gprintf.h>
+#include "gegl-types.h"
+#include "gegl-buffer-private.h"
 #include "gegl-sampler-cubic.h"
-#include "gegl-buffer-private.h" /* XXX */
 #include <string.h>
 #include <math.h>
 
-/* XXX WARNING: This code compiles, but is functionally broken, and
- * currently not used by the rest of GeglBuffer */
-
 enum
 {
   PROP_0,
   PROP_B,
+  PROP_C,
   PROP_TYPE,
   PROP_LAST
 };
 
-static void     get_property (GObject      *gobject,
-                              guint         prop_id,
-                              GValue       *value,
-                              GParamSpec   *pspec);
-static void     set_property (GObject      *gobject,
-                              guint         prop_id,
-                              const GValue *value,
-                              GParamSpec   *pspec);
-static inline float cubicKernel(float x, float b, float c);
-static void    finalize                         (GObject       *gobject);
-
-static void    gegl_sampler_cubic_get     (GeglSampler *self,
-                                                 gdouble           x,
-                                                 gdouble           y,
-                                                 void             *output);
-
-static void    gegl_sampler_cubic_prepare (GeglSampler *self);
+static void      gegl_sampler_cubic_get (GeglSampler  *sampler,
+                                         gdouble       x,
+                                         gdouble       y,
+                                         void         *output);
+static void      get_property           (GObject      *gobject,
+                                         guint         prop_id,
+                                         GValue       *value,
+                                         GParamSpec   *pspec);
+static void      set_property           (GObject      *gobject,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec);
+static inline gfloat cubicKernel       (gfloat        x,
+                                        gfloat        b,
+                                        gfloat        c);
 
 
 G_DEFINE_TYPE (GeglSamplerCubic, gegl_sampler_cubic, GEGL_TYPE_SAMPLER)
@@ -53,14 +54,12 @@
 static void
 gegl_sampler_cubic_class_init (GeglSamplerCubicClass *klass)
 {
-  GObjectClass          *object_class       = G_OBJECT_CLASS (klass);
   GeglSamplerClass *sampler_class = GEGL_SAMPLER_CLASS (klass);
+  GObjectClass     *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize     = finalize;
   object_class->set_property = set_property;
   object_class->get_property = get_property;
 
-  sampler_class->prepare = gegl_sampler_cubic_prepare;
   sampler_class->get     = gegl_sampler_cubic_get;
 
   g_object_class_install_property (object_class, PROP_B,
@@ -69,6 +68,15 @@
                                                         "B-spline parameter",
                                                         0.0,
                                                         1.0,
+                                                        1.0,
+                                                        G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_C,
+                                   g_param_spec_double ("c",
+                                                        "C",
+                                                        "C-spline parameter",
+                                                        0.0,
+                                                        1.0,
                                                         0.0,
                                                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 
@@ -78,21 +86,18 @@
                                                         "B-spline type (cubic | catmullrom | formula) 2c+b=1",
                                                         "cubic",
                                                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
 }
 
 static void
 gegl_sampler_cubic_init (GeglSamplerCubic *self)
 {
-}
-
-void
-gegl_sampler_cubic_prepare (GeglSampler *sampler)
-{
-  GeglSamplerCubic *self  = GEGL_SAMPLER_CUBIC (sampler);
-
-  /* fill the internal bufer */
-
-  if (strcmp (self->type, "cubic"))
+ GEGL_SAMPLER (self)->context_rect= (GeglRectangle){-1,-1,4,4};
+ self->b=1;
+ self->c=0;
+ self->type = g_strdup("cubic");
+ return;
+ if (strcmp (self->type, "cubic"))
     {
       /* cubic B-spline */
       self->b = 0.0;
@@ -106,95 +111,67 @@
     }
   else if (strcmp (self->type, "formula"))
     {
-      self->c = (1 - self->b) / 2.0;
+      self->c = (1.0 - self->b) / 2.0;
     }
-}
-
-static void
-finalize (GObject *object)
-{
-  GeglSamplerCubic *self         = GEGL_SAMPLER_CUBIC (object);
-
-  if (self->type)
-    g_free (self->type);
-  G_OBJECT_CLASS (gegl_sampler_cubic_parent_class)->finalize (object);
+  GEGL_SAMPLER (self)->interpolate_format = babl_format ("RaGaBaA float");
 }
 
 void
-gegl_sampler_cubic_get (GeglSampler *sampler,
-                             gdouble           x,
-                             gdouble           y,
-                             void             *output)
-{
-  GeglSamplerCubic *self      = GEGL_SAMPLER_CUBIC (sampler);
-  gfloat                *cache_buffer = sampler->cache_buffer;
-  GeglRectangle         *rectangle = &sampler->cache_rectangle;
-  GeglBuffer            *buffer    = sampler->buffer;
-  gfloat                *buf_ptr;
-  gfloat                 factor;
-
-  gdouble                arecip;
-  gdouble                newval[4];
-
-  gfloat                 dst[4];
-  gfloat                 abyss = 0.;
-  gint                   i, j, pu, pv;
-
-  gegl_sampler_fill_buffer (sampler, x, y);
-  cache_buffer = sampler->cache_buffer;
-  if (!buffer)
-    return;
-
-  if (x >= 0 &&
-      y >= 0 &&
-      x < buffer->extent.width &&
-      y < buffer->extent.height)
+gegl_sampler_cubic_get (GeglSampler *self,
+                        gdouble      x,
+                        gdouble      y,
+                        void        *output)
+{
+  GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
+  GeglRectangle     context_rect;
+  gfloat           *sampler_bptr;
+  gfloat            factor;
+  gdouble           arecip;
+  gdouble           newval[4];
+  gfloat            abyss = 0.;
+  gfloat            dst[4];
+  gint              u,v;
+  gint              dx,dy;
+
+  context_rect = self->context_rect;
+  dx = (gint) x;
+  dy = (gint) y;
+  newval[0] = newval[1] = newval[2] = newval[3] = 0.;
+  for (v=dy+context_rect.y ; v < dy+context_rect.y+context_rect.height ; v++)
+    for (u=dx+context_rect.x ; u < dx+context_rect.x+context_rect.width  ; u++)
+      {
+        sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
+        factor     = cubicKernel (y - v, cubic->b, cubic->c) *
+                     cubicKernel (x - u, cubic->b, cubic->c);
+        newval[0] += factor * sampler_bptr[0] * sampler_bptr[3];
+        newval[1] += factor * sampler_bptr[1] * sampler_bptr[3];
+        newval[2] += factor * sampler_bptr[2] * sampler_bptr[3];
+        newval[3] += factor * sampler_bptr[3];
+      }
+  if (newval[3] <= abyss)
     {
-      gint u = (gint) (x - rectangle->x);
-      gint v = (gint) (y - rectangle->y);
-      newval[0] = newval[1] = newval[2] = newval[3] = 0.0;
-      for (j = -1; j <= 2; j++)
-        for (i = -1; i <= 2; i++)
-          {
-            pu         = CLAMP (u + i, 0, rectangle->width - 1);
-            pv         = CLAMP (v + j, 0, rectangle->height - 1);
-            factor     = cubicKernel ((y - rectangle->y) - pv, self->b, self->c) *
-                         cubicKernel ((x - rectangle->x) - pu, self->b, self->c);
-            buf_ptr    = cache_buffer + ((pv * rectangle->width + pu) * 4);
-            newval[0] += factor * buf_ptr[0] * buf_ptr[3];
-            newval[1] += factor * buf_ptr[1] * buf_ptr[3];
-            newval[2] += factor * buf_ptr[2] * buf_ptr[3];
-            newval[3] += factor * buf_ptr[3];
-          }
-      if (newval[3] <= 0.0)
-        {
-          arecip    = 0.0;
-          newval[3] = 0;
-        }
-      else if (newval[3] > G_MAXDOUBLE)
-        {
-          arecip    = 1.0 / newval[3];
-          newval[3] = G_MAXDOUBLE;
-        }
-      else
-        {
-          arecip = 1.0 / newval[3];
-        }
-
-      dst[0] = CLAMP (newval[0] * arecip, 0, G_MAXDOUBLE);
-      dst[1] = CLAMP (newval[1] * arecip, 0, G_MAXDOUBLE);
-      dst[2] = CLAMP (newval[2] * arecip, 0, G_MAXDOUBLE);
-      dst[3] = CLAMP (newval[3], 0, G_MAXDOUBLE);
+      arecip    = abyss;
+      newval[3] = abyss;
+    }
+  else if (newval[3] > G_MAXDOUBLE)
+    {
+      arecip    = 1.0 / newval[3];
+      newval[3] = G_MAXDOUBLE;
     }
   else
     {
-      dst[0] = abyss;
-      dst[1] = abyss;
-      dst[2] = abyss;
-      dst[3] = abyss;
+      arecip = 1.0 / newval[3];
     }
-  babl_process (babl_fish (sampler->interpolate_format, sampler->format),
+
+  /* FIXME: shouldn't clamp a computed value like this, it gets evaluated twice */
+  dst[0] = CLAMP (newval[0] * arecip, 0, G_MAXDOUBLE);
+  dst[1] = CLAMP (newval[1] * arecip, 0, G_MAXDOUBLE);
+  dst[2] = CLAMP (newval[2] * arecip, 0, G_MAXDOUBLE);
+  dst[3] = CLAMP (newval[3], 0, G_MAXDOUBLE);
+
+  babl_process (babl_fish (self->interpolate_format, self->format),
                 dst, output, 1);
+
 }
 
 static void
@@ -236,10 +213,9 @@
 
       case PROP_TYPE:
       {
-        const gchar *type = g_value_get_string (value);
         if (self->type)
           g_free (self->type);
-        self->type = g_strdup (type);
+        self->type = g_strdup (g_value_get_string (value));
         break;
       }
 
@@ -248,10 +224,13 @@
     }
 }
 
-static inline float cubicKernel (float x, float b, float c)
-{
-  float weight, x2, x3;
-  float ax = (float) fabs (x);
+static inline gfloat
+cubicKernel (gfloat x,
+             gfloat b,
+             gfloat c)
+ {
+  gfloat weight, x2, x3;
+  gfloat ax = (gfloat) fabs (x);
 
   if (ax > 2) return 0;
 
@@ -270,3 +249,4 @@
 
   return weight * (1.0 / 6.0);
 }
+

Modified: trunk/gegl/buffer/gegl-sampler-lanczos.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-lanczos.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-lanczos.c	Sat Jun 14 13:25:17 2008
@@ -18,11 +18,17 @@
 /* XXX WARNING: This code compiles, but is functionally broken, and
  * currently not used by the rest of GeglBuffer */
 
+
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <glib/gprintf.h>
+#include "gegl-types.h"
+#include "gegl-buffer-private.h"
 #include "gegl-sampler-lanczos.h"
-#include "gegl-buffer-private.h" /* XXX */
 #include <string.h>
 #include <math.h>
 
+
 enum
 {
   PROP_0,
@@ -31,86 +37,42 @@
   PROP_LAST
 };
 
-static void
-get_property (GObject    *object,
-              guint       prop_id,
-              GValue     *value,
-              GParamSpec *pspec)
-{
-  GeglSamplerLanczos *self         = GEGL_SAMPLER_LANCZOS (object);
-
-  switch (prop_id)
-    {
-      case PROP_LANCZOS_WIDTH:
-        g_value_set_int (value, self->lanczos_width);
-        break;
-
-      case PROP_LANCZOS_SAMPLES:
-        g_value_set_int (value, self->lanczos_spp);
-        break;
-
-      default:
-        break;
-    }
-}
-
-static void
-set_property (GObject      *object,
-              guint         prop_id,
-              const GValue *value,
-              GParamSpec   *pspec)
-{
-  GeglSamplerLanczos *self         = GEGL_SAMPLER_LANCZOS (object);
-
-  switch (prop_id)
-    {
-      case PROP_LANCZOS_WIDTH:
-        self->lanczos_width = g_value_get_int (value);
-        break;
-
-      case PROP_LANCZOS_SAMPLES:
-        self->lanczos_spp = g_value_get_int (value);
-        break;
-
-      default:
-        break;
-    }
-}
-
-static void    gegl_sampler_lanczos_get (GeglSampler *self,
-                                              gdouble           x,
-                                              gdouble           y,
-                                              void             *output);
-
-static void    gegl_sampler_lanczos_prepare (GeglSampler *self);
-
 static inline gdouble sinc (gdouble x);
-static void           lanczos_lookup (GeglSampler *sampler);
+static void           lanczos_lookup (GeglSamplerLanczos *sampler);
+static void           gegl_sampler_lanczos_get (GeglSampler  *sampler,
+                                                gdouble       x,
+                                                gdouble       y,
+                                                void         *output);
+static void           get_property             (GObject      *gobject,
+                                                guint         prop_id,
+                                                GValue       *value,
+                                                GParamSpec   *pspec);
+static void           set_property             (GObject      *gobject,
+                                                guint         prop_id,
+                                                const GValue *value,
+                                                GParamSpec   *pspec);
+static GObject *
+gegl_sampler_lanczos_constructor (GType                  type,
+                                  guint                  n_params,
+                                  GObjectConstructParam *params);
+static void finalize (GObject *object);
 
-G_DEFINE_TYPE (GeglSamplerLanczos, gegl_sampler_lanczos, GEGL_TYPE_SAMPLER)
 
-static void
-finalize (GObject *object)
-{
-  GeglSamplerLanczos *self         = GEGL_SAMPLER_LANCZOS (object);
-  GeglSampler        *sampler = GEGL_SAMPLER (object);
+G_DEFINE_TYPE (GeglSamplerLanczos, gegl_sampler_lanczos, GEGL_TYPE_SAMPLER)
+static GObjectClass * parent_class = NULL;
 
-  g_free (self->lanczos_lookup);
-  g_free (sampler->cache_buffer);
-  G_OBJECT_CLASS (gegl_sampler_lanczos_parent_class)->finalize (object);
-}
 
 static void
 gegl_sampler_lanczos_class_init (GeglSamplerLanczosClass *klass)
 {
-  GObjectClass          *object_class       = G_OBJECT_CLASS (klass);
   GeglSamplerClass *sampler_class = GEGL_SAMPLER_CLASS (klass);
-
+  GObjectClass     *object_class = G_OBJECT_CLASS (klass);
+  parent_class                = g_type_class_peek_parent (klass);
   object_class->finalize     = finalize;
   object_class->set_property = set_property;
   object_class->get_property = get_property;
+  object_class->constructor  = gegl_sampler_lanczos_constructor;
 
-  sampler_class->prepare = gegl_sampler_lanczos_prepare;
   sampler_class->get     = gegl_sampler_lanczos_get;
 
   g_object_class_install_property (object_class, PROP_LANCZOS_WIDTH,
@@ -136,115 +98,175 @@
 static void
 gegl_sampler_lanczos_init (GeglSamplerLanczos *self)
 {
+
 }
 
-void
-gegl_sampler_lanczos_prepare (GeglSampler *sampler)
+static GObject *
+gegl_sampler_lanczos_constructor (GType                  type,
+                                  guint                  n_params,
+                                  GObjectConstructParam *params)
 {
-  /*GeglBuffer *input = GEGL_BUFFER (sampler->input);*/
+  GObject            *object;
+  GeglSamplerLanczos *self;
+  gint                i;
+
+  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
+  self   = GEGL_SAMPLER_LANCZOS (object);
+  for (i = 0; i < n_params; i++) {
+    if (!strcmp (params[i].pspec->name, "lanczos_spp"))
+      g_object_set(object, params[i].pspec->name, g_value_get_int (params[i].value), NULL);
+    if (!strcmp (params[i].pspec->name, "lanczos_width"))
+      g_object_set(object, params[i].pspec->name, g_value_get_int (params[i].value), NULL);
+  }
 
-  /* calculate lookup */
-  lanczos_lookup (sampler);
+  lanczos_lookup (self);
+  return object;
 }
 
-void
-gegl_sampler_lanczos_get (GeglSampler *sampler,
-                          gdouble           x,
-                          gdouble           y,
-                          void             *output)
+static void
+finalize (GObject *object)
 {
-  GeglSamplerLanczos *self   = GEGL_SAMPLER_LANCZOS (sampler);
-  GeglBuffer              *buffer  = sampler->buffer;
-  gfloat                  *cache_buffer;
-  gfloat                  *buf_ptr;
+  GeglSamplerLanczos *self    = GEGL_SAMPLER_LANCZOS (object);
+
+  if ( self->lanczos_lookup != NULL )
+    {
+       g_free (self->lanczos_lookup);
+       self->lanczos_lookup = NULL;
+     }
+
+  G_OBJECT_CLASS (gegl_sampler_lanczos_parent_class)->finalize (object);
+}
 
+void
+gegl_sampler_lanczos_get (GeglSampler *self,
+                          gdouble      x,
+                          gdouble      y,
+                          void        *output)
+{
+  GeglSamplerLanczos      *lanczos      = GEGL_SAMPLER_LANCZOS (self);
+  GeglRectangle            context_rect = self->context_rect;
+  gfloat                  *sampler_bptr;
   gdouble                  x_sum, y_sum, arecip;
   gdouble                  newval[4];
 
   gfloat                   dst[4];
-  gfloat                   abyss = 0.;
-  gint                     i, j, pos, pu, pv;
-  gint                     lanczos_spp    = self->lanczos_spp;
-  gint                     lanczos_width  = self->lanczos_width;
-  gint                     lanczos_width2 = lanczos_width * 2 + 1;
-
-  gdouble                  x_kernel[lanczos_width2], /* 1-D kernels of Lanczos window coeffs */
-                           y_kernel[lanczos_width2];
-  
-  gegl_sampler_fill_buffer (sampler, x, y);
-  cache_buffer = sampler->cache_buffer;
-  if (!cache_buffer)
-    return;
-
-  if (x >= 0 &&
-      y >= 0 &&
-      x < buffer->extent.width &&
-      y < buffer->extent.height)
+  gint                     i, j;
+  gint                     spp    = lanczos->lanczos_spp;
+  gint                     width  = lanczos->lanczos_width;
+  gint                     width2 = context_rect.width;
+  gint                     dx,dy;
+  gint                     u,v;
+
+  gdouble                  x_kernel[width2], /* 1-D kernels of Lanczos window coeffs */
+                           y_kernel[width2];
+
+  self->interpolate_format = babl_format ("RaGaBaA float");
+
+  dx = (gint) ((x - ((gint) x)) * spp + 0.5);
+  dy = (gint) ((y - ((gint) y)) * spp + 0.5);
+  /* fill 1D kernels */
+  for (x_sum = y_sum = 0.0, i = width; i >= -width; i--)
     {
-      gint u = (gint) x;
-      gint v = (gint) y;
-      /* get weight for fractional error */
-      gint su = (gint) ((x - u) * lanczos_spp + 0.5);
-      gint sv = (gint) ((y - v) * lanczos_spp + 0.5);
-      /* fill 1D kernels */
-      for (x_sum = y_sum = 0.0, i = lanczos_width; i >= -lanczos_width; i--)
-        {
-          pos    = i * lanczos_spp;
-          x_sum += x_kernel[lanczos_width + i] = self->lanczos_lookup[ABS (su - pos)];
-          y_sum += y_kernel[lanczos_width + i] = self->lanczos_lookup[ABS (sv - pos)];
-        }
-
-      /* normalise the weighted arrays */
-      for (i = 0; i < lanczos_width2; i++)
-        {
-          x_kernel[i] /= x_sum;
-          y_kernel[i] /= y_sum;
-        }
+      gint pos    = i * spp;
+      x_sum += x_kernel[width + i] = lanczos->lanczos_lookup[ABS (dx - pos)];
+      y_sum += y_kernel[width + i] = lanczos->lanczos_lookup[ABS (dy - pos)];
+    }
 
-      newval[0] = newval[1] = newval[2] = newval[3] = 0.0;
-      for (j = 0; j < lanczos_width2; j++)
-        for (i = 0; i < lanczos_width2; i++)
-          {
-            pu         = CLAMP (u + i - lanczos_width, 0, buffer->extent.width - 1);
-            pv         = CLAMP (v + j - lanczos_width, 0, buffer->extent.height - 1);
-            buf_ptr    = cache_buffer + ((pv * buffer->extent.width + pu) * 4);
-            newval[0] += y_kernel[j] * x_kernel[i] * buf_ptr[0] * buf_ptr[3];
-            newval[1] += y_kernel[j] * x_kernel[i] * buf_ptr[1] * buf_ptr[3];
-            newval[2] += y_kernel[j] * x_kernel[i] * buf_ptr[2] * buf_ptr[3];
-            newval[3] += y_kernel[j] * x_kernel[i] * buf_ptr[3];
-          }
-      if (newval[3] <= 0.0)
-        {
-          arecip    = 0.0;
-          newval[3] = 0;
-        }
-      else if (newval[3] > G_MAXDOUBLE)
-        {
-          arecip    = 1.0 / newval[3];
-          newval[3] = G_MAXDOUBLE;
-        }
-      else
-        {
-          arecip = 1.0 / newval[3];
-        }
+  /* normalise the weighted arrays */
+  for (i = 0; i < width2; i++)
+    {
+      x_kernel[i] /= x_sum;
+      y_kernel[i] /= y_sum;
+    }
+  arecip    = 0.0;
+  newval[0] = newval[1] = newval[2] = newval[3] = 0.0;
 
-      dst[0] = CLAMP (newval[0] * arecip, 0, G_MAXDOUBLE);
-      dst[1] = CLAMP (newval[1] * arecip, 0, G_MAXDOUBLE);
-      dst[2] = CLAMP (newval[2] * arecip, 0, G_MAXDOUBLE);
-      dst[3] = CLAMP (newval[3], 0, G_MAXDOUBLE);
+  dx = (gint) x;
+  dy = (gint) y;
+  for (v=dy+context_rect.y, j = 0; v < dy+context_rect.y+context_rect.height; j++, v++)
+    for (u=dx+context_rect.x, i = 0; u < dx+context_rect.x+context_rect.width; i++, u++)
+      {
+         sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
+         newval[0] += y_kernel[j] * x_kernel[i] * sampler_bptr[0] * sampler_bptr[3];
+         newval[1] += y_kernel[j] * x_kernel[i] * sampler_bptr[1] * sampler_bptr[3];
+         newval[2] += y_kernel[j] * x_kernel[i] * sampler_bptr[2] * sampler_bptr[3];
+         newval[3] += y_kernel[j] * x_kernel[i] * sampler_bptr[3];
+      }
+  if (newval[3] <= 0.0)
+    {
+      arecip    = 0.0;
+      newval[3] = 0;
+    }
+  else if (newval[3] > G_MAXDOUBLE)
+    {
+      arecip    = 1.0 / newval[3];
+      newval[3] = G_MAXDOUBLE;
     }
   else
     {
-      dst[0] = abyss;
-      dst[1] = abyss;
-      dst[2] = abyss;
-      dst[3] = abyss;
+      arecip = 1.0 / newval[3];
     }
-  babl_process (babl_fish (sampler->interpolate_format, sampler->format),
+
+  dst[0] = CLAMP (newval[0] * arecip, 0, G_MAXDOUBLE);
+  dst[1] = CLAMP (newval[1] * arecip, 0, G_MAXDOUBLE);
+  dst[2] = CLAMP (newval[2] * arecip, 0, G_MAXDOUBLE);
+  dst[3] = CLAMP (newval[3], 0, G_MAXDOUBLE);
+
+  babl_process (babl_fish (self->interpolate_format, self->format),
                 dst, output, 1);
 }
 
+static void
+get_property (GObject    *object,
+              guint       prop_id,
+              GValue     *value,
+              GParamSpec *pspec)
+{
+  GeglSamplerLanczos *self         = GEGL_SAMPLER_LANCZOS (object);
+
+  switch (prop_id)
+    {
+      case PROP_LANCZOS_WIDTH:
+        g_value_set_int (value, self->lanczos_width);
+        break;
+
+      case PROP_LANCZOS_SAMPLES:
+        g_value_set_int (value, self->lanczos_spp);
+        break;
+
+      default:
+        break;
+    }
+}
+
+static void
+set_property (GObject      *object,
+              guint         prop_id,
+              const GValue *value,
+              GParamSpec   *pspec)
+{
+  GeglSamplerLanczos *self         = GEGL_SAMPLER_LANCZOS (object);
+
+  switch (prop_id)
+    {
+      case PROP_LANCZOS_WIDTH:
+        {
+        self->lanczos_width = g_value_get_int (value);
+        GEGL_SAMPLER (self)->context_rect.x = - self->lanczos_width;
+        GEGL_SAMPLER (self)->context_rect.y = - self->lanczos_width;
+        GEGL_SAMPLER (self)->context_rect.width = self->lanczos_width*2+1;
+        GEGL_SAMPLER (self)->context_rect.height = self->lanczos_width*2+1;
+        }
+        break;
 
+      case PROP_LANCZOS_SAMPLES:
+        self->lanczos_spp = g_value_get_int (value);
+        break;
+
+      default:
+        break;
+    }
+}
 
 /* Internal lanczos */
 
@@ -260,14 +282,13 @@
 }
 
 static void
-lanczos_lookup (GeglSampler *sampler)
+lanczos_lookup (GeglSamplerLanczos *sampler)
 {
   GeglSamplerLanczos *self = GEGL_SAMPLER_LANCZOS (sampler);
 
   const gint    lanczos_width = self->lanczos_width;
   const gint    samples       = (self->lanczos_spp * (lanczos_width + 1));
   const gdouble dx            = (gdouble) lanczos_width / (gdouble) (samples - 1);
-
   gdouble x = 0.0;
   gint    i;
 

Modified: trunk/gegl/buffer/gegl-sampler-linear.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-linear.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-linear.c	Sat Jun 14 13:25:17 2008
@@ -14,28 +14,36 @@
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
  */
-#include "gegl-sampler-linear.h"
+
+
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <glib/gprintf.h>
+#include "gegl-types.h"
 #include "gegl-buffer-private.h"
+#include "gegl-sampler-linear.h"
 #include <string.h>
+#include <math.h>
+
+
 enum
 {
   PROP_0,
-  PROP_CONTEXT_PIXELS,
   PROP_LAST
 };
 
-static void    gegl_sampler_linear_get (GeglSampler *self,
-                                        gdouble           x,
-                                        gdouble           y,
-                                        void             *output);
+static void    gegl_sampler_linear_get (GeglSampler  *self,
+                                        gdouble       x,
+                                        gdouble       y,
+                                        void         *output);
 static void    set_property            (GObject      *gobject,
                                         guint         prop_id,
                                         const GValue *value,
                                         GParamSpec   *pspec);
-static void    get_property            (GObject    *gobject,
-                                        guint       prop_id,
-                                        GValue     *value,
-                                        GParamSpec *pspec);
+static void    get_property            (GObject      *gobject,
+                                        guint         prop_id,
+                                        GValue       *value,
+                                        GParamSpec   *pspec);
 
 
 G_DEFINE_TYPE (GeglSamplerLinear, gegl_sampler_linear, GEGL_TYPE_SAMPLER)
@@ -50,99 +58,73 @@
   object_class->get_property = get_property;
 
   sampler_class->get     = gegl_sampler_linear_get;
-
-  g_object_class_install_property (object_class, PROP_CONTEXT_PIXELS,
-                                   g_param_spec_int ("context-pixels",
-                                                     "ContextPixels",
-                                                     "number of neighbourhood pixels needed in each direction",
-                                                     0, 16, 1,
-                                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-
 }
 
 static void
 gegl_sampler_linear_init (GeglSamplerLinear *self)
 {
-  GEGL_SAMPLER (self)->context_pixels=1;
+  GEGL_SAMPLER (self)->context_rect = (GeglRectangle){ 0, 0, 2, 2};
+  GEGL_SAMPLER (self)->interpolate_format = babl_format ("RaGaBaA float");
 }
 
 void
-gegl_sampler_linear_get (GeglSampler *sampler,
-                              gdouble           x,
-                              gdouble           y,
-                              void             *output)
-{
-  GeglRectangle *rect;
-  gfloat        *cache_buffer;
-  gfloat         dst[4];
-  gfloat         abyss = 0.;
-
-  gegl_sampler_fill_buffer (sampler, x, y);
-  rect = &sampler->cache_rectangle;
-  cache_buffer = sampler->cache_buffer;
-  if (!cache_buffer)
-    return;
-
-  if (x >= rect->x &&
-      y >= rect->y &&
-      x < rect->x+rect->width &&
-      y < rect->y+rect->height)
+gegl_sampler_linear_get (GeglSampler *self,
+                         gdouble      x,
+                         gdouble      y,
+                         void        *output)
+{
+  GeglRectangle      context_rect = self->context_rect;
+  gfloat            *sampler_bptr;
+  gfloat             abyss = 0.;
+  gfloat             dst[4];
+  gdouble            arecip;
+  gdouble            newval[4];
+  gdouble            q[4];
+  gdouble            dx,dy;
+  gdouble            uf, vf;
+  gint               u,v;
+  gint               i;
+
+
+  uf = x - (gint) x;
+  vf = y - (gint) y;
+
+  q[0] = (1 - uf) * (1 - vf);
+  q[1] = uf * (1 - vf);
+  q[2] = (1 - uf) * vf;
+  q[3] = uf * vf;
+  dx = (gint) x;
+  dy = (gint) y;
+  newval[0] = newval[1] = newval[2] = newval[3] = 0.;
+  for (i=0, v=dy+context_rect.y; v < dy+context_rect.height ; v++)
+    for (u=dx+context_rect.x; u < dx+context_rect.width  ; u++, i++)
+      {
+        sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
+        newval[0] += q[i] * sampler_bptr[0] * sampler_bptr[3];
+        newval[1] += q[i] * sampler_bptr[1] * sampler_bptr[3];
+        newval[2] += q[i] * sampler_bptr[2] * sampler_bptr[3];
+        newval[3] += q[i] * sampler_bptr[3];
+      }
+
+  if (newval[3] <= abyss)
     {
-      gint     i;
-      gint     x0;
-      gint     y0;
-      gint     x1;
-      gint     y1;
-      gint     u;
-      gint     v;
-      gdouble  uf;
-      gdouble  vf;
-      gdouble  q1;
-      gdouble  q2;
-      gdouble  q3;
-      gdouble  q4;
-      gfloat * p00;
-      gfloat * p01;
-      gfloat * p10;
-      gfloat * p11;
-      x -= rect->x;
-      y -= rect->y;
-      x0 = 0;
-      y0 = 0;
-      x1 = rect->width - 1;
-      y1 = rect->height - 1;
-      u  = (gint) x;
-      v  = (gint) y;
-      uf = x - u;
-      vf = y - v;
-      q1 = (1 - uf) * (1 - vf);
-      q2 = uf * (1 - vf);
-      q3 = (1 - uf) * vf;
-      q4 = uf * vf;
-      p00 = cache_buffer + (v * rect->width + u) * 4;
-      u = CLAMP ((gint) x + 0, x0, x1);
-      v = CLAMP ((gint) y + 1, y0, y1);
-      p01 = cache_buffer + (v * rect->width + u) * 4;
-      u = CLAMP ((gint) x + 1, x0, x1);
-      v = CLAMP ((gint) y + 0, y0, y1);
-      p10 = cache_buffer + (v * rect->width + u) * 4;
-      u = CLAMP ((gint) x + 1, x0, x1);
-      v = CLAMP ((gint) y + 1, y0, y1);
-      p11 = cache_buffer + (v * rect->width + u) * 4;
-      for (i = 0; i < 4; i++)
-        {
-          dst[i] = q1 * p00[i] + q2 * p10[i] + q3 * p01[i] + q4 * p11[i];
-        }
+      arecip    = abyss;
+      newval[3] = abyss;
+    }
+  else if (newval[3] > G_MAXDOUBLE)
+    {
+      arecip    = 1.0 / newval[3];
+      newval[3] = G_MAXDOUBLE;
     }
   else
     {
-      dst[0] = abyss;
-      dst[1] = abyss;
-      dst[2] = abyss;
-      dst[3] = abyss;
+      arecip = 1.0 / newval[3];
     }
-  babl_process (babl_fish (sampler->interpolate_format, sampler->format),
+  dst[0] = CLAMP (newval[0] * arecip, 0, G_MAXDOUBLE);
+  dst[1] = CLAMP (newval[1] * arecip, 0, G_MAXDOUBLE);
+  dst[2] = CLAMP (newval[2] * arecip, 0, G_MAXDOUBLE);
+  dst[3] = CLAMP (newval[3], 0, G_MAXDOUBLE);
+  babl_process (babl_fish (self->interpolate_format, self->format),
                 dst, output, 1);
 }
 
@@ -156,9 +138,6 @@
 {
   switch (property_id)
     {
-      case PROP_CONTEXT_PIXELS:
-        g_object_set_property (gobject, "GeglSampler::context-pixels", value);
-        break;
 
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
@@ -174,9 +153,6 @@
 {
   switch (property_id)
     {
-      case PROP_CONTEXT_PIXELS:
-        g_object_get_property (gobject, "GeglSampler::context-pixels", value);
-        break;
 
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);

Modified: trunk/gegl/buffer/gegl-sampler-nearest.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-nearest.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-nearest.c	Sat Jun 14 13:25:17 2008
@@ -14,15 +14,31 @@
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
  */
-#include "gegl-sampler-nearest.h"
+
+#include <glib-object.h>
+#include "gegl-types.h"
 #include "gegl-buffer-private.h"
+#include "gegl-sampler-nearest.h"
 #include <string.h>
 
-static void    gegl_sampler_nearest_get (GeglSampler *self,
-                                         gdouble      x,
-                                         gdouble      y,
-                                         void        *output);
-
+enum
+{
+  PROP_0,
+  PROP_LAST
+};
+
+static void    gegl_sampler_nearest_get (GeglSampler  *self,
+                                         gdouble       x,
+                                         gdouble       y,
+                                         void         *output);
+static void    set_property             (GObject      *gobject,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec);
+static void    get_property             (GObject      *gobject,
+                                         guint         prop_id,
+                                         GValue       *value,
+                                         GParamSpec   *pspec);
 
 G_DEFINE_TYPE (GeglSamplerNearest, gegl_sampler_nearest, GEGL_TYPE_SAMPLER)
 
@@ -30,6 +46,10 @@
 gegl_sampler_nearest_class_init (GeglSamplerNearestClass *klass)
 {
   GeglSamplerClass *sampler_class = GEGL_SAMPLER_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = set_property;
+  object_class->get_property = get_property;
 
   sampler_class->get     = gegl_sampler_nearest_get;
 
@@ -38,6 +58,8 @@
 static void
 gegl_sampler_nearest_init (GeglSamplerNearest *self)
 {
+   GEGL_SAMPLER (self)->context_rect = (GeglRectangle){0,0,1,1};
+   GEGL_SAMPLER (self)->interpolate_format = babl_format ("RaGaBaA float");
 }
 
 void
@@ -46,37 +68,35 @@
                           gdouble      y,
                           void        *output)
 {
-  gfloat        * cache_buffer;
-  GeglRectangle * rect;
-  gint  u;
-  gint  v;
-  gfloat         dst[4];
-
-  gegl_sampler_fill_buffer (self, x, y);
-
-  rect = &self->cache_rectangle;
-  cache_buffer = self->cache_buffer;
-  if (!cache_buffer)
-    return;
-  u = (x - rect->x);
-  v = (y - rect->y);
-
-  if (u >= 0 &&
-      v >= 0 &&
-      u < rect->width &&
-      v < rect->height)
+  gfloat             *sampler_bptr;
+  sampler_bptr = gegl_sampler_get_from_buffer (self, (gint)x, (gint)y);
+  babl_process (babl_fish (self->interpolate_format, self->format), sampler_bptr, output, 1);
+}
+
+static void
+set_property (GObject      *gobject,
+              guint         property_id,
+              const GValue *value,
+              GParamSpec   *pspec)
+{
+  switch (property_id)
     {
-      gint pos = (v * rect->width + u) * 4;
-      memcpy (dst, cache_buffer + pos, sizeof (gfloat) * 4);
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+        break;
     }
-  else
+}
+
+static void
+get_property (GObject    *gobject,
+              guint       property_id,
+              GValue     *value,
+              GParamSpec *pspec)
+{
+  switch (property_id)
     {
-      dst[0] = 0.0;
-      dst[1] = 0.0;
-      dst[2] = 0.0;
-      dst[3] = 0.0;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+        break;
     }
-  babl_process (babl_fish (self->interpolate_format, self->format),
-                dst, output, 1);
 }
-

Modified: trunk/gegl/buffer/gegl-sampler.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler.c	(original)
+++ trunk/gegl/buffer/gegl-sampler.c	Sat Jun 14 13:25:17 2008
@@ -15,26 +15,31 @@
  *
  * 2007 Â Ãyvind KolÃs
  */
-
-#define SIZE 16  /* the cached region around a fetched pixel value is
-                    SIZEÃSIZE pixels. */
-
 #include "config.h"
 
 #include <glib-object.h>
 #include <string.h>
 
 #include "gegl-types.h"
-#include "gegl-sampler.h"
+#include "gegl-buffer.h"
 #include "gegl-utils.h"
 #include "gegl-buffer-private.h"
 
+#include "gegl-sampler-nearest.h"
+#include "gegl-sampler-linear.h"
+#include "gegl-sampler-cubic.h"
+#include "gegl-sampler-lanczos.h"
+
+#if ENABLE_MP
+GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
+#endif
+
 enum
 {
   PROP_0,
   PROP_BUFFER,
   PROP_FORMAT,
-  PROP_CONTEXT_PIXELS,
+  PROP_CONTEXT_RECT,
   PROP_LAST
 };
 
@@ -50,6 +55,8 @@
                                      guint         prop_id,
                                      const GValue *value,
                                      GParamSpec   *pspec);
+static void set_buffer              (GeglSampler  *self,
+                                     GeglBuffer   *buffer);
 
 G_DEFINE_TYPE (GeglSampler, gegl_sampler, G_TYPE_OBJECT)
 
@@ -63,16 +70,11 @@
 
   klass->prepare = NULL;
   klass->get     = NULL;
+  klass->set_buffer   = set_buffer;
 
   object_class->set_property = set_property;
   object_class->get_property = get_property;
 
-  g_object_class_install_property (object_class, PROP_BUFFER,
-                                   g_param_spec_object ("buffer",
-                                                        "Buffer",
-                                                        "Input pad, for image buffer input.",
-                                                        GEGL_TYPE_BUFFER,
-                                                        G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (object_class, PROP_FORMAT,
                                    g_param_spec_pointer ("format",
@@ -80,21 +82,23 @@
                                                          "babl format",
                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
-  g_object_class_install_property (object_class, PROP_CONTEXT_PIXELS,
-                                   g_param_spec_int ("context-pixels",
-                                                     "ContextPixels",
-                                                     "number of neighbourhood pixels needed in each direction",
-                                                     0, 16, 0,
-                                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
+  g_object_class_install_property (object_class, PROP_BUFFER,
+                                   g_param_spec_object ("buffer",
+                                                        "Buffer",
+                                                        "Input pad, for image buffer input.",
+                                                        GEGL_TYPE_BUFFER,
+                                                        G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 }
 
 static void
 gegl_sampler_init (GeglSampler *self)
 {
-  self->cache_buffer = NULL;
+  GeglRectangle context_rect = {0,0,1,1};
+  GeglRectangle sampler_rectangle = {0,0,0,0};
+  self->sampler_buffer = NULL;
   self->buffer = NULL;
-  self->context_pixels = 0;
+  self->context_rect = context_rect;
+  self->sampler_rectangle = sampler_rectangle;
 }
 
 void
@@ -135,14 +139,28 @@
 #endif
 }
 
+void
+gegl_sampler_set_buffer (GeglSampler *self, GeglBuffer *buffer)
+{
+  GeglSamplerClass *klass;
+
+  g_return_if_fail (GEGL_IS_SAMPLER (self));
+
+  klass = GEGL_SAMPLER_GET_CLASS (self);
+
+  if (klass->set_buffer)
+    klass->set_buffer (self, buffer);
+}
+
+
 static void
 finalize (GObject *gobject)
 {
   GeglSampler *sampler = GEGL_SAMPLER (gobject);
-  if (sampler->cache_buffer)
+  if (sampler->sampler_buffer)
     {
-      g_free (sampler->cache_buffer);
-      sampler->cache_buffer = NULL;
+      g_free (sampler->sampler_buffer);
+      sampler->sampler_buffer = NULL;
     }
   G_OBJECT_CLASS (gegl_sampler_parent_class)->finalize (gobject);
 }
@@ -159,50 +177,45 @@
   G_OBJECT_CLASS (gegl_sampler_parent_class)->dispose (gobject);
 }
 
-void
-gegl_sampler_fill_buffer (GeglSampler *sampler,
-                          gdouble      x,
-                          gdouble      y)
-{
-  GeglBuffer    *buffer;
-  GeglRectangle  surround;
- 
-  buffer = sampler->buffer;
-  g_assert (buffer);
-
-  if (sampler->cache_buffer) 
-    {
-      GeglRectangle r = sampler->cache_rectangle;
-
-      /* check if the cache-buffer includes both the desired coordinates and
-       * a sufficient surrounding context 
-       */
-      if (x - r.x >= sampler->context_pixels &&
-          x - r.x < r.width - sampler->context_pixels &&
-          y - r.y >= sampler->context_pixels &&
-          y - r.y < r.height - sampler->context_pixels)
-        {
-          return;  /* we can reuse our cached interpolation source buffer */
-        }
-
-      g_free (sampler->cache_buffer);
-      sampler->cache_buffer = NULL;
-    }
-
-  surround.x = x - SIZE/2;
-  surround.y = y - SIZE/2;
-  surround.width  = SIZE;
-  surround.height = SIZE;
-
-  sampler->cache_buffer = g_malloc0 (surround.width *
-                                          surround.height *
-                                          4 * sizeof (gfloat));
-  sampler->cache_rectangle = surround;
-  sampler->interpolate_format = babl_format ("RaGaBaA float");
-
-  gegl_buffer_get (buffer, 1.0, &surround,
-                   sampler->interpolate_format,
-                   sampler->cache_buffer, GEGL_AUTO_ROWSTRIDE);
+gfloat *
+gegl_sampler_get_from_buffer (GeglSampler *sampler,
+                              gint       x,
+                              gint       y)
+{
+   const GeglRectangle *buffer_rectangle;
+   guchar              *buffer_ptr;
+   gint                 dx;
+   gint                 dy;
+   gint                 bpp;
+   gint                 sof;
+
+   /* Initialise */
+   bpp = sampler->interpolate_format->format.bytes_per_pixel;
+   buffer_rectangle  = gegl_buffer_get_extent(sampler->buffer);
+   if ( !gegl_rectangle_contains (buffer_rectangle, &sampler->sampler_rectangle) ||
+        sampler->sampler_buffer == NULL )
+     {
+       gint buffer_size = (buffer_rectangle->width *
+                           buffer_rectangle->height *
+                           bpp);
+       if (  sampler->sampler_buffer == NULL )
+         sampler->sampler_buffer    = g_malloc0 (buffer_size);
+       else
+         sampler->sampler_buffer    = g_realloc (sampler->sampler_buffer, buffer_size);
+       gegl_buffer_get (sampler->buffer,
+                        1.0,
+                        buffer_rectangle,
+                        sampler->interpolate_format,
+                        sampler->sampler_buffer,
+                        GEGL_AUTO_ROWSTRIDE);
+       gegl_rectangle_copy (&sampler->sampler_rectangle,buffer_rectangle);
+     }
+
+   dx = x - buffer_rectangle->x;
+   dy = y - buffer_rectangle->y;
+   buffer_ptr = (guchar *)sampler->sampler_buffer;
+   sof = ( dx +  (dy * buffer_rectangle->width)) * bpp;
+   return (gfloat*)(buffer_ptr+sof);
 }
 
 static void
@@ -223,10 +236,6 @@
         g_value_set_pointer (value, self->format);
         break;
 
-      case PROP_CONTEXT_PIXELS:
-        g_value_set_int (value, self->context_pixels);
-        break;
-
       default:
         break;
     }
@@ -250,11 +259,64 @@
         self->format = g_value_get_pointer (value);
         break;
 
-      case PROP_CONTEXT_PIXELS:
-        self->context_pixels = g_value_get_int (value);
-        break;
-
       default:
         break;
     }
 }
+
+
+static void
+set_buffer (GeglSampler *self, GeglBuffer *buffer)
+{
+   if (self->buffer != buffer)
+     {
+        if (GEGL_IS_BUFFER(self->buffer))
+          g_object_unref(self->buffer);
+        if (GEGL_IS_BUFFER (buffer))
+          self->buffer = gegl_buffer_dup (buffer);
+        else
+          self->buffer = NULL;
+     }
+}
+
+GeglInterpolation
+gegl_buffer_interpolation_from_string (const gchar *string)
+{
+  if (g_str_equal (string, "nearest") ||
+      g_str_equal (string, "none"))
+    return GEGL_INTERPOLATION_NEAREST;
+
+  if (g_str_equal (string, "linear") ||
+      g_str_equal (string, "bilinear"))
+    return GEGL_INTERPOLATION_LINEAR;
+
+  if (g_str_equal (string, "cubic") ||
+      g_str_equal (string, "bicubic"))
+    return GEGL_INTERPOLATION_CUBIC;
+
+  if (g_str_equal (string, "lanczos"))
+    return GEGL_INTERPOLATION_LANCZOS;
+
+  return GEGL_INTERPOLATION_NEAREST;
+}
+
+
+GType
+gegl_sampler_type_from_interpolation (GeglInterpolation interpolation)
+{
+  switch (interpolation)
+    {
+      case GEGL_INTERPOLATION_NEAREST:
+        return GEGL_TYPE_SAMPLER_NEAREST;
+      case GEGL_INTERPOLATION_LINEAR:
+        return GEGL_TYPE_SAMPLER_LINEAR;
+#if 0 /* disabled for now */
+      case GEGL_INTERPOLATION_CUBIC:
+        return GEGL_TYPE_SAMPLER_CUBIC;
+      case GEGL_INTERPOLATION_LANCZOS:
+        return GEGL_TYPE_SAMPLER_LANCZOS;
+#endif
+      default:        
+        return GEGL_TYPE_SAMPLER_LINEAR;
+    }
+}

Modified: trunk/gegl/buffer/gegl-sampler.h
==============================================================================
--- trunk/gegl/buffer/gegl-sampler.h	(original)
+++ trunk/gegl/buffer/gegl-sampler.h	Sat Jun 14 13:25:17 2008
@@ -20,8 +20,8 @@
 
 #include <glib-object.h>
 #include <babl/babl.h>
-#include "gegl-types.h"
-#include "buffer/gegl-buffer-types.h"
+
+/* this file needs to be included by gegl-buffer-private */
 
 G_BEGIN_DECLS
 
@@ -33,6 +33,7 @@
 #define GEGL_SAMPLER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GEGL_TYPE_SAMPLER, GeglSamplerClass))
 
 typedef struct _GeglSamplerClass GeglSamplerClass;
+typedef struct _GeglSampler    GeglSampler;
 
 struct _GeglSampler
 {
@@ -41,22 +42,24 @@
   /*< private >*/
   GeglBuffer    *buffer;
   Babl          *format;
-
-  GeglRectangle  cache_rectangle;
-  void          *cache_buffer;
   Babl          *interpolate_format;
-  gint           context_pixels;
+  GeglRectangle  context_rect;
+  void          *sampler_buffer;
+  GeglRectangle  sampler_rectangle;
+
 };
 
 struct _GeglSamplerClass
 {
   GObjectClass  parent_class;
 
-  void (* prepare) (GeglSampler *self);
-  void (* get)     (GeglSampler *self,
-                    gdouble      x,
-                    gdouble      y,
-                    void        *output);
+  void (* prepare)   (GeglSampler *self);
+  void (* get)       (GeglSampler *self,
+                      gdouble      x,
+                      gdouble      y,
+                      void        *output);
+ void  (*set_buffer) (GeglSampler  *self,
+                      GeglBuffer   *buffer);
 };
 
 GType gegl_sampler_get_type    (void) G_GNUC_CONST;
@@ -67,10 +70,13 @@
                                 gdouble      x,
                                 gdouble      y,
                                 void        *output);
+void  gegl_sampler_set_buffer  (GeglSampler *self,
+                                GeglBuffer  *buffer);
+
+gfloat * gegl_sampler_get_from_buffer (GeglSampler *sampler,
+                                       gint         x,
+                                       gint         y);
 
-void  gegl_sampler_fill_buffer (GeglSampler *sampler,
-                                gdouble      x,
-                                gdouble      y);
 
 G_END_DECLS
 

Modified: trunk/operations/affine/affine.c
==============================================================================
--- trunk/operations/affine/affine.c	(original)
+++ trunk/operations/affine/affine.c	Sat Jun 14 13:25:17 2008
@@ -25,10 +25,11 @@
 
 #include <math.h>
 #include <gegl-plugin.h>
+#include "buffer/gegl-sampler.h"
 #include <graph/gegl-pad.h>
 #include <graph/gegl-node.h>
 #include <graph/gegl-connection.h>
-/*#include "buffer/gegl-sampler.h"*/
+
 
 #include "affine.h"
 #include "module.h"
@@ -118,19 +119,74 @@
   return g_define_type_id;
 }
 
+
+GType
+gegl_sampler_type_from_interpolation (GeglInterpolation interpolation);
+
 /* ************************* */
+static void
+op_affine_sampler_init (OpAffine *self)
+{
+  Babl                 *format;
+  GeglSampler          *sampler;
+  GType                 desired_type;
+  GeglInterpolation     interpolation;
+
+  format = babl_format ("RaGaBaA float");
+
+  interpolation = gegl_buffer_interpolation_from_string (self->filter);
+  desired_type = gegl_sampler_type_from_interpolation (interpolation);
+
+  if (self->sampler != NULL &&
+      !G_TYPE_CHECK_INSTANCE_TYPE (self->sampler, desired_type))
+    {
+      self->sampler->buffer=NULL;
+      g_object_unref(self->sampler);
+      self->sampler = NULL;
+    }
+
+  if (self->sampler == NULL)
+    {
+      if (interpolation == GEGL_INTERPOLATION_LANCZOS)
+        {
+          sampler = g_object_new (desired_type,
+                                  "format", format,
+                                  "lanczos_width",  self->lanczos_width,
+                                  NULL);
+        }
+      else
+        {
+          sampler = g_object_new (desired_type,
+                                  "format", format,
+                                  NULL);
+        }
+      self->sampler = g_object_ref(sampler);
+    }
+}
 
 static void
 prepare (GeglOperation *operation)
 {
-  Babl *format = babl_format ("RaGaBaA float");
-
+  OpAffine  *affine = (OpAffine *) operation;
+  Babl      *format = babl_format ("RaGaBaA float");
+  op_affine_sampler_init (affine);
   /*gegl_operation_set_format (operation, "input", format);
   gegl_operation_set_format (operation, "aux", format); XXX(not used yet) */
   gegl_operation_set_format (operation, "output", format);
 }
 
 static void
+finalize (GObject *object)
+{
+  OpAffine  *affine = (OpAffine *) object;
+  if (affine->sampler != NULL)
+    {
+      g_object_unref(affine->sampler);
+      affine->sampler = NULL;
+    }
+}
+
+static void
 op_affine_class_init (OpAffineClass *klass)
 {
   GObjectClass             *gobject_class = G_OBJECT_CLASS (klass);
@@ -139,6 +195,7 @@
 
   gobject_class->set_property = set_property;
   gobject_class->get_property = get_property;
+  gobject_class->finalize = finalize;
 
   op_class->get_invalidated_by_change = get_invalidated_by_change;
   op_class->get_bounding_box = get_bounding_box;
@@ -147,6 +204,7 @@
   op_class->categories = "transform";
   op_class->prepare = prepare;
 
+
   filter_class->process = process;
 
   klass->create_matrix = NULL;
@@ -171,7 +229,7 @@
                                    g_param_spec_string (
                                      "filter",
                                      "Filter",
-                                     "Filter type (nearest, linear, lanczos)",
+                                     "Filter type (nearest, linear, lanczos, cubic)",
                                      "linear",
                                      G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class, PROP_HARD_EDGES,
@@ -190,6 +248,7 @@
                                      G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 }
 
+
 static void
 op_affine_init (OpAffine *self)
 {
@@ -370,8 +429,15 @@
   gdouble        have_points [8];
   gint           i;
 
+  GeglRectangle  context_rect;
+  GeglSampler   *sampler;
+
+  sampler = affine->sampler;
+  context_rect = sampler->context_rect;
+
+
   if (gegl_operation_source_get_bounding_box (op, "input"))
-  in_rect = *gegl_operation_source_get_bounding_box (op, "input");
+    in_rect = *gegl_operation_source_get_bounding_box (op, "input");
 
   /* invoke child's matrix creation function */
   g_assert (klass->create_matrix);
@@ -394,21 +460,10 @@
       return in_rect;
     }
 
-  if (! strcmp (affine->filter, "linear"))
-    {
-      if (affine->hard_edges)
-        {
-          in_rect.width ++;
-          in_rect.height ++;
-        }
-      else
-        {
-          in_rect.x--;
-          in_rect.y--;
-          in_rect.width  += 2;
-          in_rect.height  += 2;
-        }
-    }
+  in_rect.x      += context_rect.x;
+  in_rect.y      += context_rect.y;
+  in_rect.width  += context_rect.width;
+  in_rect.height += context_rect.height;
 
   have_points [0] = in_rect.x;
   have_points [1] = in_rect.y;
@@ -427,7 +482,6 @@
                              have_points + i, have_points + i + 1);
 
   bounding_box (have_points, 4, &have_rect);
-
   return have_rect;
 }
 
@@ -472,10 +526,14 @@
   Matrix3        inverse;
   GeglRectangle  requested_rect,
                  need_rect;
+  GeglRectangle  context_rect;
+  GeglSampler   *sampler;
   gdouble        need_points [8];
   gint           i;
 
   requested_rect = *region;
+  sampler = affine->sampler;
+  context_rect = sampler->context_rect;
 
   matrix3_copy (inverse, affine->matrix);
   matrix3_invert (inverse);
@@ -506,22 +564,10 @@
                              need_points + i, need_points + i + 1);
   bounding_box (need_points, 4, &need_rect);
 
-  if (! strcmp (affine->filter, "linear"))
-    {
-      if (affine->hard_edges)
-        {
-          need_rect.width ++;
-          need_rect.height ++;
-        }
-      else
-        {
-          need_rect.x--;
-          need_rect.y--;
-          need_rect.width  += 2;
-          need_rect.height  += 2;
-        }
-    }
-
+  need_rect.x      += context_rect.x;
+  need_rect.y      += context_rect.y;
+  need_rect.width  += context_rect.width;
+  need_rect.height += context_rect.height;
   return need_rect;
 }
 
@@ -530,13 +576,18 @@
                            const gchar         *input_pad,
                            const GeglRectangle *input_region)
 {
-  OpAffine      *affine  = (OpAffine *) op;
-  OpAffineClass *klass   = OP_AFFINE_GET_CLASS (affine);
-  GeglRectangle  affected_rect;
-  gdouble        affected_points [8];
-  gint           i;
-  GeglRectangle  region = *input_region;
-
+  OpAffine          *affine  = (OpAffine *) op;
+  OpAffineClass     *klass   = OP_AFFINE_GET_CLASS (affine);
+  GeglRectangle      affected_rect;
+  GeglRectangle      context_rect;
+  GeglSampler       *sampler;
+  gdouble            affected_points [8];
+  gint               i;
+  GeglRectangle      region = *input_region;
+
+  op_affine_sampler_init (affine);
+  sampler = affine->sampler;
+  context_rect = sampler->context_rect;
   /* invoke child's matrix creation function */
   g_assert (klass->create_matrix);
   matrix3_identity (affine->matrix);
@@ -558,21 +609,10 @@
       return region;
     }
 
-  if (! strcmp (affine->filter, "linear"))
-    {
-      if (affine->hard_edges)
-        {
-          region.width ++;
-          region.height ++;
-        }
-      else
-        {
-          region.x--;
-          region.y--;
-          region.width  += 2;
-          region.height  += 2;
-        }
-    }
+  region.x      += context_rect.x;
+  region.y      += context_rect.y;
+  region.width  += context_rect.width;
+  region.height += context_rect.height;
 
   affected_points [0] = region.x;
   affected_points [1] = region.y;
@@ -591,7 +631,6 @@
                              affected_points + i, affected_points + i + 1);
 
   bounding_box (affected_points, 4, &affected_rect);
-
   return affected_rect;
 
 }
@@ -605,7 +644,7 @@
 affine_generic (GeglBuffer        *dest,
                 GeglBuffer        *src,
                 Matrix3            matrix,
-                GeglInterpolation  interpolation)
+                GeglSampler       *sampler)
 {
   const GeglRectangle *dest_extent;
   gint                  x, y;
@@ -640,17 +679,12 @@
   v_start = inverse[1][0] * dest_extent->x + inverse[1][1] * dest_extent->y
             + inverse[1][2];
 
-  /* correct rounding on e.g. negative scaling (is this sound?) */
+    /* correct rounding on e.g. negative scaling (is this sound?) */
   if (inverse [0][0] < 0.)
     u_start -= .001;
   if (inverse [1][1] < 0.)
     v_start -= .001;
 
-  if (src->sampler)
-    {
-      gegl_sampler_prepare (src->sampler);
-    }
-
   for (dest_ptr = dest_buf, y = dest_extent->height; y--;)
     {
       u_float = u_start;
@@ -658,13 +692,9 @@
 
       for (x = dest_extent->width; x--;)
         {
-          gfloat  pix[4];
-          gegl_buffer_sample (src, u_float, v_float, 1.0, pix, format, interpolation);
+          gegl_sampler_get (sampler, u_float, v_float, dest_ptr);
 
-          *dest_ptr++ = pix[0];
-          *dest_ptr++ = pix[1];
-          *dest_ptr++ = pix[2];
-          *dest_ptr++ = pix[3];
+          dest_ptr+=4;
 
           u_float += inverse [0][0];
           v_float += inverse [1][0];
@@ -672,7 +702,7 @@
       u_start += inverse [0][1];
       v_start += inverse [1][1];
     }
-  gegl_buffer_sample_cleanup (src);
+
   gegl_buffer_set (dest, NULL, format, dest_buf, GEGL_AUTO_ROWSTRIDE);
   g_free (dest_buf);
 }
@@ -687,11 +717,6 @@
 {
   OpAffine            *affine = (OpAffine *) operation;
 
-  /*g_warning ("%i,%i %ix%i | %i,%i %ix%i | %i,%i  %ix%i",
-     input->x, input->y, input->width, input->height,
-     output->x, output->y, output->width, output->height,
-     result->x, result->y, result->width, result->height);*/
-
   if (is_intermediate_node (affine) ||
       matrix3_is_identity (affine->matrix))
     {
@@ -726,9 +751,12 @@
   else
     {
       /* XXX: add back more samplers */
-      affine_generic (output, input, affine->matrix,
-                      gegl_buffer_interpolation_from_string (affine->filter));
+      g_object_set(affine->sampler, "buffer", input, NULL);
+      affine_generic (output, input, affine->matrix, affine->sampler);
+      g_object_unref(affine->sampler->buffer);
+      affine->sampler->buffer = NULL;
     }
 
   return TRUE;
 }
+

Modified: trunk/operations/affine/affine.h
==============================================================================
--- trunk/operations/affine/affine.h	(original)
+++ trunk/operations/affine/affine.h	Sat Jun 14 13:25:17 2008
@@ -2,6 +2,7 @@
 #define __OP_AFFINE_H__
 
 #include "matrix.h"
+#include "gegl-buffer-private.h"
 
 G_BEGIN_DECLS
 
@@ -19,12 +20,13 @@
 {
   GeglOperationFilter parent;
 
-  Matrix3   matrix;
-  gdouble   origin_x,
-            origin_y;
-  gchar    *filter;
-  gboolean  hard_edges;
-  gint      lanczos_width;
+  Matrix3      matrix;
+  gdouble      origin_x,
+               origin_y;
+  gchar       *filter;
+  gboolean     hard_edges;
+  gint         lanczos_width;
+  GeglSampler *sampler;
 };
 
 typedef struct _OpAffineClass OpAffineClass;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]