summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-09-04 00:46:56 +0100
committerRobin Watts <robin.watts@artifex.com>2014-09-08 12:20:37 +0100
commit6cb578962a4a2e0f78bc5fac220555614b9a8d65 (patch)
tree2e6f364a890abc7750e4806d17252e8e0297d638 /source/fitz
parentf8eb384499f5b89e90cbbea961ba073536c49bc5 (diff)
downloadmupdf-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.c6
-rw-r--r--source/fitz/test-device.c54
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);