diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-07-30 11:57:31 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-07-30 11:57:31 +0000 |
commit | 4f49317deff939df854a8d9fecd7502cf2b4c9b2 (patch) | |
tree | 58f3b921bb557572a7c7931b91a30a8e7a539d6e | |
parent | 39ebb88a7bed4d0963895debb80a7462530e4c91 (diff) | |
download | mupdf-4f49317deff939df854a8d9fecd7502cf2b4c9b2.tar.xz |
Make an educated guess at the stream length by looking at the filters used in pdf_loadstream.
-rw-r--r-- | fitz/fitz.h | 2 | ||||
-rw-r--r-- | fitz/stm_read.c | 7 | ||||
-rw-r--r-- | mupdf/pdf_stream.c | 40 |
3 files changed, 44 insertions, 5 deletions
diff --git a/fitz/fitz.h b/fitz/fitz.h index 1af70f6a..44f1c070 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -501,7 +501,7 @@ void fz_seek(fz_stream *stm, int offset, int whence); int fz_read(fz_stream *stm, unsigned char *buf, int len); void fz_readline(fz_stream *stm, char *buf, int max); -fz_error fz_readall(fz_buffer **bufp, fz_stream *stm); +fz_error fz_readall(fz_buffer **bufp, fz_stream *stm, int initial); static inline int fz_readbyte(fz_stream *stm) { diff --git a/fitz/stm_read.c b/fitz/stm_read.c index 3bdddade..fb251214 100644 --- a/fitz/stm_read.c +++ b/fitz/stm_read.c @@ -55,12 +55,15 @@ fz_fillbuffer(fz_stream *stm) } fz_error -fz_readall(fz_buffer **bufp, fz_stream *stm) +fz_readall(fz_buffer **bufp, fz_stream *stm, int initial) { fz_buffer *buf; int n; - buf = fz_newbuffer(16 * 1024); + if (initial < 1024) + initial = 1024; + + buf = fz_newbuffer(initial); while (1) { diff --git a/mupdf/pdf_stream.c b/mupdf/pdf_stream.c index c5645293..db0ffaa5 100644 --- a/mupdf/pdf_stream.c +++ b/mupdf/pdf_stream.c @@ -315,12 +315,22 @@ pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) { fz_error error; fz_stream *stm; + fz_obj *dict; + int len; + + error = pdf_loadobject(&dict, xref, num, gen); + if (error) + return fz_rethrow(error, "cannot load stream dictionary (%d %d R)", num, gen); + + len = fz_toint(fz_dictgets(dict, "Length")); + + fz_dropobj(dict); error = pdf_openrawstream(&stm, xref, num, gen); if (error) return fz_rethrow(error, "cannot open raw stream (%d %d R)", num, gen); - error = fz_readall(bufp, stm); + error = fz_readall(bufp, stm, len); if (error) { fz_close(stm); @@ -331,6 +341,18 @@ pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) return fz_okay; } +static int +pdf_guessfilterlength(int len, char *filter) +{ + if (!strcmp(filter, "ASCIIHexDecode")) + return len / 2; + if (!strcmp(filter, "FlateDecode")) + return len * 3; + if (!strcmp(filter, "LZWDecode")) + return len * 2; + return len; +} + /* * Load uncompressed contents of a stream into buf. */ @@ -339,12 +361,26 @@ pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) { fz_error error; fz_stream *stm; + fz_obj *dict, *obj; + int i, len; error = pdf_openstream(&stm, xref, num, gen); if (error) return fz_rethrow(error, "cannot open stream (%d %d R)", num, gen); - error = fz_readall(bufp, stm); + error = pdf_loadobject(&dict, xref, num, gen); + if (error) + return fz_rethrow(error, "cannot load stream dictionary (%d %d R)", num, gen); + + len = fz_toint(fz_dictgets(dict, "Length")); + obj = fz_dictgets(dict, "Filter"); + len = pdf_guessfilterlength(len, fz_toname(obj)); + for (i = 0; i < fz_arraylen(obj); i++) + len = pdf_guessfilterlength(len, fz_toname(fz_arrayget(obj, i))); + + fz_dropobj(dict); + + error = fz_readall(bufp, stm, len); if (error) { fz_close(stm); |