[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