Index: paint-funcs.c
===================================================================
RCS file: /cvs/gnome/gimp/app/paint-funcs/paint-funcs.c,v
retrieving revision 1.166
diff -u -r1.166 paint-funcs.c
--- paint-funcs.c	30 Jul 2004 00:57:21 -0000	1.166
+++ paint-funcs.c	17 Sep 2004 16:46:43 -0000
@@ -153,8 +153,14 @@
 
 static inline void rotate_pointers       (guchar         **p,
                                           guint32          n);
-
-
+static void
+separate_alpha (guchar *buf,
+                gint    width,
+                gint    bytes);
+static void
+separate_alpha (guchar *buf,
+                gint    width,
+                gint    bytes);
 
 static void
 update_tile_rowhints (Tile *tile,
@@ -2640,7 +2646,8 @@
 void
 gaussian_blur_region (PixelRegion *srcR,
                       gdouble      radius_x,
-                      gdouble      radius_y)
+                      gdouble      radius_y,
+                      gboolean     has_alpha)
 {
   gdouble std_dev;
   glong   width, height;
@@ -2691,6 +2698,8 @@
       for (col = 0; col < width; col++)
         {
           pixel_region_get_col (srcR, col + srcR->x, srcR->y, height, src, 1);
+          if (has_alpha)
+            multiply_alpha (src, height, bytes);
           sp = src + alpha;
 
           initial_p = sp[0];
@@ -2727,6 +2736,8 @@
 
               sp[row * bytes] = val / total;
             }
+         if (has_alpha)
+            separate_alpha (src, height, bytes);
 
           pixel_region_set_col (srcR, col + srcR->x, srcR->y, height, src);
         }
@@ -5147,3 +5158,47 @@
 {
   replace_pixels (src1, src2, dest, mask, length, opacity, affect, bytes1, bytes2);
 }
+
+/* Convert from separated to premultiplied alpha, on a single scan line. */
+static void
+multiply_alpha (guchar *buf,
+                gint    width,
+                gint    bytes)
+{
+  gint    i, j;
+  gdouble alpha;
+
+  for (i = 0; i < width * bytes; i += bytes)
+    {
+      alpha = buf[i + bytes - 1] * (1.0 / 255.0);
+      for (j = 0; j < bytes - 1; j++)
+        buf[i + j] *= alpha;
+    }
+}
+
+/* Convert from premultiplied to separated alpha, on a single scan
+   line. */
+static void
+separate_alpha (guchar *buf,
+                gint    width,
+                gint    bytes)
+{
+  gint   i, j;
+  guchar alpha;
+  gdouble recip_alpha;
+  gint    new_val;
+
+  for (i = 0; i < width * bytes; i += bytes)
+    {
+      alpha = buf[i + bytes - 1];
+      if (alpha != 0 && alpha != 255)
+        {
+          recip_alpha = 255.0 / alpha;
+          for (j = 0; j < bytes - 1; j++)
+            {
+              new_val = buf[i + j] * recip_alpha;
+              buf[i + j] = MIN (255, new_val);
+            }
+        }
+    }
+}
\ No newline at end of file
