[poppler] [PATCH] speed up mono images significantly

Jeff Muizelaar jeff at infidigm.net
Sun Apr 24 16:47:10 PDT 2005


The included patch takes rendering the first 6 pages of
http://freedesktop.org/~jrmuizel/uw-apr-bog-agenda.pdf
from 25s to 5s. 

Right now memory usage is a big problem for this file. Splash uses much
less memory than cairo does (though I am not exactly sure why yet). If
cairo supported mono images (i think it sort of does... using A1)
it would help out alot both in performance and memory usage.

-Jeff


Index: poppler/CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.7
diff -u -r1.7 CairoOutputDev.cc
--- poppler/CairoOutputDev.cc	22 Apr 2005 04:09:23 -0000	1.7
+++ poppler/CairoOutputDev.cc	24 Apr 2005 23:39:41 -0000
@@ -534,56 +534,13 @@
   double *ctm;
   cairo_matrix_t *mat;
   int is_identity_transform;
-  
+
   buffer = (char *)malloc (width * height * 4);
 
   if (buffer == NULL) {
     error(-1, "Unable to allocate memory for image.");
     return;
   }
-
-  /* TODO: Do we want to cache these? */
-  imgStr = new ImageStream(str, width,
-			   colorMap->getNumPixelComps(),
-			   colorMap->getBits());
-  imgStr->reset();
-  
-  /* ICCBased color space doesn't do any color correction
-   * so check its underlying color space as well */
-  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
-		  colorMap->getColorSpace()->getMode() == csICCBased && 
-		  ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB;
-  
-  for (y = 0; y < height; y++) {
-    dest = buffer + y * 4 * width;
-    pix = imgStr->getLine();
-    for (x = 0; x < width; x++, pix += colorMap->getNumPixelComps()) {
-      if (maskColors) {
-	alpha = 0;
-	for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
-	  if (pix[i] < maskColors[2*i] ||
-	      pix[i] > maskColors[2*i+1]) {
-	    alpha = 255;
-	    break;
-	  }
-	}
-      } else {
-	alpha = 255;
-      }
-      if (is_identity_transform) {
-	*dest++ = pix[2];
-	*dest++ = pix[1];
-	*dest++ = pix[0];
-      } else {      
-	colorMap->getRGB(pix, &rgb);
-	*dest++ = soutRound(255 * rgb.b);
-	*dest++ = soutRound(255 * rgb.g);
-	*dest++ = soutRound(255 * rgb.r);
-      }
-      *dest++ = alpha;
-    }
-  }
-
   cairo_save (cairo);
 
   ctm = state->getCTM();
@@ -599,15 +556,74 @@
 			   ctm[2] + ctm[4], ctm[3] + ctm[5]);
   cairo_concat_matrix (cairo, mat);
   cairo_matrix_destroy (mat);
-  
+
+  if (colorMap->getColorSpace()->getMode() == csDeviceGray && colorMap->getBits() == 1 && colorMap->getNumPixelComps() == 1) {
+    str->reset();
+    for (y = 0; y < height; y++) {
+      dest = buffer + y * 4 * width;
+      for (x = 0; x < width; x += 8) {
+	int c;
+	c = str->getChar();
+	for (int j=7; j>=0; j--) {
+	  char out = ((c >> j) & 1) ? 255 : 0;
+	  *dest++ = out;
+	  *dest++ = out;
+	  *dest++ = out;
+	  *dest++ = 255;
+	}
+      }
+    }
+  } else {
+    /* TODO: Do we want to cache these? */
+    imgStr = new ImageStream(str, width,
+	colorMap->getNumPixelComps(),
+	colorMap->getBits());
+    imgStr->reset();
+
+    /* ICCBased color space doesn't do any color correction
+     * so check its underlying color space as well */
+    is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
+      colorMap->getColorSpace()->getMode() == csICCBased && 
+      ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB;
+
+    for (y = 0; y < height; y++) {
+      dest = buffer + y * 4 * width;
+      pix = imgStr->getLine();
+      for (x = 0; x < width; x++, pix += colorMap->getNumPixelComps()) {
+	if (maskColors) {
+	  alpha = 0;
+	  for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
+	    if (pix[i] < maskColors[2*i] ||
+		pix[i] > maskColors[2*i+1]) {
+	      alpha = 255;
+	      break;
+	    }
+	  }
+	} else {
+	  alpha = 255;
+	}
+	if (is_identity_transform) {
+	  *dest++ = pix[2];
+	  *dest++ = pix[1];
+	  *dest++ = pix[0];
+	} else {
+	  colorMap->getRGB(pix, &rgb);
+	  *dest++ = soutRound(255 * rgb.b);
+	  *dest++ = soutRound(255 * rgb.g);
+	  *dest++ = soutRound(255 * rgb.r);
+	}
+	*dest++ = alpha;
+      }
+    }
+    delete imgStr;
+  }
   image = cairo_surface_create_for_image (
-              buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4);
+	buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4);
   cairo_surface_set_filter (image, CAIRO_FILTER_BEST);
   cairo_show_surface (cairo, image, width, height);
 
   cairo_restore (cairo);
-  
+
   cairo_surface_destroy (image);
   free (buffer);
-  delete imgStr;
 }


More information about the poppler mailing list