diff -urN gtk+-2.10.9.orig/config.h.in gtk+-2.10.9-integer-pixops/config.h.in
--- gtk+-2.10.9.orig/config.h.in	2007-01-22 09:01:23.000000000 -0700
+++ gtk+-2.10.9-integer-pixops/config.h.in	2007-02-10 12:15:39.000000000 -0700
@@ -259,3 +259,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
+
diff -urN gtk+-2.10.9.orig/configure.in gtk+-2.10.9-integer-pixops/configure.in
--- gtk+-2.10.9.orig/configure.in	2007-01-22 08:59:41.000000000 -0700
+++ gtk+-2.10.9-integer-pixops/configure.in	2007-02-10 12:15:39.000000000 -0700
@@ -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])],,
diff -urN gtk+-2.10.9.orig/gdk-pixbuf/pixops/pixops.c gtk+-2.10.9-integer-pixops/gdk-pixbuf/pixops/pixops.c
--- gtk+-2.10.9.orig/gdk-pixbuf/pixops/pixops.c	2007-01-22 08:50:43.000000000 -0700
+++ gtk+-2.10.9-integer-pixops/gdk-pixbuf/pixops/pixops.c	2007-02-12 01:00:23.000000000 -0700
@@ -28,21 +28,42 @@
 #define SUBSAMPLE_MASK ((1 << SUBSAMPLE_BITS)-1)
 #define SCALE_SHIFT 16
 
+/* TODO: Add a FLOOR() and CEIL() macro to handle normalized values) */
+/* TODO: Get rid of standard C numeric types (ie. int). Replace with glib types */
+#ifdef ENABLE_INTEGER_PIXOPS
+/* The bigger the value of FRAC is, the better the accuracy. Be wary of 
+   overflows, though */
+#define FRAC 0x10000ULL
+#define NORMALIZE(d) (d * FRAC)
+#define UNNORMALIZE(t,i) ((t)(i) / FRAC)
+#define FLOOR(i) (int)((i) / FRAC)
+#define CEIL(i) (((i) - 1) / FRAC + 1)
+#define DOUBLE_TYPE gint32
+#define BIG_DOUBLE_TYPE gint64
+#else
+#define NORMALIZE(d) (d)
+#define UNNORMALIZE(t,i) (t)(i)
+#define FLOOR(i) floor(i)
+#define CEIL(i) ceil(i)
+#define DOUBLE_TYPE double
+#define BIG_DOUBLE_TYPE double
+#endif
+
 typedef struct _PixopsFilter PixopsFilter;
 typedef struct _PixopsFilterDimension PixopsFilterDimension;
 
 struct _PixopsFilterDimension
 {
   int n;
-  double offset;
-  double *weights;
+  BIG_DOUBLE_TYPE offset;
+  DOUBLE_TYPE *weights;
 };
 
 struct _PixopsFilter
 {
   PixopsFilterDimension x;
   PixopsFilterDimension y;
-  double overall_alpha;
+  gint32 overall_alpha; /* Normalized: alpha * 255; Not sure why original devs chose 255 */
 }; 
 
 typedef guchar *(*PixopsLineFunc) (int *weights, int n_x, int n_y,
@@ -86,13 +107,13 @@
 		      int            src_rowstride,
 		      int            src_channels,
 		      gboolean       src_has_alpha,
-		      double         scale_x,
-		      double         scale_y)
+		      DOUBLE_TYPE    scale_x,
+		      DOUBLE_TYPE    scale_y)
 {
   int i;
   int x;
-  int x_step = (1 << SCALE_SHIFT) / scale_x;
-  int y_step = (1 << SCALE_SHIFT) / scale_y;
+  int x_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_x;
+  int y_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_y;
   int xmax, xstart, xstop, x_pos, y_pos;
   const guchar *p;
 
@@ -175,14 +196,14 @@
 			  int            src_rowstride,
 			  int            src_channels,
 			  gboolean       src_has_alpha,
-			  double         scale_x,
-			  double         scale_y,
+			  DOUBLE_TYPE    scale_x,
+			  DOUBLE_TYPE    scale_y,
 			  int            overall_alpha)
 {
   int i;
   int x;
-  int x_step = (1 << SCALE_SHIFT) / scale_x;
-  int y_step = (1 << SCALE_SHIFT) / scale_y;
+  int x_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_x;
+  int y_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_y;
   int xmax, xstart, xstop, x_pos, y_pos;
   const guchar *p;
   unsigned int  a0;
@@ -260,8 +281,8 @@
 				int            src_rowstride,
 				int            src_channels,
 				gboolean       src_has_alpha,
-				double         scale_x,
-				double         scale_y,
+				DOUBLE_TYPE    scale_x,
+				DOUBLE_TYPE    scale_y,
 				int            overall_alpha,
 				int            check_x,
 				int            check_y,
@@ -271,8 +292,8 @@
 {
   int i, j;
   int x;
-  int x_step = (1 << SCALE_SHIFT) / scale_x;
-  int y_step = (1 << SCALE_SHIFT) / scale_y;
+  int x_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_x;
+  int y_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_y;
   int r1, g1, b1, r2, g2, b2;
   int check_shift = get_check_shift (check_size);
   int xmax, xstart, xstop, x_pos, y_pos;
@@ -977,9 +998,9 @@
                int    n_x, 
                int    n_y,
                int    total, 
-               double overall_alpha)
+               gint32 overall_alpha)
 {
-  int correction = (int)(0.5 + 65536 * overall_alpha) - total;
+  int correction = (int)(0.5 + 65536 / 255 * overall_alpha) - total;
   int remaining, c, d, i;
   
   if (correction != 0)
@@ -1009,7 +1030,7 @@
   for (i_offset=0; i_offset < SUBSAMPLE; i_offset++)
     for (j_offset=0; j_offset < SUBSAMPLE; j_offset++)
       {
-        double weight;
+        DOUBLE_TYPE weight;
         int *pixel_weights = weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y;
         int total = 0;
         int i, j;
@@ -1017,13 +1038,15 @@
         for (i=0; i < n_y; i++)
           for (j=0; j < n_x; j++)
             {
-              weight = filter->x.weights[(j_offset * n_x) + j] *
+              weight = UNNORMALIZE(DOUBLE_TYPE, filter->x.weights[(j_offset * n_x) + j] *
                        filter->y.weights[(i_offset * n_y) + i] *
-                       filter->overall_alpha * 65536 + 0.5;
+                       filter->overall_alpha * 65536 / 255) + NORMALIZE(0.5);
+                       /* Wonder how I should treat the "+ 0.5" for scientific
+                       rouding off */
 
-              total += (int)weight;
+              total += UNNORMALIZE(int, weight);
 
-              *(pixel_weights + n_x * i + j) = weight;
+              *(pixel_weights + n_x * i + j) = UNNORMALIZE(int, weight);
             }
 
         correct_total (pixel_weights, n_x, n_y, total, filter->overall_alpha);
@@ -1047,8 +1070,8 @@
 		int             src_rowstride,
 		int             src_channels,
 		gboolean        src_has_alpha,
-		double          scale_x,
-		double          scale_y,
+		DOUBLE_TYPE     scale_x,
+		DOUBLE_TYPE     scale_y,
 		int             check_x,
 		int             check_y,
 		int             check_size,
@@ -1064,12 +1087,13 @@
   guchar **line_bufs = g_new (guchar *, filter->y.n);
   int *filter_weights = make_filter_table (filter);
 
-  int x_step = (1 << SCALE_SHIFT) / scale_x; /* X step in source (fixed point) */
-  int y_step = (1 << SCALE_SHIFT) / scale_y; /* Y step in source (fixed point) */
+  int x_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_x; /* X step in source (fixed point) */
+  int y_step = NORMALIZE((1 << SCALE_SHIFT)) / scale_y; /* Y step in source (fixed point) */
 
   int check_shift = check_size ? get_check_shift (check_size) : 0;
 
-  int scaled_x_offset = floor (filter->x.offset * (1 << SCALE_SHIFT));
+  /* Possible overflow when scale-shifting which is why offset is BIG_DOUBLE_TYPE */
+  int scaled_x_offset = FLOOR(filter->x.offset * (1 << SCALE_SHIFT));
 
   /* Compute the index where we run off the end of the source buffer. The furthest
    * source pixel we access at index i is:
@@ -1087,7 +1111,7 @@
   int run_end_index = MYDIV (run_end_x + x_step - 1, x_step) - render_x0;
   run_end_index = MIN (run_end_index, render_x1 - render_x0);
 
-  y = render_y0 * y_step + floor (filter->y.offset * (1 << SCALE_SHIFT));
+  y = render_y0 * y_step + FLOOR(filter->y.offset * (1 << SCALE_SHIFT));
   for (i = 0; i < (render_y1 - render_y0); i++)
     {
       int dest_x;
@@ -1180,37 +1204,37 @@
  */
 static void
 tile_make_weights (PixopsFilterDimension *dim,
-		   double                 scale)
+		   DOUBLE_TYPE            scale)
 {
-  int n = ceil (1 / scale + 1);
-  double *pixel_weights = g_new (double, SUBSAMPLE * n);
+  int n = CEIL(NORMALIZE(NORMALIZE(1)) / scale + NORMALIZE(1)); /* Another possible overflow */
+  DOUBLE_TYPE *pixel_weights = g_new (DOUBLE_TYPE, SUBSAMPLE * n);
   int offset;
   int i;
-
+  
   dim->n = n;
-  dim->offset = 0;
+  dim->offset = NORMALIZE(0);
   dim->weights = pixel_weights;
 
   for (offset = 0; offset < SUBSAMPLE; offset++)
     {
-      double x = (double)offset / SUBSAMPLE;
-      double a = x + 1 / scale;
+      DOUBLE_TYPE x = (DOUBLE_TYPE)NORMALIZE(offset) / SUBSAMPLE;
+      DOUBLE_TYPE a = x + NORMALIZE(NORMALIZE(1)) / scale;
 
       for (i = 0; i < n; i++)
         {
-          if (i < x)
+          if (NORMALIZE(i) < x)
             {
-              if (i + 1 > x)
-                *(pixel_weights++)  = (MIN (i + 1, a) - x) * scale;
+              if (NORMALIZE(i + 1) > x)
+                *(pixel_weights++)  = UNNORMALIZE(DOUBLE_TYPE, (MIN(NORMALIZE(i + 1), a) - x) * scale);
               else
-                *(pixel_weights++) = 0;
+                *(pixel_weights++) = NORMALIZE(0);
             }
           else
             {
-              if (a > i)
-                *(pixel_weights++)  = (MIN (i + 1, a) - i) * scale;
+              if (a > NORMALIZE(i))
+                *(pixel_weights++)  = UNNORMALIZE(DOUBLE_TYPE, (MIN(NORMALIZE(i + 1), a) - i) * scale);
               else
-                *(pixel_weights++) = 0;
+                *(pixel_weights++) = NORMALIZE(0);
             }
        }
     }
@@ -1222,41 +1246,44 @@
  */
 static void
 bilinear_magnify_make_weights (PixopsFilterDimension *dim,
-			       double                 scale)
+			       DOUBLE_TYPE            scale)
 {
-  double *pixel_weights;
+  DOUBLE_TYPE *pixel_weights;
   int n;
   int offset;
   int i;
 
-  if (scale > 1.0)            /* Linear */
+  if (scale > NORMALIZE(1.0))            /* Linear */
     {
       n = 2;
-      dim->offset = 0.5 * (1 / scale - 1);
+      dim->offset = NORMALIZE(NORMALIZE(0.5) / (scale - NORMALIZE(1)));
     }
   else                          /* Tile */
     {
-      n = ceil (1.0 + 1.0 / scale);
-      dim->offset = 0.0;
+      n = CEIL(NORMALIZE(1.0) + NORMALIZE(NORMALIZE(1.0)) / scale);
+      dim->offset = NORMALIZE(0.0);
     }
-
+  
   dim->n = n;
-  dim->weights = g_new (double, SUBSAMPLE * n);
+  dim->weights = g_new (DOUBLE_TYPE, SUBSAMPLE * n);
 
   pixel_weights = dim->weights;
 
   for (offset=0; offset < SUBSAMPLE; offset++)
     {
-      double x = (double)offset / SUBSAMPLE;
+      DOUBLE_TYPE x = (DOUBLE_TYPE)NORMALIZE(offset) / SUBSAMPLE;
 
-      if (scale > 1.0)      /* Linear */
+      if (scale > NORMALIZE(1.0))      /* Linear */
         {
           for (i = 0; i < n; i++)
-            *(pixel_weights++) = (((i == 0) ? (1 - x) : x) / scale) * scale;
+            /* In the original, what is the point of dividing by scale then multiplying by scale? */
+            /* *(pixel_weights++) = (((i == 0) ? (1 - x) : x) / scale) * scale;*/
+            /* *(pixel_weights++) = i == 0 ? NORMALIZE(1) - x : x; */
+            *(pixel_weights++) = (((i == 0) ? NORMALIZE(1) - x : x) / scale) * scale;
         }
       else                  /* Tile */
         {
-          double a = x + 1 / scale;
+          DOUBLE_TYPE a = x + NORMALIZE(NORMALIZE(1)) / scale;
 
           /*           x
            * ---------|--.-|----|--.-|-------  SRC
@@ -1264,19 +1291,19 @@
            */
           for (i = 0; i < n; i++)
             {
-              if (i < x)
+              if (NORMALIZE(i) < x)
                 {
-                  if (i + 1 > x)
-                    *(pixel_weights++) = (MIN (i + 1, a) - x) * scale;
+                  if (NORMALIZE(i + 1) > x)
+                    *(pixel_weights++) = UNNORMALIZE(DOUBLE_TYPE, (MIN(NORMALIZE(i + 1), a) - x) * scale);
                   else
-                    *(pixel_weights++) = 0;
+                    *(pixel_weights++) = NORMALIZE(0);
                 }
               else
                 {
-                  if (a > i)
-                    *(pixel_weights++) = (MIN (i + 1, a) - i) * scale;
+                  if (a > NORMALIZE(i))
+                    *(pixel_weights++) = UNNORMALIZE(DOUBLE_TYPE, (MIN(NORMALIZE(i + 1), a) - i) * scale);
                   else
-                    *(pixel_weights++) = 0;
+                    *(pixel_weights++) = NORMALIZE(0);
                 }
             }
         }
@@ -1291,14 +1318,14 @@
  * We combine two of these to compute the convolution of
  * a box filter with a triangular spike.
  */
-static double
-linear_box_half (double b0, double b1)
+static DOUBLE_TYPE
+linear_box_half (DOUBLE_TYPE b0, DOUBLE_TYPE b1)
 {
-  double a0, a1;
-  double x0, x1;
+  DOUBLE_TYPE a0, a1;
+  DOUBLE_TYPE x0, x1;
 
-  a0 = 0.;
-  a1 = 1.;
+  a0 = NORMALIZE(0.);
+  a1 = NORMALIZE(1.);
 
   if (a0 < b0)
     {
@@ -1308,7 +1335,7 @@
           x1 = MIN (a1, b1);
         }
       else
-        return 0;
+        return NORMALIZE(0);
     }
   else
     {
@@ -1318,10 +1345,10 @@
           x1 = MIN (a1, b1);
         }
       else
-        return 0;
+        return NORMALIZE(0);
     }
 
-  return 0.5 * (x1*x1 - x0*x0);
+  return UNNORMALIZE(DOUBLE_TYPE, NORMALIZE(0.5) * UNNORMALIZE(DOUBLE_TYPE, (x1*x1 - x0*x0)));
 }
 
 /* Compute weights for reconstructing with bilinear
@@ -1329,28 +1356,28 @@
  */
 static void
 bilinear_box_make_weights (PixopsFilterDimension *dim,
-			   double                 scale)
+			   DOUBLE_TYPE            scale)
 {
-  int n = ceil (1/scale + 3.0);
-  double *pixel_weights = g_new (double, SUBSAMPLE * n);
-  double w;
+  int n = CEIL(NORMALIZE(NORMALIZE(1))/scale + NORMALIZE(3.0));
+  DOUBLE_TYPE *pixel_weights = g_new (DOUBLE_TYPE, SUBSAMPLE * n);
+  DOUBLE_TYPE w;
   int offset, i;
 
-  dim->offset = -1.0;
+  dim->offset = NORMALIZE(-1.0);
   dim->n = n;
   dim->weights = pixel_weights;
 
   for (offset = 0; offset < SUBSAMPLE; offset++)
     {
-      double x = (double)offset / SUBSAMPLE;
-      double a = x + 1 / scale;
+      DOUBLE_TYPE x = (DOUBLE_TYPE)NORMALIZE(offset) / SUBSAMPLE;
+      DOUBLE_TYPE a = x + NORMALIZE(NORMALIZE(1)) / scale;
 
       for (i = 0; i < n; i++)
         {
-          w  = linear_box_half (0.5 + i - a, 0.5 + i - x);
-          w += linear_box_half (1.5 + x - i, 1.5 + a - i);
+          w  = linear_box_half (NORMALIZE(0.5) + NORMALIZE(i) - a, NORMALIZE(0.5) + NORMALIZE(i) - x);
+          w += linear_box_half (NORMALIZE(1.5) - NORMALIZE(i) + x, NORMALIZE(1.5) - NORMALIZE(i) + a);
       
-          *(pixel_weights++) = w * scale;
+          *(pixel_weights++) = UNNORMALIZE(DOUBLE_TYPE, w * scale);
         }
     }
 }
@@ -1358,8 +1385,8 @@
 static void
 make_weights (PixopsFilter     *filter,
 	      PixopsInterpType  interp_type,	      
-	      double            scale_x,
-	      double            scale_y)
+	      DOUBLE_TYPE       scale_x,
+	      DOUBLE_TYPE       scale_y)
 {
   switch (interp_type)
     {
@@ -1399,8 +1426,8 @@
 			 int             src_rowstride,
 			 int             src_channels,
 			 gboolean        src_has_alpha,
-			 double          scale_x,
-			 double          scale_y,
+			 double          scale_x_d,
+			 double          scale_y_d,
 			 PixopsInterpType   interp_type,
 			 int             overall_alpha,
 			 int             check_x,
@@ -1409,6 +1436,8 @@
 			 guint32         color1,
 			 guint32         color2)
 {
+  DOUBLE_TYPE scale_x = NORMALIZE(scale_x_d);
+  DOUBLE_TYPE scale_y = NORMALIZE(scale_y_d);
   PixopsFilter filter;
   PixopsLineFunc line_func;
   
@@ -1419,7 +1448,7 @@
   g_return_if_fail (!(dest_channels == 3 && dest_has_alpha));
   g_return_if_fail (!(src_channels == 3 && src_has_alpha));
 
-  if (scale_x == 0 || scale_y == 0)
+  if (scale_x == NORMALIZE(0) || scale_y == NORMALIZE(0))
     return;
 
   if (!src_has_alpha && overall_alpha == 255)
@@ -1427,7 +1456,7 @@
       _pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
 		     dest_rowstride, dest_channels, dest_has_alpha,
 		     src_buf, src_width, src_height, src_rowstride, src_channels,
-		     src_has_alpha, scale_x, scale_y, interp_type);
+		     src_has_alpha, UNNORMALIZE(double, scale_x), UNNORMALIZE(double, scale_y), interp_type);
       return;
     }
 
@@ -1441,7 +1470,8 @@
       return;
     }
   
-  filter.overall_alpha = overall_alpha / 255.;
+  /* filter.overall_alpha = overall_alpha / 255.; /* Why is it 255 instead of 256? */
+  filter.overall_alpha = overall_alpha;
   make_weights (&filter, interp_type, scale_x, scale_y);
 
 #ifdef USE_MMX
@@ -1501,11 +1531,13 @@
 		   int            src_rowstride,
 		   int            src_channels,
 		   gboolean       src_has_alpha,
-		   double         scale_x,
-		   double         scale_y,
+		   double         scale_x_d,
+		   double         scale_y_d,
 		   PixopsInterpType  interp_type,
 		   int            overall_alpha)
 {
+  DOUBLE_TYPE scale_x = NORMALIZE(scale_x_d);
+  DOUBLE_TYPE scale_y = NORMALIZE(scale_y_d);
   PixopsFilter filter;
   PixopsLineFunc line_func;
   
@@ -1516,7 +1548,7 @@
   g_return_if_fail (!(dest_channels == 3 && dest_has_alpha));
   g_return_if_fail (!(src_channels == 3 && src_has_alpha));
 
-  if (scale_x == 0 || scale_y == 0)
+  if (scale_x == NORMALIZE(0) || scale_y == NORMALIZE(0))
     return;
 
   if (!src_has_alpha && overall_alpha == 255)
@@ -1524,7 +1556,7 @@
       _pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1,
 		     dest_rowstride, dest_channels, dest_has_alpha,
 		     src_buf, src_width, src_height, src_rowstride, src_channels,
-		     src_has_alpha, scale_x, scale_y, interp_type);
+		     src_has_alpha, UNNORMALIZE(double, scale_x), UNNORMALIZE(double, scale_y), interp_type);
       return;
     }
 
@@ -1537,7 +1569,7 @@
       return;
     }
   
-  filter.overall_alpha = overall_alpha / 255.;
+  filter.overall_alpha = overall_alpha;
   make_weights (&filter, interp_type, scale_x, scale_y);
 
   if (filter.x.n == 2 && filter.y.n == 2 &&
@@ -1578,10 +1610,12 @@
 	       int            src_rowstride,
 	       int            src_channels,
 	       gboolean       src_has_alpha,
-	       double         scale_x,
-	       double         scale_y,
+	       double         scale_x_d,
+	       double         scale_y_d,
 	       PixopsInterpType  interp_type)
 {
+  DOUBLE_TYPE scale_x = NORMALIZE(scale_x_d);
+  DOUBLE_TYPE scale_y = NORMALIZE(scale_y_d);
   PixopsFilter filter;
   PixopsLineFunc line_func;
 
@@ -1593,7 +1627,7 @@
   g_return_if_fail (!(src_channels == 3 && src_has_alpha));
   g_return_if_fail (!(src_has_alpha && !dest_has_alpha));
 
-  if (scale_x == 0 || scale_y == 0)
+  if (scale_x == NORMALIZE(0) || scale_y == NORMALIZE(0))
     return;
 
   if (interp_type == PIXOPS_INTERP_NEAREST)
@@ -1605,7 +1639,7 @@
       return;
     }
   
-  filter.overall_alpha = 1.0;
+  filter.overall_alpha = 255;
   make_weights (&filter, interp_type, scale_x, scale_y);
 
   if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 3 && src_channels == 3)