diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-05-07 11:30:05 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-05-08 15:14:57 +0100 |
commit | 636652daee46a9cf9836746135e3f9678db796ec (patch) | |
tree | 110e78a0ffcb4a873088c92864ff182d783fdbc3 /xps | |
parent | 2433a4d16d114a0576e6a4ff9ca61ae4f29fdda0 (diff) | |
download | mupdf-636652daee46a9cf9836746135e3f9678db796ec.tar.xz |
Switch to reading content streams on the fly during interpretation.
Previously, before interpreting a pages content stream we would
load it entirely into a buffer. Then we would interpret that
buffer. This has a cost in memory use.
Here, we update the code to read from a stream on the fly.
This has required changes in various different parts of the code.
Firstly, we have removed all use of the FILE lock - as stream
reads can now safely be interrupted by resource (or object) reads
from elsewhere in the file, the file lock becomes a very hard
thing to maintain, and doesn't actually benefit us at all. The
choices were to either use a recursive lock, or to remove it
entirely; I opted for the latter.
The file lock enum value remains as a placeholder for future use in
extendable data streams.
Secondly, we add a new 'concat' filter that concatenates a series of
streams together into one, optionally putting whitespace between each
stream (as the pdf parser requires this).
Finally, we change page/xobject/pattern content streams to work
on the fly, but we leave type3 glyphs using buffers (as presumably
these will be run repeatedly).
Diffstat (limited to 'xps')
-rw-r--r-- | xps/xps_zip.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/xps/xps_zip.c b/xps/xps_zip.c index ff43abf2..bb6857ee 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -108,13 +108,11 @@ xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) int code; fz_context *ctx = doc->ctx; - fz_lock(ctx, FZ_LOCK_FILE); fz_seek(doc->file, ent->offset, 0); sig = getlong(doc->file); if (sig != ZIP_LOCAL_FILE_SIG) { - fz_unlock(ctx, FZ_LOCK_FILE); fz_throw(doc->ctx, "wrong zip local file signature (0x%x)", sig); } @@ -137,7 +135,7 @@ xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) } else if (method == 8) { - inbuf = fz_malloc(doc->ctx, ent->csize); + inbuf = fz_malloc(ctx, ent->csize); fz_read(doc->file, inbuf, ent->csize); @@ -153,34 +151,29 @@ xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) code = inflateInit2(&stream, -15); if (code != Z_OK) { - fz_unlock(ctx, FZ_LOCK_FILE); - fz_free(doc->ctx, inbuf); - fz_throw(doc->ctx, "zlib inflateInit2 error: %s", stream.msg); + fz_free(ctx, inbuf); + fz_throw(ctx, "zlib inflateInit2 error: %s", stream.msg); } code = inflate(&stream, Z_FINISH); if (code != Z_STREAM_END) { inflateEnd(&stream); - fz_unlock(ctx, FZ_LOCK_FILE); - fz_free(doc->ctx, inbuf); - fz_throw(doc->ctx, "zlib inflate error: %s", stream.msg); + fz_free(ctx, inbuf); + fz_throw(ctx, "zlib inflate error: %s", stream.msg); } code = inflateEnd(&stream); if (code != Z_OK) { - fz_unlock(ctx, FZ_LOCK_FILE); - fz_free(doc->ctx, inbuf); - fz_throw(doc->ctx, "zlib inflateEnd error: %s", stream.msg); + fz_free(ctx, inbuf); + fz_throw(ctx, "zlib inflateEnd error: %s", stream.msg); } - fz_free(doc->ctx, inbuf); + fz_free(ctx, inbuf); } else { - fz_unlock(ctx, FZ_LOCK_FILE); - fz_throw(doc->ctx, "unknown compression method (%d)", method); + fz_throw(ctx, "unknown compression method (%d)", method); } - fz_unlock(ctx, FZ_LOCK_FILE); } /* @@ -306,7 +299,6 @@ xps_find_and_read_zip_dir(xps_document *doc) int i, n; fz_context *ctx = doc->ctx; - fz_lock(ctx, FZ_LOCK_FILE); fz_seek(doc->file, 0, SEEK_END); file_size = fz_tell(doc->file); @@ -322,7 +314,6 @@ xps_find_and_read_zip_dir(xps_document *doc) if (!memcmp(buf + i, "PK\5\6", 4)) { xps_read_zip_dir(doc, file_size - back + i); - fz_unlock(ctx, FZ_LOCK_FILE); return; } } @@ -330,8 +321,7 @@ xps_find_and_read_zip_dir(xps_document *doc) back += sizeof buf - 4; } - fz_unlock(ctx, FZ_LOCK_FILE); - fz_throw(doc->ctx, "cannot find end of central directory"); + fz_throw(ctx, "cannot find end of central directory"); } /* |