--- /tmp/config.h.in	2006-12-23 00:00:38.000000000 +0100
+++ gtk+-2.10.6/config.h.in	2006-12-23 00:01:05.632227000 +0100
@@ -253,3 +253,7 @@
 
 /* Define to `int' if <sys/types.h> doesn't define. */
 #undef uid_t
+
+/* Define to use integer math rather than floating point where possible.  */
+#undef ENABLE_INTEGER_PIXOPS
+
--- /tmp/configure.in	2006-12-23 00:02:16.000000000 +0100
+++ gtk+-2.10.6/configure.in	2006-12-23 00:05:11.172227000 +0100
@@ -203,6 +203,15 @@
               [AC_HELP_STRING([--disable-rebuilds],
                               [disable all source autogeneration rules])],,
               [enable_rebuilds=yes])
+AC_ARG_ENABLE(integer-pixops, 
+              [AC_HELP_STRING([--enable-integer-pixops],
+	                      [use integer math where possible])],,
+	      [enable_integer_pixops=no])
+
+if test "x$enable_integer_pixops" = "xyes"; then
+  AC_DEFINE(ENABLE_INTEGER_PIXOPS)
+fi
+
 AC_ARG_ENABLE(visibility,
               [AC_HELP_STRING([--disable-visibility],
                               [don't use ELF visibility attributes])],,
--- /tmp/pixops.c	2006-12-23 10:04:02.000000000 +0100
+++ gtk+-2.10.6/gdk-pixbuf/pixops/pixops.c	2006-12-23 10:04:21.772227000 +0100
@@ -28,6 +28,10 @@
 #define SUBSAMPLE_MASK ((1 << SUBSAMPLE_BITS)-1)
 #define SCALE_SHIFT 16
 
+#ifdef ENABLE_INTEGER_PIXOPS
+#define FRAC 0x10000ULL
+#endif
+
 typedef struct _PixopsFilter PixopsFilter;
 typedef struct _PixopsFilterDimension PixopsFilterDimension;
 
@@ -972,6 +976,29 @@
   (*pixel_func) (dest, dest_x, dest_channels, dest_has_alpha, src_has_alpha, check_size, color1, color2, r, g, b, a);
 }
 
+#ifdef ENABLE_INTEGER_PIXOPS
+
+static void
+correct_total (int    *weights,
+               int    n_x,
+               int    n_y,
+               int    total,
+               unsigned long overall_alpha)
+{
+  int correction = (int)(overall_alpha - total);
+  int i;
+  for (i = n_x * n_y - 1; i >= 0; i--)
+    {
+      if (*(weights + i) + correction >= 0)
+       {
+         *(weights + i) += correction;
+         break;
+       }
+    }
+}
+
+#else
+
 static void 
 correct_total (int    *weights, 
                int    n_x, 
@@ -998,6 +1025,8 @@
     }
 }
 
+#endif
+
 static int *
 make_filter_table (PixopsFilter *filter)
 {
@@ -1026,7 +1055,11 @@
               *(pixel_weights + n_x * i + j) = weight;
             }
 
-        correct_total (pixel_weights, n_x, n_y, total, filter->overall_alpha);
+#ifdef ENABLE_INTEGER_PIXOPS   
+        correct_total (pixel_weights, n_x, n_y, total, overall_alpha * FRAC);
+#else
+        correct_total (pixel_weights, n_x, n_y, total, overall_alpha);
+#endif
       }
 
   return weights;
@@ -1178,6 +1211,93 @@
 /* Compute weights for reconstruction by replication followed by
  * sampling with a box filter
  */
+#ifdef ENABLE_INTEGER_PIXOPS
+
+static void
+tile_make_weights (PixopsFilter *filter, double x_scale_d, double y_scale_d, double overall_alpha_d)
+{
+  int i_offset, j_offset;
+  unsigned long x_scale = x_scale_d * FRAC;
+  unsigned long y_scale = y_scale_d * FRAC;
+  unsigned long overall_alpha = overall_alpha_d * FRAC;
+  unsigned long x_scale_r = FRAC / x_scale;
+  unsigned long y_scale_r = FRAC / y_scale;
+
+  int n_x = ceil(1/x_scale_d + 1);
+  int n_y = ceil(1/y_scale_d + 1);
+
+  filter->x_offset = 0;
+  filter->y_offset = 0;
+  filter->n_x = n_x;
+  filter->n_y = n_y;
+  filter->weights = g_new (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y);
+
+  for (i_offset=0; i_offset<SUBSAMPLE; i_offset++)
+    for (j_offset=0; j_offset<SUBSAMPLE; j_offset++)
+      {
+       int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y;
+       unsigned long x = j_offset * FRAC / SUBSAMPLE;
+       unsigned long y = i_offset * FRAC / SUBSAMPLE;
+       int i,j;
+       int total = 0;
+
+       for (i = 0; i < n_y; i++)
+         {
+           unsigned long tw, th;
+
+           if (i < y)
+             {
+
+               if (i + FRAC > y)
+                 th = MIN(i+FRAC, y + y_scale_r) - y;
+               else
+                 th = 0;
+             }
+           else
+             {
+               if (y + FRAC/y_scale > i)
+                 th = MIN(i+FRAC, y + y_scale_r) - i;
+               else
+                 th = 0;
+             }
+
+           for (j = 0; j < n_x; j++)
+             {
+               int weight;
+
+               if (j < x)
+                 {
+                   if (j + FRAC > x)
+                     tw = MIN(j+FRAC, x + x_scale_r) - x;
+                   else
+                     tw = 0;
+                 }
+               else
+                 {
+                   if (x + FRAC/x_scale > j)
+                     tw = MIN(j+FRAC, x + x_scale_r) - j;
+                   else
+                     tw = 0;
+                 }
+
+               {
+                 unsigned long lweight = (tw * x_scale) / FRAC;
+                 lweight = (lweight * th) / FRAC;
+                 lweight = (lweight * y_scale) / FRAC;
+                 lweight = (lweight * overall_alpha) / FRAC;
+                 weight = lweight;
+               }
+               total += weight;
+               *(pixel_weights + n_x * i + j) = weight;
+             }
+         }
+
+       correct_total (pixel_weights, n_x, n_y, total, overall_alpha);
+      }
+}
+
+#else 
+ 
 static void
 tile_make_weights (PixopsFilterDimension *dim,
 		   double                 scale)
@@ -1216,10 +1336,151 @@
     }
 }
 
+#endif
+
 /* Compute weights for a filter that, for minification
  * is the same as 'tiles', and for magnification, is bilinear
  * reconstruction followed by a sampling with a delta function.
  */
+#ifdef ENABLE_INTEGER_PIXOPS
+
+static void
+bilinear_magnify_make_weights (PixopsFilter *filter, double x_scale_d, double y_scale_d, double overall_alpha_d)
+{
+  int i_offset, j_offset;
+  unsigned long *x_weights, *y_weights;
+  int n_x, n_y;
+  unsigned long x_scale = x_scale_d * FRAC;
+  unsigned long y_scale = y_scale_d * FRAC;
+  unsigned long overall_alpha = overall_alpha_d * FRAC;
+  unsigned long x_scale_r = (FRAC / x_scale_d);
+  unsigned long y_scale_r = (FRAC / y_scale_d);
+
+  if (x_scale > FRAC)          /* Bilinear */
+    {
+      n_x = 2;
+      filter->x_offset = 0.5 * (1/x_scale_d - 1);
+    }
+  else                         /* Tile */
+    {
+      n_x = ceil(1.0 + 1.0/x_scale_d);
+      filter->x_offset = 0.0;
+    }
+
+  if (y_scale > FRAC)          /* Bilinear */
+    {
+      n_y = 2;
+      filter->y_offset = 0.5 * (1/y_scale_d - 1);
+    }
+  else                         /* Tile */
+    {
+      n_y = ceil(1.0 + 1.0/y_scale_d);
+      filter->y_offset = 0.0;
+    }
+
+  filter->n_y = n_y;
+  filter->n_x = n_x;
+  filter->weights = g_new (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y);
+
+  x_weights = g_new (unsigned long, n_x);
+  y_weights = g_new (unsigned long, n_y);
+
+  for (i_offset=0; i_offset<SUBSAMPLE; i_offset++)
+    for (j_offset=0; j_offset<SUBSAMPLE; j_offset++)
+      {
+       int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y;
+       unsigned long x = j_offset * FRAC / SUBSAMPLE;
+       unsigned long y = i_offset * FRAC / SUBSAMPLE;
+       int i,j;
+       int total = 0;
+
+       if (x_scale > FRAC)     /* Bilinear */
+         {
+           for (i = 0; i < n_x; i++)
+             {
+               /* x_weights[i] = ((i == 0) ? (1 - x) : x) / x_scale; */
+               unsigned long w = (((i == 0) ? (FRAC - x) : x) * x_scale_r);
+               x_weights[i] = w / FRAC;
+             }
+         }
+       else                    /* Tile */
+         {
+           /*           x
+            * ---------|--.-|----|--.-|-------  SRC
+            * ------------|---------|---------  DEST
+            */
+           for (i = 0; i < n_x; i++)
+             {
+               if (i < x)
+                 {
+                   if (i + 1 > x)
+                     x_weights[i] = MIN(FRAC*(i+1), FRAC * x + (((unsigned long long)(FRAC * FRAC)) / (unsigned long)x_scale)) - (x * FRAC);
+                   else
+                     x_weights[i] = 0;
+                 }
+               else
+                 {
+                   if (x + 1/x_scale > i)
+                     x_weights[i] = MIN(FRAC*(i+1), FRAC * x + (((unsigned long long)(FRAC * FRAC)) / (unsigned long)x_scale)) - (i * FRAC);
+                   else
+                     x_weights[i] = 0;
+                 }
+             }
+         }
+
+       if (y_scale > FRAC)     /* Bilinear */
+         {
+           for (i = 0; i < n_y; i++)
+             {
+               unsigned long w = ((unsigned long)((i == 0) ? (FRAC - y) : y) * y_scale_r);
+               y_weights[i] = w / FRAC;
+             }
+         }
+       else                    /* Tile */
+         {
+           /*           y
+            * ---------|--.-|----|--.-|-------  SRC
+            * ------------|---------|---------  DEST
+            */
+           for (i = 0; i < n_y; i++)
+             {
+               if (i < y)
+                 {
+                   if (i + 1 > y)
+                     y_weights[i] = MIN(FRAC*(i+1), FRAC * y + (FRAC * FRAC / (unsigned long)y_scale)) - (y * FRAC);
+                   else
+                     y_weights[i] = 0;
+                 }
+               else
+                 {
+                   if (y + 1/y_scale > i)
+                     y_weights[i] = MIN(FRAC*(i+1), FRAC * y + (FRAC * FRAC / (unsigned long)y_scale)) - (i * FRAC);
+                   else
+                     y_weights[i] = 0;
+                 }
+             }
+         }
+
+       for (i = 0; i < n_y; i++)
+         for (j = 0; j < n_x; j++)
+           {
+             unsigned long long weight = (x_weights[j] * x_scale) / FRAC;
+             weight = (weight * y_weights[i]) / FRAC;
+             weight = (weight * y_scale) / FRAC;
+             weight = (weight * overall_alpha) / FRAC;
+             *(pixel_weights + n_x * i + j) = (unsigned long)weight;
+             total += (unsigned long)weight;
+           }
+
+       correct_total (pixel_weights, n_x, n_y, total, overall_alpha);
+      }
+
+  g_free (x_weights);
+  g_free (y_weights);
+}
+
+#else
+ 
 static void
 bilinear_magnify_make_weights (PixopsFilterDimension *dim,
 			       double                 scale)
@@ -1283,6 +1544,8 @@
     }
 }
 
+#endif
+
 /* Computes the integral from b0 to b1 of
  *
  * f(x) = x; 0 <= x < 1