Index: pixops.c
===================================================================
RCS file: /cvs/gnome/gdk-pixbuf/gdk-pixbuf/pixops/pixops.c,v
retrieving revision 1.17
diff -u -r1.17 pixops.c
--- pixops.c	2002/01/23 00:37:47	1.17
+++ pixops.c	2002/03/05 09:23:11
@@ -219,6 +219,86 @@
 }
 
 static void
+pixops_composite_nearest_noscale (guchar        *dest_buf,
+				  int            render_x0,
+				  int            render_y0,
+				  int            render_x1,
+				  int            render_y1,
+				  int            dest_rowstride,
+				  int            dest_channels,
+				  gboolean       dest_has_alpha,
+				  const guchar  *src_buf,
+				  int            src_width,
+				  int            src_height,
+				  int            src_rowstride,
+				  int            src_channels,
+				  gboolean       src_has_alpha,
+				  int            overall_alpha)
+{
+  int i, j;
+  int x;
+
+  for (i = 0; i < (render_y1 - render_y0); i++)
+    {
+      const guchar *src  = src_buf + (i + render_y0) * src_rowstride;
+      guchar       *dest = dest_buf + i * dest_rowstride;
+
+      x = render_x0 * src_channels;
+
+      for (j=0; j < (render_x1 - render_x0); j++)
+	{
+	  const guchar *p = src + x;
+	  unsigned int  a0;
+	    
+	  if (src_has_alpha)
+	    a0 = (p[3] * overall_alpha) / 0xff;
+	  else
+	    a0 = overall_alpha;
+	    
+	  switch (a0)
+	    {
+	    case 0:
+	      break;
+	    case 255:
+	      dest[0] = p[0];
+	      dest[1] = p[1];
+	      dest[2] = p[2];
+	      if (dest_has_alpha)
+		dest[3] = 0xff;
+	      break;
+	    default:
+	      if (dest_has_alpha)
+	      {
+		unsigned int w0 = 0xff * a0;
+		unsigned int w1 = (0xff - a0) * dest[3];
+		unsigned int w = w0 + w1;
+		    
+		dest[0] = (w0 * p[0] + w1 * dest[0]) / w;
+		dest[1] = (w0 * p[1] + w1 * dest[1]) / w;
+		dest[2] = (w0 * p[2] + w1 * dest[2]) / w;
+		dest[3] = w / 0xff;
+	      }
+	      else
+	      {
+		unsigned int a1 = 0xff - a0;
+		unsigned int tmp;
+		  
+		tmp = a0 * p[0] + a1 * dest[0] + 0x80;
+		dest[0] = (tmp + (tmp >> 8)) >> 8;
+		tmp = a0 * p[1] + a1 * dest[1] + 0x80;
+		dest[1] = (tmp + (tmp >> 8)) >> 8;
+		tmp = a0 * p[2] + a1 * dest[2] + 0x80;
+		dest[2] = (tmp + (tmp >> 8)) >> 8;
+	      }
+	      break;
+	    }
+	  dest += dest_channels;
+	  x += src_channels;
+	}
+    }
+}
+
+static void
 pixops_composite_color_nearest (guchar        *dest_buf,
 				int            render_x0,
 				int            render_y0,
@@ -1502,10 +1582,16 @@
   switch (interp_type)
     {
     case PIXOPS_INTERP_NEAREST:
-      pixops_composite_nearest (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, overall_alpha);
+      if (scale_x == 1.0 && scale_y == 1.0)
+	pixops_composite_nearest_noscale (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, overall_alpha);
+      else
+	pixops_composite_nearest (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, overall_alpha);
       return;
 
     case PIXOPS_INTERP_TILES:
