summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-05-14 19:34:35 +0100
committerRobin Watts <robin.watts@artifex.com>2012-05-31 13:26:00 +0100
commit65b8ae915465849babc1fa712971c701136f4ed5 (patch)
tree9724b5951eb266f7192c647d4fb26a127cd901fd /fitz
parent97716e53a6fa6947a183ed88df54702f96ba97b5 (diff)
downloadmupdf-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.c2
-rw-r--r--fitz/fitz-internal.h9
-rw-r--r--fitz/fitz.h11
-rw-r--r--fitz/stm_buffer.c81
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;
+}