--- rsvg-filter - Kopie.c	2012-08-19 17:59:52 +0000
+++ rsvg-filter.c	2012-11-20 02:39:16 +0000
@@ -1341,17 +1341,20 @@
 };
 
 static void
-box_blur (cairo_surface_t *in, 
-          cairo_surface_t *output, 
-          guchar *intermediate, 
+box_blur (cairo_surface_t *in,
+          cairo_surface_t *output,
           gint kw,
-          gint kh, 
-          RsvgIRect boundarys, 
+          gint kh,
+          gint shiftx,
+          gint shifty,
+          RsvgIRect boundarys,
           RsvgFilterPrimitiveOutput op)
 {
     gint ch;
     gint x, y;
+    gint offset;
     gint rowstride;
+    guchar *intermediate;
     guchar *in_pixels;
     guchar *output_pixels;
     gint sum;
@@ -1361,14 +1364,9 @@
 
     rowstride = cairo_image_surface_get_stride (in);
 
-    if (kw > boundarys.x1 - boundarys.x0)
-        kw = boundarys.x1 - boundarys.x0;
-
-    if (kh > boundarys.y1 - boundarys.y0)
-        kh = boundarys.y1 - boundarys.y0;
+    intermediate = g_new (guchar, MAX (kw, kh));
 
-
-    if (kw >= 1) {
+    if (kw > 1) {
         for (ch = 0; ch < 4; ch++) {
             switch (ch) {
             case 0:
@@ -1384,31 +1382,32 @@
                 if (!op.Aused)
                     continue;
             }
+
+            offset = shiftx - kw / 2;
             for (y = boundarys.y0; y < boundarys.y1; y++) {
                 sum = 0;
                 for (x = boundarys.x0; x < boundarys.x0 + kw; x++) {
                     sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);
-
-                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
-                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
+                    if (x + offset >= 0 && x + offset < boundarys.x1)
+                        output_pixels[4 * (x + offset) + y * rowstride + ch] = sum / (x - boundarys.x0 + 1);
                 }
                 for (x = boundarys.x0 + kw; x < boundarys.x1; x++) {
                     sum -= intermediate[x % kw];
                     sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);
-                    output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
+                    if (x + offset >= 0 && x + offset < boundarys.x1)
+                        output_pixels[4 * (x + offset) + y * rowstride + ch] = sum / kw;
                 }
                 for (x = boundarys.x1; x < boundarys.x1 + kw; x++) {
                     sum -= intermediate[x % kw];
-
-                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
-                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
+                    if (x + offset >= 0 && x + offset < boundarys.x1)
+                        output_pixels[4 * (x + offset) + y * rowstride + ch] = sum / (boundarys.x1 + kw - x);
                 }
             }
         }
         in_pixels = output_pixels;
     }
 
-    if (kh >= 1) {
+    if (kh > 1) {
         for (ch = 0; ch < 4; ch++) {
             switch (ch) {
             case 0:
@@ -1425,30 +1424,31 @@
                     continue;
             }
 
-
+            offset = shifty - kh / 2;
             for (x = boundarys.x0; x < boundarys.x1; x++) {
                 sum = 0;
 
                 for (y = boundarys.y0; y < boundarys.y0 + kh; y++) {
                     sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);
-
-                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
-                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
+                    if (y + offset >= 0 && y + offset < boundarys.y1)
+                        output_pixels[4 * x + (y + offset) * rowstride + ch] = sum / (y - boundarys.y0 + 1);
                 }
                 for (y = boundarys.y0 + kh; y < boundarys.y1; y++) {
                     sum -= intermediate[y % kh];
                     sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);
-                    output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
+                    if (y + offset >= 0 && y + offset < boundarys.y1)
+                        output_pixels[4 * x + (y + offset) * rowstride + ch] = sum / kh;
                 }
                 for (y = boundarys.y1; y < boundarys.y1 + kh; y++) {
                     sum -= intermediate[y % kh];
-
-                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
-                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
+                    if (y + offset >= 0 && y + offset < boundarys.y1)
+                        output_pixels[4 * x + (y + offset) * rowstride + ch] = sum / (boundarys.y1 + kh - y);
                 }
             }
         }
     }
+    
+    g_free (intermediate);
 }
 
 static void
@@ -1460,23 +1460,33 @@
            RsvgFilterPrimitiveOutput op)
 {
     gint kx, ky;
-    guchar *intermediate;
 
     cairo_surface_flush (in);
 
     kx = floor (sx * 3 * sqrt (2 * M_PI) / 4 + 0.5);
     ky = floor (sy * 3 * sqrt (2 * M_PI) / 4 + 0.5);
 
-    if (kx < 1 && ky < 1)
-        return;
-
-    intermediate = g_new (guchar, MAX (kx, ky));
-
-    box_blur (in, output, intermediate, kx, ky, boundarys, op);
-    box_blur (output, output, intermediate, kx, ky, boundarys, op);
-    box_blur (output, output, intermediate, kx, ky, boundarys, op);
-
-    g_free (intermediate);
+    if (kx > boundarys.x1 - boundarys.x0)
+        kx = boundarys.x1 - boundarys.x0;
+    if (ky > boundarys.y1 - boundarys.y0)
+        ky = boundarys.y1 - boundarys.y0;
+    if (kx < 1) kx = 1;
+    if (ky < 1) ky = 1;
+
+    if (kx <= 1 && ky <= 1)
+    {
+        size_t size;
+        guchar *in_pixels;
+        guchar *output_pixels;
+        size = cairo_image_surface_get_stride (output) * cairo_image_surface_get_height (output);
+        in_pixels = cairo_image_surface_get_data (in);
+        output_pixels = cairo_image_surface_get_data (output);
+        memcpy (output_pixels, in_pixels, size); 
+    } else {
+        box_blur (in, output, kx, ky, 0, 0, boundarys, op);
+        box_blur (output, output, kx, ky, (kx+1) % 2, (ky+1) % 2, boundarys, op);
+        box_blur (output, output, kx + (kx+1) % 2, ky + (ky+1) % 2, 0, 0, boundarys, op);
+    }
 
     cairo_surface_mark_dirty (output);
 }
