[cairo-commit] 2 commits - src/cairo-image-surface.c src/cairo-pdf-surface.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Fri Aug 5 05:42:45 PDT 2011


 src/cairo-image-surface.c |   15 +++++++++-
 src/cairo-pdf-surface.c   |   64 ++++++++++++++++++++++++----------------------
 2 files changed, 47 insertions(+), 32 deletions(-)

New commits:
commit b11b89e8e0c6cb0a05c9de69e3235bedc0c27756
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Aug 5 22:09:57 2011 +0930

    pdf: check if smask is bilevel and encode as such

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index b2e6a1d..01ebcf1 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1871,9 +1871,8 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
     unsigned long alpha_size;
     uint32_t *pixel32;
     uint8_t *pixel8;
-    int i, x, y;
-    cairo_bool_t opaque;
-    uint8_t a;
+    int i, x, y, bit, a;
+    cairo_image_transparency_t transparency;
 
     /* This is the only image format we support, which simplifies things. */
     assert (image->format == CAIRO_FORMAT_ARGB32 ||
@@ -1881,8 +1880,11 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 	    image->format == CAIRO_FORMAT_A1 );
 
     stream_ret->id = 0;
+    transparency = _cairo_image_analyze_transparency (image);
+    if (transparency == CAIRO_IMAGE_IS_OPAQUE)
+	return status;
 
-    if (image->format == CAIRO_FORMAT_A1) {
+    if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA) {
 	alpha_size = (image->width + 7) / 8 * image->height;
 	alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
     } else {
@@ -1895,44 +1897,46 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 	goto CLEANUP;
     }
 
-    opaque = TRUE;
     i = 0;
+    bit = 7;
     for (y = 0; y < image->height; y++) {
-	if (image->format == CAIRO_FORMAT_ARGB32) {
-	    pixel32 = (uint32_t *) (image->data + y * image->stride);
-
-	    for (x = 0; x < image->width; x++, pixel32++) {
-		a = (*pixel32 & 0xff000000) >> 24;
-		alpha[i++] = a;
-		if (a != 0xff)
-		    opaque = FALSE;
-	    }
-	} else if (image->format == CAIRO_FORMAT_A8){
+	if (image->format == CAIRO_FORMAT_A1) {
 	    pixel8 = (uint8_t *) (image->data + y * image->stride);
 
-	    for (x = 0; x < image->width; x++, pixel8++) {
+	    for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
 		a = *pixel8;
+		a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
 		alpha[i++] = a;
-		if (a != 0xff)
-		    opaque = FALSE;
 	    }
-	} else { /* image->format == CAIRO_FORMAT_A1 */
+	} else {
 	    pixel8 = (uint8_t *) (image->data + y * image->stride);
+	    pixel32 = (uint32_t *) (image->data + y * image->stride);
+	    for (x = 0; x < image->width; x++) {
+		if (image->format == CAIRO_FORMAT_ARGB32) {
+		    a = (*pixel32 & 0xff000000) >> 24;
+		    pixel32++;
+		} else {
+		    a = *pixel8;
+		    pixel8++;
+		}
 
-	    for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
-		a = *pixel8;
-		a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
-		alpha[i++] = a;
-		if (a != 0xff)
-		    opaque = FALSE;
+		if (transparency == CAIRO_IMAGE_HAS_ALPHA) {
+		    alpha[i++] = a;
+		} else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA */
+		    if (bit == 7)
+			alpha[i] = 0;
+		    if (a != 0)
+			alpha[i] |= (1 << bit);
+		    bit--;
+		    if (bit < 0) {
+			bit = 7;
+			i++;
+		    }
+		}
 	    }
 	}
     }
 
-    /* Bail out without emitting smask if it's all opaque. */
-    if (opaque)
-	goto CLEANUP_ALPHA;
-
     status = _cairo_pdf_surface_open_stream (surface,
 					     NULL,
 					     TRUE,
@@ -1943,7 +1947,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 					     "   /ColorSpace /DeviceGray\n"
 					     "   /BitsPerComponent %d\n",
 					     image->width, image->height,
-					     image->format == CAIRO_FORMAT_A1 ? 1 : 8);
+					     transparency == CAIRO_IMAGE_HAS_ALPHA ? 8 : 1);
     if (unlikely (status))
 	goto CLEANUP_ALPHA;
 
commit 16bc8d93615ce3e92c86dcbd7fbbcd6de0890ce8
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Aug 5 21:15:21 2011 +0930

    image: check if A8 image is bilevel when analyzing transparency

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index af5df41..c2afbab 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -4879,10 +4879,21 @@ _cairo_image_analyze_transparency (cairo_image_surface_t      *image)
 	return image->transparency = CAIRO_IMAGE_IS_OPAQUE;
 
     if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) {
-	if (image->format == CAIRO_FORMAT_A1)
+	if (image->format == CAIRO_FORMAT_A1) {
 	    return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
-	else
+	} else if (image->format == CAIRO_FORMAT_A8) {
+	    for (y = 0; y < image->height; y++) {
+		uint8_t *alpha = (uint8_t *) (image->data + y * image->stride);
+
+		for (x = 0; x < image->width; x++, alpha++) {
+		    if (*alpha > 0 && *alpha < 255)
+			return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+		}
+	    }
+	    return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	} else {
 	    return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+	}
     }
 
     if (image->format == CAIRO_FORMAT_RGB16_565) {


More information about the cairo-commit mailing list