[cairo-commit] cairo/src cairoint.h, 1.199, 1.200 cairo-png.c, 1.21, 1.22

Billy Biggs commit at pdx.freedesktop.org
Sat Aug 20 16:05:15 EST 2005


Committed by: vektor

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv7786/src

Modified Files:
	cairoint.h cairo-png.c 
Log Message:
	Fix for bug #4096:

	* src/cairo-png.c: (multiply_alpha), (premultiply_data): Improve
	the performance of png reading by adding special cases for fully
	transparent and fully opaque alpha, and using the standard
	optimization for 8-bit division by 255.

	* src/cairoint.h: Add an INLINE macro for gcc.



Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.199
retrieving revision 1.200
diff -u -d -r1.199 -r1.200
--- cairoint.h	19 Aug 2005 06:10:41 -0000	1.199
+++ cairoint.h	20 Aug 2005 06:05:13 -0000	1.200
@@ -124,6 +124,12 @@
 #define __attribute__(x)
 #endif
 
+#if defined(__GNUC__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+
 #if HAVE_PTHREAD_H
 # include <pthread.h>
 # define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER

Index: cairo-png.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-png.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- cairo-png.c	28 Jul 2005 18:42:33 -0000	1.21
+++ cairo-png.c	20 Aug 2005 06:05:13 -0000	1.22
@@ -288,6 +288,13 @@
     return write_png (surface, stream_write_func, &png_closure);
 }				     
 
+static INLINE int
+multiply_alpha (int alpha, int color)
+{
+    int temp = (alpha * color) + 0x80;
+    return ((temp + (temp >> 8)) >> 8);
+}
+
 /* Premultiplies data and converts RGBA bytes => native endian */
 static void
 premultiply_data (png_structp   png,
@@ -298,16 +305,23 @@
 
     for (i = 0; i < row_info->rowbytes; i += 4) {
 	uint8_t *base = &data[i];
-	uint8_t  red = base[0];
-	uint8_t  green = base[1];
-	uint8_t  blue = base[2];
 	uint8_t  alpha = base[3];
 	uint32_t p;
 
-	red = ((unsigned) red * (unsigned) alpha + 127) / 255;
-	green = ((unsigned) green * (unsigned) alpha + 127) / 255;
-	blue = ((unsigned) blue * (unsigned) alpha + 127) / 255;
-	p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+	if (alpha == 0) {
+	    p = 0;
+	} else {
+	    uint8_t  red = base[0];
+	    uint8_t  green = base[1];
+	    uint8_t  blue = base[2];
+
+	    if (alpha != 0xff) {
+		red = multiply_alpha (alpha, red);
+		green = multiply_alpha (alpha, green);
+		blue = multiply_alpha (alpha, blue);
+	    }
+	    p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+	}
 	memcpy (base, &p, sizeof (uint32_t));
     }
 }



More information about the cairo-commit mailing list