poppler/CairoOutputDev.cc | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-)
New commits: commit f93f5e17d8f23f3e2862f3411f43a95b334e6c91 Author: Carlos Garcia Campos <[email protected]> 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); _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
