summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--apps/pdfapp.c2
-rw-r--r--apps/pdfclean.c6
-rw-r--r--apps/pdfextract.c11
-rw-r--r--apps/pdfshow.c8
-rw-r--r--fitz/filt_basic.c624
-rw-r--r--fitz/filt_dctd.c328
-rw-r--r--fitz/filt_faxd.c241
-rw-r--r--fitz/filt_flate.c119
-rw-r--r--fitz/filt_jbig2d.c142
-rw-r--r--fitz/filt_jpxd.c193
-rw-r--r--fitz/filt_lzwd.c207
-rw-r--r--fitz/filt_pipeline.c131
-rw-r--r--fitz/filt_predict.c236
-rw-r--r--fitz/fitz.h208
-rw-r--r--fitz/stm_buffer.c75
-rw-r--r--fitz/stm_filter.c55
-rw-r--r--fitz/stm_open.c128
-rw-r--r--fitz/stm_read.c354
-rw-r--r--mupdf/cmapdump.c3
-rw-r--r--mupdf/mupdf.h4
-rw-r--r--mupdf/pdf_cmap_load.c4
-rw-r--r--mupdf/pdf_colorspace.c21
-rw-r--r--mupdf/pdf_crypt.c10
-rw-r--r--mupdf/pdf_font.c4
-rw-r--r--mupdf/pdf_fontfile.c4
-rw-r--r--mupdf/pdf_function.c19
-rw-r--r--mupdf/pdf_image.c54
-rw-r--r--mupdf/pdf_interpret.c7
-rw-r--r--mupdf/pdf_lex.c42
-rw-r--r--mupdf/pdf_page.c15
-rw-r--r--mupdf/pdf_parse.c6
-rw-r--r--mupdf/pdf_repair.c26
-rw-r--r--mupdf/pdf_shade.c4
-rw-r--r--mupdf/pdf_stream.c245
-rw-r--r--mupdf/pdf_xobject.c2
-rw-r--r--mupdf/pdf_xref.c130
-rw-r--r--win32/mupdf/mupdf.vcproj8
38 files changed, 1418 insertions, 2260 deletions
diff --git a/Makefile b/Makefile
index 55848975..178ae584 100644
--- a/Makefile
+++ b/Makefile
@@ -98,7 +98,6 @@ FITZ_SRC := \
fitz/filt_jbig2d.c \
fitz/filt_jpxd.c \
fitz/filt_lzwd.c \
- fitz/filt_pipeline.c \
fitz/filt_predict.c \
fitz/obj_array.c \
fitz/obj_dict.c \
@@ -111,7 +110,6 @@ FITZ_SRC := \
fitz/res_shade.c \
fitz/res_text.c \
fitz/stm_buffer.c \
- fitz/stm_filter.c \
fitz/stm_open.c \
fitz/stm_read.c
FITZ_OBJ := $(FITZ_SRC:fitz/%.c=$(OBJDIR)/%.o)
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 5a2d2322..1393d4e3 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -106,7 +106,7 @@ void pdfapp_open(pdfapp_t *app, char *filename, int fd)
error = pdf_openxrefwithstream(&app->xref, file, NULL);
if (error)
pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename));
- fz_dropstream(file);
+ fz_close(file);
/*
* Handle encrypted PDF files
diff --git a/apps/pdfclean.c b/apps/pdfclean.c
index 27c8693c..aca76e2a 100644
--- a/apps/pdfclean.c
+++ b/apps/pdfclean.c
@@ -380,7 +380,7 @@ static void copystream(fz_obj *obj, int num, int gen)
fprintf(out, "%d %d obj\n", num, gen);
fz_fprintobj(out, obj, !doexpand);
fprintf(out, "stream\n");
- fwrite(buf->rp, 1, buf->wp - buf->rp, out);
+ fwrite(buf->data, 1, buf->len, out);
fprintf(out, "endstream\nendobj\n\n");
fz_dropbuffer(buf);
@@ -400,14 +400,14 @@ static void expandstream(fz_obj *obj, int num, int gen)
fz_dictdels(newdict, "Filter");
fz_dictdels(newdict, "DecodeParms");
- newlen = fz_newint(buf->wp - buf->rp);
+ newlen = fz_newint(buf->len);
fz_dictputs(newdict, "Length", newlen);
fz_dropobj(newlen);
fprintf(out, "%d %d obj\n", num, gen);
fz_fprintobj(out, newdict, !doexpand);
fprintf(out, "stream\n");
- fwrite(buf->rp, 1, buf->wp - buf->rp, out);
+ fwrite(buf->data, 1, buf->len, out);
fprintf(out, "endstream\nendobj\n\n");
fz_dropobj(newdict);
diff --git a/apps/pdfextract.c b/apps/pdfextract.c
index e0da93e6..cb10e117 100644
--- a/apps/pdfextract.c
+++ b/apps/pdfextract.c
@@ -92,8 +92,8 @@ static void savefont(fz_obj *dict, int num)
fz_obj *obj;
char *ext = "";
FILE *f;
- unsigned char *p;
char *fontname = "font";
+ int n;
obj = fz_dictgets(dict, "FontName");
if (obj)
@@ -148,13 +148,14 @@ static void savefont(fz_obj *dict, int num)
f = fopen(name, "wb");
if (f == NULL)
- die(fz_throw("Error creating image file"));
+ die(fz_throw("Error creating font file"));
- for (p = buf->rp; p < buf->wp; p ++)
- fprintf(f, "%c", *p);
+ n = fwrite(buf, 1, buf->len, f);
+ if (n < buf->len)
+ die(fz_throw("Error writing font file"));
if (fclose(f) < 0)
- die(fz_throw("Error closing image file"));
+ die(fz_throw("Error closing font file"));
fz_dropbuffer(buf);
}
diff --git a/apps/pdfshow.c b/apps/pdfshow.c
index cb15fd99..b05f6013 100644
--- a/apps/pdfshow.c
+++ b/apps/pdfshow.c
@@ -111,9 +111,9 @@ static void showstream(int num, int gen)
while (1)
{
- error = fz_read(&n, stm, buf, sizeof buf);
- if (error)
- die(error);
+ n = fz_read(stm, buf, sizeof buf);
+ if (n < 0)
+ die(n);
if (n == 0)
break;
if (showbinary)
@@ -122,7 +122,7 @@ static void showstream(int num, int gen)
showsafe(buf, n);
}
- fz_dropstream(stm);
+ fz_close(stm);
}
static void showobject(int num, int gen)
diff --git a/fitz/filt_basic.c b/fitz/filt_basic.c
index b9ec347e..90be39ee 100644
--- a/fitz/filt_basic.c
+++ b/fitz/filt_basic.c
@@ -1,97 +1,51 @@
#include "fitz.h"
-/* Identity filter */
+/* Pretend we have a filter that just copies data forever */
-fz_filter *
-fz_newcopyfilter(void)
+fz_stream *
+fz_opencopy(fz_stream *chain)
{
- FZ_NEWFILTER(fz_filter, f, copyfilter);
- return f;
+ return fz_keepstream(chain);
}
-void
-fz_dropcopyfilter(fz_filter *f)
-{
-}
-
-fz_error
-fz_processcopyfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
-{
- int n;
-
- while (1)
- {
- if (in->rp + 1 > in->wp)
- {
- if (in->eof)
- return fz_iodone;
- return fz_ioneedin;
- }
-
- if (out->wp + 1 > out->ep)
- return fz_ioneedout;
-
- n = MIN(in->wp - in->rp, out->ep - out->wp);
- if (n)
- {
- memcpy(out->wp, in->rp, n);
- in->rp += n;
- out->wp += n;
- }
- }
-}
-
-/* Null filter copies data until a specified length */
-
-typedef struct fz_nullfilter_s fz_nullfilter;
+/* Null filter copies a specified amount of data */
-struct fz_nullfilter_s
+struct nullfilter
{
- fz_filter super;
- int len;
- int cur;
+ fz_stream *chain;
+ int remain;
};
-fz_filter *
-fz_newnullfilter(int len)
+static int
+readnull(fz_stream *stm, unsigned char *buf, int len)
{
- FZ_NEWFILTER(fz_nullfilter, f, nullfilter);
- f->len = len;
- f->cur = 0;
- return (fz_filter *)f;
+ struct nullfilter *state = stm->state;
+ int amount = MIN(len, state->remain);
+ int n = fz_read(state->chain, buf, amount);
+ if (n < 0)
+ return fz_rethrow(n, "read error in null filter");
+ state->remain -= n;
+ return n;
}
-void
-fz_dropnullfilter(fz_filter *f)
+static void
+closenull(fz_stream *stm)
{
+ struct nullfilter *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
}
-fz_error
-fz_processnullfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+fz_stream *
+fz_opennull(fz_stream *chain, int len)
{
- fz_nullfilter *f = (fz_nullfilter*)filter;
- int n;
-
- n = MIN(in->wp - in->rp, out->ep - out->wp);
- if (f->len >= 0)
- n = MIN(n, f->len - f->cur);
-
- if (n)
- {
- memcpy(out->wp, in->rp, n);
- in->rp += n;
- out->wp += n;
- f->cur += n;
- }
+ struct nullfilter *state;
- if (f->cur == f->len)
- return fz_iodone;
- if (in->rp == in->wp)
- return fz_ioneedin;
- if (out->wp == out->ep)
- return fz_ioneedout;
+ state = fz_malloc(sizeof(struct nullfilter));
+ state->chain = chain;
+ state->remain = len;
- return fz_throw("braindead programmer trapped in nullfilter");
+ return fz_newstream(state, readnull, closenull);
}
/* ASCII Hex Decode */
@@ -100,9 +54,8 @@ typedef struct fz_ahxd_s fz_ahxd;
struct fz_ahxd_s
{
- fz_filter super;
- int odd;
- int a;
+ fz_stream *chain;
+ int eod;
};
static inline int iswhite(int a)
@@ -133,58 +86,71 @@ static inline int fromhex(int a)
return 0;
}
-fz_filter *
-fz_newahxd(fz_obj *params)
-{
- FZ_NEWFILTER(fz_ahxd, f, ahxd);
- f->odd = 0;
- f->a = 0;
- return (fz_filter *)f;
-}
-
-void
-fz_dropahxd(fz_filter *f)
+static int
+readahxd(fz_stream *stm, unsigned char *buf, int len)
{
-}
+ fz_ahxd *state = stm->state;
+ unsigned char *p = buf;
+ int a, b, c, odd;
-fz_error
-fz_processahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
-{
- fz_ahxd *f = (fz_ahxd*)filter;
- int b, c;
+ odd = 0;
- while (1)
+ while (p < buf + len)
{
- if (in->rp == in->wp)
- return fz_ioneedin;
+ if (state->eod)
+ return p - buf;
- if (out->wp == out->ep)
- return fz_ioneedout;
+ c = fz_readbyte(state->chain);
+ if (c < 0)
+ return p - buf;
- c = *in->rp++;
-
- if (ishex(c)) {
- if (!f->odd) {
- f->a = fromhex(c);
- f->odd = 1;
+ if (ishex(c))
+ {
+ if (!odd)
+ {
+ a = fromhex(c);
+ odd = 1;
}
- else {
+ else
+ {
b = fromhex(c);
- *out->wp++ = (f->a << 4) | b;
- f->odd = 0;
+ *p++ = (a << 4) | b;
+ odd = 0;
}
}
-
- else if (c == '>') {
- if (f->odd)
- *out->wp++ = (f->a << 4);
- return fz_iodone;
+ else if (c == '>')
+ {
+ if (odd)
+ *p++ = (a << 4);
+ state->eod = 1;
}
-
- else if (!iswhite(c)) {
+ else if (!iswhite(c))
+ {
return fz_throw("bad data in ahxd: '%c'", c);
}
}
+
+ return p - buf;
+}
+
+static void
+closeahxd(fz_stream *stm)
+{
+ fz_ahxd *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openahxd(fz_stream *chain)
+{
+ fz_ahxd *state;
+
+ state = fz_malloc(sizeof(fz_ahxd));
+ state->chain = chain;
+ state->eod = 0;
+
+ return fz_newstream(state, readahxd, closeahxd);
}
/* ASCII 85 Decode */
@@ -193,187 +159,207 @@ typedef struct fz_a85d_s fz_a85d;
struct fz_a85d_s
{
- fz_filter super;
- unsigned long word;
- int count;
+ fz_stream *chain;
+ unsigned char buf[4];
+ int remain;
+ int eod;
};
-fz_filter *
-fz_newa85d(fz_obj *params)
-{
- FZ_NEWFILTER(fz_a85d, f, a85d);
- f->word = 0;
- f->count = 0;
- return (fz_filter *)f;
-}
-
-void
-fz_dropa85d(fz_filter *f)
-{
-}
-
-fz_error
-fz_processa85d(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+static int
+reada85d(fz_stream *stm, unsigned char *buf, int len)
{
- fz_a85d *f = (fz_a85d*)filter;
+ fz_a85d *state = stm->state;
+ unsigned char *p = buf;
+ int count = 0;
+ int word = 0;
int c;
- while (1)
- {
- if (in->rp == in->wp)
- return fz_ioneedin;
+ while (state->remain > 0 && p < buf + len)
+ *p++ = state->buf[4 - state->remain];
- c = *in->rp++;
+ while (p < buf + len)
+ {
+ if (state->eod)
+ return p - buf;
- if (c >= '!' && c <= 'u') {
- if (f->count == 4) {
- if (out->wp + 4 > out->ep) {
- in->rp --;
- return fz_ioneedout;
- }
+ c = fz_readbyte(state->chain);
+ if (c < 0)
+ return p - buf;
- f->word = f->word * 85 + (c - '!');
+ if (c >= '!' && c <= 'u')
+ {
+ if (count == 4)
+ {
+ word = word * 85 + (c - '!');
- *out->wp++ = (f->word >> 24) & 0xff;
- *out->wp++ = (f->word >> 16) & 0xff;
- *out->wp++ = (f->word >> 8) & 0xff;
- *out->wp++ = (f->word) & 0xff;
+ state->buf[0] = (word >> 24) & 0xff;
+ state->buf[1] = (word >> 16) & 0xff;
+ state->buf[2] = (word >> 8) & 0xff;
+ state->buf[3] = (word) & 0xff;
+ state->remain = 4;
- f->word = 0;
- f->count = 0;
+ word = 0;
+ count = 0;
}
- else {
- f->word = f->word * 85 + (c - '!');
- f->count ++;
+ else
+ {
+ word = word * 85 + (c - '!');
+ count ++;
}
}
- else if (c == 'z' && f->count == 0) {
- if (out->wp + 4 > out->ep) {
- in->rp --;
- return fz_ioneedout;
- }
- *out->wp++ = 0;
- *out->wp++ = 0;
- *out->wp++ = 0;
- *out->wp++ = 0;
+ else if (c == 'z' && count == 0)
+ {
+ state->buf[0] = 0;
+ state->buf[1] = 0;
+ state->buf[2] = 0;
+ state->buf[3] = 0;
+ state->remain = 4;
}
- else if (c == '~') {
- if (in->rp == in->wp) {
- in->rp --;
- return fz_ioneedin;
- }
-
- c = *in->rp++;
-
- if (c != '>') {
+ else if (c == '~')
+ {
+ c = fz_readbyte(state->chain);
+ if (c != '>')
return fz_throw("bad eod marker in a85d");
- }
-
- if (out->wp + f->count - 1 > out->ep) {
- in->rp -= 2;
- return fz_ioneedout;
- }
- switch (f->count) {
+ switch (count) {
case 0:
break;
case 1:
return fz_throw("partial final byte in a85d");
case 2:
- f->word = f->word * (85L * 85 * 85) + 0xffffffL;
- goto o1;
+ word = word * (85 * 85 * 85) + 0xffffff;
+ state->buf[0] = word >> 24;
+ state->remain = 1;
+ break;
case 3:
- f->word = f->word * (85L * 85) + 0xffffL;
- goto o2;
+ word = word * (85 * 85) + 0xffff;
+ state->buf[0] = word >> 24;
+ state->buf[1] = word >> 16;
+ state->remain = 2;
+ break;
case 4:
- f->word = f->word * 85 + 0xffL;
- *(out->wp+2) = f->word >> 8;
- o2: *(out->wp+1) = f->word >> 16;
- o1: *(out->wp+0) = f->word >> 24;
- out->wp += f->count - 1;
+ word = word * 85 + 0xff;
+ state->buf[0] = word >> 24;
+ state->buf[1] = word >> 16;
+ state->buf[2] = word >> 8;
+ state->remain = 3;
break;
}
- return fz_iodone;
+ state->eod = 1;
}
- else if (!iswhite(c)) {
+ else if (!iswhite(c))
+ {
return fz_throw("bad data in a85d: '%c'", c);
}
+
+ while (state->remain > 0 && p < buf + len)
+ *p++ = state->buf[4 - state->remain];
}
-}
-/* Run Length Decode */
+ return p - buf;
+}
-fz_filter *
-fz_newrld(fz_obj *params)
+static void
+closea85d(fz_stream *stm)
{
- FZ_NEWFILTER(fz_filter, f, rld);
- return f;
+ fz_a85d *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
}
-void
-fz_droprld(fz_filter *rld)
+fz_stream *
+fz_opena85d(fz_stream *chain)
{
+ fz_a85d *state;
+
+ state = fz_malloc(sizeof(fz_a85d));
+ state->chain = chain;
+ state->remain = 0;
+ state->eod = 0;
+
+ return fz_newstream(state, reada85d, closea85d);
}
-fz_error
-fz_processrld(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+/* Run Length Decode */
+
+typedef struct fz_rld_s fz_rld;
+
+struct fz_rld_s
+{
+ fz_stream *chain;
+ int run, n, c;
+};
+
+static int
+readrld(fz_stream *stm, unsigned char *buf, int len)
{
- int run, i;
- unsigned char c;
+ fz_rld *state = stm->state;
+ unsigned char *p = buf;
- while (1)
+ while (p < buf + len)
{
- if (in->rp == in->wp)
+ if (state->run == 128)
+ return p - buf;
+
+ if (state->n == 0)
{
- if (in->eof)
+ state->run = fz_readbyte(state->chain);
+ if (state->run < 0)
+ state->run = 128;
+ if (state->run < 128)
+ state->n = state->run + 1;
+ if (state->run > 128)
{
- return fz_iodone;
+ state->n = 257 - state->run;
+ state->c = fz_readbyte(state->chain);
+ if (state->c < 0)
+ return fz_throw("premature end of data in run length decode");
}
- return fz_ioneedin;
}
- if (out->wp == out->ep)
- return fz_ioneedout;
-
- run = *in->rp++;
-
- if (run == 128)
+ if (state->run < 128)
{
- return fz_iodone;
- }
-
- else if (run < 128) {
- run = run + 1;
- if (in->rp + run > in->wp) {
- in->rp --;
- return fz_ioneedin;
- }
- if (out->wp + run > out->ep) {
- in->rp --;
- return fz_ioneedout;
+ while (p < buf + len && state->n--)
+ {
+ int c = fz_readbyte(state->chain);
+ if (c < 0)
+ return fz_throw("premature end of data in run length decode");
+ *p++ = c;
}
- for (i = 0; i < run; i++)
- *out->wp++ = *in->rp++;
}
- else if (run > 128) {
- run = 257 - run;
- if (in->rp + 1 > in->wp) {
- in->rp --;
- return fz_ioneedin;
- }
- if (out->wp + run > out->ep) {
- in->rp --;
- return fz_ioneedout;
- }
- c = *in->rp++;
- for (i = 0; i < run; i++)
- *out->wp++ = c;
+ if (state->run > 128)
+ {
+ while (p < buf + len && state->n--)
+ *p++ = state->c;
}
}
+
+ return p - buf;
+}
+
+static void
+closerld(fz_stream *stm)
+{
+ fz_rld *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openrld(fz_stream *chain)
+{
+ fz_rld *state;
+
+ state = fz_malloc(sizeof(fz_rld));
+ state->run = 0;
+ state->n = 0;
+ state->c = 0;
+
+ return fz_newstream(state, readrld, closerld);
}
/* RC4 Filter */
@@ -382,44 +368,43 @@ typedef struct fz_arc4c_s fz_arc4c;
struct fz_arc4c_s
{
- fz_filter super;
+ fz_stream *chain;
fz_arc4 arc4;
};
-fz_filter *
-fz_newarc4filter(unsigned char *key, unsigned keylen)
+static int
+readarc4(fz_stream *stm, unsigned char *buf, int len)
{
- FZ_NEWFILTER(fz_arc4c, f, arc4filter);
- fz_arc4init(&f->arc4, key, keylen);
- return (fz_filter *)f;
+ fz_arc4c *state = stm->state;
+ int n;
+
+ n = fz_read(state->chain, buf, len);
+ if (n < 0)
+ return fz_rethrow(n, "read error in arc4 filter");
+
+ fz_arc4encrypt(&state->arc4, buf, buf, n);
+
+ return n;
}
-void
-fz_droparc4filter(fz_filter *f)
+static void
+closearc4(fz_stream *stm)
{
+ fz_arc4c *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
}
-fz_error
-fz_processarc4filter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+fz_stream *
+fz_openarc4(fz_stream *chain, unsigned char *key, unsigned keylen)
{
- fz_arc4c *f = (fz_arc4c*)filter;
- int n;
+ fz_arc4c *state;
- while (1)
- {
- if (in->rp + 1 > in->wp) {
- if (in->eof)
- return fz_iodone;
- return fz_ioneedin;
- }
- if (out->wp + 1 > out->ep)
- return fz_ioneedout;
+ state = fz_malloc(sizeof(fz_arc4c));
+ state->chain = chain;
+ fz_arc4init(&state->arc4, key, keylen);
- n = MIN(in->wp - in->rp, out->ep - out->wp);
- fz_arc4encrypt(&f->arc4, out->wp, in->rp, n);
- in->rp += n;
- out->wp += n;
- }
+ return fz_newstream(state, readarc4, closearc4);
}
/* AES Filter */
@@ -428,65 +413,80 @@ typedef struct fz_aesd_s fz_aesd;
struct fz_aesd_s
{
- fz_filter super;
+ fz_stream *chain;
fz_aes aes;
unsigned char iv[16];
int ivcount;
+ unsigned char buf[16];
+ int remain;
};
-fz_filter *
-fz_newaesdfilter(unsigned char *key, unsigned keylen)
+static int
+readaesd(fz_stream *stm, unsigned char *buf, int len)
{
- FZ_NEWFILTER(fz_aesd, f, aesdfilter);
- aes_setkey_dec(&f->aes, key, keylen * 8);
- f->ivcount = 0;
- return (fz_filter *)f;
-}
+ fz_aesd *state = stm->state;
+ unsigned char *p = buf;
-void
-fz_dropaesdfilter(fz_filter *f)
-{
-}
+ while (state->ivcount < 16)
+ {
+ int c = fz_readbyte(state->chain);
+ if (c < 0)
+ return fz_throw("premature end in AES filter");
+ state->iv[state->ivcount++] = c;
+ }
-fz_error
-fz_processaesdfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
-{
- fz_aesd *f = (fz_aesd*)filter;
- int n;
+ while (p < buf + len && state->remain-- > 0)
+ *p++ = state->buf[16 - state->remain];
- while (1)
+ while (p < buf + len)
{
- if (in->rp + 16 > in->wp)
+ while (state->remain < 16)
{
- if (in->eof)
- return fz_iodone;
- return fz_ioneedin;
+ int c = fz_readbyte(state->chain);
+ if (c < 0)
+ {
+ if (state->remain > 0)
+ return fz_throw("premature end in AES filter");
+ return p - buf;
+ }
+ state->buf[state->remain++] = c;
}
- if (f->ivcount < 16)
+ aes_crypt_cbc(&state->aes, AES_DECRYPT, 16, state->iv, state->buf, state->buf);
+
+ /* strip padding at end of file */
+ if (fz_peekbyte(state->chain) == EOF)
{
- f->iv[f->ivcount++] = *in->rp++;
+ int pad = state->buf[15];
+ if (pad < 1 || pad > 16)
+ return fz_throw("aes padding out of range: %d", pad);
+ state->remain -= pad;
}
- else
- {
- if (out->wp + 16 > out->ep)
- return fz_ioneedout;
- n = MIN(in->wp - in->rp, out->ep - out->wp);
- n = (n / 16) * 16;
+ while (p < buf + len && state->remain-- > 0)
+ *p++ = state->buf[16 - state->remain];
+ }
- aes_crypt_cbc(&f->aes, AES_DECRYPT, n, f->iv, in->rp, out->wp);
- in->rp += n;
- out->wp += n;
+ return p - buf;
+}
- /* Remove padding bytes */
- if (in->eof && in->rp == in->wp)
- {
- int pad = out->wp[-1];
- if (pad < 1 || pad > 16)
- return fz_throw("aes padding out of range: %d", pad);
- out->wp -= pad;
- }
- }
- }
+static void
+closeaesd(fz_stream *stm)
+{
+ fz_aesd *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openaesd(fz_stream *chain, unsigned char *key, unsigned keylen)
+{
+ fz_aesd *state;
+
+ state = fz_malloc(sizeof(fz_aesd));
+ state->chain = chain;
+ aes_setkey_dec(&state->aes, key, keylen * 8);
+ state->ivcount = 0;
+
+ return fz_newstream(state, readaesd, closeaesd);
}
diff --git a/fitz/filt_dctd.c b/fitz/filt_dctd.c
index 3b3cc415..e260b34c 100644
--- a/fitz/filt_dctd.c
+++ b/fitz/filt_dctd.c
@@ -5,254 +5,212 @@
typedef struct fz_dctd_s fz_dctd;
-struct myerrmgr
+struct fz_dctd_s
{
- struct jpeg_error_mgr super;
+ fz_stream *chain;
+ int colortransform;
+ int init, done;
+ unsigned char *scanline;
+ int stride;
+ int remain;
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_source_mgr srcmgr;
+ struct jpeg_error_mgr errmgr;
jmp_buf jb;
char msg[JMSG_LENGTH_MAX];
};
-static void myerrexit(j_common_ptr cinfo)
+static void error_exit(j_common_ptr cinfo)
{
- struct myerrmgr *err = (struct myerrmgr *)cinfo->err;
- char msgbuf[JMSG_LENGTH_MAX];
- err->super.format_message(cinfo, msgbuf);
- fz_strlcpy(err->msg, msgbuf, sizeof err->msg);
- longjmp(err->jb, 1);
+ fz_dctd *state = cinfo->client_data;
+ cinfo->err->format_message(cinfo, state->msg);
+ longjmp(state->jb, 1);
}
-static void myoutmess(j_common_ptr cinfo)
+static void init_source(j_decompress_ptr cinfo)
{
- struct myerrmgr *err = (struct myerrmgr *)cinfo->err;
- char msgbuf[JMSG_LENGTH_MAX];
- err->super.format_message(cinfo, msgbuf);
- fz_warn("jpeg error: %s", msgbuf);
+ /* nothing to do */
}
-static void myiniterr(struct myerrmgr *err)
+static void term_source(j_decompress_ptr cinfo)
{
- jpeg_std_error(&err->super);
- err->super.error_exit = myerrexit;
- err->super.output_message = myoutmess;
+ /* nothing to do */
}
-struct mysrcmgr
+static boolean fill_input_buffer(j_decompress_ptr cinfo)
{
- struct jpeg_source_mgr super;
- fz_buffer *buf;
- int skip;
-};
+ struct jpeg_source_mgr *src = cinfo->src;
+ fz_dctd *state = cinfo->client_data;
+ fz_stream *chain = state->chain;
-struct fz_dctd_s
-{
- fz_filter super;
- struct jpeg_decompress_struct cinfo;
- struct mysrcmgr src;
- struct myerrmgr err;
- int colortransform;
- int stage;
-};
+ if (chain->rp == chain->wp)
+ fz_fillbuffer(chain);
-static void myinitsource(j_decompress_ptr cinfo) { /* empty */ }
-static int myfillinput(j_decompress_ptr cinfo) { return FALSE; }
-static void mytermsource(j_decompress_ptr cinfo) { /* empty */ }
-
-static void myskipinput(j_decompress_ptr cinfo, long n)
-{
- struct mysrcmgr *src = (struct mysrcmgr *)cinfo->src;
- fz_buffer *in = src->buf;
+ src->next_input_byte = chain->rp;
+ src->bytes_in_buffer = chain->wp - chain->rp;
+ chain->rp = chain->wp;
- assert(src->skip == 0);
-
- in->rp = in->wp - src->super.bytes_in_buffer;
-
- if (in->rp + n > in->wp) {
- src->skip = (in->rp + n) - in->wp;
- in->rp = in->wp;
- }
- else {
- src->skip = 0;
- in->rp += n;
- }
-
- src->super.bytes_in_buffer = in->wp - in->rp;
- src->super.next_input_byte = in->rp;
-}
-
-fz_filter *
-fz_newdctd(fz_obj *params)
-{
- fz_obj *obj;
- int colortransform;
-
- FZ_NEWFILTER(fz_dctd, d, dctd);
-
- colortransform = -1; /* "unset" */
-
- if (params)
+ if (src->bytes_in_buffer == 0)
{
- obj = fz_dictgets(params, "ColorTransform");
- if (obj)
- colortransform = fz_toint(obj);
+ static unsigned char eoi[2] = { 0xFF, JPEG_EOI };
+ fz_warn("premature end of file in jpeg");
+ src->next_input_byte = eoi;
+ src->bytes_in_buffer = 2;
}
- d->colortransform = colortransform;
- d->stage = 0;
-
- /* setup error callback first thing */
- myiniterr(&d->err);
- d->cinfo.err = (struct jpeg_error_mgr*) &d->err;
-
- if (setjmp(d->err.jb))
- fz_warn("cannot initialise jpeg: %s", d->err.msg);
-
- /* create decompression object. this zeroes cinfo except for err. */
- jpeg_create_decompress(&d->cinfo);
-
- /* prepare source manager */
- d->cinfo.src = (struct jpeg_source_mgr *)&d->src;
- d->src.super.init_source = myinitsource;
- d->src.super.fill_input_buffer = myfillinput;
- d->src.super.skip_input_data = myskipinput;
- d->src.super.resync_to_restart = jpeg_resync_to_restart;
- d->src.super.term_source = mytermsource;
-
- d->src.super.bytes_in_buffer = 0;
- d->src.super.next_input_byte = nil;
- d->src.skip = 0;
-
- return (fz_filter *)d;
+ return 1;
}
-void
-fz_dropdctd(fz_filter *filter)
+static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
- fz_dctd *d = (fz_dctd*)filter;
- if (setjmp(d->err.jb)) {
- fz_warn("jpeg error: jpeg_destroy_decompress: %s", d->err.msg);
- return;
+ struct jpeg_source_mgr *src = cinfo->src;
+ if (num_bytes > 0)
+ {
+ while (num_bytes > src->bytes_in_buffer)
+ {
+ num_bytes -= src->bytes_in_buffer;
+ (void) src->fill_input_buffer(cinfo);
+ }
+ src->next_input_byte += num_bytes;
+ src->bytes_in_buffer -= num_bytes;
}
- jpeg_destroy_decompress(&d->cinfo);
}
-fz_error
-fz_processdctd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+static int
+readdctd(fz_stream *stm, unsigned char *buf, int len)
{
- fz_dctd *d = (fz_dctd*)filter;
- int b;
- int i;
- int stride;
- JSAMPROW scanlines[1];
-
- d->src.buf = in;
+ fz_dctd *state = stm->state;
+ j_decompress_ptr cinfo = &state->cinfo;
+ unsigned char *p = buf;
- /* skip any bytes left over from myskipinput() */
- if (d->src.skip > 0) {
- if (in->rp + d->src.skip > in->wp) {
- d->src.skip = (in->rp + d->src.skip) - in->wp;
- in->rp = in->wp;
- goto needinput;
- }
- else {
- in->rp += d->src.skip;
- d->src.skip = 0;
- }
- }
-
- d->src.super.bytes_in_buffer = in->wp - in->rp;
- d->src.super.next_input_byte = in->rp;
-
- if (setjmp(d->err.jb))
+ if (setjmp(state->jb))
{
- return fz_throw("cannot decode jpeg: %s", d->err.msg);
+ state->done = 1;
+ return fz_throw("jpeg error: %s", state->msg);
}
- switch (d->stage)
+ if (!state->init)
{
- case 0:
- i = jpeg_read_header(&d->cinfo, TRUE);
- if (i == JPEG_SUSPENDED)
- goto needinput;
+ cinfo->client_data = state;
+ cinfo->err = &state->errmgr;
+ jpeg_std_error(cinfo->err);
+ cinfo->err->error_exit = error_exit;
+ jpeg_create_decompress(cinfo);
+
+ cinfo->src = &state->srcmgr;
+ cinfo->src->init_source = init_source;
+ cinfo->src->fill_input_buffer = fill_input_buffer;
+ cinfo->src->skip_input_data = skip_input_data;
+ cinfo->src->resync_to_restart = jpeg_resync_to_restart;
+ cinfo->src->term_source = term_source;
+ cinfo->src->next_input_byte = state->chain->rp;
+ cinfo->src->bytes_in_buffer = 0;
+
+ jpeg_read_header(cinfo, 1);
/* speed up jpeg decoding a bit */
- d->cinfo.dct_method = JDCT_FASTEST;
- d->cinfo.do_fancy_upsampling = FALSE;
+ cinfo->dct_method = JDCT_FASTEST;
+ cinfo->do_fancy_upsampling = FALSE;
/* default value if ColorTransform is not set */
- if (d->colortransform == -1)
+ if (state->colortransform == -1)
{
- if (d->cinfo.num_components == 3)
- d->colortransform = 1;
+ if (state->cinfo.num_components == 3)
+ state->colortransform = 1;
else
- d->colortransform = 0;
+ state->colortransform = 0;
}
- if (d->cinfo.saw_Adobe_marker)
- d->colortransform = d->cinfo.Adobe_transform;
+ if (cinfo->saw_Adobe_marker)
+ state->colortransform = cinfo->Adobe_transform;
/* Guess the input colorspace, and set output colorspace accordingly */
- switch (d->cinfo.num_components)
+ switch (cinfo->num_components)
{
case 3:
- if (d->colortransform)
- d->cinfo.jpeg_color_space = JCS_YCbCr;
+ if (state->colortransform)
+ cinfo->jpeg_color_space = JCS_YCbCr;
else
- d->cinfo.jpeg_color_space = JCS_RGB;
+ cinfo->jpeg_color_space = JCS_RGB;
break;
case 4:
- if (d->colortransform)
- d->cinfo.jpeg_color_space = JCS_YCCK;
+ if (state->colortransform)
+ cinfo->jpeg_color_space = JCS_YCCK;
else
- d->cinfo.jpeg_color_space = JCS_CMYK;
+ cinfo->jpeg_color_space = JCS_CMYK;
break;
}
- /* fall through */
- d->stage = 1;
+ jpeg_start_decompress(cinfo);
+
+ state->stride = cinfo->output_width * cinfo->output_components;
+ state->remain = 0;
+ state->scanline = fz_malloc(state->stride);
- case 1:
- b = jpeg_start_decompress(&d->cinfo);
- if (b == FALSE)
- goto needinput;
+ state->init = 1;
+ }
- /* fall through */
- d->stage = 2;
+ while (state->remain > 0 && p < buf + len)
+ *p++ = state->scanline[state->stride - state->remain--];
- case 2:
- stride = d->cinfo.output_width * d->cinfo.output_components;
+ while (p < buf + len)
+ {
+ if (state->done)
+ return p - buf;
- while (d->cinfo.output_scanline < d->cinfo.output_height)
+ if (cinfo->output_scanline == cinfo->output_height)
{
- if (out->wp + stride > out->ep)
- goto needoutput;
+ state->done = 1;
+ jpeg_finish_decompress(cinfo);
+ jpeg_destroy_decompress(cinfo);
+ return p - buf;
+ }
- scanlines[0] = out->wp;
+ if (p + state->stride <= buf + len)
+ {
+ jpeg_read_scanlines(cinfo, &p, 1);
+ p += state->stride;
+ }
+ else
+ {
+ jpeg_read_scanlines(cinfo, &state->scanline, 1);
+ state->remain = state->stride;
+ }
- i = jpeg_read_scanlines(&d->cinfo, scanlines, 1);
+ while (state->remain > 0 && p < buf + len)
+ *p++ = state->scanline[state->stride - state->remain--];
+ }
- if (i == 0)
- goto needinput;
+ return p - buf;
+}
- out->wp += stride;
- }
+static void
+closedctd(fz_stream *stm)
+{
+ fz_dctd *state = stm->state;
+ fz_free(state->scanline);
+ fz_close(state->chain);
+ fz_free(state);
+}
- /* fall through */
- d->stage = 3;
+fz_stream *
+fz_opendctd(fz_stream *chain, fz_obj *params)
+{
+ fz_dctd *state;
+ fz_obj *obj;
- case 3:
- b = jpeg_finish_decompress(&d->cinfo);
- if (b == FALSE)
- goto needinput;
- d->stage = 4;
- in->rp = in->wp - d->src.super.bytes_in_buffer;
- return fz_iodone;
- }
+ state = fz_malloc(sizeof(fz_dctd));
+ state->chain = chain;
+ state->colortransform = -1; /* unset */
+ state->init = 0;
+ state->done = 0;
+ state->scanline = nil;
+ state->stride = 0;
+ state->remain = 0;
-needinput:
- in->rp = in->wp - d->src.super.bytes_in_buffer;
- return fz_ioneedin;
+ obj = fz_dictgets(params, "ColorTransform");
+ if (obj)
+ state->colortransform = fz_toint(obj);
-needoutput:
- in->rp = in->wp - d->src.super.bytes_in_buffer;
- return fz_ioneedout;
+ return fz_newstream(state, readdctd, closedctd);
}
diff --git a/fitz/filt_faxd.c b/fitz/filt_faxd.c
index 7361735d..57e206bf 100644
--- a/fitz/filt_faxd.c
+++ b/fitz/filt_faxd.c
@@ -261,11 +261,13 @@ findchangingcolor(const unsigned char *line, int x, int w, int color)
return x;
}
-static const unsigned char lm[8] =
-{ 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
+static const unsigned char lm[8] = {
+ 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01
+};
-static const unsigned char rm[8] =
-{ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
+static const unsigned char rm[8] = {
+ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
+};
static inline void
setbits(unsigned char *line, int x0, int x1)
@@ -300,12 +302,13 @@ typedef enum fax_stage_e
SNORMAL, /* neutral state, waiting for any code */
SMAKEUP, /* got a 1d makeup code, waiting for terminating code */
SEOL, /* at eol, needs output buffer space */
- SH1, SH2 /* in H part 1 and 2 (both makeup and terminating codes) */
+ SH1, SH2, /* in H part 1 and 2 (both makeup and terminating codes) */
+ SDONE /* all done */
} fax_stage_e;
struct fz_faxd_s
{
- fz_filter super;
+ fz_stream *chain;
int k;
int endofline;
@@ -326,95 +329,31 @@ struct fz_faxd_s
int a, c, dim, eolc;
unsigned char *ref;
unsigned char *dst;
+ int remain;
};
-fz_filter *
-fz_newfaxd(fz_obj *params)
-{
- fz_obj *obj;
-
- FZ_NEWFILTER(fz_faxd, fax, faxd);
-
- fax->ref = nil;
- fax->dst = nil;
-
- fax->k = 0;
- fax->endofline = 0;
- fax->encodedbytealign = 0;
- fax->columns = 1728;
- fax->rows = 0;
- fax->endofblock = 1;
- fax->blackis1 = 0;
-
- obj = fz_dictgets(params, "K");
- if (obj) fax->k = fz_toint(obj);
-
- obj = fz_dictgets(params, "EndOfLine");
- if (obj) fax->endofline = fz_tobool(obj);
-
- obj = fz_dictgets(params, "EncodedByteAlign");
- if (obj) fax->encodedbytealign = fz_tobool(obj);
-
- obj = fz_dictgets(params, "Columns");
- if (obj) fax->columns = fz_toint(obj);
-
- obj = fz_dictgets(params, "Rows");
- if (obj) fax->rows = fz_toint(obj);
-
- obj = fz_dictgets(params, "EndOfBlock");
- if (obj) fax->endofblock = fz_tobool(obj);
-
- obj = fz_dictgets(params, "BlackIs1");
- if (obj) fax->blackis1 = fz_tobool(obj);
-
- fax->stride = ((fax->columns - 1) >> 3) + 1;
- fax->ridx = 0;
- fax->bidx = 32;
- fax->word = 0;
-
- fax->stage = SNORMAL;
- fax->a = -1;
- fax->c = 0;
- fax->dim = fax->k < 0 ? 2 : 1;
- fax->eolc = 0;
-
- fax->ref = fz_malloc(fax->stride);
- fax->dst = fz_malloc(fax->stride);
-
- memset(fax->ref, 0, fax->stride);
- memset(fax->dst, 0, fax->stride);
-
- return (fz_filter*)fax;
-}
-
-void
-fz_dropfaxd(fz_filter *p)
-{
- fz_faxd *fax = (fz_faxd*) p;
- fz_free(fax->ref);
- fz_free(fax->dst);
-}
-
-static inline void eatbits(fz_faxd *fax, int nbits)
+static inline void
+eatbits(fz_faxd *fax, int nbits)
{
fax->word <<= nbits;
fax->bidx += nbits;
}
-static inline fz_error fillbits(fz_faxd *fax, fz_buffer *in)
+static inline int
+fillbits(fz_faxd *fax)
{
while (fax->bidx >= 8)
{
- if (in->rp + 1 > in->wp)
- return fz_ioneedin;
+ int c = fz_readbyte(fax->chain);
+ if (c == EOF)
+ return EOF;
fax->bidx -= 8;
- fax->word |= *in->rp << fax->bidx;
- in->rp ++;
+ fax->word |= c << fax->bidx;
}
- return fz_okay;
+ return 0;
}
-static int
+static inline int
getcode(fz_faxd *fax, const cfd_node *table, int initialbits)
{
unsigned int word = fax->word;
@@ -602,33 +541,30 @@ dec2d(fz_faxd *fax)
return 0;
}
-fz_error
-fz_processfaxd(fz_filter *f, fz_buffer *in, fz_buffer *out)
+static int
+readfaxd(fz_stream *stm, unsigned char *buf, int len)
{
- fz_faxd *fax = (fz_faxd*)f;
+ fz_faxd *fax = stm->state;
+ unsigned char *p = buf;
+ unsigned char *tmp;
fz_error error;
int i;
- unsigned char *tmp;
+
+ if (fax->stage == SDONE)
+ return 0;
if (fax->stage == SEOL)
goto eol;
loop:
- if (fillbits(fax, in))
+ if (fillbits(fax))
{
- if (in->eof)
+ if (fax->bidx > 31)
{
- if (fax->bidx > 31)
- {
- if (fax->a > 0)
- goto eol;
- goto rtc;
- }
- }
- else
- {
- return fz_ioneedin;
+ if (fax->a > 0)
+ goto eol;
+ goto rtc;
}
}
@@ -667,14 +603,15 @@ loop:
{
fax->eolc = 0;
error = dec1d(fax);
- if (error) return error; /* can be fz_io* or real error */
-
+ if (error)
+ return fz_rethrow(error, "cannot decode 1d code");
}
else if (fax->dim == 2)
{
fax->eolc = 0;
error = dec2d(fax);
- if (error) return error; /* can be fz_io* or real error */
+ if (error)
+ return fz_rethrow(error, "cannot decode 2d code");
}
/* no eol check after makeup codes nor in the middle of an H code */
@@ -694,24 +631,27 @@ loop:
eol:
fax->stage = SEOL;
- if (out->wp + fax->stride > out->ep)
- return fz_ioneedout;
if (fax->blackis1)
- memcpy(out->wp, fax->dst, fax->stride);
- else {
- unsigned char * restrict d = out->wp;
- unsigned char * restrict s = fax->dst;
- int w = fax->stride;
- for (i = 0; i < w; i++)
- *d++ = *s++ ^ 0xff;
+ {
+ while (p < buf + len && fax->remain-- > 0)
+ *p++ = fax->dst[fax->stride - fax->remain];
+ }
+ else
+ {
+ while (p < buf + len && fax->remain-- > 0)
+ *p++ = fax->dst[fax->stride - fax->remain] ^ 0xff;
}
+ if (fax->remain > 0)
+ return p - buf;
+
+ fax->remain = fax->stride;
+
tmp = fax->ref;
fax->ref = fax->dst;
fax->dst = tmp;
memset(fax->dst, 0, fax->stride);
- out->wp += fax->stride;
fax->stage = SNORMAL;
fax->c = 0;
@@ -745,9 +685,84 @@ eol:
goto loop;
rtc:
+ fax->stage = SDONE;
+
+ /* try to put back any extra bytes we read */
i = (32 - fax->bidx) / 8;
- while (i-- && in->rp > in->bp)
- in->rp --;
+ while (i--)
+ fz_unreadbyte(fax->chain);
+
+ return p - buf;
+}
+
+static void
+closefaxd(fz_stream *stm)
+{
+ fz_faxd *fax = stm->state;
+ fz_close(fax->chain);
+ fz_free(fax->ref);
+ fz_free(fax->dst);
+ fz_free(fax);
+}
+
+fz_stream *
+fz_openfaxd(fz_stream *chain, fz_obj *params)
+{
+ fz_faxd *fax;
+ fz_obj *obj;
+
+ fax = fz_malloc(sizeof(fz_faxd));
+ fax->chain = chain;
+
+ fax->ref = nil;
+ fax->dst = nil;
+
+ fax->k = 0;
+ fax->endofline = 0;
+ fax->encodedbytealign = 0;
+ fax->columns = 1728;
+ fax->rows = 0;
+ fax->endofblock = 1;
+ fax->blackis1 = 0;
+
+ obj = fz_dictgets(params, "K");
+ if (obj) fax->k = fz_toint(obj);
+
+ obj = fz_dictgets(params, "EndOfLine");
+ if (obj) fax->endofline = fz_tobool(obj);
+
+ obj = fz_dictgets(params, "EncodedByteAlign");
+ if (obj) fax->encodedbytealign = fz_tobool(obj);
+
+ obj = fz_dictgets(params, "Columns");
+ if (obj) fax->columns = fz_toint(obj);
+
+ obj = fz_dictgets(params, "Rows");
+ if (obj) fax->rows = fz_toint(obj);
+
+ obj = fz_dictgets(params, "EndOfBlock");
+ if (obj) fax->endofblock = fz_tobool(obj);
+
+ obj = fz_dictgets(params, "BlackIs1");
+ if (obj) fax->blackis1 = fz_tobool(obj);
+
+ fax->stride = ((fax->columns - 1) >> 3) + 1;
+ fax->ridx = 0;
+ fax->bidx = 32;
+ fax->word = 0;
+
+ fax->stage = SNORMAL;
+ fax->a = -1;
+ fax->c = 0;
+ fax->dim = fax->k < 0 ? 2 : 1;
+ fax->eolc = 0;
+
+ fax->ref = fz_malloc(fax->stride);
+ fax->dst = fz_malloc(fax->stride);
+ fax->remain = fax->stride;
+
+ memset(fax->ref, 0, fax->stride);
+ memset(fax->dst, 0, fax->stride);
- return fz_iodone;
+ return fz_newstream(fax, readfaxd, closefaxd);
}
diff --git a/fitz/filt_flate.c b/fitz/filt_flate.c
index 96a7a09a..bb3ac692 100644
--- a/fitz/filt_flate.c
+++ b/fitz/filt_flate.c
@@ -6,97 +6,88 @@ typedef struct fz_flate_s fz_flate;
struct fz_flate_s
{
- fz_filter super;
+ fz_stream *chain;
z_stream z;
};
-static void *
-zmalloc(void *opaque, unsigned int items, unsigned int size)
+static void * zmalloc(void *opaque, unsigned int items, unsigned int size)
{
return fz_malloc(items * size);
}
-static void
-zfree(void *opaque, void *ptr)
+static void zfree(void *opaque, void *ptr)
{
fz_free(ptr);
}
-fz_filter *
-fz_newflated(fz_obj *params)
+static int
+readflated(fz_stream *stm, unsigned char *outbuf, int outlen)
{
- int ei;
+ fz_flate *state = stm->state;
+ fz_stream *chain = state->chain;
+ z_streamp zp = &state->z;
+ int inlen, code;
+
+ if (chain->rp == chain->wp)
+ fz_fillbuffer(chain);
- FZ_NEWFILTER(fz_flate, f, flated);
+ inlen = chain->wp - chain->rp;
+ zp->next_in = chain->rp;
+ zp->avail_in = inlen;
+ zp->next_out = outbuf;
+ zp->avail_out = outlen;
- f->z.zalloc = zmalloc;
- f->z.zfree = zfree;
- f->z.opaque = nil;
- f->z.next_in = nil;
- f->z.avail_in = 0;
+ code = inflate(zp, Z_SYNC_FLUSH);
- ei = inflateInit(&f->z);
+ chain->rp = chain->wp - zp->avail_in;
- if (ei != Z_OK)
+ if (code == Z_STREAM_END || code == Z_OK)
{
- fz_warn("zlib error: inflateInit: %s", f->z.msg);
+ return outlen - zp->avail_out;
+ }
+ else if (code == Z_DATA_ERROR && inlen == 0)
+ {
+ fz_warn("ignoring zlib error: %s", zp->msg);
+ return outlen - zp->avail_out;
+ }
+ else
+ {
+ return fz_throw("zlib error: %s", zp->msg);
}
-
- return (fz_filter*)f;
}
-void
-fz_dropflated(fz_filter *f)
+static void
+closeflated(fz_stream *stm)
{
- z_streamp zp = &((fz_flate*)f)->z;
- int err;
+ fz_flate *state = stm->state;
+ int code;
+
+ code = inflateEnd(&state->z);
+ if (code != Z_OK)
+ fz_warn("zlib error: inflateEnd: %s", state->z.msg);
- err = inflateEnd(zp);
- if (err != Z_OK)
- fz_warn("inflateEnd: %s", zp->msg);
+ fz_close(state->chain);
+ fz_free(state);
}
-fz_error
-fz_processflated(fz_filter *f, fz_buffer *in, fz_buffer *out)
+fz_stream *
+fz_openflated(fz_stream *chain)
{
- z_streamp zp = &((fz_flate*)f)->z;
- int err;
-
- if (in->rp == in->wp && !in->eof)
- return fz_ioneedin;
- if (out->wp == out->ep)
- return fz_ioneedout;
+ fz_flate *state;
+ int code;
- zp->next_in = in->rp;
- zp->avail_in = in->wp - in->rp;
+ state = fz_malloc(sizeof(fz_flate));
+ state->chain = chain;
- zp->next_out = out->wp;
- zp->avail_out = out->ep - out->wp;
+ state->z.zalloc = zmalloc;
+ state->z.zfree = zfree;
+ state->z.opaque = nil;
+ state->z.next_in = nil;
+ state->z.avail_in = 0;
- err = inflate(zp, Z_SYNC_FLUSH);
+ code = inflateInit(&state->z);
+ if (code != Z_OK)
+ fz_warn("zlib error: inflateInit: %s", state->z.msg);
- in->rp = in->wp - zp->avail_in;
- out->wp = out->ep - zp->avail_out;
-
- if (err == Z_DATA_ERROR && in->eof && in->rp == in->wp)
- {
- fz_warn("ignoring zlib error: %s", zp->msg);
- return fz_iodone;
- }
- else if (err == Z_STREAM_END || err == Z_BUF_ERROR)
- {
- return fz_iodone;
- }
- else if (err == Z_OK)
- {
- if (in->rp == in->wp && !in->eof)
- return fz_ioneedin;
- if (out->wp == out->ep)
- return fz_ioneedout;
- return fz_ioneedin; /* hmm, what's going on here? */
- }
- else
- {
- return fz_throw("zlib error: inflate: %s", zp->msg);
- }
+ return fz_newstream(state, readflated, closeflated);
}
diff --git a/fitz/filt_jbig2d.c b/fitz/filt_jbig2d.c
index b079ba7f..37d976ea 100644
--- a/fitz/filt_jbig2d.c
+++ b/fitz/filt_jbig2d.c
@@ -1,17 +1,5 @@
#include "fitz.h"
-/* TODO: complete rewrite with error checking and use fitz memctx */
-
-/*
-<rillian> so to use a global_ctx, you run your global data through a normal ctx
-<rillian> then call jbig2_make_global_ctx with the normal context
-<rillian> that does the (currently null) conversion
-<maskros> make_global_ctx after i fed it all the global stream data?
-<rillian> maskros: yes
-<rillian> and you pass the new global ctx object to jbig2_ctx_new() when you
-+create the per-page ctx
-*/
-
#ifdef _WIN32 /* Microsoft Visual C++ */
typedef signed char int8_t;
@@ -33,90 +21,82 @@ typedef struct fz_jbig2d_s fz_jbig2d;
struct fz_jbig2d_s
{
- fz_filter super;
+ fz_stream *chain;
Jbig2Ctx *ctx;
Jbig2GlobalCtx *gctx;
Jbig2Image *page;
int idx;
};
-fz_filter *
-fz_newjbig2d(fz_obj *params)
+static void
+closejbig2d(fz_stream *stm)
{
- FZ_NEWFILTER(fz_jbig2d, d, jbig2d);
- d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, nil, nil, nil);
- d->gctx = nil;
- d->page = nil;
- d->idx = 0;
- return (fz_filter*)d;
+ fz_jbig2d *state = stm->state;
+ if (state->page)
+ jbig2_release_page(state->ctx, state->page);
+ if (state->gctx)
+ jbig2_global_ctx_free(state->gctx);
+ jbig2_ctx_free(state->ctx);
+ fz_close(state->chain);
+ fz_free(state);
}
-void
-fz_dropjbig2d(fz_filter *filter)
+static int
+readjbig2d(fz_stream *stm, unsigned char *buf, int len)
{
- fz_jbig2d *d = (fz_jbig2d*)filter;
- if (d->gctx)
- jbig2_global_ctx_free(d->gctx);
- jbig2_ctx_free(d->ctx);
-}
+ fz_jbig2d *state = stm->state;
+ unsigned char tmp[4096];
+ unsigned char *p = buf;
+ unsigned char *s;
+ int x, w, n;
-fz_error
-fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len)
-{
- fz_jbig2d *d = (fz_jbig2d*)filter;
- jbig2_data_in(d->ctx, buf, len);
- d->gctx = jbig2_make_global_ctx(d->ctx);
- d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, d->gctx, nil, nil);
- return fz_okay;
+ if (!state->page)
+ {
+ while (1)
+ {
+ n = fz_read(state->chain, tmp, sizeof tmp);
+ if (n < 0)
+ return fz_rethrow(n, "read error in jbig2 filter");
+ if (n == 0)
+ break;
+ jbig2_data_in(state->ctx, tmp, n);
+ }
+
+ jbig2_complete_page(state->ctx);
+
+ state->page = jbig2_page_out(state->ctx);
+ if (!state->page)
+ return fz_throw("jbig2_page_out failed");
+ }
+
+ s = state->page->data;
+ w = state->page->height * state->page->stride;
+ x = state->idx;
+ while (p < buf + len && x < w)
+ *p++ = s[x++] ^ 0xff;
+ state->idx = x;
+
+ return p - buf;
}
-fz_error
-fz_processjbig2d(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+fz_stream *
+fz_openjbig2d(fz_stream *chain, fz_buffer *globals)
{
- fz_jbig2d *d = (fz_jbig2d*)filter;
- int len;
- int i;
+ fz_jbig2d *state;
+
+ state = fz_malloc(sizeof(fz_jbig2d));
+ state->chain = chain;
+ state->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, nil, nil, nil);
+ state->gctx = nil;
+ state->page = nil;
+ state->idx = 0;
- while (1)
+ if (globals)
{
- if (in->rp == in->wp) {
- if (!in->eof)
- return fz_ioneedin;
-
- if (!d->page) {
- jbig2_complete_page(d->ctx);
- d->page = jbig2_page_out(d->ctx);
- if (!d->page)
- return fz_throw("jbig2_page_out failed");
- }
-
- if (out->wp == out->ep)
- return fz_ioneedout;
-
- len = out->ep - out->wp;
- if (d->idx + len > d->page->height * d->page->stride)
- len = d->page->height * d->page->stride - d->idx;
-
- /* XXX memcpy(out->wp, d->page->data + d->idx, len); */
- {
- unsigned char * restrict p = &d->page->data[d->idx];
- unsigned char * restrict o = out->wp;
- for (i = 0; i < len; i++)
- *o++ = 0xff ^ *p++;
- }
-
- out->wp += len;
- d->idx += len;
-
- if (d->idx == d->page->height * d->page->stride) {
- jbig2_release_page(d->ctx, d->page);
- return fz_iodone;
- }
- }
- else {
- len = in->wp - in->rp;
- jbig2_data_in(d->ctx, in->rp, len);
- in->rp += len;
- }
+ jbig2_data_in(state->ctx, globals->data, globals->len);
+ state->gctx = jbig2_make_global_ctx(state->ctx);
+ state->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, state->gctx, nil, nil);
}
+
+ return fz_newstream(state, readjbig2d, closejbig2d);
}
diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c
index 4580224a..01f15c1b 100644
--- a/fitz/filt_jpxd.c
+++ b/fitz/filt_jpxd.c
@@ -7,12 +7,8 @@ typedef struct fz_jpxd_s fz_jpxd;
struct fz_jpxd_s
{
- fz_filter super;
- opj_event_mgr_t evtmgr;
- opj_dparameters_t params;
- opj_dinfo_t *info;
+ fz_stream *chain;
opj_image_t *image;
- int stage;
int x, y, k;
};
@@ -31,136 +27,129 @@ static void fz_opj_info_callback(const char *msg, void *client_data)
/* fprintf(stdout, "openjpeg info: %s", msg); */
}
-fz_filter *
-fz_newjpxd(fz_obj *params)
-{
- FZ_NEWFILTER(fz_jpxd, d, jpxd);
-
- d->info = nil;
- d->image = nil;
- d->stage = 0;
-
- d->x = 0;
- d->y = 0;
- d->k = 0;
-
- return (fz_filter*)d;
-}
-
-void
-fz_dropjpxd(fz_filter *filter)
+static int
+readjpxd(fz_stream *stm, unsigned char *outbuf, int outlen)
{
- fz_jpxd *d = (fz_jpxd*)filter;
- if (d->image)
- opj_image_destroy(d->image);
- if (d->info)
- opj_destroy_decompress(d->info);
-}
-
-fz_error
-fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
-{
- fz_jpxd *d = (fz_jpxd*)filter;
+ fz_jpxd *state = stm->state;
+ unsigned char *p = outbuf;
+ opj_event_mgr_t evtmgr;
+ opj_dparameters_t params;
+ opj_dinfo_t *info;
+ opj_cio_t *cio;
int format;
int n, w, h, depth, sgnd;
int k, v;
- opj_cio_t *cio;
-
- switch (d->stage)
+ if (!state->image)
{
- case 0: goto input;
- case 1: goto decode;
- case 2: goto output;
- }
-
-input:
- /* Wait until we have the entire file in the input buffer */
- if (!in->eof)
- return fz_ioneedin;
+ fz_error error;
+ fz_buffer *buf;
- d->stage = 1;
+ error = fz_readall(&buf, state->chain);
+ if (error)
+ return fz_throw("read error in jpx filter");
-decode:
- memset(&d->evtmgr, 0, sizeof(d->evtmgr));
- d->evtmgr.error_handler = fz_opj_error_callback;
- d->evtmgr.warning_handler = fz_opj_warning_callback;
- d->evtmgr.info_handler = fz_opj_info_callback;
+ if (buf->len < 2)
+ {
+ fz_dropbuffer(buf);
+ return fz_throw("not enough data to determine image format");
+ }
- opj_set_default_decoder_parameters(&d->params);
+ /* Check for SOC marker -- if found we have a bare J2K stream */
+ if (buf->data[0] == 0xFF && buf->data[1] == 0x4F)
+ format = CODEC_J2K;
+ else
+ format = CODEC_JP2;
- if (in->wp - in->rp < 2)
- return fz_throw("not enough data to determine image format");
+ memset(&evtmgr, 0, sizeof(evtmgr));
+ evtmgr.error_handler = fz_opj_error_callback;
+ evtmgr.warning_handler = fz_opj_warning_callback;
+ evtmgr.info_handler = fz_opj_info_callback;
- /* Check for SOC marker -- if found we have a bare J2K stream */
- if (in->rp[0] == 0xFF && in->rp[1] == 0x4F)
- format = CODEC_J2K;
- else
- format = CODEC_JP2;
+ opj_set_default_decoder_parameters(&params);
- d->info = opj_create_decompress(format);
- if (!d->info)
- fz_warn("assert: opj_create_decompress failed");
+ info = opj_create_decompress(format);
+ opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr);
+ opj_setup_decoder(info, &params);
- opj_set_event_mgr((opj_common_ptr)d->info, &d->evtmgr, stderr);
- opj_setup_decoder(d->info, &d->params);
+ cio = opj_cio_open((opj_common_ptr)info, buf->data, buf->len);
- cio = opj_cio_open((opj_common_ptr)d->info, in->rp, in->wp - in->rp);
- in->rp = in->wp;
+ state->image = opj_decode(info, cio);
- d->image = opj_decode(d->info, cio);
- if (!d->image)
- {
opj_cio_close(cio);
- return fz_throw("opj_decode failed");
- }
+ opj_destroy_decompress(info);
+ fz_dropbuffer(buf);
- opj_cio_close(cio);
+ if (!state->image)
+ return fz_throw("opj_decode failed");
- for (k = 1; k < d->image->numcomps; k++)
- {
- if (d->image->comps[k].w != d->image->comps[0].w)
- return fz_throw("image components have different width");
- if (d->image->comps[k].h != d->image->comps[0].h)
- return fz_throw("image components have different height");
- if (d->image->comps[k].prec != d->image->comps[0].prec)
- return fz_throw("image components have different precision");
+ for (k = 1; k < state->image->numcomps; k++)
+ {
+ if (state->image->comps[k].w != state->image->comps[0].w)
+ return fz_throw("image components have different width");
+ if (state->image->comps[k].h != state->image->comps[0].h)
+ return fz_throw("image components have different height");
+ if (state->image->comps[k].prec != state->image->comps[0].prec)
+ return fz_throw("image components have different precision");
+ }
}
- d->stage = 2;
+ n = state->image->numcomps;
+ w = state->image->comps[0].w;
+ h = state->image->comps[0].h;
+ depth = state->image->comps[0].prec;
+ sgnd = state->image->comps[0].sgnd;
-output:
- n = d->image->numcomps;
- w = d->image->comps[0].w;
- h = d->image->comps[0].h;
- depth = d->image->comps[0].prec;
- sgnd = d->image->comps[0].sgnd;
-
- while (d->y < h)
+ while (state->y < h)
{
- while (d->x < w)
+ while (state->x < w)
{
- while (d->k < n)
+ while (state->k < n)
{
- if (out->wp == out->ep)
- return fz_ioneedout;
+ if (p == outbuf + outlen)
+ return p - outbuf;
- v = d->image->comps[d->k].data[d->y * w + d->x];
+ v = state->image->comps[state->k].data[state->y * w + state->x];
if (sgnd)
v = v + (1 << (depth - 1));
if (depth > 8)
v = v >> (depth - 8);
- *out->wp++ = v;
+ *p++ = v;
- d->k ++;
+ state->k ++;
}
- d->x ++;
- d->k = 0;
+ state->x ++;
+ state->k = 0;
}
- d->y ++;
- d->x = 0;
+ state->y ++;
+ state->x = 0;
}
- return fz_iodone;
+ return p - outbuf;
+}
+
+static void
+closejpxd(fz_stream *stm)
+{
+ fz_jpxd *state = stm->state;
+ if (state->image)
+ opj_image_destroy(state->image);
+ fz_close(state->chain);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openjpxd(fz_stream *chain)
+{
+ fz_jpxd *state;
+
+ state = fz_malloc(sizeof(fz_jpxd));
+ state->chain = chain;
+ state->image = nil;
+ state->x = 0;
+ state->y = 0;
+ state->k = 0;
+
+ return fz_newstream(state, readjpxd, closejpxd);
}
diff --git a/fitz/filt_lzwd.c b/fitz/filt_lzwd.c
index b441c245..5e3c836e 100644
--- a/fitz/filt_lzwd.c
+++ b/fitz/filt_lzwd.c
@@ -9,7 +9,8 @@ enum
NUMCODES = (1 << MAXBITS),
LZW_CLEAR = 256,
LZW_EOD = 257,
- LZW_FIRST = 258
+ LZW_FIRST = 258,
+ MAXLENGTH = 4097
};
typedef struct lzw_code_s lzw_code;
@@ -26,69 +27,24 @@ typedef struct fz_lzwd_s fz_lzwd;
struct fz_lzwd_s
{
- fz_filter super;
+ fz_stream *chain;
+ int eod;
int earlychange;
unsigned int word; /* bits loaded from data */
int bidx;
- int resume; /* resume output of code from needout */
int codebits; /* num bits/code */
int code; /* current code */
int oldcode; /* previously recognized code */
int nextcode; /* next free entry */
lzw_code table[NUMCODES];
-};
-
-fz_filter *
-fz_newlzwd(fz_obj *params)
-{
- int i;
-
- FZ_NEWFILTER(fz_lzwd, lzw, lzwd);
-
- lzw->earlychange = 1;
-
- if (params)
- {
- fz_obj *obj;
- obj = fz_dictgets(params, "EarlyChange");
- if (obj) lzw->earlychange = fz_toint(obj) != 0;
- }
- lzw->bidx = 32;
- lzw->word = 0;
-
- for (i = 0; i < 256; i++)
- {
- lzw->table[i].value = i;
- lzw->table[i].firstchar = i;
- lzw->table[i].length = 1;
- lzw->table[i].prev = -1;
- }
-
- for (i = 256; i < NUMCODES; i++)
- {
- lzw->table[i].value = 0;
- lzw->table[i].firstchar = 0;
- lzw->table[i].length = 0;
- lzw->table[i].prev = -1;
- }
-
- lzw->codebits = MINBITS;
- lzw->code = -1;
- lzw->nextcode = LZW_FIRST;
- lzw->oldcode = -1;
- lzw->resume = 0;
-
- return (fz_filter *)lzw;
-}
-
-void
-fz_droplzwd(fz_filter *filter)
-{
-}
+ unsigned char output[MAXLENGTH];
+ int outlen;
+ int remain;
+};
static inline void eatbits(fz_lzwd *lzw, int nbits)
{
@@ -96,54 +52,48 @@ static inline void eatbits(fz_lzwd *lzw, int nbits)
lzw->bidx += nbits;
}
-static inline fz_error fillbits(fz_lzwd *lzw, fz_buffer *in)
+static inline int fillbits(fz_lzwd *lzw)
{
while (lzw->bidx >= 8)
{
- if (in->rp + 1 > in->wp)
- return fz_ioneedin;
+ int c = fz_readbyte(lzw->chain);
+ if (c == EOF)
+ return EOF;
lzw->bidx -= 8;
- lzw->word |= *in->rp << lzw->bidx;
- in->rp ++;
+ lzw->word |= c << lzw->bidx;
}
- return fz_okay;
+ return 0;
}
-static inline void unstuff(fz_lzwd *lzw, fz_buffer *in)
+static inline void unstuff(fz_lzwd *lzw)
{
int i = (32 - lzw->bidx) / 8;
- while (i-- && in->rp > in->bp)
- in->rp --;
+ while (i--)
+ fz_unreadbyte(lzw->chain);
}
-fz_error
-fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+static int
+readlzwd(fz_stream *stm, unsigned char *buf, int len)
{
- fz_lzwd *lzw = (fz_lzwd*)filter;
+ fz_lzwd *lzw = stm->state;
+ unsigned char *p = buf;
unsigned char *s;
- int len;
- if (lzw->resume)
- {
- lzw->resume = 0;
- goto output;
- }
+ while (lzw->remain > 0 && p < buf + len)
+ *p++ = lzw->output[lzw->outlen - lzw->remain];
- while (1)
+ while (p < buf + len)
{
- if (fillbits(lzw, in))
+ if (lzw->eod)
+ return 0;
+
+ if (fillbits(lzw))
{
- if (in->eof)
+ if (lzw->bidx > 32 - lzw->codebits)
{
- if (lzw->bidx > 32 - lzw->codebits)
- {
- unstuff(lzw, in);
- return fz_iodone;
- }
- }
- else
- {
- return fz_ioneedin;
+ unstuff(lzw);
+ lzw->eod = 1;
+ return p - buf;
}
}
@@ -153,8 +103,9 @@ fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
if (lzw->code == LZW_EOD)
{
- unstuff(lzw, in);
- return fz_iodone;
+ unstuff(lzw);
+ lzw->eod = 1;
+ return p - buf;
}
if (lzw->code == LZW_CLEAR)
@@ -195,36 +146,86 @@ fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
lzw->oldcode = lzw->code;
output:
+
/* code maps to a string, copy to output (in reverse...) */
if (lzw->code > 255)
{
- if (out->wp + lzw->table[lzw->code].length > out->ep)
- {
- lzw->resume = 1;
- return fz_ioneedout;
- }
-
- len = lzw->table[lzw->code].length;
- s = out->wp + len;
+ assert(lzw->table[lzw->code].length < MAXLENGTH);
- do
- {
+ lzw->outlen = lzw->table[lzw->code].length;
+ lzw->remain = lzw->outlen;
+ s = lzw->output + lzw->remain;
+ do {
*(--s) = lzw->table[lzw->code].value;
lzw->code = lzw->table[lzw->code].prev;
- } while (lzw->code >= 0 && s > out->wp);
- out->wp += len;
+ } while (lzw->code >= 0 && s > lzw->output);
}
/* ... or just a single character */
else
{
- if (out->wp + 1 > out->ep)
- {
- lzw->resume = 1;
- return fz_ioneedout;
- }
-
- *out->wp++ = lzw->code;
+ lzw->output[0] = lzw->code;
+ lzw->outlen = 1;
+ lzw->remain = 1;
}
+
+ /* copy to output */
+ while (lzw->remain > 0 && p < buf + len)
+ *p++ = lzw->output[lzw->outlen - lzw->remain];
+ }
+
+ return p - buf;
+}
+
+static void
+closelzwd(fz_stream *stm)
+{
+ fz_lzwd *lzw = stm->state;
+ fz_close(lzw->chain);
+ fz_free(lzw);
+}
+
+fz_stream *
+fz_openlzwd(fz_stream *chain, fz_obj *params)
+{
+ fz_lzwd *lzw;
+ fz_obj *obj;
+ int i;
+
+ lzw = fz_malloc(sizeof(fz_lzwd));
+ lzw->chain = chain;
+ lzw->eod = 0;
+ lzw->earlychange = 1;
+
+ obj = fz_dictgets(params, "EarlyChange");
+ if (obj)
+ lzw->earlychange = !!fz_toint(obj);
+
+ lzw->bidx = 32;
+ lzw->word = 0;
+
+ for (i = 0; i < 256; i++)
+ {
+ lzw->table[i].value = i;
+ lzw->table[i].firstchar = i;
+ lzw->table[i].length = 1;
+ lzw->table[i].prev = -1;
+ }
+
+ for (i = 256; i < NUMCODES; i++)
+ {
+ lzw->table[i].value = 0;
+ lzw->table[i].firstchar = 0;
+ lzw->table[i].length = 0;
+ lzw->table[i].prev = -1;
}
+
+ lzw->codebits = MINBITS;
+ lzw->code = -1;
+ lzw->nextcode = LZW_FIRST;
+ lzw->oldcode = -1;
+ lzw->remain = 0;
+ lzw->outlen = 0;
+
+ return fz_newstream(lzw, readlzwd, closelzwd);
}
diff --git a/fitz/filt_pipeline.c b/fitz/filt_pipeline.c
deleted file mode 100644
index cb496546..00000000
--- a/fitz/filt_pipeline.c
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "fitz.h"
-
-typedef struct fz_pipeline_s fz_pipeline;
-
-fz_error fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out);
-
-struct fz_pipeline_s
-{
- fz_filter super;
- fz_filter *head;
- fz_buffer *buffer;
- fz_filter *tail;
- int tailneedsin;
-};
-
-fz_filter *
-fz_chainpipeline(fz_filter *head, fz_filter *tail, fz_buffer *buf)
-{
- FZ_NEWFILTER(fz_pipeline, p, pipeline);
- p->head = fz_keepfilter(head);
- p->tail = fz_keepfilter(tail);
- p->tailneedsin = 1;
- p->buffer = fz_keepbuffer(buf);
- return (fz_filter*)p;
-}
-
-void
-fz_unchainpipeline(fz_filter *filter, fz_filter **oldfp, fz_buffer **oldbp)
-{
- fz_pipeline *p = (fz_pipeline*)filter;
-
- *oldfp = fz_keepfilter(p->head);
- *oldbp = fz_keepbuffer(p->buffer);
-
- fz_dropfilter(filter);
-}
-
-fz_filter *
-fz_newpipeline(fz_filter *head, fz_filter *tail)
-{
- FZ_NEWFILTER(fz_pipeline, p, pipeline);
-
- p->buffer = fz_newbuffer(FZ_BUFSIZE);
- p->head = fz_keepfilter(head);
- p->tail = fz_keepfilter(tail);
- p->tailneedsin = 1;
-
- return (fz_filter*)p;
-}
-
-void
-fz_droppipeline(fz_filter *filter)
-{
- fz_pipeline *p = (fz_pipeline*)filter;
- fz_dropfilter(p->head);
- fz_dropfilter(p->tail);
- fz_dropbuffer(p->buffer);
-}
-
-fz_error
-fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out)
-{
- fz_pipeline *p = (fz_pipeline*)filter;
- fz_error e;
-
- if (p->buffer->eof)
- goto tail;
-
- if (p->tailneedsin && p->head->produced)
- goto tail;
-
-head:
- e = fz_process(p->head, in, p->buffer);
-
- if (e == fz_ioneedin)
- return fz_ioneedin;
-
- else if (e == fz_ioneedout)
- {
- if (p->tailneedsin && !p->head->produced)
- {
- if (p->buffer->rp > p->buffer->bp)
- fz_rewindbuffer(p->buffer);
- else
- fz_growbuffer(p->buffer);
- goto head;
- }
- goto tail;
- }
-
- else if (e == fz_iodone)
- goto tail;
-
- else if (e)
- return fz_rethrow(e, "cannot process head filter");
-
- else
- return fz_okay;
-
-tail:
- e = fz_process(p->tail, p->buffer, out);
-
- if (e == fz_ioneedin)
- {
- if (p->buffer->eof)
- return fz_throw("ioerror: premature eof in pipeline");
- p->tailneedsin = 1;
- goto head;
- }
-
- else if (e == fz_ioneedout)
- {
- p->tailneedsin = 0;
- return fz_ioneedout;
- }
-
- else if (e == fz_iodone)
- {
- /* The head may still contain end-of-data markers or garbage */
- e = fz_process(p->head, in, p->buffer);
- if (e != fz_iodone)
- fz_catch(e, "head filter not done");
- return fz_iodone;
- }
-
- else if (e)
- return fz_rethrow(e, "cannot process tail filter");
-
- else
- return fz_okay;
-}
diff --git a/fitz/filt_predict.c b/fitz/filt_predict.c
index 78bd19b2..b0ef8d3c 100644
--- a/fitz/filt_predict.c
+++ b/fitz/filt_predict.c
@@ -8,7 +8,7 @@ typedef struct fz_predict_s fz_predict;
struct fz_predict_s
{
- fz_filter super;
+ fz_stream *chain;
int predictor;
int columns;
@@ -17,71 +17,12 @@ struct fz_predict_s
int stride;
int bpp;
- unsigned char *refbuf;
+ unsigned char *in;
+ unsigned char *out;
unsigned char *ref;
+ int outlen, outidx;
};
-fz_filter *
-fz_newpredictd(fz_obj *params)
-{
- fz_obj *obj;
-
- FZ_NEWFILTER(fz_predict, p, predict);
-
- p->predictor = 1;
- p->columns = 1;
- p->colors = 1;
- p->bpc = 8;
-
- obj = fz_dictgets(params, "Predictor");
- if (obj)
- p->predictor = fz_toint(obj);
-
- if (p->predictor != 1 && p->predictor != 2 &&
- p->predictor != 10 && p->predictor != 11 &&
- p->predictor != 12 && p->predictor != 13 &&
- p->predictor != 14 && p->predictor != 15)
- {
- fz_warn("invalid predictor: %d", p->predictor);
- p->predictor = 1;
- }
-
- obj = fz_dictgets(params, "Columns");
- if (obj)
- p->columns = fz_toint(obj);
-
- obj = fz_dictgets(params, "Colors");
- if (obj)
- p->colors = fz_toint(obj);
-
- obj = fz_dictgets(params, "BitsPerComponent");
- if (obj)
- p->bpc = fz_toint(obj);
-
- p->stride = (p->bpc * p->colors * p->columns + 7) / 8;
- p->bpp = (p->bpc * p->colors + 7) / 8;
-
- if (p->predictor >= 10)
- {
- p->refbuf = fz_malloc(p->stride);
- memset(p->refbuf, 0, p->stride);
- }
- else
- {
- p->refbuf = nil;
- }
- p->ref = nil;
-
- return (fz_filter*)p;
-}
-
-void
-fz_droppredict(fz_filter *filter)
-{
- fz_predict *p = (fz_predict*)filter;
- fz_free(p->refbuf);
-}
-
static inline int
getcomponent(unsigned char *buf, int x, int bpc)
{
@@ -118,40 +59,34 @@ paeth(int a, int b, int c)
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
}
-static inline void
-fz_predictnone(fz_predict *p, unsigned char *in, int len, unsigned char *out)
-{
- memcpy(out, in, len);
-}
-
static void
-fz_predicttiff(fz_predict *p, unsigned char *in, int len, unsigned char *out)
+fz_predicttiff(fz_predict *state, unsigned char *out, unsigned char *in, int len)
{
int left[MAXC];
int i, k;
- for (k = 0; k < p->colors; k++)
+ for (k = 0; k < state->colors; k++)
left[k] = 0;
- for (i = 0; i < p->columns; i++)
+ for (i = 0; i < state->columns; i++)
{
- for (k = 0; k < p->colors; k++)
+ for (k = 0; k < state->colors; k++)
{
- int a = getcomponent(in, i * p->colors + k, p->bpc);
+ int a = getcomponent(in, i * state->colors + k, state->bpc);
int b = a + left[k];
- int c = b % (1 << p->bpc);
- putcomponent(out, i * p->colors + k, p->bpc, c);
+ int c = b % (1 << state->bpc);
+ putcomponent(out, i * state->colors + k, state->bpc, c);
left[k] = c;
}
}
}
static void
-fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int predictor)
+fz_predictpng(fz_predict *state, unsigned char *out, unsigned char *in, int len, int predictor)
{
- int bpp = p->bpp;
+ int bpp = state->bpp;
int i;
- unsigned char *ref = p->ref;
+ unsigned char *ref = state->ref;
switch (predictor)
{
@@ -186,7 +121,7 @@ fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int
}
for (i = len - bpp; i > 0; i--)
{
- *out = *in++ + (out[-bpp] + *ref++)/2;
+ *out = *in++ + (out[-bpp] + *ref++) / 2;
out++;
}
break;
@@ -205,62 +140,105 @@ fz_predictpng(fz_predict *p, unsigned char *in, int len, unsigned char *out, int
}
}
-fz_error
-fz_processpredict(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+static int
+readpredict(fz_stream *stm, unsigned char *buf, int len)
{
- fz_predict *dec = (fz_predict*)filter;
- int remaining, toconsume, toproduce;
- int ispng = dec->predictor >= 10;
+ fz_predict *state = stm->state;
+ unsigned char *p = buf;
+ int ispng = state->predictor >= 10;
+ int n;
- dec->ref = dec->refbuf;
- while (1)
- {
- remaining = in->wp - in->rp;
- toconsume = MIN(remaining, dec->stride + ispng);
- toproduce = MIN(remaining - ispng, dec->stride);
+ while (state->outidx < state->outlen && p < buf + len)
+ *p++ = state->out[state->outidx++];
- if (remaining < dec->stride + ispng && !in->eof)
+ while (p < buf + len)
+ {
+ n = fz_read(state->chain, state->in, state->stride + ispng);
+ if (n < 0)
+ return fz_rethrow(n, "read error in prediction filter");
+ if (n == 0)
+ return p - buf;
+
+ if (state->predictor == 1)
+ memcpy(state->out, state->in, n);
+ else if (state->predictor == 2)
+ fz_predicttiff(state, state->out, state->in, n);
+ else
{
- return fz_ioneedin;
+ fz_predictpng(state, state->out, state->in + 1, n - 1, state->in[0]);
+ memcpy(state->ref, state->out, state->stride);
}
- if (out->wp + toproduce > out->ep)
- {
- return fz_ioneedout;
- }
+ state->outlen = n - ispng;
+ state->outidx = 0;
- if (toconsume > 0)
- {
- if (dec->predictor == 1)
- {
- fz_predictnone(dec, in->rp, toconsume, out->wp);
- }
- else if (dec->predictor == 2)
- {
- if (dec->bpc != 8)
- memset(out->wp, 0, toconsume);
- fz_predicttiff(dec, in->rp, toconsume, out->wp);
- }
- else
- {
- int predictor = *in->rp++;
- toconsume -= ispng;
- fz_predictpng(dec, in->rp, toconsume, out->wp, predictor);
- }
-
- if (dec->refbuf)
- {
- memcpy(dec->refbuf, out->wp, toproduce);
- dec->ref = dec->refbuf;
- }
-
- in->rp += toconsume;
- out->wp += toproduce;
- }
+ while (state->outidx < state->outlen && p < buf + len)
+ *p++ = state->out[state->outidx++];
+ }
- if (in->eof && (in->wp - in->rp <= 0))
- {
- return fz_iodone;
- }
+ return p - buf;
+}
+
+static void
+closepredict(fz_stream *stm)
+{
+ fz_predict *state = stm->state;
+ fz_close(state->chain);
+ fz_free(state->in);
+ fz_free(state->out);
+ fz_free(state->ref);
+ fz_free(state);
+}
+
+fz_stream *
+fz_openpredict(fz_stream *chain, fz_obj *params)
+{
+ fz_predict *state;
+ fz_obj *obj;
+
+ state = fz_malloc(sizeof(fz_predict));
+ state->chain = chain;
+
+ state->predictor = 1;
+ state->columns = 1;
+ state->colors = 1;
+ state->bpc = 8;
+
+ obj = fz_dictgets(params, "Predictor");
+ if (obj)
+ state->predictor = fz_toint(obj);
+
+ if (state->predictor != 1 && state->predictor != 2 &&
+ state->predictor != 10 && state->predictor != 11 &&
+ state->predictor != 12 && state->predictor != 13 &&
+ state->predictor != 14 && state->predictor != 15)
+ {
+ fz_warn("invalid predictor: %d", state->predictor);
+ state->predictor = 1;
}
+
+ obj = fz_dictgets(params, "Columns");
+ if (obj)
+ state->columns = fz_toint(obj);
+
+ obj = fz_dictgets(params, "Colors");
+ if (obj)
+ state->colors = fz_toint(obj);
+
+ obj = fz_dictgets(params, "BitsPerComponent");
+ if (obj)
+ state->bpc = fz_toint(obj);
+
+ state->stride = (state->bpc * state->colors * state->columns + 7) / 8;
+ state->bpp = (state->bpc * state->colors + 7) / 8;
+
+ state->in = fz_malloc(state->stride + 1);
+ state->out = fz_malloc(state->stride);
+ state->ref = fz_malloc(state->stride);
+ state->outlen = 0;
+ state->outidx = 0;
+
+ memset(state->ref, 0, state->stride);
+
+ return fz_newstream(state, readpredict, closepredict);
}
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 89a1cc63..696a9017 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -440,17 +440,7 @@ void fz_debugobj(fz_obj *obj);
char *fz_objkindstr(fz_obj *obj);
/*
- * Data buffers for streams and filters.
- *
- * bp is the pointer to the allocated memory
- * rp is read-position (*in->rp++ to read data)
- * wp is write-position (*out->wp++ to write data)
- * ep is the sentinel
- *
- * Only the data between rp and wp is valid data.
- *
- * Writers set eof to true at the end.
- * Readers look at eof.
+ * Data buffers.
*
* A buffer owns the memory it has allocated, unless ownsdata is false,
* in which case the creator of the buffer owns it.
@@ -463,112 +453,22 @@ typedef struct fz_buffer_s fz_buffer;
struct fz_buffer_s
{
int refs;
- int ownsdata;
- unsigned char *bp;
- unsigned char *rp;
- unsigned char *wp;
- unsigned char *ep;
- int eof;
+ unsigned char *data;
+ int cap, len;
};
fz_buffer * fz_newbuffer(int size);
fz_buffer * fz_newbufferwithmemory(unsigned char *data, int size);
void fz_resizebuffer(fz_buffer *buf, int size);
-void fz_rewindbuffer(fz_buffer *buf);
void fz_growbuffer(fz_buffer *buf);
fz_buffer *fz_keepbuffer(fz_buffer *buf);
void fz_dropbuffer(fz_buffer *buf);
/*
- * Data filters for encryption, compression and decompression.
- *
- * A filter has one method, process, that takes an input and an output buffer.
- *
- * It returns one of three statuses:
- * ioneedin -- input buffer exhausted, please give me more data (wp-rp)
- * ioneedout -- output buffer exhausted, please provide more space (ep-wp)
- * iodone -- finished, please never call me again. ever!
- * or...
- * any other error code -- oops, something blew up.
- *
- * To make using the filter easier, three variables are updated:
- * produced -- if we actually produced any new data
- * consumed -- like above
- * count -- number of bytes produced in total since the beginning
- * done -- remember if we've ever returned fz_iodone
- *
- * Most filters take fz_obj as a way to specify parameters.
- * In most cases, this is a dictionary that contains the same keys
- * that the corresponding PDF filter would expect.
- *
- * The pipeline filter is special, and needs some care when chaining
- * and unchaining new filters.
- */
-
-typedef struct fz_filter_s fz_filter;
-
-#define fz_ioneedin ((fz_error)1)
-#define fz_ioneedout ((fz_error)2)
-#define fz_iodone ((fz_error)3)
-
-/*
- * Evil looking macro to create an initialize a filter struct.
- */
-
-#define FZ_NEWFILTER(TYPE,VAR,NAME) \
- fz_error fz_process ## NAME (fz_filter*,fz_buffer*,fz_buffer*); \
- void fz_drop ## NAME (fz_filter*); \
- TYPE *VAR; \
- VAR = fz_malloc(sizeof(TYPE)); \
- ((fz_filter*)VAR)->refs = 1; \
- ((fz_filter*)VAR)->process = fz_process ## NAME ; \
- ((fz_filter*)VAR)->drop = fz_drop ## NAME ; \
- ((fz_filter*)VAR)->consumed = 0; \
- ((fz_filter*)VAR)->produced = 0; \
- ((fz_filter*)VAR)->count = 0; \
- ((fz_filter*)VAR)->done = 0;
-
-struct fz_filter_s
-{
- int refs;
- fz_error (*process)(fz_filter *filter, fz_buffer *in, fz_buffer *out);
- void (*drop)(fz_filter *filter);
- int consumed;
- int produced;
- int count;
- int done;
-};
-
-fz_error fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out);
-fz_filter *fz_keepfilter(fz_filter *f);
-void fz_dropfilter(fz_filter *f);
-
-fz_filter * fz_newpipeline(fz_filter *head, fz_filter *tail);
-fz_filter * fz_chainpipeline(fz_filter *head, fz_filter *tail, fz_buffer *buf);
-void fz_unchainpipeline(fz_filter *pipe, fz_filter **oldfp, fz_buffer **oldbp);
-
-fz_filter * fz_newnullfilter(int len);
-fz_filter * fz_newcopyfilter();
-fz_filter * fz_newarc4filter(unsigned char *key, unsigned keylen);
-fz_filter * fz_newaesdfilter(unsigned char *key, unsigned keylen);
-fz_filter * fz_newa85d(fz_obj *param);
-fz_filter * fz_newahxd(fz_obj *param);
-fz_filter * fz_newrld(fz_obj *param);
-fz_filter * fz_newdctd(fz_obj *param);
-fz_filter * fz_newfaxd(fz_obj *param);
-fz_filter * fz_newflated(fz_obj *param);
-fz_filter * fz_newlzwd(fz_obj *param);
-fz_filter * fz_newpredictd(fz_obj *param);
-fz_filter * fz_newjbig2d(fz_obj *param);
-fz_filter * fz_newjpxd(fz_obj *param);
-
-fz_error fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len);
-
-/*
- * Stream API for Fitz.
- * Read and write data to and from files, memory buffers and filters.
+ * Buffered reader.
+ * Only the data between rp and wp is valid data.
*/
typedef struct fz_stream_s fz_stream;
@@ -578,77 +478,77 @@ enum { FZ_SFILE, FZ_SBUFFER, FZ_SFILTER };
struct fz_stream_s
{
int refs;
- int kind;
int dead;
- fz_buffer *buffer;
- fz_filter *filter;
- fz_stream *chain;
- fz_error error; /* delayed error from readbyte and peekbyte */
- int file;
+ int pos;
+ unsigned char *bp, *rp, *wp, *ep;
+ void *state;
+ int (*read)(fz_stream *stm, unsigned char *buf, int len);
+ void (*close)(fz_stream *stm);
+ void (*seek)(fz_stream *stm, int offset, int whence);
+ unsigned char buf[4096];
};
-/*
- * Various stream creation functions.
- */
-
-fz_stream * fz_openfile(int file);
-fz_stream * fz_openmemory(unsigned char *mem, int len);
-fz_stream * fz_openbuffer(fz_buffer *buf);
-fz_stream * fz_openfilter(fz_filter *flt, fz_stream *chain);
-
-/*
- * Functions that are common to both input and output streams.
- */
+fz_stream *fz_openfile(int file);
+fz_stream *fz_openbuffer(fz_buffer *buf);
+void fz_close(fz_stream *stm);
+fz_stream *fz_newstream(void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_stream *));
fz_stream *fz_keepstream(fz_stream *stm);
-void fz_dropstream(fz_stream *stm);
+void fz_fillbuffer(fz_stream *stm);
int fz_tell(fz_stream *stm);
-fz_error fz_seek(fz_stream *stm, int offset, int whence);
-
-/*
- * Input stream functions.
- */
+void fz_seek(fz_stream *stm, int offset, int whence);
-fz_error fz_readimp(fz_stream *stm);
-fz_error fz_read(int *np, fz_stream *stm, unsigned char *buf, int len);
-fz_error fz_readline(fz_stream *stm, char *buf, int max);
-fz_buffer * fz_readall(fz_stream *stm, int sizehint);
-
-/*
- * Error handling when reading with readbyte/peekbyte is non-standard.
- * The cause of an error is stuck into the stream struct,
- * and EOF is returned. Not good, but any other way is too painful.
- * So we have to be careful to check the error status eventually.
- */
-
-fz_error fz_readerror(fz_stream *stm);
-int fz_readbytex(fz_stream *stm);
-int fz_peekbytex(fz_stream *stm);
+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);
static inline int fz_readbyte(fz_stream *stm)
{
- fz_buffer *buf = stm->buffer;
- if (buf->rp < buf->wp)
- return *buf->rp++;
- return fz_readbytex(stm);
+ if (stm->rp == stm->wp)
+ {
+ fz_fillbuffer(stm);
+ return stm->rp < stm->wp ? *stm->rp++ : EOF;
+ }
+ return *stm->rp++;
}
static inline int fz_peekbyte(fz_stream *stm)
{
- fz_buffer *buf = stm->buffer;
- if (buf->rp < buf->wp)
- return *buf->rp;
- return fz_peekbytex(stm);
+ if (stm->rp == stm->wp)
+ {
+ fz_fillbuffer(stm);
+ return stm->rp < stm->wp ? *stm->rp : EOF;
+ }
+ return *stm->rp;
}
static inline void fz_unreadbyte(fz_stream *stm)
{
- fz_buffer *buf = stm->buffer;
- buf->rp--;
+ if (stm->rp > stm->bp)
+ stm->rp--;
}
/*
+ * Data filters.
+ */
+
+fz_stream * fz_opencopy(fz_stream *chain);
+fz_stream * fz_opennull(fz_stream *chain, int len);
+fz_stream * fz_openarc4(fz_stream *chain, unsigned char *key, unsigned keylen);
+fz_stream * fz_openaesd(fz_stream *chain, unsigned char *key, unsigned keylen);
+fz_stream * fz_opena85d(fz_stream *chain);
+fz_stream * fz_openahxd(fz_stream *chain);
+fz_stream * fz_openrld(fz_stream *chain);
+fz_stream * fz_opendctd(fz_stream *chain, fz_obj *param);
+fz_stream * fz_openfaxd(fz_stream *chain, fz_obj *param);
+fz_stream * fz_openflated(fz_stream *chain);
+fz_stream * fz_openlzwd(fz_stream *chain, fz_obj *param);
+fz_stream * fz_openpredict(fz_stream *chain, fz_obj *param);
+fz_stream * fz_openjbig2d(fz_stream *chain, fz_buffer *global);
+fz_stream * fz_openjpxd(fz_stream *chain);
+
+/*
* Resources and other graphics related objects.
*/
diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c
index f7da8289..00530071 100644
--- a/fitz/stm_buffer.c
+++ b/fitz/stm_buffer.c
@@ -9,29 +9,9 @@ fz_newbuffer(int size)
b = fz_malloc(sizeof(fz_buffer));
b->refs = 1;
- b->ownsdata = 1;
- b->bp = fz_malloc(size);
- b->rp = b->bp;
- b->wp = b->bp;
- b->ep = b->bp + size;
- b->eof = 0;
-
- return b;
-}
-
-fz_buffer *
-fz_newbufferwithmemory(unsigned char *data, int size)
-{
- fz_buffer *b;
-
- b = fz_malloc(sizeof(fz_buffer));
- b->refs = 1;
- b->ownsdata = 0;
- b->bp = data;
- b->rp = b->bp;
- b->wp = b->bp + size;
- b->ep = b->bp + size;
- b->eof = 0;
+ b->data = fz_malloc(size);
+ b->cap = size;
+ b->len = 0;
return b;
}
@@ -48,8 +28,7 @@ fz_dropbuffer(fz_buffer *buf)
{
if (--buf->refs == 0)
{
- if (buf->ownsdata)
- fz_free(buf->bp);
+ fz_free(buf->data);
fz_free(buf);
}
}
@@ -57,50 +36,14 @@ fz_dropbuffer(fz_buffer *buf)
void
fz_resizebuffer(fz_buffer *buf, int size)
{
- int rp = MIN(buf->rp - buf->bp, size);
- int wp = MIN(buf->wp - buf->bp, size);
-
- if (!buf->ownsdata)
- {
- fz_warn("assert: resize borrowed memory");
- return;
- }
-
- buf->bp = fz_realloc(buf->bp, size);
- buf->rp = buf->bp + rp;
- buf->wp = buf->bp + wp;
- buf->ep = buf->bp + size;
+ buf->data = fz_realloc(buf->data, size);
+ buf->cap = size;
+ if (buf->len > buf->cap)
+ buf->len = buf->cap;
}
void
fz_growbuffer(fz_buffer *buf)
{
- int rp = buf->rp - buf->bp;
- int wp = buf->wp - buf->bp;
- int ep = buf->ep - buf->bp;
-
- if (!buf->ownsdata)
- {
- fz_warn("assert: grow borrowed memory");
- return;
- }
-
- buf->bp = fz_realloc(buf->bp, (ep * 3) / 2);
- buf->rp = buf->bp + rp;
- buf->wp = buf->bp + wp;
- buf->ep = buf->bp + (ep * 3) / 2;
-}
-
-void
-fz_rewindbuffer(fz_buffer *buf)
-{
- if (!buf->ownsdata)
- {
- fz_warn("assert: rewind borrowed memory");
- return;
- }
-
- memmove(buf->bp, buf->rp, buf->wp - buf->rp);
- buf->wp = buf->bp + (buf->wp - buf->rp);
- buf->rp = buf->bp;
+ fz_resizebuffer(buf, (buf->cap * 3) / 2);
}
diff --git a/fitz/stm_filter.c b/fitz/stm_filter.c
deleted file mode 100644
index b4da7773..00000000
--- a/fitz/stm_filter.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "fitz.h"
-
-fz_error
-fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out)
-{
- fz_error reason;
- unsigned char *oldrp;
- unsigned char *oldwp;
-
- oldrp = in->rp;
- oldwp = out->wp;
-
- if (f->done)
- return fz_iodone;
-
- assert(!out->eof);
-
- reason = f->process(f, in, out);
-
- assert(in->rp <= in->wp);
- assert(out->wp <= out->ep);
-
- f->consumed = in->rp > oldrp;
- f->produced = out->wp > oldwp;
- f->count += out->wp - oldwp;
-
- /* iodone or error */
- if (reason != fz_ioneedin && reason != fz_ioneedout)
- {
- if (reason != fz_iodone)
- reason = fz_rethrow(reason, "cannot process filter");
- out->eof = 1;
- f->done = 1;
- }
-
- return reason;
-}
-
-fz_filter *
-fz_keepfilter(fz_filter *f)
-{
- f->refs ++;
- return f;
-}
-
-void
-fz_dropfilter(fz_filter *f)
-{
- if (--f->refs == 0)
- {
- if (f->drop)
- f->drop(f);
- fz_free(f);
- }
-}
diff --git a/fitz/stm_open.c b/fitz/stm_open.c
index e70a4580..d59062cc 100644
--- a/fitz/stm_open.c
+++ b/fitz/stm_open.c
@@ -1,21 +1,27 @@
#include "fitz.h"
-static fz_stream *
-fz_newstream(int kind)
+fz_stream *
+fz_newstream(void *state,
+ int(*read)(fz_stream *stm, unsigned char *buf, int len),
+ void(*close)(fz_stream *stm))
{
fz_stream *stm;
stm = fz_malloc(sizeof(fz_stream));
stm->refs = 1;
- stm->kind = kind;
stm->dead = 0;
- stm->error = fz_okay;
- stm->buffer = nil;
+ stm->pos = 0;
+
+ stm->bp = stm->buf;
+ stm->rp = stm->bp;
+ stm->wp = stm->bp;
+ stm->ep = stm->buf + sizeof stm->buf;
- stm->chain = nil;
- stm->filter = nil;
- stm->file = -1;
+ stm->state = state;
+ stm->read = read;
+ stm->close = close;
+ stm->seek = nil;
return stm;
}
@@ -28,81 +34,97 @@ fz_keepstream(fz_stream *stm)
}
void
-fz_dropstream(fz_stream *stm)
+fz_close(fz_stream *stm)
{
stm->refs --;
if (stm->refs == 0)
{
- if (stm->error)
- {
- fz_catch(stm->error, "dropped unhandled ioerror");
- stm->error = fz_okay;
- }
-
- switch (stm->kind)
- {
- case FZ_SFILE:
- close(stm->file);
- break;
- case FZ_SFILTER:
- fz_dropfilter(stm->filter);
- fz_dropstream(stm->chain);
- break;
- case FZ_SBUFFER:
- break;
- }
-
- fz_dropbuffer(stm->buffer);
+ if (stm->close)
+ stm->close(stm);
fz_free(stm);
}
}
-fz_stream *
-fz_openfile(int fd)
+/* File stream */
+
+static int readfile(fz_stream *stm, unsigned char *buf, int len)
{
- fz_stream *stm;
+ int n = read(*(int*)stm->state, buf, len);
+ if (n < 0)
+ return fz_throw("read error: %s", strerror(errno));
+ return n;
+}
- stm = fz_newstream(FZ_SFILE);
- stm->buffer = fz_newbuffer(FZ_BUFSIZE);
- stm->file = fd;
+static void seekfile(fz_stream *stm, int offset, int whence)
+{
+ int n = lseek(*(int*)stm->state, offset, whence);
+ if (n < 0)
+ fz_warn("cannot lseek: %s", strerror(errno));
+ stm->pos = n;
+ stm->rp = stm->bp;
+ stm->wp = stm->bp;
+}
- return stm;
+static void closefile(fz_stream *stm)
+{
+ int n = close(*(int*)stm->state);
+ if (n < 0)
+ fz_warn("close error: %s", strerror(errno));
+ fz_free(stm->state);
}
fz_stream *
-fz_openfilter(fz_filter *flt, fz_stream *src)
+fz_openfile(int fd)
{
fz_stream *stm;
+ int *state;
+
+ state = fz_malloc(sizeof(int));
+ *state = fd;
- stm = fz_newstream(FZ_SFILTER);
- stm->buffer = fz_newbuffer(FZ_BUFSIZE);
- stm->chain = fz_keepstream(src);
- stm->filter = fz_keepfilter(flt);
+ stm = fz_newstream(state, readfile, closefile);
+ stm->seek = seekfile;
return stm;
}
-fz_stream *
-fz_openbuffer(fz_buffer *buf)
+/* Memory stream */
+
+static int readbuffer(fz_stream *stm, unsigned char *buf, int len)
{
- fz_stream *stm;
+ return 0;
+}
- stm = fz_newstream(FZ_SBUFFER);
- stm->buffer = fz_keepbuffer(buf);
- stm->buffer->eof = 1;
+static void seekbuffer(fz_stream *stm, int offset, int whence)
+{
+ if (whence == 0)
+ stm->rp = stm->bp + offset;
+ if (whence == 1)
+ stm->rp += offset;
+ if (whence == 2)
+ stm->rp = stm->wp - offset;
+ stm->rp = CLAMP(stm->rp, stm->bp, stm->wp);
+}
- return stm;
+static void closebuffer(fz_stream *stm)
+{
+ fz_dropbuffer(stm->state);
}
fz_stream *
-fz_openmemory(unsigned char *mem, int len)
+fz_openbuffer(fz_buffer *buf)
{
- fz_buffer *buf;
fz_stream *stm;
- buf = fz_newbufferwithmemory(mem, len);
- stm = fz_openbuffer(buf);
- fz_dropbuffer(buf);
+ stm = fz_newstream(fz_keepbuffer(buf), readbuffer, closebuffer);
+ stm->seek = seekbuffer;
+
+ stm->bp = buf->data;
+ stm->rp = buf->data;
+ stm->wp = buf->data + buf->len;
+ stm->ep = buf->data + buf->len;
+
+ stm->pos = buf->len;
return stm;
}
diff --git a/fitz/stm_read.c b/fitz/stm_read.c
index d4d27f66..3bdddade 100644
--- a/fitz/stm_read.c
+++ b/fitz/stm_read.c
@@ -1,283 +1,91 @@
#include "fitz.h"
-fz_error
-fz_readimp(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
- fz_error error;
- fz_error reason;
- int produced;
- int n;
-
- if (stm->dead)
- return fz_throw("assert: read from dead stream");
-
- if (buf->eof)
- return fz_okay;
-
- fz_rewindbuffer(buf);
- if (buf->ep - buf->wp == 0)
- fz_growbuffer(buf);
-
- switch (stm->kind)
- {
-
- case FZ_SFILE:
- n = read(stm->file, buf->wp, buf->ep - buf->wp);
- if (n == -1)
- {
- stm->dead = 1;
- return fz_throw("syserr: read: %s", strerror(errno));
- }
-
- if (n == 0)
- buf->eof = 1;
- buf->wp += n;
-
- return fz_okay;
-
- case FZ_SFILTER:
- produced = 0;
-
- while (1)
- {
- reason = fz_process(stm->filter, stm->chain->buffer, buf);
-
- if (stm->filter->produced)
- produced = 1;
-
- if (reason == fz_ioneedin)
- {
- error = fz_readimp(stm->chain);
- if (error)
- {
- stm->dead = 1;
- return fz_rethrow(error, "cannot read from input stream");
- }
- }
-
- else if (reason == fz_ioneedout)
- {
- if (produced)
- return 0;
-
- if (buf->rp > buf->bp)
- fz_rewindbuffer(buf);
- else
- fz_growbuffer(buf);
- }
-
- else if (reason == fz_iodone)
- {
- return fz_okay;
- }
-
- else
- {
- stm->dead = 1;
- return fz_rethrow(reason, "cannot process filter");
- }
- }
-
- case FZ_SBUFFER:
- return fz_okay;
-
- default:
- return fz_throw("assert: unknown stream type");
- }
-}
-
int
-fz_tell(fz_stream *stm)
+fz_read(fz_stream *stm, unsigned char *buf, int len)
{
- fz_buffer *buf = stm->buffer;
- int t;
-
- if (stm->dead)
- return EOF;
+ int avail, count;
- switch (stm->kind)
+ avail = stm->wp - stm->rp;
+ if (avail)
{
- case FZ_SFILE:
- t = lseek(stm->file, 0, 1);
- if (t < 0)
- {
- fz_warn("syserr: lseek: %s", strerror(errno));
- stm->dead = 1;
- return EOF;
- }
- return t - (buf->wp - buf->rp);
-
- case FZ_SFILTER:
- return stm->filter->count - (buf->wp - buf->rp);
-
- case FZ_SBUFFER:
- return buf->rp - buf->bp;
-
- default:
- return EOF;
+ count = MIN(len, avail);
+ memcpy(buf, stm->rp, count);
+ stm->rp += count;
}
-}
-
-fz_error
-fz_seek(fz_stream *stm, int offset, int whence)
-{
- fz_error error;
- fz_buffer *buf = stm->buffer;
- int t, c;
-
- if (stm->dead)
- return fz_throw("assert: seek in dead stream");
-
- if (whence == 1)
+ else
{
- int cur = fz_tell(stm);
- if (cur < 0)
- return fz_throw("cannot tell current position");
- offset = cur + offset;
- whence = 0;
+ count = 0;
}
- buf->eof = 0;
+ if (stm->dead)
+ return count;
- switch (stm->kind)
+ while (len > count)
{
- case FZ_SFILE:
- t = lseek(stm->file, offset, whence);
- if (t < 0)
+ int n = stm->read(stm, buf + count, len - count);
+ if (n < 0)
{
stm->dead = 1;
- return fz_throw("syserr: lseek: %s", strerror(errno));
- }
-
- buf->rp = buf->bp;
- buf->wp = buf->bp;
-
- return fz_okay;
-
- case FZ_SFILTER:
- if (whence == 0)
- {
- if (offset < fz_tell(stm))
- {
- stm->dead = 1;
- return fz_throw("assert: seek backwards in filter");
- }
- while (fz_tell(stm) < offset)
- {
- c = fz_readbyte(stm);
- if (c == EOF)
- {
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "cannot seek forward in filter");
- break;
- }
- }
- return fz_okay;
+ return fz_rethrow(n, "read error");
}
-
- stm->dead = 1;
- return fz_throw("assert: relative seek in filter");
-
- case FZ_SBUFFER:
- if (whence == 0)
- buf->rp = CLAMP(buf->bp + offset, buf->bp, buf->ep);
- else
- buf->rp = CLAMP(buf->ep + offset, buf->bp, buf->ep);
- return fz_okay;
-
- default:
- return fz_throw("unknown stream type");
+ if (n == 0)
+ break;
+ stm->pos += n;
+ count += n;
}
+
+ return count;
}
-fz_error
-fz_read(int *np, fz_stream *stm, unsigned char *mem, int n)
+void
+fz_fillbuffer(fz_stream *stm)
{
- fz_error error;
- fz_buffer *buf = stm->buffer;
- int i = 0;
-
- while (i < n)
- {
- while (buf->rp < buf->wp && i < n)
- mem[i++] = *buf->rp++;
+ int n;
- if (buf->rp == buf->wp)
- {
- if (buf->eof)
- {
- *np = i;
- return fz_okay;
- }
+ assert(stm->rp == stm->wp);
- error = fz_readimp(stm);
- if (error)
- return fz_rethrow(error, "cannot produce data");
- }
+ n = fz_read(stm, stm->bp, stm->ep - stm->bp);
+ if (n < 0)
+ fz_catch(n, "read error; treating as end of file");
+ else
+ {
+ stm->rp = stm->bp;
+ stm->wp = stm->bp + n;
}
-
- *np = i;
- return fz_okay;
}
fz_error
-fz_readerror(fz_stream *stm)
+fz_readall(fz_buffer **bufp, fz_stream *stm)
{
- fz_error error;
- if (stm->error)
- {
- error = stm->error;
- stm->error = fz_okay;
- return fz_rethrow(error, "delayed read error");
- }
- return fz_okay;
-}
+ fz_buffer *buf;
+ int n;
-int
-fz_readbytex(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
+ buf = fz_newbuffer(16 * 1024);
- if (buf->rp == buf->wp)
+ while (1)
{
- if (!buf->eof && !stm->error)
- {
- fz_error error = fz_readimp(stm);
- if (error)
- stm->error = fz_rethrow(error, "cannot read data");
- }
- }
-
- return buf->rp < buf->wp ? *buf->rp++ : EOF ;
-}
-
-int
-fz_peekbytex(fz_stream *stm)
-{
- fz_buffer *buf = stm->buffer;
+ if (buf->len == buf->cap)
+ fz_growbuffer(buf);
- if (buf->rp == buf->wp)
- {
- if (!buf->eof && !stm->error)
+ n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len);
+ if (n < 0)
{
- fz_error error = fz_readimp(stm);
- if (error)
- stm->error = fz_rethrow(error, "cannot read data");
+ fz_dropbuffer(buf);
+ return fz_rethrow(n, "read error");
}
+ if (n == 0)
+ break;
+
+ buf->len += n;
}
- return buf->rp < buf->wp ? *buf->rp : EOF ;
+ *bufp = buf;
+ return fz_okay;
}
-/* Read a line terminated by LF or CR or CRLF. */
-
-fz_error
+void
fz_readline(fz_stream *stm, char *mem, int n)
{
- fz_error error;
-
char *s = mem;
int c = EOF;
while (n > 1)
@@ -298,57 +106,29 @@ fz_readline(fz_stream *stm, char *mem, int n)
}
if (n)
*s = '\0';
-
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "cannot read line");
- return fz_okay;
}
-static inline int
-fz_fillbuf(fz_stream *stm, fz_buffer *buf)
+int
+fz_tell(fz_stream *stm)
{
- int remaining = buf->ep - buf->wp;
- int available = stm->buffer->wp - stm->buffer->rp;
-
- if (available == 0 && remaining > 0)
- {
- int c = fz_readbytex(stm);
- if (c == EOF)
- return EOF;
-
- *buf->wp++ = c;
-
- remaining = buf->ep - buf->wp;
- available = stm->buffer->wp - stm->buffer->rp;
- }
-
- memmove(buf->wp, stm->buffer->rp, MIN(remaining, available));
- buf->wp += MIN(remaining, available);
- stm->buffer->rp += MIN(remaining, available);
-
- if (stm->buffer->rp == stm->buffer->wp && stm->buffer->eof)
- return EOF;
- return 0;
+ return stm->pos - (stm->wp - stm->rp);
}
-/* Read the contents of an input stream into a new buffer. */
-
-fz_buffer *
-fz_readall(fz_stream *stm, int sizehint)
+void
+fz_seek(fz_stream *stm, int offset, int whence)
{
- fz_buffer *buf;
-
- if (sizehint == 0)
- sizehint = 4 * 1024;
-
- buf = fz_newbuffer(sizehint);
-
- while (fz_fillbuf(stm, buf) != EOF)
+ if (stm->seek)
+ stm->seek(stm, offset, whence);
+ else if (whence != 2)
{
- if (buf->wp == buf->ep)
- fz_growbuffer(buf);
+ if (whence == 0)
+ offset -= fz_tell(stm);
+ if (offset < 0)
+ fz_warn("cannot seek backwards");
+ /* dog slow, but rare enough */
+ while (offset-- > 0)
+ fz_readbyte(stm);
}
-
- return buf;
+ else
+ fz_warn("cannot seek");
}
diff --git a/mupdf/cmapdump.c b/mupdf/cmapdump.c
index 51e30255..b08b5628 100644
--- a/mupdf/cmapdump.c
+++ b/mupdf/cmapdump.c
@@ -10,7 +10,6 @@
#include "../fitz/base_memory.c"
#include "../fitz/base_string.c"
#include "../fitz/stm_buffer.c"
-#include "../fitz/stm_filter.c"
#include "../fitz/stm_open.c"
#include "../fitz/stm_read.c"
@@ -170,7 +169,7 @@ main(int argc, char **argv)
fprintf(fo, "};\n\n");
- fz_dropstream(fi);
+ fz_close(fi);
}
if (fclose(fo))
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index abd9c9ec..fa42f30d 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -104,7 +104,7 @@ fz_error pdf_newcrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id);
void pdf_freecrypt(pdf_crypt *crypt);
fz_error pdf_parsecryptfilter(pdf_cryptfilter *cf, fz_obj *dict, int defaultlength);
-fz_filter * pdf_cryptstream(pdf_crypt *crypt, pdf_cryptfilter *cf, int num, int gen);
+fz_stream * pdf_opencrypt(fz_stream *chain, pdf_crypt *crypt, pdf_cryptfilter *cf, int num, int gen);
void pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int num, int gen);
int pdf_needspassword(pdf_xref *xref);
@@ -153,7 +153,7 @@ fz_error pdf_loadobject(fz_obj **objp, pdf_xref *, int num, int gen);
void pdf_updateobject( pdf_xref *xref, int num, int gen, fz_obj *newobj);
int pdf_isstream(pdf_xref *xref, int num, int gen);
-fz_filter * pdf_buildinlinefilter(pdf_xref *xref, fz_obj *stmobj, int length);
+fz_stream * pdf_openinlinestream(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int length);
fz_error pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen);
fz_error pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen);
fz_error pdf_openrawstream(fz_stream **stmp, pdf_xref *, int num, int gen);
diff --git a/mupdf/pdf_cmap_load.c b/mupdf/pdf_cmap_load.c
index e031aad2..eae52d8d 100644
--- a/mupdf/pdf_cmap_load.c
+++ b/mupdf/pdf_cmap_load.c
@@ -36,7 +36,7 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmobj)
goto cleanup;
}
- fz_dropstream(file);
+ fz_close(file);
wmode = fz_dictgets(stmobj, "WMode");
if (fz_isint(wmode))
@@ -80,7 +80,7 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmobj)
cleanup:
if (file)
- fz_dropstream(file);
+ fz_close(file);
if (cmap)
pdf_dropcmap(cmap);
return error; /* already rethrown */
diff --git a/mupdf/pdf_colorspace.c b/mupdf/pdf_colorspace.c
index ad793264..e0a3ab8e 100644
--- a/mupdf/pdf_colorspace.c
+++ b/mupdf/pdf_colorspace.c
@@ -243,7 +243,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
fz_obj *highobj = fz_arrayget(array, 2);
fz_obj *lookup = fz_arrayget(array, 3);
fz_colorspace *base;
- int n;
+ int i, n;
pdf_logrsrc("load Indexed {\n");
@@ -267,7 +267,6 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
if (fz_isstring(lookup) && fz_tostrlen(lookup) == n)
{
unsigned char *buf;
- int i;
pdf_logrsrc("string lookup\n");
@@ -277,22 +276,26 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
}
else if (fz_isindirect(lookup))
{
- fz_buffer *buf;
- int i;
+ fz_stream *file;
pdf_logrsrc("stream lookup\n");
- error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup));
+ /* TODO: openstream, read, close instead */
+ error = pdf_openstream(&file, xref, fz_tonum(lookup), fz_togen(lookup));
if (error)
{
fz_dropcolorspace(cs);
- return fz_rethrow(error, "cannot load colorpsace lookup table (%d %d R)", fz_tonum(lookup), fz_togen(lookup));
+ return fz_rethrow(error, "cannot open colorspace lookup table (%d 0 R)", fz_tonum(lookup));
}
- for (i = 0; i < n && i < (buf->wp - buf->rp); i++)
- idx->lookup[i] = buf->rp[i];
+ i = fz_read(file, idx->lookup, n);
+ if (i < 0)
+ {
+ fz_dropcolorspace(cs);
+ return fz_throw("cannot read colorspace lookup table (%d 0 R)", fz_tonum(lookup));
+ }
- fz_dropbuffer(buf);
+ fz_close(file);
}
else
{
diff --git a/mupdf/pdf_crypt.c b/mupdf/pdf_crypt.c
index d5d496aa..1b0f0787 100644
--- a/mupdf/pdf_crypt.c
+++ b/mupdf/pdf_crypt.c
@@ -588,8 +588,8 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int num, int gen)
*
* Create filter suitable for de/encrypting a stream.
*/
-fz_filter *
-pdf_cryptstream(pdf_crypt * crypt, pdf_cryptfilter * stmf, int num, int gen)
+fz_stream *
+pdf_opencrypt(fz_stream *chain, pdf_crypt *crypt, pdf_cryptfilter *stmf, int num, int gen)
{
unsigned char key[16];
int len;
@@ -597,10 +597,10 @@ pdf_cryptstream(pdf_crypt * crypt, pdf_cryptfilter * stmf, int num, int gen)
len = pdf_computeobjectkey(crypt, stmf, num, gen, key);
if (stmf->method == PDF_CRYPT_RC4)
- return fz_newarc4filter(key, len);
+ return fz_openarc4(chain, key, len);
if (stmf->method == PDF_CRYPT_AESV2)
- return fz_newaesdfilter(key, len);
+ return fz_openaesd(chain, key, len);
- return fz_newcopyfilter();
+ return fz_opencopy(chain);
}
diff --git a/mupdf/pdf_font.c b/mupdf/pdf_font.c
index eaa567e3..0758f0a8 100644
--- a/mupdf/pdf_font.c
+++ b/mupdf/pdf_font.c
@@ -648,10 +648,10 @@ loadcidfont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *enco
if (error)
goto cleanup;
- fontdesc->ncidtogid = (buf->wp - buf->rp) / 2;
+ fontdesc->ncidtogid = (buf->len) / 2;
fontdesc->cidtogid = fz_malloc(fontdesc->ncidtogid * sizeof(unsigned short));
for (i = 0; i < fontdesc->ncidtogid; i++)
- fontdesc->cidtogid[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1];
+ fontdesc->cidtogid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1];
fz_dropbuffer(buf);
}
diff --git a/mupdf/pdf_fontfile.c b/mupdf/pdf_fontfile.c
index c461823f..b0bf828a 100644
--- a/mupdf/pdf_fontfile.c
+++ b/mupdf/pdf_fontfile.c
@@ -277,14 +277,14 @@ pdf_loadembeddedfont(pdf_fontdesc *fontdesc, pdf_xref *xref, fz_obj *stmref)
if (error)
return fz_rethrow(error, "cannot load font stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref));
- error = fz_newfontfrombuffer(&fontdesc->font, buf->rp, buf->wp - buf->rp, 0);
+ error = fz_newfontfrombuffer(&fontdesc->font, buf->data, buf->len, 0);
if (error)
{
fz_dropbuffer(buf);
return fz_rethrow(error, "cannot load embedded font (%d %d R)", fz_tonum(stmref), fz_togen(stmref));
}
- fontdesc->buffer = buf->rp; /* save the buffer so we can free it later */
+ fontdesc->buffer = buf->data; /* save the buffer so we can free it later */
fz_free(buf); /* only free the fz_buffer struct, not the contained data */
fontdesc->isembedded = 1;
diff --git a/mupdf/pdf_function.c b/mupdf/pdf_function.c
index 0f7107a1..603759e1 100644
--- a/mupdf/pdf_function.c
+++ b/mupdf/pdf_function.c
@@ -508,13 +508,13 @@ loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, in
error = pdf_lex(&tok, stream, buf, sizeof buf, &len);
if (error)
{
- fz_dropstream(stream);
+ fz_close(stream);
return fz_rethrow(error, "stream is not a calculator function");
}
if (tok != PDF_TOBRACE)
{
- fz_dropstream(stream);
+ fz_close(stream);
return fz_throw("stream is not a calculator function");
}
@@ -525,11 +525,11 @@ loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, in
error = parsecode(func, stream, &codeptr);
if (error)
{
- fz_dropstream(stream);
+ fz_close(stream);
return fz_rethrow(error, "cannot parse calculator function (%d %d R)", num, gen);
}
- fz_dropstream(stream);
+ fz_close(stream);
return fz_okay;
}
@@ -1057,10 +1057,7 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int ge
{
if (fz_peekbyte(stream) == EOF && bits == 0)
{
- error = fz_readerror(stream);
- fz_dropstream(stream);
- if (error)
- return fz_rethrow(error, "truncated sample stream");
+ fz_close(stream);
return fz_throw("truncated sample stream");
}
@@ -1089,13 +1086,9 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int ge
func->u.sa.samples[i] = s;
}
-
- error = fz_readerror(stream);
- if (error)
- return fz_rethrow(error, "truncated sample stream");
}
- fz_dropstream(stream);
+ fz_close(stream);
pdf_logrsrc("}\n");
diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c
index 6350c858..b10133e8 100644
--- a/mupdf/pdf_image.c
+++ b/mupdf/pdf_image.c
@@ -142,9 +142,8 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref,
{
fz_error error;
pdf_image *img;
- fz_filter *filter;
fz_stream *subfile;
- int n;
+ int i, n;
pdf_logimage("load inline image {\n");
@@ -152,27 +151,25 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref,
if (error)
return fz_rethrow(error, "cannot load inline image");
- filter = pdf_buildinlinefilter(xref, dict, img->stride * img->h);
- subfile = fz_openfilter(filter, file);
+ subfile = pdf_openinlinestream(file, xref, dict, img->stride * img->h);
img->samples = fz_newbuffer(img->h * img->stride);
- error = fz_read(&n, subfile, img->samples->bp, img->h * img->stride);
- if (error)
+ n = fz_read(subfile, img->samples->data, img->h * img->stride);
+ if (n < 0)
{
pdf_dropimage(img);
- return fz_rethrow(error, "cannot load inline image data");
+ return fz_rethrow(n, "cannot load inline image data");
}
- img->samples->wp += n;
+ img->samples->len = n;
- fz_dropstream(subfile);
- fz_dropfilter(filter);
+ fz_close(subfile);
if (img->imagemask)
{
/* 0=opaque and 1=transparent so we need to invert */
- unsigned char *p;
- for (p = img->samples->bp; p < img->samples->ep; p++)
- *p = ~*p;
+ unsigned char *p = img->samples->data;
+ for (i = 0; i < img->samples->len; i++)
+ p[i] = ~p[i];
}
pdf_logimage("}\n");
@@ -185,7 +182,9 @@ fz_error
pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
{
fz_error error;
+ fz_stream *stm;
pdf_image *img;
+ int i, n;
if ((*imgp = pdf_finditem(xref->store, pdf_dropimage, dict)))
{
@@ -199,28 +198,39 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
if (error)
return fz_rethrow(error, "cannot load image (%d %d R)", fz_tonum(dict), fz_togen(dict));
- error = pdf_loadstream(&img->samples, xref, fz_tonum(dict), fz_togen(dict));
+ error = pdf_openstream(&stm, xref, fz_tonum(dict), fz_togen(dict));
if (error)
{
pdf_dropimage(img);
return fz_rethrow(error, "cannot load image data (%d %d R)", fz_tonum(dict), fz_togen(dict));
}
+ img->samples = fz_newbuffer(img->h * img->stride);
+ n = fz_read(stm, img->samples->data, img->h * img->stride);
+ if (n < 0)
+ {
+ pdf_dropimage(img);
+ fz_close(stm);
+ return fz_rethrow(n, "cannot load inline image data");
+ }
+ img->samples->len = n;
+
+ fz_close(stm);
+
/* Pad truncated images */
- if (img->samples->wp - img->samples->bp < img->stride * img->h)
+ if (img->samples->len < img->stride * img->h)
{
fz_warn("padding truncated image");
- fz_resizebuffer(img->samples, img->stride * img->h);
- memset(img->samples->wp, 0, img->samples->ep - img->samples->wp);
- img->samples->wp = img->samples->bp + img->stride * img->h;
+ memset(img->samples->data + img->samples->len, 0, img->samples->cap - img->samples->len);
+ img->samples->len = img->samples->cap;
}
if (img->imagemask)
{
/* 0=opaque and 1=transparent so we need to invert */
- unsigned char *p;
- for (p = img->samples->bp; p < img->samples->ep; p++)
- *p = ~*p;
+ unsigned char *p = img->samples->data;
+ for (i = 0; i < img->samples->len; i++)
+ p[i] = ~p[i];
}
pdf_logimage("}\n");
@@ -269,7 +279,7 @@ pdf_loadtile(pdf_image *img /* ...bbox/y+h should go here... */)
}
}
- fz_unpacktile(tile, img->samples->bp, img->n, img->bpc, img->stride, scale);
+ fz_unpacktile(tile, img->samples->data, img->n, img->bpc, img->stride, scale);
if (img->usecolorkey)
pdf_maskcolorkey(tile, img->n, img->colorkey);
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 95f2ed42..8faad1d0 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -1452,9 +1452,6 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
if (ch == '\r')
if (fz_peekbyte(file) == '\n')
fz_readbyte(file);
- error = fz_readerror(file);
- if (error)
- return fz_rethrow(error, "cannot parse whitespace before inline image");
error = pdf_runinlineimage(csi, rdb, file, obj);
fz_dropobj(obj);
@@ -1482,11 +1479,9 @@ pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
{
fz_stream *file;
fz_error error;
- contents->rp = contents->bp;
file = fz_openbuffer(contents);
error = pdf_runcsifile(csi, rdb, file, csi->xref->scratch, sizeof csi->xref->scratch);
- fz_dropstream(file);
- contents->rp = contents->bp;
+ fz_close(file);
if (error)
return fz_rethrow(error, "cannot parse content stream");
return fz_okay;
diff --git a/mupdf/pdf_lex.c b/mupdf/pdf_lex.c
index d4f98bc0..16e12a13 100644
--- a/mupdf/pdf_lex.c
+++ b/mupdf/pdf_lex.c
@@ -389,17 +389,14 @@ pdf_tokenfromkeyword(char *key)
fz_error
pdf_lex(pdf_token_e *tok, fz_stream *f, char *buf, int n, int *sl)
{
- fz_error error;
- int c;
-
while (1)
{
- c = fz_readbyte(f);
+ int c = fz_readbyte(f);
switch (c)
{
case EOF:
*tok = PDF_TEOF;
- goto cleanupokay;
+ return fz_okay;
case ISWHITE:
lexwhite(f);
break;
@@ -410,11 +407,11 @@ pdf_lex(pdf_token_e *tok, fz_stream *f, char *buf, int n, int *sl)
lexname(f, buf, n);
*sl = strlen(buf);
*tok = PDF_TNAME;
- goto cleanupokay;
+ return fz_okay;
case '(':
*sl = lexstring(f, buf, n);
*tok = PDF_TSTRING;
- goto cleanupokay;
+ return fz_okay;
case ')':
*tok = PDF_TERROR;
goto cleanuperror;
@@ -430,57 +427,42 @@ pdf_lex(pdf_token_e *tok, fz_stream *f, char *buf, int n, int *sl)
*sl = lexhexstring(f, buf, n);
*tok = PDF_TSTRING;
}
- goto cleanupokay;
+ return fz_okay;
case '>':
c = fz_readbyte(f);
if (c == '>')
{
*tok = PDF_TCDICT;
- goto cleanupokay;
+ return fz_okay;
}
*tok = PDF_TERROR;
goto cleanuperror;
case '[':
*tok = PDF_TOARRAY;
- goto cleanupokay;
+ return fz_okay;
case ']':
*tok = PDF_TCARRAY;
- goto cleanupokay;
+ return fz_okay;
case '{':
*tok = PDF_TOBRACE;
- goto cleanupokay;
+ return fz_okay;
case '}':
*tok = PDF_TCBRACE;
- goto cleanupokay;
+ return fz_okay;
case ISNUMBER:
fz_unreadbyte(f);
*sl = lexnumber(f, buf, n, tok);
- goto cleanupokay;
+ return fz_okay;
default: /* isregular: !isdelim && !iswhite && c != EOF */
fz_unreadbyte(f);
lexname(f, buf, n);
*sl = strlen(buf);
*tok = pdf_tokenfromkeyword(buf);
- goto cleanupokay;
+ return fz_okay;
}
}
-cleanupokay:
- error = fz_readerror(f);
- if (error)
- {
- *tok = PDF_TERROR;
- return fz_rethrow(error, "cannot read token");
- }
- return fz_okay;
-
cleanuperror:
- error = fz_readerror(f);
- if (error)
- {
- *tok = PDF_TERROR;
- return fz_rethrow(error, "cannot read token");
- }
*tok = PDF_TERROR;
return fz_throw("lexical error");
}
diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c
index 2edada66..75e10eeb 100644
--- a/mupdf/pdf_page.c
+++ b/mupdf/pdf_page.c
@@ -9,10 +9,12 @@ pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
fz_error error;
fz_buffer *big;
fz_buffer *one;
- int i, n;
+ int i;
pdf_logpage("multiple content streams: %d\n", fz_arraylen(list));
+ /* TODO: openstream, read, close into big buffer at once */
+
big = fz_newbuffer(32 * 1024);
for (i = 0; i < fz_arraylen(list); i++)
@@ -25,12 +27,11 @@ pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
return fz_rethrow(error, "cannot load content stream part %d/%d (%d %d R)", i + 1, fz_arraylen(list), fz_tonum(stm), fz_togen(stm));
}
- n = one->wp - one->rp;
- while (big->wp + n + 1 > big->ep)
- fz_growbuffer(big);
- memcpy(big->wp, one->rp, n);
- big->wp += n;
- *big->wp++ = ' ';
+ if (big->len + one->len + 1 > big->cap)
+ fz_resizebuffer(big, big->len + one->len + 1);
+ memcpy(big->data + big->len, one->data, one->len);
+ big->data[big->len + one->len] = ' ';
+ big->len += one->len + 1;
fz_dropbuffer(one);
}
diff --git a/mupdf/pdf_parse.c b/mupdf/pdf_parse.c
index 94b0504c..942c5d33 100644
--- a/mupdf/pdf_parse.c
+++ b/mupdf/pdf_parse.c
@@ -506,12 +506,6 @@ skip:
else
fz_readbyte(file);
}
- error = fz_readerror(file);
- if (error)
- {
- fz_dropobj(obj);
- return fz_rethrow(error, "cannot parse indirect object (%d %d R)", num, gen);
- }
stmofs = fz_tell(file);
}
else if (tok == PDF_TENDOBJ)
diff --git a/mupdf/pdf_repair.c b/mupdf/pdf_repair.c
index 9404b1f2..1652073a 100644
--- a/mupdf/pdf_repair.c
+++ b/mupdf/pdf_repair.c
@@ -69,32 +69,24 @@ fz_repairobj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, in
fz_readbyte(file);
}
- error = fz_readerror(file);
- if (error)
- return fz_rethrow(error, "cannot read from file");
-
*stmofsp = fz_tell(file);
if (*stmofsp < 0)
return fz_throw("cannot seek in file");
if (stmlen > 0)
{
- error = fz_seek(file, *stmofsp + stmlen, 0);
- if (error)
- return fz_rethrow(error, "cannot seek in file");
+ fz_seek(file, *stmofsp + stmlen, 0);
error = pdf_lex(&tok, file, buf, cap, &len);
if (error)
fz_catch(error, "cannot find endstream token, falling back to scanning");
if (tok == PDF_TENDSTREAM)
goto atobjend;
- error = fz_seek(file, *stmofsp, 0);
- if (error)
- return fz_rethrow(error, "cannot seek in file");
+ fz_seek(file, *stmofsp, 0);
}
- error = fz_read(&n, file, (unsigned char *) buf, 9);
- if (error)
- return fz_rethrow(error, "cannot read from file");
+ n = fz_read(file, (unsigned char *) buf, 9);
+ if (n < 0)
+ return fz_rethrow(n, "cannot read from file");
while (memcmp(buf, "endstream", 9) != 0)
{
@@ -105,10 +97,6 @@ fz_repairobj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, in
buf[8] = c;
}
- error = fz_readerror(file);
- if (error)
- return fz_rethrow(error, "cannot read from file");
-
*stmlenp = fz_tell(file) - *stmofsp - 9;
atobjend:
@@ -149,9 +137,7 @@ pdf_repairxref(pdf_xref *xref, char *buf, int bufsize)
pdf_logxref("repairxref %p\n", xref);
- error = fz_seek(xref->file, 0, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to beginning of file");
+ fz_seek(xref->file, 0, 0);
listlen = 0;
listcap = 1024;
diff --git a/mupdf/pdf_shade.c b/mupdf/pdf_shade.c
index 51a73ca4..2aacef31 100644
--- a/mupdf/pdf_shade.c
+++ b/mupdf/pdf_shade.c
@@ -1261,7 +1261,7 @@ pdf_loadshadingdict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix t
goto cleanup;
if (stream)
- fz_dropstream(stream);
+ fz_close(stream);
for (i = 0; i < funcs; i++)
if (func[i])
pdf_dropfunction(func[i]);
@@ -1273,7 +1273,7 @@ pdf_loadshadingdict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix t
cleanup:
if (stream)
- fz_dropstream(stream);
+ fz_close(stream);
for (i = 0; i < funcs; i++)
if (func[i])
pdf_dropfunction(func[i]);
diff --git a/mupdf/pdf_stream.c b/mupdf/pdf_stream.c
index 539b4b3f..2e4032c9 100644
--- a/mupdf/pdf_stream.c
+++ b/mupdf/pdf_stream.c
@@ -35,17 +35,15 @@ pdf_streamhascrypt(fz_obj *stm)
filters = fz_dictgetsa(stm, "Filter", "F");
if (filters)
{
- if (fz_isname(filters))
- if (!strcmp(fz_toname(filters), "Crypt"))
- return 1;
+ if (!strcmp(fz_toname(filters), "Crypt"))
+ return 1;
if (fz_isarray(filters))
{
for (i = 0; i < fz_arraylen(filters); i++)
{
obj = fz_arrayget(filters, i);
- if (fz_isname(obj))
- if (!strcmp(fz_toname(obj), "Crypt"))
- return 1;
+ if (!strcmp(fz_toname(obj), "Crypt"))
+ return 1;
}
}
}
@@ -55,60 +53,43 @@ pdf_streamhascrypt(fz_obj *stm)
/*
* Create a filter given a name and param dictionary.
*/
-static fz_filter *
-buildonefilter(pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
+static fz_stream *
+buildfilter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
{
- fz_filter *decompress;
- fz_filter *predict;
- fz_filter *pipe;
fz_error error;
char *s;
s = fz_toname(f);
if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx"))
- return fz_newahxd(p);
+ return fz_openahxd(chain);
else if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85"))
- return fz_newa85d(p);
+ return fz_opena85d(chain);
else if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF"))
- return fz_newfaxd(p);
+ return fz_openfaxd(chain, p);
else if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT"))
- return fz_newdctd(p);
+ return fz_opendctd(chain, p);
else if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL"))
- return fz_newrld(p);
+ return fz_openrld(chain);
else if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl"))
{
fz_obj *obj = fz_dictgets(p, "Predictor");
- if (obj)
- {
- decompress = fz_newflated(p);
- predict = fz_newpredictd(p);
- pipe = fz_newpipeline(decompress, predict);
- fz_dropfilter(decompress);
- fz_dropfilter(predict);
- return pipe;
- }
- return fz_newflated(p);
+ if (fz_toint(obj) > 1)
+ return fz_openpredict(fz_openflated(chain), p);
+ return fz_openflated(chain);
}
else if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW"))
{
fz_obj *obj = fz_dictgets(p, "Predictor");
- if (obj)
- {
- decompress = fz_newlzwd(p);
- predict = fz_newpredictd(p);
- pipe = fz_newpipeline(decompress, predict);
- fz_dropfilter(decompress);
- fz_dropfilter(predict);
- return pipe;
- }
- return fz_newlzwd(p);
+ if (fz_toint(obj) > 1)
+ return fz_openpredict(fz_openlzwd(chain, p), p);
+ return fz_openlzwd(chain, p);
}
else if (!strcmp(s, "JBIG2Decode"))
@@ -117,29 +98,18 @@ buildonefilter(pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
if (obj)
{
fz_buffer *globals;
- fz_filter *dec;
-
- dec = fz_newjbig2d(p);
-
error = pdf_loadstream(&globals, xref, fz_tonum(obj), fz_togen(obj));
if (error)
fz_catch(error, "cannot load jbig2 global segments");
- else
- {
- error = fz_setjbig2dglobalstream(dec, globals->rp, globals->wp - globals->rp);
- if (error)
- fz_catch(error, "cannot apply jbig2 global segments");
- }
-
+ chain = fz_openjbig2d(chain, globals);
fz_dropbuffer(globals);
-
- return dec;
+ return chain;
}
- return fz_newjbig2d(p);
+ return fz_openjbig2d(chain, nil);
}
else if (!strcmp(s, "JPXDecode"))
- return fz_newjpxd(p);
+ return fz_openjpxd(chain);
else if (!strcmp(s, "Crypt"))
{
@@ -149,7 +119,7 @@ buildonefilter(pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
if (!xref->crypt)
{
fz_warn("crypt filter in unencrypted document");
- return fz_newcopyfilter();
+ return chain;
}
name = fz_dictgets(p, "Name");
@@ -162,14 +132,15 @@ buildonefilter(pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
if (error)
fz_catch(error, "cannot parse crypt filter (%d %d R)", fz_tonum(obj), fz_togen(obj));
else
- return pdf_cryptstream(xref->crypt, &cf, num, gen);
+ return pdf_opencrypt(chain, xref->crypt, &cf, num, gen);
}
}
- return fz_newcopyfilter();
+
+ return chain;
}
fz_warn("unknown filter name (%s)", s);
- return fz_newcopyfilter();
+ return chain;
}
/*
@@ -177,12 +148,9 @@ buildonefilter(pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen)
* If head is given, start filter chain with it.
* Assume ownership of head.
*/
-static fz_filter *
-buildfilterchain(pdf_xref *xref, fz_filter *head,
- fz_obj *fs, fz_obj *ps, int num, int gen)
+static fz_stream *
+buildfilterchain(fz_stream *chain, pdf_xref *xref, fz_obj *fs, fz_obj *ps, int num, int gen)
{
- fz_filter *newhead;
- fz_filter *tail;
fz_obj *f;
fz_obj *p;
int i;
@@ -190,24 +158,11 @@ buildfilterchain(pdf_xref *xref, fz_filter *head,
for (i = 0; i < fz_arraylen(fs); i++)
{
f = fz_arrayget(fs, i);
- if (fz_isarray(ps))
- p = fz_arrayget(ps, i);
- else
- p = nil;
-
- tail = buildonefilter(xref, f, p, num, gen);
- if (head)
- {
- newhead = fz_newpipeline(head, tail);
- fz_dropfilter(head);
- fz_dropfilter(tail);
- head = newhead;
- }
- else
- head = tail;
+ p = fz_arrayget(ps, i);
+ chain = buildfilter(chain, xref, f, p, num, gen);
}
- return head;
+ return chain;
}
/*
@@ -215,41 +170,31 @@ buildfilterchain(pdf_xref *xref, fz_filter *head,
* This is a null filter to constrain reading to the
* stream length, followed by a decryption filter.
*/
-static fz_filter *
-buildrawfilter(pdf_xref *xref, fz_obj *stmobj, int num, int gen)
+static fz_stream *
+pdf_openrawfilter(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int num, int gen)
{
- fz_filter *base;
- fz_obj *stmlen;
- int len;
int hascrypt;
+ int len;
- hascrypt = pdf_streamhascrypt(stmobj);
-
- stmlen = fz_dictgets(stmobj, "Length");
- len = fz_toint(stmlen);
+ /* don't close chain when we close this filter */
+ fz_keepstream(chain);
- base = fz_newnullfilter(len);
+ len = fz_toint(fz_dictgets(stmobj, "Length"));
+ chain = fz_opennull(chain, len);
+ hascrypt = pdf_streamhascrypt(stmobj);
if (xref->crypt && !hascrypt)
- {
- fz_filter *crypt;
- fz_filter *pipe;
- crypt = pdf_cryptstream(xref->crypt, &xref->crypt->stmf, num, gen);
- pipe = fz_newpipeline(base, crypt);
- fz_dropfilter(base);
- fz_dropfilter(crypt);
- return pipe;
- }
+ chain = pdf_opencrypt(chain, xref->crypt, &xref->crypt->stmf, num, gen);
- return base;
+ return chain;
}
/*
- * Construct a filter to decode a stream, without
- * constraining to stream length, and without decryption.
+ * Construct a filter to decode a stream, constraining
+ * to stream length and decrypting.
*/
-fz_filter *
-pdf_buildinlinefilter(pdf_xref *xref, fz_obj *stmobj, int length)
+static fz_stream *
+pdf_openfilter(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int num, int gen)
{
fz_obj *filters;
fz_obj *params;
@@ -257,48 +202,38 @@ pdf_buildinlinefilter(pdf_xref *xref, fz_obj *stmobj, int length)
filters = fz_dictgetsa(stmobj, "Filter", "F");
params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
+ chain = pdf_openrawfilter(chain, xref, stmobj, num, gen);
+
if (fz_isname(filters))
- return buildonefilter(xref, filters, params, 0, 0);
+ return buildfilter(chain, xref, filters, params, num, gen);
if (fz_arraylen(filters) > 0)
- return buildfilterchain(xref, nil, filters, params, 0, 0);
+ return buildfilterchain(chain, xref, filters, params, num, gen);
- return fz_newnullfilter(length);
+ return chain;
}
/*
- * Construct a filter to decode a stream, constraining
- * to stream length and decrypting.
+ * Construct a filter to decode a stream, without
+ * constraining to stream length, and without decryption.
*/
-static fz_filter *
-pdf_buildfilter(pdf_xref *xref, fz_obj *stmobj, int num, int gen)
+fz_stream *
+pdf_openinlinestream(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int length)
{
- fz_filter *base, *pipe, *tmp;
fz_obj *filters;
fz_obj *params;
filters = fz_dictgetsa(stmobj, "Filter", "F");
params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
- base = buildrawfilter(xref, stmobj, num, gen);
+ /* don't close chain when we close this filter */
+ fz_keepstream(chain);
- if (filters)
- {
- if (fz_isname(filters))
- {
- tmp = buildonefilter(xref, filters, params, num, gen);
- pipe = fz_newpipeline(base, tmp);
- fz_dropfilter(base);
- fz_dropfilter(tmp);
- return pipe;
- }
- else
- {
- /* The pipeline chain takes ownership of base */
- return buildfilterchain(xref, base, filters, params, num, gen);
- }
- }
+ if (fz_isname(filters))
+ return buildfilter(chain, xref, filters, params, 0, 0);
+ if (fz_arraylen(filters) > 0)
+ return buildfilterchain(chain, xref, filters, params, 0, 0);
- return base;
+ return fz_opennull(chain, length);
}
/*
@@ -310,7 +245,6 @@ pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int num, int gen)
{
pdf_xrefentry *x;
fz_error error;
- fz_filter *filter;
if (num < 0 || num >= xref->len)
return fz_throw("object id out of range (%d %d R)", num, gen);
@@ -323,14 +257,8 @@ pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int num, int gen)
if (x->stmofs)
{
- filter = buildrawfilter(xref, x->obj, num, gen);
-
- error = fz_seek(xref->file, x->stmofs, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to stream");
-
- *stmp = fz_openfilter(filter, xref->file);
- fz_dropfilter(filter);
+ *stmp = pdf_openrawfilter(xref->file, xref, x->obj, num, gen);
+ fz_seek(xref->file, x->stmofs, 0);
return fz_okay;
}
@@ -347,7 +275,6 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int num, int gen)
{
pdf_xrefentry *x;
fz_error error;
- fz_filter *filter;
if (num < 0 || num >= xref->len)
return fz_throw("object id out of range (%d %d R)", num, gen);
@@ -360,14 +287,8 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int num, int gen)
if (x->stmofs)
{
- filter = pdf_buildfilter(xref, x->obj, num, gen);
-
- error = fz_seek(xref->file, x->stmofs, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to stream");
-
- *stmp = fz_openfilter(filter, xref->file);
- fz_dropfilter(filter);
+ *stmp = pdf_openfilter(xref->file, xref, x->obj, num, gen);
+ fz_seek(xref->file, x->stmofs, 0);
return fz_okay;
}
@@ -377,22 +298,12 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int num, int gen)
fz_error
pdf_openstreamat(fz_stream **stmp, pdf_xref *xref, int num, int gen, fz_obj *dict, int stmofs)
{
- fz_error error;
- fz_filter *filter;
-
if (stmofs)
{
- filter = pdf_buildfilter(xref, dict, num, gen);
-
- error = fz_seek(xref->file, stmofs, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to stream");
-
- *stmp = fz_openfilter(filter, xref->file);
- fz_dropfilter(filter);
+ *stmp = pdf_openfilter(xref->file, xref, dict, num, gen);
+ fz_seek(xref->file, stmofs, 0);
return fz_okay;
}
-
return fz_throw("object is not a stream");
}
@@ -404,24 +315,19 @@ pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen)
{
fz_error error;
fz_stream *stm;
- fz_buffer *buf;
error = pdf_openrawstream(&stm, xref, num, gen);
if (error)
return fz_rethrow(error, "cannot open raw stream (%d %d R)", num, gen);
- buf = fz_readall(stm, 0);
- error = fz_readerror(stm);
+ error = fz_readall(bufp, stm);
if (error)
{
- fz_dropbuffer(buf);
- fz_dropstream(stm);
+ fz_close(stm);
return fz_rethrow(error, "cannot read raw stream (%d %d R)", num, gen);
}
- fz_dropstream(stm);
-
- *bufp = buf;
+ fz_close(stm);
return fz_okay;
}
@@ -433,23 +339,18 @@ pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int num, int gen)
{
fz_error error;
fz_stream *stm;
- fz_buffer *buf;
error = pdf_openstream(&stm, xref, num, gen);
if (error)
return fz_rethrow(error, "cannot open stream (%d %d R)", num, gen);
- buf = fz_readall(stm, 0);
- error = fz_readerror(stm);
+ error = fz_readall(bufp, stm);
if (error)
{
- fz_dropbuffer(buf);
- fz_dropstream(stm);
+ fz_close(stm);
return fz_rethrow(error, "cannot read raw stream (%d %d R)", num, gen);
}
- fz_dropstream(stm);
-
- *bufp = buf;
+ fz_close(stm);
return fz_okay;
}
diff --git a/mupdf/pdf_xobject.c b/mupdf/pdf_xobject.c
index 9a9fc212..8f94eccf 100644
--- a/mupdf/pdf_xobject.c
+++ b/mupdf/pdf_xobject.c
@@ -75,7 +75,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict)
return fz_rethrow(error, "cannot load xobject content stream (%d %d R)", fz_tonum(dict), fz_togen(dict));
}
- pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);
+ pdf_logrsrc("stream %d bytes\n", form->contents->len);
pdf_logrsrc("}\n");
*formp = form;
diff --git a/mupdf/pdf_xref.c b/mupdf/pdf_xref.c
index 196b633e..c9734e71 100644
--- a/mupdf/pdf_xref.c
+++ b/mupdf/pdf_xref.c
@@ -15,16 +15,10 @@ static inline int iswhite(int ch)
static fz_error
pdf_loadversion(pdf_xref *xref)
{
- fz_error error;
char buf[20];
- error = fz_seek(xref->file, 0, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to beginning of file");
-
- error = fz_readline(xref->file, buf, sizeof buf);
- if (error)
- return fz_rethrow(error, "cannot read version marker");
+ fz_seek(xref->file, 0, 0);
+ fz_readline(xref->file, buf, sizeof buf);
if (memcmp(buf, "%PDF-", 5) != 0)
return fz_throw("cannot recognize version marker");
@@ -38,25 +32,20 @@ pdf_loadversion(pdf_xref *xref)
static fz_error
pdf_readstartxref(pdf_xref *xref)
{
- fz_error error;
unsigned char buf[1024];
int t, n;
int i;
- error = fz_seek(xref->file, 0, 2);
- if (error)
- return fz_rethrow(error, "cannot seek to end of file");
+ fz_seek(xref->file, 0, 2);
xref->filesize = fz_tell(xref->file);
t = MAX(0, xref->filesize - (int)sizeof buf);
- error = fz_seek(xref->file, t, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to offset %d", t);
+ fz_seek(xref->file, t, 0);
- error = fz_read(&n, xref->file, buf, sizeof buf);
- if (error)
- return fz_rethrow(error, "cannot read from file");
+ n = fz_read(xref->file, buf, sizeof buf);
+ if (n < 0)
+ return fz_rethrow(n, "cannot read from file");
for (i = n - 9; i >= 0; i--)
{
@@ -91,9 +80,7 @@ pdf_readoldtrailer(pdf_xref *xref, char *buf, int cap)
pdf_logxref("load old xref format trailer\n");
- error = fz_readline(xref->file, buf, cap);
- if (error)
- return fz_rethrow(error, "cannot read xref marker");
+ fz_readline(xref->file, buf, cap);
if (strncmp(buf, "xref", 4) != 0)
return fz_throw("cannot find xref marker");
@@ -103,10 +90,7 @@ pdf_readoldtrailer(pdf_xref *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- error = fz_readline(xref->file, buf, cap);
- if (error)
- return fz_rethrow(error, "cannot read xref count");
-
+ fz_readline(xref->file, buf, cap);
s = buf;
fz_strsep(&s, " "); /* ignore ofs */
if (!s)
@@ -115,25 +99,15 @@ pdf_readoldtrailer(pdf_xref *xref, char *buf, int cap)
/* broken pdfs where the section is not on a separate line */
if (s && *s != '\0')
- {
- error = fz_seek(xref->file, -(2 + (int)strlen(s)), 1);
- if (error)
- return fz_rethrow(error, "cannot seek in file");
- }
+ fz_seek(xref->file, -(2 + (int)strlen(s)), 1);
t = fz_tell(xref->file);
if (t < 0)
return fz_throw("cannot tell in file");
- error = fz_seek(xref->file, t + 20 * len, 0);
- if (error)
- return fz_rethrow(error, "cannot seek in file");
+ fz_seek(xref->file, t + 20 * len, 0);
}
- error = fz_readerror(xref->file);
- if (error)
- return fz_rethrow(error, "cannot read from file");
-
error = pdf_lex(&tok, xref->file, buf, cap, &n);
if (error)
return fz_rethrow(error, "cannot parse trailer");
@@ -171,18 +145,12 @@ pdf_readtrailer(pdf_xref *xref, char *buf, int cap)
fz_error error;
int c;
- error = fz_seek(xref->file, xref->startxref, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to startxref");
+ fz_seek(xref->file, xref->startxref, 0);
while (iswhite(fz_peekbyte(xref->file)))
fz_readbyte(xref->file);
c = fz_peekbyte(xref->file);
- error = fz_readerror(xref->file);
- if (error)
- return fz_rethrow(error, "cannot read trailer");
-
if (c == 'x')
{
error = pdf_readoldtrailer(xref, buf, cap);
@@ -220,9 +188,7 @@ pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
pdf_logxref("load old xref format\n");
- error = fz_readline(xref->file, buf, cap);
- if (error)
- return fz_rethrow(error, "cannot read xref marker");
+ fz_readline(xref->file, buf, cap);
if (strncmp(buf, "xref", 4) != 0)
return fz_throw("cannot find xref marker");
@@ -232,10 +198,7 @@ pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- error = fz_readline(xref->file, buf, cap);
- if (error)
- return fz_rethrow(error, "cannot read xref count");
-
+ fz_readline(xref->file, buf, cap);
s = buf;
ofs = atoi(fz_strsep(&s, " "));
len = atoi(fz_strsep(&s, " "));
@@ -244,14 +207,11 @@ pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
if (s && *s != '\0')
{
fz_warn("broken xref section. proceeding anyway.");
- error = fz_seek(xref->file, -(2 + (int)strlen(s)), 1);
- if (error)
- return fz_rethrow(error, "cannot seek to xref");
+ fz_seek(xref->file, -(2 + (int)strlen(s)), 1);
}
- /* broken pdfs where size in trailer undershoots
- entries in xref sections */
- if ((ofs + len) > xref->cap)
+ /* broken pdfs where size in trailer undershoots entries in xref sections */
+ if (ofs + len > xref->cap)
{
fz_warn("broken xref section, proceeding anyway.");
xref->cap = ofs + len;
@@ -273,9 +233,9 @@ pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
for (i = ofs; i < ofs + len; i++)
{
- error = fz_read(&n, xref->file, (unsigned char *) buf, 20);
- if (error)
- return fz_rethrow(error, "cannot read xref table");
+ n = fz_read(xref->file, (unsigned char *) buf, 20);
+ if (n < 0)
+ return fz_rethrow(n, "cannot read xref table");
if (!xref->table[i].type)
{
s = buf;
@@ -315,7 +275,6 @@ pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
static fz_error
pdf_readnewxrefsection(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0, int w1, int w2)
{
- fz_error error;
int i, n;
if (i0 < 0 || i0 + i1 > xref->len)
@@ -328,12 +287,7 @@ pdf_readnewxrefsection(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0, i
int c = 0;
if (fz_peekbyte(stm) == EOF)
- {
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "truncated xref stream");
return fz_throw("truncated xref stream");
- }
for (n = 0; n < w0; n++)
a = (a << 8) + fz_readbyte(stm);
@@ -342,10 +296,6 @@ pdf_readnewxrefsection(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0, i
for (n = 0; n < w2; n++)
c = (c << 8) + fz_readbyte(stm);
- error = fz_readerror(stm);
- if (error)
- return fz_rethrow(error, "truncated xref stream");
-
if (!xref->table[i].type)
{
int t = w0 ? a : 1;
@@ -447,7 +397,7 @@ pdf_readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
error = pdf_readnewxrefsection(xref, stm, 0, size, w0, w1, w2);
if (error)
{
- fz_dropstream(stm);
+ fz_close(stm);
fz_dropobj(trailer);
return fz_rethrow(error, "cannot read xref stream (%d %d R)", num, gen);
}
@@ -461,14 +411,14 @@ pdf_readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
error = pdf_readnewxrefsection(xref, stm, i0, i1, w0, w1, w2);
if (error)
{
- fz_dropstream(stm);
+ fz_close(stm);
fz_dropobj(trailer);
return fz_rethrow(error, "cannot read xref stream section (%d %d R)", num, gen);
}
}
}
- fz_dropstream(stm);
+ fz_close(stm);
*trailerp = trailer;
@@ -481,18 +431,12 @@ pdf_readxref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap)
fz_error error;
int c;
- error = fz_seek(xref->file, ofs, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to xref");
+ fz_seek(xref->file, ofs, 0);
while (iswhite(fz_peekbyte(xref->file)))
fz_readbyte(xref->file);
c = fz_peekbyte(xref->file);
- error = fz_readerror(xref->file);
- if (error)
- return fz_rethrow(error, "cannot read trailer");
-
if (c == 'x')
{
error = pdf_readoldxref(trailerp, xref, buf, cap);
@@ -728,7 +672,7 @@ pdf_freexref(pdf_xref *xref)
}
if (xref->file)
- fz_dropstream(xref->file);
+ fz_close(xref->file);
if (xref->trailer)
fz_dropobj(xref->trailer);
if (xref->crypt)
@@ -812,21 +756,11 @@ pdf_loadobjstm(pdf_xref *xref, int num, int gen, char *buf, int cap)
ofsbuf[i] = atoi(buf);
}
- error = fz_seek(stm, first, 0);
- if (error)
- {
- error = fz_rethrow(error, "cannot seek in object stream (%d %d R)", num, gen);
- goto cleanupstm;
- }
+ fz_seek(stm, first, 0);
for (i = 0; i < count; i++)
{
- error = fz_seek(stm, first + ofsbuf[i], 0);
- if (error)
- {
- error = fz_rethrow(error, "cannot seek in object stream (%d %d R)", num, gen);
- goto cleanupstm;
- }
+ fz_seek(stm, first + ofsbuf[i], 0);
error = pdf_parsestmobj(&obj, xref, stm, buf, cap);
if (error)
@@ -854,14 +788,14 @@ pdf_loadobjstm(pdf_xref *xref, int num, int gen, char *buf, int cap)
}
}
- fz_dropstream(stm);
+ fz_close(stm);
fz_free(ofsbuf);
fz_free(numbuf);
fz_dropobj(objstm);
return fz_okay;
cleanupstm:
- fz_dropstream(stm);
+ fz_close(stm);
cleanupbuf:
fz_free(ofsbuf);
fz_free(numbuf);
@@ -895,9 +829,7 @@ pdf_cacheobject(pdf_xref *xref, int num, int gen)
}
else if (x->type == 'n')
{
- error = fz_seek(xref->file, x->ofs, 0);
- if (error)
- return fz_rethrow(error, "cannot seek to object (%d %d R) offset %d", num, gen, x->ofs);
+ fz_seek(xref->file, x->ofs, 0);
error = pdf_parseindobj(&x->obj, xref, xref->file, xref->scratch, sizeof xref->scratch,
&rnum, &rgen, &x->stmofs);
@@ -987,7 +919,7 @@ pdf_openxref(pdf_xref **xrefp, char *filename, char *password)
error = pdf_openxrefwithstream(&xref, file, password);
if (error)
return fz_rethrow(error, "cannot load document '%s'", filename);
- fz_dropstream(file);
+ fz_close(file);
*xrefp = xref;
return fz_okay;
diff --git a/win32/mupdf/mupdf.vcproj b/win32/mupdf/mupdf.vcproj
index c0d19e3e..ac0af2e9 100644
--- a/win32/mupdf/mupdf.vcproj
+++ b/win32/mupdf/mupdf.vcproj
@@ -381,10 +381,6 @@
>
</File>
<File
- RelativePath="..\..\fitz\filt_pipeline.c"
- >
- </File>
- <File
RelativePath="..\..\fitz\filt_predict.c"
>
</File>
@@ -437,10 +433,6 @@
>
</File>
<File
- RelativePath="..\..\fitz\stm_filter.c"
- >
- </File>
- <File
RelativePath="..\..\fitz\stm_open.c"
>
</File>