diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-05-14 19:34:35 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-05-31 13:26:00 +0100 |
commit | 65b8ae915465849babc1fa712971c701136f4ed5 (patch) | |
tree | 9724b5951eb266f7192c647d4fb26a127cd901fd /fitz | |
parent | 97716e53a6fa6947a183ed88df54702f96ba97b5 (diff) | |
download | mupdf-65b8ae915465849babc1fa712971c701136f4ed5.tar.xz |
Add linearization to pdf_write function.
Extend mupdfclean to have a new -l file that writes the file
linearized. This should still be considered experimental
When writing a pdf file, analyse object use, flatten resource use,
reorder the objects, generate a hintstream and output with linearisaton
parameters.
This is enough for Acrobat to accept the file as being optimised
for Fast Web View. We ought to add more tables to the hintstream
in some cases, but I doubt anyone actually uses it, the spec is so
badly written. Certainly acrobat accepts the file as being optimised
for 'Fast Web View'.
Update fz_dict_put to allow for us adding a reference to the dictionary
that is the sole owner of that reference already (i.e. don't drop then
keep something that has a reference count of just 1).
Update pdf_load_image_stream to use the stm_buf from the xref if there
is one.
Update pdf_close_document to discard any stm_bufs it may be holding.
Update fz_dict_put to be pdf_dict_put - this was missed in a renaming
ages ago and has been inconsistent since.
Diffstat (limited to 'fitz')
-rw-r--r-- | fitz/doc_document.c | 2 | ||||
-rw-r--r-- | fitz/fitz-internal.h | 9 | ||||
-rw-r--r-- | fitz/fitz.h | 11 | ||||
-rw-r--r-- | fitz/stm_buffer.c | 81 |
4 files changed, 97 insertions, 6 deletions
diff --git a/fitz/doc_document.c b/fitz/doc_document.c index 961dfff8..1233aeb9 100644 --- a/fitz/doc_document.c +++ b/fitz/doc_document.c @@ -131,7 +131,7 @@ fz_meta(fz_document *doc, int key, void *ptr, int size) } void -fz_write(fz_document *doc, char *filename, fz_write_options *opts) +fz_write_document(fz_document *doc, char *filename, fz_write_options *opts) { if (doc && doc->write) doc->write(doc, filename, opts); diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index b3f7a73c..05d7b52f 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -369,6 +369,7 @@ struct fz_buffer_s int refs; unsigned char *data; int cap, len; + int unused_bits; }; /* @@ -410,6 +411,14 @@ void fz_grow_buffer(fz_context *ctx, fz_buffer *buf); */ void fz_trim_buffer(fz_context *ctx, fz_buffer *buf); +void fz_write_buffer(fz_context *ctx, fz_buffer *buf, unsigned char *data, int len); + +void fz_write_buffer_byte(fz_context *ctx, fz_buffer *buf, int val); + +void fz_write_buffer_bits(fz_context *ctx, fz_buffer *buf, int val, int bits); + +void fz_write_buffer_pad(fz_context *ctx, fz_buffer *buf); + struct fz_stream_s { fz_context *ctx; diff --git a/fitz/fitz.h b/fitz/fitz.h index 10dce6c9..a10fd4dc 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -2255,16 +2255,17 @@ typedef struct fz_write_options_s fz_write_options; */ struct fz_write_options_s { - int doascii; /* If non-zero then attempt (where possible) to + int do_ascii; /* If non-zero then attempt (where possible) to make the output ascii. */ - int doexpand; /* Bitflags; each non zero bit indicates an aspect + int do_expand; /* Bitflags; each non zero bit indicates an aspect of the file that should be 'expanded' on writing. */ - int dogarbage; /* If non-zero then attempt (where possible) to + int do_garbage; /* If non-zero then attempt (where possible) to garbage collect the file before writing. */ + int do_linear; /* If non-zero then write linearised. */ }; -/* An enumeration of bitflags to use in the above 'doexpand' field of +/* An enumeration of bitflags to use in the above 'do_expand' field of fz_write_options. */ enum @@ -2290,6 +2291,6 @@ enum May throw exceptions. */ -void fz_write(fz_document *doc, char *filename, fz_write_options *opts); +void fz_write_document(fz_document *doc, char *filename, fz_write_options *opts); #endif diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c index 4be0165a..58539bf8 100644 --- a/fitz/stm_buffer.c +++ b/fitz/stm_buffer.c @@ -20,6 +20,7 @@ fz_new_buffer(fz_context *ctx, int size) } b->cap = size; b->len = 0; + b->unused_bits = 0; return b; } @@ -64,6 +65,17 @@ fz_grow_buffer(fz_context *ctx, fz_buffer *buf) fz_resize_buffer(ctx, buf, (buf->cap * 3) / 2); } +static void +fz_ensure_buffer(fz_context *ctx, fz_buffer *buf, int min) +{ + int newsize = buf->cap; + while (newsize < min) + { + newsize = (newsize * 3) / 2; + } + fz_resize_buffer(ctx, buf, newsize); +} + void fz_trim_buffer(fz_context *ctx, fz_buffer *buf) { @@ -78,3 +90,72 @@ fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap) *datap = (buf ? buf->data : NULL); return (buf ? buf->len : 0); } + +void fz_write_buffer(fz_context *ctx, fz_buffer *buf, unsigned char *data, int len) +{ + if (buf->len + len > buf->cap) + fz_ensure_buffer(ctx, buf, buf->len + len); + memcpy(buf->data + buf->len, data, len); + buf->len += len; + buf->unused_bits = 0; +} + +void fz_write_buffer_byte(fz_context *ctx, fz_buffer *buf, int val) +{ + if (buf->len > buf->cap) + fz_grow_buffer(ctx, buf); + buf->data[buf->len++] = val; + buf->unused_bits = 0; +} + +void fz_write_buffer_bits(fz_context *ctx, fz_buffer *buf, int val, int bits) +{ + int extra; + int shift; + + if (bits == 0) + return; + + /* buf->len always covers all the bits in the buffer, including + * any unused ones in the last byte, which will always be 0. + * buf->unused_bits = the number of unused bits in the last byte. + */ + + /* Extend the buffer as required before we start; that way we never + * fail part way during writing. */ + shift = (buf->unused_bits - bits); + if (shift < 0) + { + extra = (7-buf->unused_bits)>>3; + fz_ensure_buffer(ctx, buf, buf->len + extra); + } + + /* Write any bits that will fit into the existing byte */ + if (buf->unused_bits) + { + buf->data[buf->len-1] |= (shift >= 0 ? (((unsigned int)val)<<shift) : (((unsigned int)val)>>-shift)); + if (shift >= 0) + return; + bits += shift; + } + + /* Write any whole bytes */ + while (bits >= 8) + { + bits -= 8; + buf->data[buf->len++] = val>>bits; + } + + /* Write trailing bits (with 0's in unused bits) */ + if (bits > 0) + { + bits += 8; + buf->data[buf->len++] = val<<bits; + } + buf->unused_bits = bits; +} + +void fz_write_buffer_pad(fz_context *ctx, fz_buffer *buf) +{ + buf->unused_bits = 0; +} |