diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2011-08-05 22:09:57 +0930 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2011-08-05 22:09:57 +0930 |
commit | b11b89e8e0c6cb0a05c9de69e3235bedc0c27756 (patch) | |
tree | 4e1f63f75c94ac1ca8087c942bb7a19022dd76c2 /src/cairo-pdf-surface.c | |
parent | 16bc8d93615ce3e92c86dcbd7fbbcd6de0890ce8 (diff) |
pdf: check if smask is bilevel and encode as such
Diffstat (limited to 'src/cairo-pdf-surface.c')
-rw-r--r-- | src/cairo-pdf-surface.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index b2e6a1db..01ebcf1d 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; |