[gdk-pixbuf] pixops: Special-case compositing/copying with no scaling



commit cc5fce6315dcc1127a3e2106223305ff763be815
Author: Hans Petter Jansson <hpj copyleft no>
Date:   Thu Nov 10 19:13:00 2005 +0000

    pixops: Special-case compositing/copying with no scaling
    
    When there is no scaling involved, make gdk_pixbuf_composite_color()
    faster by avoiding the scaling code path.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=80927

 gdk-pixbuf/pixops/pixops.c |   95 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 90 insertions(+), 5 deletions(-)
---
diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
index 993223e..29a1c14 100644
--- a/gdk-pixbuf/pixops/pixops.c
+++ b/gdk-pixbuf/pixops/pixops.c
@@ -421,6 +421,86 @@ pixops_composite_nearest (guchar        *dest_buf,
 }
 
 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,
@@ -1781,11 +1861,16 @@ _pixops_composite_real (guchar          *dest_buf,
 
   if (interp_type == 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;
     }
   


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]