summaryrefslogtreecommitdiff
path: root/fitz/stm_buffer.c
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/stm_buffer.c
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/stm_buffer.c')
-rw-r--r--fitz/stm_buffer.c81
1 files changed, 81 insertions, 0 deletions
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;
+}