[poppler] poppler/CairoOutputDev.cc
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Mon Jul 20 08:16:45 PDT 2009
poppler/CairoOutputDev.cc | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
New commits:
commit f93f5e17d8f23f3e2862f3411f43a95b334e6c91
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Mon Jul 20 17:10:37 2009 +0200
[cairo] Improve performance when rendering one-channel images
It implements the same idea already used in SplashOutputDev, for
one-channel (monochrome/gray/separation) images we build a lookup table
so that we won't need to call colorMap->getRGBLine when filling the
image buffer. Fixes bug #18017.
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index a14f68a..0f9b621 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -1798,7 +1798,8 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
ImageStream *imgStr;
cairo_matrix_t matrix;
unsigned char *buffer;
- int stride;
+ int stride, i;
+ GfxRGB *lookup = NULL;
/* TODO: Do we want to cache these? */
imgStr = new ImageStream(str, width,
@@ -1822,12 +1823,42 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
if (cairo_surface_status (image))
goto cleanup;
+ // special case for one-channel (monochrome/gray/separation) images:
+ // build a lookup table here
+ if (colorMap->getNumPixelComps() == 1) {
+ int n;
+ Guchar pix;
+
+ n = 1 << colorMap->getBits();
+ lookup = (GfxRGB *)gmallocn(n, sizeof(GfxRGB));
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+
+ colorMap->getRGB(&pix, &lookup[i]);
+ }
+ }
+
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 (lookup) {
+ Guchar *p = pix;
+ GfxRGB rgb;
+
+ for (i = 0; i < width; i++) {
+ rgb = lookup[*p];
+ dest[i] =
+ ((int) colToByte(rgb.r) << 16) |
+ ((int) colToByte(rgb.g) << 8) |
+ ((int) colToByte(rgb.b) << 0);
+ p++;
+ }
+ } else {
+ colorMap->getRGBLine (pix, dest, width);
+ }
if (maskColors) {
for (int x = 0; x < width; x++) {
@@ -1848,6 +1879,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
}
}
}
+ gfree(lookup);
pattern = cairo_pattern_create_for_surface (image);
cairo_surface_destroy (image);
More information about the poppler
mailing list