--- gimp-1.3.12.orig/plug-ins/common/whirlpinch.c	2003-01-09 23:01:23.000000000 +0100
+++ gimp-1.3.12/plug-ins/common/whirlpinch.c	2003-03-02 03:00:51.000000000 +0100
@@ -342,6 +342,68 @@
   gimp_drawable_detach (drawable);
 }
 
+/*
+ * gimp_bilinear_8 () equivalent, but on whole pixels.
+ * FIXME: this shouldn't be called gimp_*
+ *        OTOH something like this should probably go to libgimpcolor
+ */
+static void
+gimp_bilinear_pixels_8 (guchar *dest,
+                        gdouble x,
+                        gdouble y,
+                        guint bpp,
+                        gboolean has_alpha,
+                        guchar **values)
+{
+  guint i;
+
+  g_assert (dest != NULL);
+  g_assert (values != NULL);
+  for (i = 0; i < bpp; i++)
+    g_assert (values[i]);
+
+  x = fmod (x, 1.0);
+  y = fmod (y, 1.0);
+
+  if (x < 0.0)
+    x += 1.0;
+  if (y < 0.0)
+    y += 1.0;
+
+  if (has_alpha)
+    {
+      guint ai = bpp-1;
+      gdouble alpha0 = values[0][ai];
+      gdouble alpha1 = values[1][ai];
+      gdouble alpha2 = values[2][ai];
+      gdouble alpha3 = values[3][ai];
+      gdouble alpha = (1.0 - y) * ((1.0 - x) * alpha0 + x * alpha1)
+                      + y * ((1.0 - x) * alpha2 + x * alpha3);
+
+      dest[ai] = (guchar) alpha;
+      if (dest[ai])
+        {
+          for (i = 0; i < ai; i++)
+            {
+              gdouble m0 = (1.0 - x) * values[0][i] * alpha0
+                          + x * values[1][i] * alpha1;
+              gdouble m1 = (1.0 - x) * values[2][i] * alpha2
+                          + x * values[3][i] * alpha3;
+              dest[i] = (guchar) (((1.0 - y) * m0 + y * m1) / alpha);
+            }
+        }
+    }
+  else
+    {
+      for (i = 0; i < bpp; i++)
+        {
+          gdouble m0 = (1.0 - x) * values[0][i] + x * values[1][i];
+          gdouble m1 = (1.0 - x) * values[2][i] + x * values[3][i];
+          dest[i] = (guchar) ((1.0 - y) * m0 + y * m1);
+        }
+    }
+}
+
 static void
 whirl_pinch (void)
 {
@@ -350,8 +412,7 @@
   guchar          *top_row, *bot_row;
   guchar          *top_p, *bot_p;
   gint             row, col;
-  guchar           pixel[4][4];
-  guchar           values[4];
+  guchar           **pixel;
   double           whirl;
   double           cx, cy;
   int              ix, iy;
@@ -361,6 +422,9 @@
   /* Initialize rows */
   top_row = g_malloc (img_bpp * sel_width);
   bot_row = g_malloc (img_bpp * sel_width);
+  pixel = g_new (guchar *, 4);
+  for (i = 0; i < 4; i++)
+    pixel[i] = g_new (guchar, 4);
 
   /* Initialize pixel region */
   gimp_pixel_rgn_init (&dest_rgn, drawable,
@@ -408,16 +472,9 @@
 	      gimp_pixel_fetcher_get_pixel (pft, ix,     iy + 1, pixel[2]);
 	      gimp_pixel_fetcher_get_pixel (pft, ix + 1, iy + 1, pixel[3]);
 
-	      for (i = 0; i < img_bpp; i++)
-		{
-		  values[0] = pixel[0][i];
-		  values[1] = pixel[1][i];
-		  values[2] = pixel[2][i];
-		  values[3] = pixel[3][i];
-
-		  *top_p++ = gimp_bilinear_8 (cx, cy, values);
-		}
-
+              gimp_bilinear_pixels_8 (top_p, cx, cy, img_bpp, img_has_alpha,
+                                      pixel);
+              top_p += img_bpp;
 	      /* Bottom */
 
 	      cx = cen_x + (cen_x - cx);
@@ -438,17 +495,9 @@
 	      gimp_pixel_fetcher_get_pixel (pfb, ix,     iy + 1, pixel[2]);
 	      gimp_pixel_fetcher_get_pixel (pfb, ix + 1, iy + 1, pixel[3]);
 
-	      for (i = 0; i < img_bpp; i++)
-		{
-		  values[0] = pixel[0][i];
-		  values[1] = pixel[1][i];
-		  values[2] = pixel[2][i];
-		  values[3] = pixel[3][i];
-
-		  *bot_p++ = gimp_bilinear_8 (cx, cy, values);
-		}
-
-	      bot_p -= 2 * img_bpp; /* We move backwards! */
+              gimp_bilinear_pixels_8 (bot_p, cx, cy, img_bpp, img_has_alpha,
+                                      pixel);
+              bot_p -= img_bpp;
 	    }
 	  else
 	    {
@@ -492,6 +541,9 @@
   gimp_pixel_fetcher_destroy (pft);
   gimp_pixel_fetcher_destroy (pfb);
 
+  for (i = 0; i < 4; i++)
+    g_free (pixel[i]);
+  g_free (pixel);
   g_free (top_row);
   g_free (bot_row);
 
