summaryrefslogtreecommitdiff
path: root/src/cairo-pdf-surface.c
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2011-08-05 22:09:57 +0930
committerAdrian Johnson <ajohnson@redneon.com>2011-08-05 22:09:57 +0930
commitb11b89e8e0c6cb0a05c9de69e3235bedc0c27756 (patch)
tree4e1f63f75c94ac1ca8087c942bb7a19022dd76c2 /src/cairo-pdf-surface.c
parent16bc8d93615ce3e92c86dcbd7fbbcd6de0890ce8 (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.c64
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;