[poppler] 3 commits - poppler/CairoOutputDev.cc
Chris Wilson
ickle at kemper.freedesktop.org
Wed Jul 8 09:41:09 PDT 2009
poppler/CairoOutputDev.cc | 109 +++++++++++++++++++---------------------------
1 file changed, 47 insertions(+), 62 deletions(-)
New commits:
commit 6ae0a6c0044713affa23eb1ee6a070785ed6c2f3
Author: Chris Wilson <chris at chris-wilson.co.uk>
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 <chris at chris-wilson.co.uk>
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 <chris at chris-wilson.co.uk>
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;
}
More information about the poppler
mailing list