diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-09-04 00:46:56 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-09-08 12:20:37 +0100 |
commit | 6cb578962a4a2e0f78bc5fac220555614b9a8d65 (patch) | |
tree | 2e6f364a890abc7750e4806d17252e8e0297d638 /source/fitz | |
parent | f8eb384499f5b89e90cbbea961ba073536c49bc5 (diff) | |
download | mupdf-6cb578962a4a2e0f78bc5fac220555614b9a8d65.tar.xz |
Update test-device to check images piecemeal.
Rather than decoding entire image only to give up after we find the
very first pixel is color, add code so that the test-device can
treat the image as a stream. This means that (for most image types
at least) we can bale out without decoding everything.
This reduces the runtime of 3001Pages.pdf from 14 minutes to 18 seconds.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/filter-dct.c | 6 | ||||
-rw-r--r-- | source/fitz/test-device.c | 54 |
2 files changed, 57 insertions, 3 deletions
diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c index 2929fb05..344dbdbf 100644 --- a/source/fitz/filter-dct.c +++ b/source/fitz/filter-dct.c @@ -292,8 +292,12 @@ close_dctd(fz_context *ctx, void *state_) goto skip; } + /* We call jpeg_abort rather than the more usual + * jpeg_finish_decompress here. This has the same effect, + * but doesn't spew warnings if we didn't read enough data etc. + */ if (state->init) - jpeg_finish_decompress(&state->cinfo); + jpeg_abort((j_common_ptr)&state->cinfo); skip: if (state->cinfo.src) diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c index 9f575f4c..32d3a5f6 100644 --- a/source/fitz/test-device.c +++ b/source/fitz/test-device.c @@ -134,6 +134,55 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float if (*t->is_color || !image->colorspace || image->colorspace == fz_device_gray(ctx)) return; + if (image->buffer && image->bpc == 8) + { + fz_stream *stream = fz_open_compressed_buffer(ctx, image->buffer); + count = (unsigned int)image->w * (unsigned int)image->h; + if (image->colorspace == fz_device_rgb(ctx)) + { + int threshold_u8 = t->threshold * 255; + for (i = 0; i < count; i++) + { + int r = fz_read_byte(stream); + int g = fz_read_byte(stream); + int b = fz_read_byte(stream); + if (is_rgb_color_u8(threshold_u8, r, g, b)) + { + *t->is_color = 1; + dev->hints |= FZ_IGNORE_IMAGE; + break; + } + } + } + else + { + fz_color_converter cc; + unsigned int n = (unsigned int)image->n; + + fz_init_cached_color_converter(ctx, &cc, fz_device_rgb(ctx), image->colorspace); + for (i = 0; i < count; i++) + { + float cs[FZ_MAX_COLORS]; + float ds[FZ_MAX_COLORS]; + + for (k = 0; k < n; k++) + cs[k] = fz_read_byte(stream) / 255.0f; + + cc.convert(&cc, ds, cs); + + if (is_rgb_color(t->threshold, ds[0], ds[1], ds[2])) + { + *t->is_color = 1; + dev->hints |= FZ_IGNORE_IMAGE; + break; + } + } + fz_fin_cached_color_converter(&cc); + } + fz_close(stream); + return; + } + pix = fz_new_pixmap_from_image(ctx, image, 0, 0); if (pix == NULL) /* Should never happen really, but... */ return; @@ -146,7 +195,7 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float int threshold_u8 = t->threshold * 255; for (i = 0; i < count; i++) { - if (is_rgb_color_u8(threshold_u8, s[0], s[1], s[2])) + if (s[3] != 0 && is_rgb_color_u8(threshold_u8, s[0], s[1], s[2])) { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; @@ -168,7 +217,8 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float for (k = 0; k < n; k++) cs[k] = (*s++) / 255.0f; - s++; + if (*s++ == 0) + continue; cc.convert(&cc, ds, cs); |