[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