[gegl] Use 3x3 boxfilter for most buffer_get formats



commit f6f56b477330f1f9d588dea2da60f629b9fc6ef1
Author: Daniel Sabo <DanielSabo gmail com>
Date:   Wed Nov 13 05:51:45 2013 -0800

    Use 3x3 boxfilter for most buffer_get formats
    
    u8, u16, u32, and float are supported now

 gegl/Makefile.am                   |    3 +
 gegl/buffer/gegl-buffer-access.c   |  200 ++++++------------------------------
 gegl/gegl-algorithms-boxfilter.inc |   71 +++++++++++++
 gegl/gegl-algorithms.c             |  164 +++++++++++++++++++++++++++++
 gegl/gegl-algorithms.h             |  101 ++++++++++++++++++
 5 files changed, 369 insertions(+), 170 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index 4ab8abe..4e38bf1 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -68,6 +68,7 @@ GEGL_public_HEADERS = \
 
 GEGL_sources = \
        gegl-c.c                        \
+       gegl-algorithms.c \
        gegl-apply.c                    \
        gegl-config.c                   \
        gegl-cpuaccel.c                 \
@@ -83,6 +84,7 @@ GEGL_sources = \
        gegl-random.c                   \
        gegl-matrix.c                   \
        \
+       gegl-algorithms.h \
        gegl-apply.h                    \
        gegl-chant.h                    \
        gegl-config.h                   \
@@ -102,6 +104,7 @@ GEGL_sources = \
        gegl-types-internal.h           \
        gegl-xml.h
 
+EXTRA_DIST = gegl-algorithms-boxfilter.inc
 
 lib_LTLIBRARIES = libgegl- GEGL_API_VERSION@.la
 
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 0a5c9ed..896b303 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -42,6 +42,8 @@
 #include "gegl-buffer-iterator.h"
 #include "gegl-buffer-cl-cache.h"
 
+ #include "gegl-algorithms.h"
+
 #if 0
 static inline void
 gegl_buffer_pixel_set (GeglBuffer *buffer,
@@ -1301,146 +1303,6 @@ gegl_buffer_set (GeglBuffer          *buffer,
   gegl_buffer_unlock (buffer);
 }
 
-#ifdef BOXFILTER_FLOAT
-typedef float            T;
-#define double2T(a)      (a)
-#define projectionT      babl_type ("float")
-#define T_components     babl_format_get_n_components (format)
-#else
-typedef guchar           T;
-#define double2T(a)      (lrint (a))
-#define projectionT      babl_type ("u8")
-#define T_components     bpp
-#endif
-#define EPSILON 1.e-6
-
-static void
-resample_nearest (guchar              *dst,
-                  const guchar        *src,
-                  const GeglRectangle *dst_rect,
-                  const GeglRectangle *src_rect,
-                  const gint           src_stride,
-                  const gdouble        scale,
-                  const gint           bpp,
-                  const gint           dst_stride)
-{
-  int i, j;
-
-  for (i = 0; i < dst_rect->height; i++)
-    {
-      const gdouble sy = (dst_rect->y + .5 + i) / scale - src_rect->y;
-      const gint    ii = floor (sy + EPSILON);
-
-      for (j = 0; j < dst_rect->width; j++)
-        {
-          const gdouble sx = (dst_rect->x + .5 + j) / scale - src_rect->x;
-          const gint    jj = floor (sx + EPSILON);
-
-          memcpy (&dst[i * dst_stride + j * bpp],
-                  &src[ii * src_stride + jj * bpp],
-                  bpp);
-        }
-    }
-}
-
-static inline void
-box_filter (gdouble   left_weight,
-            gdouble   center_weight,
-            gdouble   right_weight,
-            gdouble   top_weight,
-            gdouble   middle_weight,
-            gdouble   bottom_weight,
-            const T **src,   /* the 9 surrounding source pixels */
-            T        *dest,
-            gint      components)
-{
-   const gdouble lt = left_weight * top_weight;
-   const gdouble lm = left_weight * middle_weight;
-   const gdouble lb = left_weight * bottom_weight;
-   const gdouble ct = center_weight * top_weight;
-   const gdouble cm = center_weight * middle_weight;
-   const gdouble cb = center_weight * bottom_weight;
-   const gdouble rt = right_weight * top_weight;
-   const gdouble rm = right_weight * middle_weight;
-   const gdouble rb = right_weight * bottom_weight;
-
-#define docomponent(i) \
-      dest[i] = double2T (src[0][i] * lt + src[3][i] * lm + src[6][i] * lb + \
-                          src[1][i] * ct + src[4][i] * cm + src[7][i] * cb + \
-                          src[2][i] * rt + src[5][i] * rm + src[8][i] * rb)
-  switch (components)
-    {
-      case 5: docomponent(4);
-      case 4: docomponent(3);
-      case 3: docomponent(2);
-      case 2: docomponent(1);
-      case 1: docomponent(0);
-    }
-#undef docomponent
-}
-
-static void
-resample_boxfilter_T  (guchar              *dest_buf,
-                       const guchar        *source_buf,
-                       const GeglRectangle *dst_rect,
-                       const GeglRectangle *src_rect,
-                       const gint           s_rowstride,
-                       const gdouble        scale,
-                       const gint           components,
-                       const gint           d_rowstride)
-{
-  gdouble  left_weight, center_weight, right_weight;
-  gdouble  top_weight, middle_weight, bottom_weight;
-  const T *src[9];
-  gint     x, y;
-
-  for (y = 0; y < dst_rect->height; y++)
-    {
-      const gdouble  sy = (dst_rect->y + y + .5) / scale - src_rect->y;
-      const gint     ii = floor (sy);
-      T             *dst = (T*)(dest_buf + y * d_rowstride);
-      const guchar  *src_base = source_buf + ii * s_rowstride;
-
-      top_weight    = MAX (0., .5 - scale * (sy - ii));
-      bottom_weight = MAX (0., .5 - scale * ((ii + 1 ) - sy));
-      middle_weight = 1. - top_weight - bottom_weight;
-
-      for (x = 0; x < dst_rect->width; x++)
-        {
-          const gdouble  sx = (dst_rect->x + x + .5) / scale - src_rect->x;
-          const gint     jj = floor (sx);
-
-          left_weight   = MAX (0., .5 - scale * (sx - jj));
-          right_weight  = MAX (0., .5 - scale * ((jj + 1) - sx));
-          center_weight = 1. - left_weight - right_weight;
-
-          src[4] = (const T*)src_base + jj * components;
-          src[1] = (const T*)(src_base - s_rowstride) + jj * components;
-          src[7] = (const T*)(src_base + s_rowstride) + jj * components;
-
-          src[2] = src[1] + components;
-          src[5] = src[4] + components;
-          src[8] = src[7] + components;
-
-          src[0] = src[1] - components;
-          src[3] = src[4] - components;
-          src[6] = src[7] - components;
-
-          box_filter (left_weight,
-                      center_weight,
-                      right_weight,
-                      top_weight,
-                      middle_weight,
-                      bottom_weight,
-                      src,   /* the 9 surrounding source pixels */
-                      dst,
-                      components);
-
-          dst += components;
-        }
-    }
-}
-
 /* Expand roi by scale so it uncludes all pixels needed
  * to satisfy a gegl_buffer_get() call at level 0.
  */
@@ -1453,15 +1315,14 @@ _gegl_get_required_for_scale (const Babl          *format,
     return *roi;
   else
     {
-      gint x1 = floor (roi->x / scale + EPSILON);
-      gint x2 = ceil ((roi->x + roi->width) / scale - EPSILON);
-      gint y1 = floor (roi->y / scale + EPSILON);
-      gint y2 = ceil ((roi->y + roi->height) / scale - EPSILON);
+      gint x1 = floor (roi->x / scale + GEGL_SCALE_EPSILON);
+      gint x2 = ceil ((roi->x + roi->width) / scale - GEGL_SCALE_EPSILON);
+      gint y1 = floor (roi->y / scale + GEGL_SCALE_EPSILON);
+      gint y2 = ceil ((roi->y + roi->height) / scale - GEGL_SCALE_EPSILON);
 
       gint pad = (1.0 / scale > 1.0) ? ceil (1.0 / scale) : 1;
 
-      if ((babl_format_get_type (format, 0) == projectionT) ||
-          (scale < 1.0))
+      if (scale < 1.0)
         {
           return *GEGL_RECTANGLE (x1 - pad,
                                   y1 - pad,
@@ -1536,10 +1397,10 @@ gegl_buffer_get_unlocked (GeglBuffer          *buffer,
       gint          bpp         = babl_format_get_bytes_per_pixel (format);
       GeglRectangle sample_rect;
       void         *sample_buf;
-      gint          x1 = floor (rect->x / scale + EPSILON);
-      gint          x2 = ceil ((rect->x + rect->width) / scale - EPSILON);
-      gint          y1 = floor (rect->y / scale + EPSILON);
-      gint          y2 = ceil ((rect->y + rect->height) / scale - EPSILON);
+      gint          x1 = floor (rect->x / scale + GEGL_SCALE_EPSILON);
+      gint          x2 = ceil ((rect->x + rect->width) / scale - GEGL_SCALE_EPSILON);
+      gint          y1 = floor (rect->y / scale + GEGL_SCALE_EPSILON);
+      gint          y2 = ceil ((rect->y + rect->height) / scale - GEGL_SCALE_EPSILON);
       gint          factor = 1;
       gint          stride;
       gint          offset = 0;
@@ -1559,8 +1420,7 @@ gegl_buffer_get_unlocked (GeglBuffer          *buffer,
       buf_height = y2 - y1;
 
       /* ensure we always have some data to sample from */
-      if (scale != 1.0 && scale < 1.99 &&
-          babl_format_get_type (format, 0) == projectionT)
+      if (scale != 1.0 && scale <= 1.99)
         {
           buf_width  += 2;
           buf_height += 2;
@@ -1584,21 +1444,21 @@ gegl_buffer_get_unlocked (GeglBuffer          *buffer,
       if (rowstride == GEGL_AUTO_ROWSTRIDE)
         rowstride = rect->width * bpp;
 
-      if (scale <= 1.99 && babl_format_get_type (format, 0) == projectionT)
-        { /* do box-filter resampling if we're 8bit (which projections are) */
+      if (scale <= 1.99)
+        {
           sample_rect.x      = x1 - 1;
           sample_rect.y      = y1 - 1;
           sample_rect.width  = x2 - x1 + 2;
           sample_rect.height = y2 - y1 + 2;
 
-          resample_boxfilter_T  (dest_buf,
-                                 sample_buf,
-                                 rect,
-                                 &sample_rect,
-                                 buf_width * bpp,
-                                 scale,
-                                 T_components,
-                                 rowstride);
+          gegl_resample_boxfilter (dest_buf,
+                                   sample_buf,
+                                   rect,
+                                   &sample_rect,
+                                   buf_width * bpp,
+                                   scale,
+                                   format,
+                                   rowstride);
         }
       else
         {
@@ -1607,14 +1467,14 @@ gegl_buffer_get_unlocked (GeglBuffer          *buffer,
           sample_rect.width  = x2 - x1;
           sample_rect.height = y2 - y1;
 
-          resample_nearest (dest_buf,
-                            sample_buf,
-                            rect,
-                            &sample_rect,
-                            buf_width * bpp,
-                            scale,
-                            bpp,
-                            rowstride);
+          gegl_resample_nearest (dest_buf,
+                                 sample_buf,
+                                 rect,
+                                 &sample_rect,
+                                 buf_width * bpp,
+                                 scale,
+                                 bpp,
+                                 rowstride);
         }
       g_free (sample_buf);
     }
diff --git a/gegl/gegl-algorithms-boxfilter.inc b/gegl/gegl-algorithms-boxfilter.inc
new file mode 100644
index 0000000..21514eb
--- /dev/null
+++ b/gegl/gegl-algorithms-boxfilter.inc
@@ -0,0 +1,71 @@
+void
+BOXFILTER_FUNCNAME (guchar              *dest_buf,
+                    const guchar        *source_buf,
+                    const GeglRectangle *dst_rect,
+                    const GeglRectangle *src_rect,
+                    const gint           s_rowstride,
+                    const gdouble        scale,
+                    const gint           components,
+                    const gint           d_rowstride)
+{
+  gdouble  left_weight, center_weight, right_weight;
+  gdouble  top_weight, middle_weight, bottom_weight;
+  const BOXFILTER_TYPE *src[9];
+  gint     x, y;
+
+  for (y = 0; y < dst_rect->height; y++)
+    {
+      const gdouble  sy = (dst_rect->y + y + .5) / scale - src_rect->y;
+      const gint     ii = floor (sy);
+      BOXFILTER_TYPE             *dst = (BOXFILTER_TYPE*)(dest_buf + y * d_rowstride);
+      const guchar  *src_base = source_buf + ii * s_rowstride;
+
+      top_weight    = MAX (0., .5 - scale * (sy - ii));
+      bottom_weight = MAX (0., .5 - scale * ((ii + 1 ) - sy));
+      middle_weight = 1. - top_weight - bottom_weight;
+
+      for (x = 0; x < dst_rect->width; x++)
+        {
+          const gdouble  sx = (dst_rect->x + x + .5) / scale - src_rect->x;
+          const gint     jj = floor (sx);
+
+          left_weight   = MAX (0., .5 - scale * (sx - jj));
+          right_weight  = MAX (0., .5 - scale * ((jj + 1) - sx));
+          center_weight = 1. - left_weight - right_weight;
+
+          src[4] = (const BOXFILTER_TYPE*)src_base + jj * components;
+          src[1] = (const BOXFILTER_TYPE*)(src_base - s_rowstride) + jj * components;
+          src[7] = (const BOXFILTER_TYPE*)(src_base + s_rowstride) + jj * components;
+
+          src[2] = src[1] + components;
+          src[5] = src[4] + components;
+          src[8] = src[7] + components;
+
+          src[0] = src[1] - components;
+          src[3] = src[4] - components;
+          src[6] = src[7] - components;
+
+          {
+            const gdouble lt = left_weight * top_weight;
+            const gdouble lm = left_weight * middle_weight;
+            const gdouble lb = left_weight * bottom_weight;
+            const gdouble ct = center_weight * top_weight;
+            const gdouble cm = center_weight * middle_weight;
+            const gdouble cb = center_weight * bottom_weight;
+            const gdouble rt = right_weight * top_weight;
+            const gdouble rm = right_weight * middle_weight;
+            const gdouble rb = right_weight * bottom_weight;
+
+            for (gint i = 0; i < components; ++i)
+              {
+                dst[i] = BOXFILTER_ROUND(
+                  src[0][i] * lt + src[3][i] * lm + src[6][i] * lb +
+                  src[1][i] * ct + src[4][i] * cm + src[7][i] * cb +
+                  src[2][i] * rt + src[5][i] * rm + src[8][i] * rb);
+              }
+          }
+
+          dst += components;
+        }
+    }
+}
diff --git a/gegl/gegl-algorithms.c b/gegl/gegl-algorithms.c
new file mode 100644
index 0000000..273f20c
--- /dev/null
+++ b/gegl/gegl-algorithms.c
@@ -0,0 +1,164 @@
+/* This file is part of GEGL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2006,2007 Øyvind Kolås <pippin gimp org>
+ *           2013 Daniel Sabo
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib-object.h>
+
+#include <babl/babl.h>
+
+#include "gegl-types.h"
+#include "gegl-algorithms.h"
+
+#include <math.h>
+
+void gegl_resample_boxfilter (guchar              *dest_buf,
+                              const guchar        *source_buf,
+                              const GeglRectangle *dst_rect,
+                              const GeglRectangle *src_rect,
+                              gint                 s_rowstride,
+                              gdouble              scale,
+                              const Babl          *format,
+                              gint                 d_rowstride)
+{
+  const Babl *comp_type  = babl_format_get_type (format, 0);
+  guint num_componenets;
+
+  void (*resample_boxfilter_func) (guchar              *dest_buf,
+                                   const guchar        *source_buf,
+                                   const GeglRectangle *dst_rect,
+                                   const GeglRectangle *src_rect,
+                                   gint                 s_rowstride,
+                                   gdouble              scale,
+                                   gint                 components,
+                                   gint                 d_rowstride) = NULL;
+
+  if (comp_type == babl_type ("u8"))
+    {
+      resample_boxfilter_func = gegl_resample_boxfilter_u8;
+    }
+  else if (comp_type == babl_type ("u16"))
+    {
+      resample_boxfilter_func = gegl_resample_boxfilter_u16;
+    }
+  else if (comp_type == babl_type ("u32"))
+    {
+      resample_boxfilter_func = gegl_resample_boxfilter_u32;
+    }
+  else if (comp_type == babl_type ("float"))
+    {
+      resample_boxfilter_func = gegl_resample_boxfilter_float;
+    }
+  else
+    {
+      gegl_resample_nearest (dest_buf,
+                             source_buf,
+                             dst_rect,
+                             src_rect,
+                             s_rowstride,
+                             scale,
+                             babl_format_get_bytes_per_pixel (format),
+                             d_rowstride);
+      return;
+    }
+
+  num_componenets = babl_format_get_n_components (format);
+
+  resample_boxfilter_func (dest_buf,
+                           source_buf,
+                           dst_rect,
+                           src_rect,
+                           s_rowstride,
+                           scale,
+                           num_componenets,
+                           d_rowstride);
+}
+
+void
+gegl_resample_nearest (guchar              *dst,
+                       const guchar        *src,
+                       const GeglRectangle *dst_rect,
+                       const GeglRectangle *src_rect,
+                       const gint           src_stride,
+                       const gdouble        scale,
+                       const gint           bpp,
+                       const gint           dst_stride)
+{
+  int i, j;
+
+  for (i = 0; i < dst_rect->height; i++)
+    {
+      const gdouble sy = (dst_rect->y + .5 + i) / scale - src_rect->y;
+      const gint    ii = floor (sy + GEGL_SCALE_EPSILON);
+
+      for (j = 0; j < dst_rect->width; j++)
+        {
+          const gdouble sx = (dst_rect->x + .5 + j) / scale - src_rect->x;
+          const gint    jj = floor (sx + GEGL_SCALE_EPSILON);
+
+          memcpy (&dst[i * dst_stride + j * bpp],
+                  &src[ii * src_stride + jj * bpp],
+                  bpp);
+        }
+    }
+}
+
+/*
+#define BOXFILTER_FUNCNAME   gegl_resample_boxfilter_double
+#define BOXFILTER_TYPE       gdouble
+#define BOXFILTER_ROUND(val) (val)
+#include "gegl-algorithms-boxfilter.inc"
+#undef BOXFILTER_FUNCNAME
+#undef BOXFILTER_TYPE
+#undef BOXFILTER_ROUND
+*/
+
+#define BOXFILTER_FUNCNAME   gegl_resample_boxfilter_float
+#define BOXFILTER_TYPE       gfloat
+#define BOXFILTER_ROUND(val) (val)
+#include "gegl-algorithms-boxfilter.inc"
+#undef BOXFILTER_FUNCNAME
+#undef BOXFILTER_TYPE
+#undef BOXFILTER_ROUND
+
+#define BOXFILTER_FUNCNAME   gegl_resample_boxfilter_u8
+#define BOXFILTER_TYPE       guchar
+#define BOXFILTER_ROUND(val) (lrint(val))
+#include "gegl-algorithms-boxfilter.inc"
+#undef BOXFILTER_FUNCNAME
+#undef BOXFILTER_TYPE
+#undef BOXFILTER_ROUND
+
+#define BOXFILTER_FUNCNAME   gegl_resample_boxfilter_u16
+#define BOXFILTER_TYPE       guint16
+#define BOXFILTER_ROUND(val) (lrint(val))
+#include "gegl-algorithms-boxfilter.inc"
+#undef BOXFILTER_FUNCNAME
+#undef BOXFILTER_TYPE
+#undef BOXFILTER_ROUND
+
+#define BOXFILTER_FUNCNAME   gegl_resample_boxfilter_u32
+#define BOXFILTER_TYPE       guint32
+#define BOXFILTER_ROUND(val) (lrint(val))
+#include "gegl-algorithms-boxfilter.inc"
+#undef BOXFILTER_FUNCNAME
+#undef BOXFILTER_TYPE
+#undef BOXFILTER_ROUND
\ No newline at end of file
diff --git a/gegl/gegl-algorithms.h b/gegl/gegl-algorithms.h
new file mode 100644
index 0000000..8008f28
--- /dev/null
+++ b/gegl/gegl-algorithms.h
@@ -0,0 +1,101 @@
+/* This file is part of GEGL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * 2013 Daniel Sabo
+ */
+
+
+#ifndef __GEGL_ALGORITHMS_H__
+#define __GEGL_ALGORITHMS_H__
+
+G_BEGIN_DECLS
+
+#define GEGL_SCALE_EPSILON 1.e-6
+
+/*
+typedef void (GeglBoxfilterFunction *) (guchar              *dest_buf,
+                                        const guchar        *source_buf,
+                                        const GeglRectangle *dst_rect,
+                                        const GeglRectangle *src_rect,
+                                        gint                 s_rowstride,
+                                        gdouble              scale,
+                                        gint                 components,
+                                        gint                 d_rowstride);
+
+GeglBoxfilterFunction *
+gegl_resample_get_boxfilter_function (const Babl *format);
+*/
+
+/* Attempt to resable with a 3x3 boxfilter, if no boxfilter is
+ * available for #format fall back to nearest neighbor.
+ * #scale is assumed to be between 0.5 and +inf.
+ */
+void gegl_resample_boxfilter (guchar              *dest_buf,
+                              const guchar        *source_buf,
+                              const GeglRectangle *dst_rect,
+                              const GeglRectangle *src_rect,
+                              gint                 s_rowstride,
+                              gdouble              scale,
+                              const Babl          *format,
+                              gint                 d_rowstride);
+
+void gegl_resample_boxfilter_float (guchar              *dest_buf,
+                                    const guchar        *source_buf,
+                                    const GeglRectangle *dst_rect,
+                                    const GeglRectangle *src_rect,
+                                    gint                 s_rowstride,
+                                    gdouble              scale,
+                                    gint                 components,
+                                    gint                 d_rowstride);
+
+void gegl_resample_boxfilter_u32 (guchar              *dest_buf,
+                                  const guchar        *source_buf,
+                                  const GeglRectangle *dst_rect,
+                                  const GeglRectangle *src_rect,
+                                  gint                 s_rowstride,
+                                  gdouble              scale,
+                                  gint                 components,
+                                  gint                 d_rowstride);
+
+void gegl_resample_boxfilter_u16 (guchar              *dest_buf,
+                                  const guchar        *source_buf,
+                                  const GeglRectangle *dst_rect,
+                                  const GeglRectangle *src_rect,
+                                  gint                 s_rowstride,
+                                  gdouble              scale,
+                                  gint                 components,
+                                  gint                 d_rowstride);
+
+void gegl_resample_boxfilter_u8 (guchar              *dest_buf,
+                                 const guchar        *source_buf,
+                                 const GeglRectangle *dst_rect,
+                                 const GeglRectangle *src_rect,
+                                 gint                 s_rowstride,
+                                 gdouble              scale,
+                                 gint                 components,
+                                 gint                 d_rowstride);
+
+void gegl_resample_nearest (guchar              *dst,
+                            const guchar        *src,
+                            const GeglRectangle *dst_rect,
+                            const GeglRectangle *src_rect,
+                            gint                 src_stride,
+                            gdouble              scale,
+                            gint                 bpp,
+                            gint                 dst_stride);
+
+G_END_DECLS
+
+#endif /* __GEGL_ALGORITHMS_H__ */
\ No newline at end of file


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