Index: libpipi/trunk/pipi/filter/convolution.c
===================================================================
--- libpipi/trunk/pipi/filter/convolution.c	(revision 2710)
+++ libpipi/trunk/pipi/filter/convolution.c	(revision 2793)
@@ -28,49 +28,8 @@
 #include "pipi_internals.h"
 
-#define FLAG_GRAY ((FLAGS) & SET_FLAG_GRAY)
-#define FLAG_WRAP ((FLAGS) & SET_FLAG_WRAP)
-
-#define SET_FLAG_GRAY 0x01
-#define SET_FLAG_WRAP 0x02
-
-#undef FUNC1
-#undef FUNC2
-#undef PIXEL
-#undef FLAGS
-#define FUNC1 conv_std_rgba_f
-#define FUNC2 conv_sep_rgba_f
-#define PIXEL float
-#define FLAGS 0
-#include "convolution_template.h"
-
-#undef FUNC1
-#undef FUNC2
-#undef PIXEL
-#undef FLAGS
-#define FUNC1 conv_std_y_f
-#define FUNC2 conv_sep_y_f
-#define PIXEL float
-#define FLAGS SET_FLAG_GRAY
-#include "convolution_template.h"
-
-#undef FUNC1
-#undef FUNC2
-#undef PIXEL
-#undef FLAGS
-#define FUNC1 wrap_std_rgba_f
-#define FUNC2 wrap_sep_rgba_f
-#define PIXEL float
-#define FLAGS SET_FLAG_WRAP
-#include "convolution_template.h"
-
-#undef FUNC1
-#undef FUNC2
-#undef PIXEL
-#undef FLAGS
-#define FUNC1 wrap_std_y_f
-#define FUNC2 wrap_sep_y_f
-#define PIXEL float
-#define FLAGS SET_FLAG_GRAY|SET_FLAG_WRAP
-#include "convolution_template.h"
+#if !defined TEMPLATE_FILE /* This file uses the template system */
+#define TEMPLATE_FLAGS SET_FLAG_GRAY | SET_FLAG_WRAP
+#define TEMPLATE_FILE "filter/convolution.c"
+#include "pipi_template.h"
 
 pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
@@ -116,12 +75,12 @@
                 {
                     if(src->wrap)
-                        return wrap_std_y_f(src, m, n, mat);
-                    return conv_std_y_f(src, m, n, mat);
+                        return conv_gray_wrap(src, m, n, mat);
+                    return conv_gray(src, m, n, mat);
                 }
                 else
                 {
                     if(src->wrap)
-                        return wrap_std_rgba_f(src, m, n, mat);
-                    return conv_std_rgba_f(src, m, n, mat);
+                        return conv_wrap(src, m, n, mat);
+                    return conv(src, m, n, mat);
                 }
             }
@@ -140,9 +99,9 @@
 
     if(src->last_modified == PIPI_PIXELS_Y_F)
-        ret = src->wrap ? wrap_sep_y_f(src, m, hvec, n, vvec)
-                        : conv_sep_y_f(src, m, hvec, n, vvec);
+        ret = src->wrap ? sepconv_gray_wrap(src, m, hvec, n, vvec)
+                        : sepconv_gray(src, m, hvec, n, vvec);
     else
-        ret = src->wrap ? wrap_sep_rgba_f(src, m, hvec, n, vvec)
-                        : conv_sep_rgba_f(src, m, hvec, n, vvec);
+        ret = src->wrap ? sepconv_wrap(src, m, hvec, n, vvec)
+                        : sepconv(src, m, hvec, n, vvec);
 
     free(hvec);
@@ -152,2 +111,206 @@
 }
 
+#else /* XXX: the following functions use the template system */
+
+static pipi_image_t *SUFFIX(conv)(pipi_image_t *src,
+                                  int m, int n, double mat[])
+{
+    pipi_image_t *dst;
+    pipi_pixels_t *srcp, *dstp;
+    float *srcdata, *dstdata;
+    int x, y, i, j, w, h;
+
+    w = src->w;
+    h = src->h;
+
+    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
+                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
+    srcdata = (float *)srcp->pixels;
+
+    dst = pipi_new(w, h);
+    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
+                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
+    dstdata = (float *)dstp->pixels;
+
+    for(y = 0; y < h; y++)
+    {
+        for(x = 0; x < w; x++)
+        {
+            if(FLAG_GRAY)
+            {
+                double Y = 0.;
+                int x2, y2;
+
+                for(j = 0; j < n; j++)
+                {
+                    y2 = y + j - n / 2;
+                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
+                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
+
+                    for(i = 0; i < m; i++)
+                    {
+                        x2 = x + i - m / 2;
+                        if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
+                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
+
+                        Y += mat[j * m + i] * srcdata[y2 * w + x2];
+                    }
+                }
+
+                dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y;
+            }
+            else
+            {
+                double R = 0., G = 0., B = 0.;
+                int x2, y2, off = 4 * (y * w + x);
+
+                for(j = 0; j < n; j++)
+                {
+                    y2 = y + j - n / 2;
+                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
+                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
+
+                    for(i = 0; i < m; i++)
+                    {
+                        double f = mat[j * m + i];
+
+                        x2 = x + i - m / 2;
+                        if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
+                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
+
+                        R += f * srcdata[(y2 * w + x2) * 4];
+                        G += f * srcdata[(y2 * w + x2) * 4 + 1];
+                        B += f * srcdata[(y2 * w + x2) * 4 + 2];
+                    }
+                }
+
+                dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R;
+                dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G;
+                dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B;
+            }
+        }
+    }
+
+    return dst;
+}
+
+static pipi_image_t *SUFFIX(sepconv)(pipi_image_t *src,
+                            int m, double hvec[], int n, double vvec[])
+{
+    pipi_image_t *dst;
+    pipi_pixels_t *srcp, *dstp;
+    float *srcdata, *dstdata;
+    double *buffer;
+    int x, y, i, j, w, h;
+
+    w = src->w;
+    h = src->h;
+
+    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
+                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
+    srcdata = (float *)srcp->pixels;
+
+    dst = pipi_new(w, h);
+    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
+                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
+    dstdata = (float *)dstp->pixels;
+
+    buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double));
+
+    for(y = 0; y < h; y++)
+    {
+        for(x = 0; x < w; x++)
+        {
+            if(FLAG_GRAY)
+            {
+                double Y = 0.;
+                int x2;
+
+                for(i = 0; i < m; i++)
+                {
+                    x2 = x + i - m / 2;
+                    if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
+                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
+
+                    Y += hvec[i] * srcdata[y * w + x2];
+                }
+
+                buffer[y * w + x] = Y;
+            }
+            else
+            {
+                double R = 0., G = 0., B = 0.;
+                int x2, off = 4 * (y * w + x);
+
+                for(i = 0; i < m; i++)
+                {
+                    double f = hvec[i];
+
+                    x2 = x + i - m / 2;
+                    if(x2 < 0) x2 = FLAG_WRAP ? w - 1 - ((-x2 - 1) % w) : 0;
+                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
+
+                    R += f * srcdata[(y * w + x2) * 4];
+                    G += f * srcdata[(y * w + x2) * 4 + 1];
+                    B += f * srcdata[(y * w + x2) * 4 + 2];
+                }
+
+                buffer[off] = R;
+                buffer[off + 1] = G;
+                buffer[off + 2] = B;
+            }
+        }
+    }
+
+    for(y = 0; y < h; y++)
+    {
+        for(x = 0; x < w; x++)
+        {
+            if(FLAG_GRAY)
+            {
+                double Y = 0.;
+                int y2;
+
+                for(j = 0; j < n; j++)
+                {
+                    y2 = y + j - n / 2;
+                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
+                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
+
+                    Y += vvec[j] * buffer[y2 * w + x];
+                }
+
+                dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y;
+            }
+            else
+            {
+                double R = 0., G = 0., B = 0.;
+                int y2, off = 4 * (y * w + x);
+
+                for(j = 0; j < n; j++)
+                {
+                    double f = vvec[j];
+
+                    y2 = y + j - n / 2;
+                    if(y2 < 0) y2 = FLAG_WRAP ? h - 1 - ((-y2 - 1) % h) : 0;
+                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
+
+                    R += f * buffer[(y2 * w + x) * 4];
+                    G += f * buffer[(y2 * w + x) * 4 + 1];
+                    B += f * buffer[(y2 * w + x) * 4 + 2];
+                }
+
+                dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R;
+                dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G;
+                dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B;
+            }
+        }
+    }
+
+    free(buffer);
+
+    return dst;
+}
+
+#endif
+
