poppler/CairoOutputDev.cc | 109 +++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 62 deletions(-)
New commits: commit 6ae0a6c0044713affa23eb1ee6a070785ed6c2f3 Author: Chris Wilson <[email protected]> Date: Wed Jul 8 16:48:26 2009 +0100 [cairo] premultiply image mask Cairo uses a premultiplied colour-space, so when creating the image mask in drawImage() we need to remember to multiply by the alpha. In this case it just requires zeroing out the masked pixels. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index b59e406..e033e50 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1802,15 +1802,20 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, if (maskColors) { for (int x = 0; x < width; x++) { + bool is_opaque = false; for (int i = 0; i < colorMap->getNumPixelComps(); ++i) { if (pix[i] < maskColors[2*i] || pix[i] > maskColors[2*i+1]) { - *dest |= 0xff000000; + is_opaque = true; break; } } - pix += colorMap->getNumPixelComps(); + if (is_opaque) + *dest |= 0xff000000; + else + *dest = 0; dest++; + pix += colorMap->getNumPixelComps(); } } } commit 646e5884e748ecce7094c673400484aa1d902bdd Author: Chris Wilson <[email protected]> Date: Wed Jul 8 17:00:34 2009 +0100 [cairo] maskColors is an array of ints, no scaling required drawImage() was erroneously scaling the maskColors from what it believed to be [0:1] to [0:255]. However maskColors is already an integer array, [0:255]. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index eaabb50..b59e406 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1803,8 +1803,8 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, if (maskColors) { for (int x = 0; x < width; x++) { for (int i = 0; i < colorMap->getNumPixelComps(); ++i) { - if (pix[i] < 255*maskColors[2*i] || - pix[i] > 255*maskColors[2*i+1]) { + if (pix[i] < maskColors[2*i] || + pix[i] > maskColors[2*i+1]) { *dest |= 0xff000000; break; } commit d75feb1ee84385a9f94308cf47a43f4583092ddf Author: Chris Wilson <[email protected]> Date: Wed Jul 8 16:37:19 2009 +0100 [cairo] cleanse DrawImage() Just a small bit of code rearrangement to reduce repetition and invalid checks. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 2fa9815..eaabb50 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1764,43 +1764,48 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, GBool interpolate, int *maskColors, GBool inlineImg) { - unsigned char *buffer; - unsigned int *dest; cairo_surface_t *image; cairo_pattern_t *pattern; - int x, y; ImageStream *imgStr; - Guchar *pix; - int i; cairo_matrix_t matrix; - int is_identity_transform; - - buffer = (unsigned char *)gmallocn3 (width, height, 4); + unsigned char *buffer; + int stride; /* TODO: Do we want to cache these? */ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits()); imgStr->reset(); - + +#if 0 /* ICCBased color space doesn't do any color correction * so check its underlying color space as well */ + int is_identity_transform; is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || - (colorMap->getColorSpace()->getMode() == csICCBased && + (colorMap->getColorSpace()->getMode() == csICCBased && ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB); +#endif + + image = cairo_image_surface_create (maskColors ? + CAIRO_FORMAT_ARGB32 : + CAIRO_FORMAT_RGB24, + width, height); + if (cairo_surface_status (image)) + goto cleanup; + + buffer = cairo_image_surface_get_data (image); + stride = cairo_image_surface_get_stride (image); + for (int y = 0; y < height; y++) { + uint32_t *dest = (uint32_t *) (buffer + y * stride); + Guchar *pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); - if (maskColors) { - for (y = 0; y < height; y++) { - dest = (unsigned int *) (buffer + y * 4 * width); - pix = imgStr->getLine(); - colorMap->getRGBLine (pix, dest, width); - - for (x = 0; x < width; x++) { - for (i = 0; i < colorMap->getNumPixelComps(); ++i) { - - if (pix[i] < maskColors[2*i] * 255|| - pix[i] > maskColors[2*i+1] * 255) { - *dest = *dest | 0xff000000; + if (maskColors) { + for (int x = 0; x < width; x++) { + for (int i = 0; i < colorMap->getNumPixelComps(); ++i) { + if (pix[i] < 255*maskColors[2*i] || + pix[i] > 255*maskColors[2*i+1]) { + *dest |= 0xff000000; break; } } @@ -1808,64 +1813,39 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, dest++; } } - - image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_ARGB32, - width, height, width * 4); } - else { - for (y = 0; y < height; y++) { - dest = (unsigned int *) (buffer + y * 4 * width); - pix = imgStr->getLine(); - colorMap->getRGBLine (pix, dest, width); - } - image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24, - width, height, width * 4); - } - - if (image == NULL) { - imgStr->close(); - delete imgStr; - return; - } pattern = cairo_pattern_create_for_surface (image); - if (pattern == NULL) { - imgStr->close(); - delete imgStr; - return; - } + cairo_surface_destroy (image); + if (cairo_pattern_status (pattern)) + goto cleanup; LOG (printf ("drawImageMask %dx%d\n", width, height)); - + cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); - cairo_pattern_set_filter (pattern, - interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST); + interpolate ? + CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); + cairo_set_source (cairo, pattern); - cairo_paint (cairo); + cairo_rectangle (cairo, 0., 0., width, height); + cairo_fill (cairo); if (cairo_shape) { -#if 0 - cairo_rectangle (cairo_shape, 0., 0., width, height); - cairo_fill (cairo_shape); -#else cairo_save (cairo_shape); - /* this should draw a rectangle the size of the image - * we use this instead of rect,fill because of the lack - * of EXTEND_PAD */ - /* NOTE: this will multiply the edges of the image twice */ + cairo_rectangle (cairo_shape, 0., 0., width, height); cairo_set_source (cairo_shape, pattern); - cairo_paint(cairo_shape); + cairo_fill (cairo_shape); cairo_restore (cairo_shape); -#endif } cairo_pattern_destroy (pattern); - cairo_surface_destroy (image); - free (buffer); + +cleanup: imgStr->close(); delete imgStr; } _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
