summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/stream.h90
-rw-r--r--platform/x11/curl_stream.c35
-rw-r--r--source/fitz/filter-basic.c268
-rw-r--r--source/fitz/filter-dct.c25
-rw-r--r--source/fitz/filter-fax.c54
-rw-r--r--source/fitz/filter-flate.c35
-rw-r--r--source/fitz/filter-jbig2.c19
-rw-r--r--source/fitz/filter-lzw.c23
-rw-r--r--source/fitz/filter-predict.c23
-rw-r--r--source/fitz/stream-open.c85
-rw-r--r--source/fitz/stream-prog.c19
-rw-r--r--source/fitz/stream-read.c97
-rw-r--r--source/pdf/pdf-op-run.c25
13 files changed, 492 insertions, 306 deletions
diff --git a/include/mupdf/fitz/stream.h b/include/mupdf/fitz/stream.h
index 206ba5be..9f38ea17 100644
--- a/include/mupdf/fitz/stream.h
+++ b/include/mupdf/fitz/stream.h
@@ -138,7 +138,7 @@ int fz_stream_meta(fz_stream *stm, int key, int size, void *ptr);
void fz_rebind_stream(fz_stream *stm, fz_context *ctx);
-typedef int (fz_stream_read_fn)(fz_stream *stm, unsigned char *buf, int len);
+typedef int (fz_stream_next_fn)(fz_stream *stm, int max);
typedef void (fz_stream_close_fn)(fz_context *ctx, void *state);
typedef void (fz_stream_seek_fn)(fz_stream *stm, int offset, int whence);
typedef int (fz_stream_meta_fn)(fz_stream *stm, int key, int size, void *ptr);
@@ -153,23 +153,21 @@ struct fz_stream_s
int pos;
int avail;
int bits;
- unsigned char *bp, *rp, *wp, *ep;
+ unsigned char *rp, *wp;
void *state;
- fz_stream_read_fn *read;
+ fz_stream_next_fn *next;
fz_stream_close_fn *close;
fz_stream_seek_fn *seek;
fz_stream_meta_fn *meta;
fz_stream_rebind_fn *rebind;
- unsigned char buf[4096];
};
fz_stream *fz_new_stream(fz_context *ctx,
void *state,
- fz_stream_read_fn *read,
+ fz_stream_next_fn *next,
fz_stream_close_fn *close,
fz_stream_rebind_fn *rebind);
fz_stream *fz_keep_stream(fz_stream *stm);
-void fz_fill_buffer(fz_stream *stm);
/*
fz_read_best: Attempt to read a stream into a buffer. If truncated
@@ -188,30 +186,86 @@ fz_buffer *fz_read_best(fz_stream *stm, int initial, int *truncated);
void fz_read_line(fz_stream *stm, char *buf, int max);
-static inline int fz_read_byte(fz_stream *stm)
+/*
+ fz_available: Ask how many bytes are available immediately from
+ a given stream.
+
+ stm: The stream to read from.
+
+ max: A hint for the underlying stream; the maximum number of
+ bytes that we are sure we will want to read. If you do not know
+ this number, give 1.
+
+ Returns the number of bytes immediately available between the
+ read and write pointers. This number is guaranteed only to be 0
+ if we have hit EOF. The number of bytes returned here need have
+ no relation to max (could be larger, could be smaller).
+*/
+static inline int fz_available(fz_stream *stm, int max)
{
- if (stm->rp == stm->wp)
+ int len = stm->wp - stm->rp;
+ int c;
+
+ if (len)
+ return len;
+ fz_try(stm->ctx)
+ {
+ c = stm->next(stm, max);
+ }
+ fz_catch(stm->ctx)
{
- fz_fill_buffer(stm);
- return stm->rp < stm->wp ? *stm->rp++ : EOF;
+ fz_rethrow_if(stm->ctx, FZ_ERROR_TRYLATER);
+ fz_warn(stm->ctx, "read error; treating as end of file");
+ stm->error = 1;
+ c = EOF;
}
- return *stm->rp++;
+ if (c == EOF)
+ {
+ stm->eof = 1;
+ return 0;
+ }
+ stm->rp--;
+ return stm->wp - stm->rp;
}
-static inline int fz_peek_byte(fz_stream *stm)
+static inline int fz_read_byte(fz_stream *stm)
{
- if (stm->rp == stm->wp)
+ int c;
+
+ if (stm->rp != stm->wp)
+ return *stm->rp++;
+ fz_try(stm->ctx)
{
- fz_fill_buffer(stm);
- return stm->rp < stm->wp ? *stm->rp : EOF;
+ c = stm->next(stm, 1);
}
- return *stm->rp;
+ fz_catch(stm->ctx)
+ {
+ fz_rethrow_if(stm->ctx, FZ_ERROR_TRYLATER);
+ fz_warn(stm->ctx, "read error; treating as end of file");
+ stm->error = 1;
+ c = EOF;
+ }
+ if (c == EOF)
+ stm->eof = 1;
+ return c;
}
-static inline void fz_unread_byte(fz_stream *stm)
+static inline int fz_peek_byte(fz_stream *stm)
{
- if (stm->rp > stm->bp)
+ int c;
+
+ if (stm->rp != stm->wp)
+ return *stm->rp;
+
+ c = stm->next(stm, 1);
+ if (c != EOF)
stm->rp--;
+ return c;
+}
+
+static inline void fz_unread_byte(fz_stream *stm)
+{
+ stm->rp--;
}
static inline int fz_is_eof(fz_stream *stm)
diff --git a/platform/x11/curl_stream.c b/platform/x11/curl_stream.c
index fe8ece66..d90ce288 100644
--- a/platform/x11/curl_stream.c
+++ b/platform/x11/curl_stream.c
@@ -46,6 +46,8 @@ struct curl_stream_state_s
void (*more_data)(void *, int);
void *more_data_arg;
+ unsigned char public_buffer[4096];
+
#ifdef _WIN32
void *thread;
DWORD thread_id;
@@ -311,13 +313,17 @@ fetcher_thread(curl_stream_state *state)
}
static int
-stream_read(fz_stream *stream, unsigned char *buf, int len)
+stream_next(fz_stream *stream, int len)
{
curl_stream_state *state = (curl_stream_state *)stream->state;
int len_read = 0;
int read_point = stream->pos;
int block = read_point>>BLOCK_SHIFT;
int left_over = (-read_point) & (BLOCK_SIZE-1);
+ unsigned char *buf = state->public_buffer;
+
+ if (len > sizeof(state->public_buffer))
+ len = sizeof(state->public_buffer);
if (state->content_length == 0)
fz_throw(stream->ctx, FZ_ERROR_TRYLATER, "read of a block we don't have (A) (offset=%d)", read_point);
@@ -328,11 +334,16 @@ stream_read(fz_stream *stream, unsigned char *buf, int len)
* content length. */
if (read_point + len > state->current_fill_point)
{
- stream->rp = stream->wp = stream->bp;
+ stream->rp = stream->wp;
fz_throw(stream->ctx, FZ_ERROR_TRYLATER, "read of a block we don't have (B) (offset=%d)", read_point);
}
memcpy(buf, state->buffer + read_point, len);
- return len;
+ stream->rp = buf;
+ stream->wp = buf + len;
+ stream->pos += len;
+ if (len == 0)
+ return EOF;
+ return *stream->rp++;
}
if (read_point + len > state->content_length)
@@ -348,7 +359,7 @@ stream_read(fz_stream *stream, unsigned char *buf, int len)
lock(state);
state->fill_point = block;
unlock(state);
- stream->rp = stream->wp = stream->bp;
+ stream->rp = stream->wp;
fz_throw(stream->ctx, FZ_ERROR_TRYLATER, "read of a block we don't have (C) (offset=%d)", read_point);
}
block++;
@@ -369,7 +380,7 @@ stream_read(fz_stream *stream, unsigned char *buf, int len)
lock(state);
state->fill_point = block;
unlock(state);
- stream->rp = stream->wp = stream->bp;
+ stream->rp = stream->wp;
fz_throw(stream->ctx, FZ_ERROR_TRYLATER, "read of a block we don't have (D) (offset=%d)", read_point);
}
block++;
@@ -388,14 +399,18 @@ stream_read(fz_stream *stream, unsigned char *buf, int len)
lock(state);
state->fill_point = block;
unlock(state);
- stream->rp = stream->wp = stream->bp;
+ stream->rp = stream->wp;
fz_throw(stream->ctx, FZ_ERROR_TRYLATER, "read of a block we don't have (E) (offset=%d)", read_point);
}
memcpy(buf, state->buffer + read_point, len);
len_read += len;
}
-
- return len_read;
+ stream->rp = state->public_buffer;
+ stream->wp = stream->rp + len_read;
+ stream->pos += len_read;
+ if (len_read == 0)
+ return EOF;
+ return *stream->rp++;
}
static void
@@ -449,7 +464,7 @@ stream_seek(fz_stream *stream, int offset, int whence)
offset = 0;
else if (state->content_length > 0 && offset > state->content_length)
offset = state->content_length;
- stream->wp = stream->rp = stream->bp;
+ stream->wp = stream->rp;
stream->pos = offset;
hack = *state;
hack_pos = offset;
@@ -518,7 +533,7 @@ fz_stream *fz_stream_from_curl(fz_context *ctx, char *filename, void (*more_data
#endif
- stream = fz_new_stream(ctx, state, stream_read, stream_close, NULL);
+ stream = fz_new_stream(ctx, state, stream_next, stream_close, NULL);
stream->seek = stream_seek;
stream->meta = stream_meta;
return stream;
diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c
index 3a64ee93..5defe066 100644
--- a/source/fitz/filter-basic.c
+++ b/source/fitz/filter-basic.c
@@ -14,21 +14,34 @@ struct null_filter
{
fz_stream *chain;
int remain;
- int pos;
+ int offset;
+ unsigned char buffer[4096];
};
static int
-read_null(fz_stream *stm, unsigned char *buf, int len)
+next_null(fz_stream *stm, int max)
{
struct null_filter *state = stm->state;
- int amount = fz_mini(len, state->remain);
int n;
- fz_seek(state->chain, state->pos, 0);
- n = fz_read(state->chain, buf, amount);
+ if (state->remain == 0)
+ return EOF;
+ fz_seek(state->chain, state->offset, 0);
+ n = fz_available(state->chain, max);
+ if (n > state->remain)
+ n = state->remain;
+ if (n > sizeof(state->buffer))
+ n = sizeof(state->buffer);
+ memcpy(state->buffer, state->chain->rp, n);
+ stm->rp = state->buffer;
+ stm->wp = stm->rp + n;
+ if (n == 0)
+ return EOF;
+ state->chain->rp += n;
state->remain -= n;
- state->pos += n;
- return n;
+ state->offset += n;
+ stm->pos += n;
+ return *stm->rp++;
}
static void
@@ -60,7 +73,7 @@ fz_open_null(fz_stream *chain, int len, int offset)
state = fz_malloc_struct(ctx, struct null_filter);
state->chain = chain;
state->remain = len;
- state->pos = offset;
+ state->offset = offset;
}
fz_catch(ctx)
{
@@ -68,7 +81,7 @@ fz_open_null(fz_stream *chain, int len, int offset)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_null, close_null, rebind_null);
+ return fz_new_stream(ctx, state, next_null, close_null, rebind_null);
}
/* Concat filter concatenates several streams into one */
@@ -79,48 +92,51 @@ struct concat_filter
int count;
int current;
int pad; /* 1 if we should add whitespace padding between streams */
- int ws; /* 1 if we should send a whitespace padding byte next */
+ unsigned char ws_buf;
fz_stream *chain[1];
};
static int
-read_concat(fz_stream *stm, unsigned char *buf, int len)
+next_concat(fz_stream *stm, int max)
{
struct concat_filter *state = (struct concat_filter *)stm->state;
int n;
- int read = 0;
- if (len <= 0)
- return 0;
-
- while (state->current != state->count && len > 0)
+ while (state->current < state->count)
{
- /* If we need to send a whitespace char, do that */
- if (state->ws)
+ /* Read the next block of underlying data. */
+ if (stm->wp == state->chain[state->current]->wp)
+ state->chain[state->current]->rp = stm->wp;
+ n = fz_available(state->chain[state->current], max);
+ if (n)
{
- *buf++ = 32;
- read++;
- len--;
- state->ws = 0;
- continue;
+ stm->rp = state->chain[state->current]->rp;
+ stm->wp = state->chain[state->current]->wp;
+ stm->pos += n;
+ return *stm->rp++;
}
- /* Otherwise, read as much data as will fit in the buffer */
- n = fz_read(state->chain[state->current], buf, len);
- read += n;
- buf += n;
- len -= n;
- /* If we didn't read any, then we must have hit the end of
- * our buffer space. Move to the next stream, and remember to
- * pad. */
- if (n == 0)
+ else
{
- fz_close(state->chain[state->current]);
+ if (state->chain[state->current]->error)
+ {
+ stm->error = 1;
+ break;
+ }
state->current++;
- state->ws = state->pad;
+ fz_close(state->chain[state->current-1]);
+ if (state->pad)
+ {
+ stm->rp = &state->ws_buf;
+ stm->wp = stm->rp + 1;
+ stm->pos++;
+ return 32;
+ }
}
}
- return read;
+ stm->rp = stm->wp;
+
+ return EOF;
}
static void
@@ -161,9 +177,9 @@ fz_open_concat(fz_context *ctx, int len, int pad)
state->count = 0;
state->current = 0;
state->pad = pad;
- state->ws = 0; /* We never send padding byte at the start */
+ state->ws_buf = 32;
- return fz_new_stream(ctx, state, read_concat, close_concat, rebind_concat);
+ return fz_new_stream(ctx, state, next_concat, close_concat, rebind_concat);
}
void
@@ -185,6 +201,7 @@ struct fz_ahxd_s
{
fz_stream *chain;
int eod;
+ unsigned char buffer[256];
};
static inline int iswhite(int a)
@@ -213,23 +230,27 @@ static inline int unhex(int a)
}
static int
-read_ahxd(fz_stream *stm, unsigned char *buf, int len)
+next_ahxd(fz_stream *stm, int max)
{
fz_ahxd *state = stm->state;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = state->buffer;
+ unsigned char *ep;
int a, b, c, odd;
+ if (max > sizeof(state->buffer))
+ max = sizeof(state->buffer);
+ ep = p + max;
+
odd = 0;
while (p < ep)
{
if (state->eod)
- return p - buf;
+ break;
c = fz_read_byte(state->chain);
if (c < 0)
- return p - buf;
+ break;
if (ishex(c))
{
@@ -250,14 +271,20 @@ read_ahxd(fz_stream *stm, unsigned char *buf, int len)
if (odd)
*p++ = (a << 4);
state->eod = 1;
+ break;
}
else if (!iswhite(c))
{
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "bad data in ahxd: '%c'", c);
}
}
+ stm->rp = state->buffer;
+ stm->wp = p;
+ stm->pos += p - state->buffer;
- return p - buf;
+ if (stm->rp != p)
+ return *stm->rp++;
+ return EOF;
}
static void
@@ -294,7 +321,7 @@ fz_open_ahxd(fz_stream *chain)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_ahxd, close_ahxd, rebind_ahxd);
+ return fz_new_stream(ctx, state, next_ahxd, close_ahxd, rebind_ahxd);
}
/* ASCII 85 Decode */
@@ -304,32 +331,32 @@ typedef struct fz_a85d_s fz_a85d;
struct fz_a85d_s
{
fz_stream *chain;
- unsigned char bp[4];
- unsigned char *rp, *wp;
+ unsigned char buffer[256];
int eod;
};
static int
-read_a85d(fz_stream *stm, unsigned char *buf, int len)
+next_a85d(fz_stream *stm, int max)
{
fz_a85d *state = stm->state;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = state->buffer;
+ unsigned char *ep;
int count = 0;
int word = 0;
int c;
- while (state->rp < state->wp && p < ep)
- *p++ = *state->rp++;
+ if (state->eod)
+ return EOF;
+
+ if (max > sizeof(state->buffer))
+ max = sizeof(state->buffer);
+ ep = p + max;
while (p < ep)
{
- if (state->eod)
- return p - buf;
-
c = fz_read_byte(state->chain);
if (c < 0)
- return p - buf;
+ break;
if (c >= '!' && c <= 'u')
{
@@ -337,12 +364,10 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len)
{
word = word * 85 + (c - '!');
- state->bp[0] = (word >> 24) & 0xff;
- state->bp[1] = (word >> 16) & 0xff;
- state->bp[2] = (word >> 8) & 0xff;
- state->bp[3] = (word) & 0xff;
- state->rp = state->bp;
- state->wp = state->bp + 4;
+ *p++ = (word >> 24) & 0xff;
+ *p++ = (word >> 16) & 0xff;
+ *p++ = (word >> 8) & 0xff;
+ *p++ = (word) & 0xff;
word = 0;
count = 0;
@@ -356,12 +381,10 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len)
else if (c == 'z' && count == 0)
{
- state->bp[0] = 0;
- state->bp[1] = 0;
- state->bp[2] = 0;
- state->bp[3] = 0;
- state->rp = state->bp;
- state->wp = state->bp + 4;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
}
else if (c == '~')
@@ -381,39 +404,38 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len)
break;
case 2:
word = word * (85 * 85 * 85) + 0xffffff;
- state->bp[0] = word >> 24;
- state->rp = state->bp;
- state->wp = state->bp + 1;
+ *p++ = word >> 24;
break;
case 3:
word = word * (85 * 85) + 0xffff;
- state->bp[0] = word >> 24;
- state->bp[1] = word >> 16;
- state->rp = state->bp;
- state->wp = state->bp + 2;
+ *p++ = word >> 24;
+ *p++ = word >> 16;
break;
case 4:
word = word * 85 + 0xff;
- state->bp[0] = word >> 24;
- state->bp[1] = word >> 16;
- state->bp[2] = word >> 8;
- state->rp = state->bp;
- state->wp = state->bp + 3;
+ *p++ = word >> 24;
+ *p++ = word >> 16;
+ *p++ = word >> 8;
break;
}
state->eod = 1;
+ break;
}
else if (!iswhite(c))
{
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "bad data in a85d: '%c'", c);
}
-
- while (state->rp < state->wp && p < ep)
- *p++ = *state->rp++;
}
- return p - buf;
+ stm->rp = state->buffer;
+ stm->wp = p;
+ stm->pos += p - state->buffer;
+
+ if (p == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
}
static void
@@ -443,8 +465,6 @@ fz_open_a85d(fz_stream *chain)
{
state = fz_malloc_struct(ctx, fz_a85d);
state->chain = chain;
- state->rp = state->bp;
- state->wp = state->bp;
state->eod = 0;
}
fz_catch(ctx)
@@ -453,7 +473,7 @@ fz_open_a85d(fz_stream *chain)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_a85d, close_a85d, rebind_a85d);
+ return fz_new_stream(ctx, state, next_a85d, close_a85d, rebind_a85d);
}
/* Run Length Decode */
@@ -464,25 +484,36 @@ struct fz_rld_s
{
fz_stream *chain;
int run, n, c;
+ unsigned char buffer[256];
};
static int
-read_rld(fz_stream *stm, unsigned char *buf, int len)
+next_rld(fz_stream *stm, int max)
{
fz_rld *state = stm->state;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = state->buffer;
+ unsigned char *ep;
+
+ if (state->run == 128)
+ return EOF;
+
+ if (max > sizeof(state->buffer))
+ max = sizeof(state->buffer);
+ ep = p + max;
while (p < ep)
{
if (state->run == 128)
- return p - buf;
+ break;
if (state->n == 0)
{
state->run = fz_read_byte(state->chain);
if (state->run < 0)
+ {
state->run = 128;
+ break;
+ }
if (state->run < 128)
state->n = state->run + 1;
if (state->run > 128)
@@ -516,7 +547,14 @@ read_rld(fz_stream *stm, unsigned char *buf, int len)
}
}
- return p - buf;
+ stm->rp = state->buffer;
+ stm->wp = p;
+ stm->pos += p - state->buffer;
+
+ if (p == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
}
static void
@@ -556,7 +594,7 @@ fz_open_rld(fz_stream *chain)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_rld, close_rld, rebind_rld);
+ return fz_new_stream(ctx, state, next_rld, close_rld, rebind_rld);
}
/* RC4 Filter */
@@ -567,15 +605,27 @@ struct fz_arc4c_s
{
fz_stream *chain;
fz_arc4 arc4;
+ unsigned char buffer[256];
};
static int
-read_arc4(fz_stream *stm, unsigned char *buf, int len)
+next_arc4(fz_stream *stm, int max)
{
fz_arc4c *state = stm->state;
- int n = fz_read(state->chain, buf, len);
- fz_arc4_encrypt(&state->arc4, buf, buf, n);
- return n;
+ int n = fz_available(state->chain, max);
+
+ if (n == 0)
+ return EOF;
+ if (n > sizeof(state->buffer))
+ n = sizeof(state->buffer);
+
+ stm->rp = state->buffer;
+ stm->wp = state->buffer + n;
+ fz_arc4_encrypt(&state->arc4, stm->rp, state->chain->rp, n);
+ state->chain->rp += n;
+ stm->pos += n;
+
+ return *stm->rp++;
}
static void
@@ -613,7 +663,7 @@ fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_arc4, close_arc4, rebind_arc4c);
+ return fz_new_stream(ctx, state, next_arc4, close_arc4, rebind_arc4c);
}
/* AES Filter */
@@ -628,14 +678,19 @@ struct fz_aesd_s
int ivcount;
unsigned char bp[16];
unsigned char *rp, *wp;
+ unsigned char buffer[256];
};
static int
-read_aesd(fz_stream *stm, unsigned char *buf, int len)
+next_aesd(fz_stream *stm, int max)
{
fz_aesd *state = stm->state;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = state->buffer;
+ unsigned char *ep;
+
+ if (max > sizeof(state->buffer))
+ max = sizeof(state->buffer);
+ ep = p + max;
while (state->ivcount < 16)
{
@@ -652,7 +707,7 @@ read_aesd(fz_stream *stm, unsigned char *buf, int len)
{
int n = fz_read(state->chain, state->bp, 16);
if (n == 0)
- return p - buf;
+ break;
else if (n < 16)
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "partial block in aes filter");
@@ -673,7 +728,14 @@ read_aesd(fz_stream *stm, unsigned char *buf, int len)
*p++ = *state->rp++;
}
- return p - buf;
+ stm->rp = state->buffer;
+ stm->wp = p;
+ stm->pos += p - state->buffer;
+
+ if (p == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
}
static void
@@ -718,5 +780,5 @@ fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_aesd, close_aesd, rebind_aesd);
+ return fz_new_stream(ctx, state, next_aesd, close_aesd, rebind_aesd);
}
diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c
index 23665909..86268032 100644
--- a/source/fitz/filter-dct.c
+++ b/source/fitz/filter-dct.c
@@ -22,6 +22,8 @@ struct fz_dctd_s
struct jpeg_error_mgr errmgr;
jmp_buf jb;
char msg[JMSG_LENGTH_MAX];
+
+ unsigned char buffer[4096];
};
static void error_exit(j_common_ptr cinfo)
@@ -48,10 +50,11 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo)
fz_stream *curr_stm = state->curr_stm;
fz_context *ctx = curr_stm->ctx;
+
curr_stm->rp = curr_stm->wp;
fz_try(ctx)
{
- fz_fill_buffer(curr_stm);
+ src->bytes_in_buffer = fz_available(curr_stm, 1);
}
fz_catch(ctx)
{
@@ -59,7 +62,6 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo)
return 0;
}
src->next_input_byte = curr_stm->rp;
- src->bytes_in_buffer = curr_stm->wp - curr_stm->rp;
if (src->bytes_in_buffer == 0)
{
@@ -88,12 +90,16 @@ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
}
static int
-read_dctd(fz_stream *stm, unsigned char *buf, int len)
+next_dctd(fz_stream *stm, int max)
{
fz_dctd *state = stm->state;
j_decompress_ptr cinfo = &state->cinfo;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = state->buffer;
+ unsigned char *ep;
+
+ if (max > sizeof(state->buffer))
+ max = sizeof(state->buffer);
+ ep = state->buffer + max;
if (setjmp(state->jb))
{
@@ -202,8 +208,13 @@ read_dctd(fz_stream *stm, unsigned char *buf, int len)
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
}
+ stm->rp = state->buffer;
+ stm->wp = p;
+ stm->pos += (p - state->buffer);
+ if (p == stm->rp)
+ return EOF;
- return p - buf;
+ return *stm->rp++;
}
static void
@@ -267,5 +278,5 @@ fz_open_dctd(fz_stream *chain, int color_transform, int l2factor, fz_stream *jpe
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_dctd, close_dctd, rebind_dctd);
+ return fz_new_stream(ctx, state, next_dctd, close_dctd, rebind_dctd);
}
diff --git a/source/fitz/filter-fax.c b/source/fitz/filter-fax.c
index 7b35c812..70692338 100644
--- a/source/fitz/filter-fax.c
+++ b/source/fitz/filter-fax.c
@@ -344,6 +344,8 @@ struct fz_faxd_s
unsigned char *ref;
unsigned char *dst;
unsigned char *rp, *wp;
+
+ unsigned char buffer[4096];
};
static inline void eat_bits(fz_faxd *fax, int nbits)
@@ -355,7 +357,10 @@ static inline void eat_bits(fz_faxd *fax, int nbits)
static int
fill_bits(fz_faxd *fax)
{
- while (fax->bidx >= 8)
+ /* The longest length of bits we'll ever need is 13. Never read more
+ * than we need to avoid unnecessary overreading of the end of the
+ * stream. */
+ while (fax->bidx > (32-13))
{
int c = fz_read_byte(fax->chain);
if (c == EOF)
@@ -551,14 +556,17 @@ dec2d(fz_context *ctx, fz_faxd *fax)
}
static int
-read_faxd(fz_stream *stm, unsigned char *buf, int len)
+next_faxd(fz_stream *stm, int max)
{
fz_context *ctx = stm->ctx;
fz_faxd *fax = stm->state;
- unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *p = fax->buffer;
+ unsigned char *ep;
unsigned char *tmp;
+ if (max > sizeof(fax->buffer))
+ max = sizeof(fax->buffer);
+ ep = p + max;
if (fax->stage == STATE_INIT && fax->end_of_line)
{
fill_bits(fax);
@@ -576,7 +584,7 @@ read_faxd(fz_stream *stm, unsigned char *buf, int len)
fax->stage = STATE_NORMAL;
if (fax->stage == STATE_DONE)
- return 0;
+ return EOF;
if (fax->stage == STATE_EOL)
goto eol;
@@ -679,7 +687,14 @@ eol:
}
if (fax->rp < fax->wp)
- return p - buf;
+ {
+ stm->rp = fax->buffer;
+ stm->wp = p;
+ stm->pos += (p - fax->buffer);
+ if (p == fax->buffer)
+ return EOF;
+ return *stm->rp++;
+ }
tmp = fax->ref;
fax->ref = fax->dst;
@@ -694,11 +709,8 @@ eol:
fax->a = -1;
fax->ridx ++;
- if (!fax->end_of_block && fax->rows)
- {
- if (fax->ridx >= fax->rows)
- goto rtc;
- }
+ if (!fax->end_of_block && fax->rows && fax->ridx >= fax->rows)
+ goto rtc;
/* we have not read dim from eol, make a guess */
if (fax->k > 0 && !fax->eolc && fax->a == -1)
@@ -719,8 +731,15 @@ eol:
}
/* no more space in output, don't decode the next row yet */
- if (p == buf + len)
- return p - buf;
+ if (p == fax->buffer + max)
+ {
+ stm->rp = fax->buffer;
+ stm->wp = p;
+ stm->pos += (p - fax->buffer);
+ if (p == fax->buffer)
+ return EOF;
+ return *stm->rp++;
+ }
goto loop;
@@ -740,7 +759,12 @@ error:
rtc:
fax->stage = STATE_DONE;
- return p - buf;
+ stm->rp = fax->buffer;
+ stm->wp = p;
+ stm->pos += (p - fax->buffer);
+ if (p == fax->buffer)
+ return EOF;
+ return *stm->rp++;
}
static void
@@ -828,5 +852,5 @@ fz_open_faxd(fz_stream *chain,
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, fax, read_faxd, close_faxd, rebind_faxd);
+ return fz_new_stream(ctx, fax, next_faxd, close_faxd, rebind_faxd);
}
diff --git a/source/fitz/filter-flate.c b/source/fitz/filter-flate.c
index 022cdb12..b306c9c3 100644
--- a/source/fitz/filter-flate.c
+++ b/source/fitz/filter-flate.c
@@ -8,6 +8,7 @@ struct fz_flate_s
{
fz_stream *chain;
z_stream z;
+ unsigned char buffer[4096];
};
static void *zalloc(void *opaque, unsigned int items, unsigned int size)
@@ -21,23 +22,27 @@ static void zfree(void *opaque, void *ptr)
}
static int
-read_flated(fz_stream *stm, unsigned char *outbuf, int outlen)
+next_flated(fz_stream *stm, int outlen)
{
fz_flate *state = stm->state;
fz_stream *chain = state->chain;
z_streamp zp = &state->z;
int code;
+ unsigned char *outbuf = state->buffer;
+
+ if (outlen > sizeof(state->buffer))
+ outlen = sizeof(state->buffer);
+
+ if (stm->eof)
+ return EOF;
zp->next_out = outbuf;
zp->avail_out = outlen;
while (zp->avail_out > 0)
{
- if (chain->rp == chain->wp)
- fz_fill_buffer(chain);
-
+ zp->avail_in = fz_available(chain, 1);
zp->next_in = chain->rp;
- zp->avail_in = chain->wp - chain->rp;
code = inflate(zp, Z_SYNC_FLUSH);
@@ -45,23 +50,23 @@ read_flated(fz_stream *stm, unsigned char *outbuf, int outlen)
if (code == Z_STREAM_END)
{
- return outlen - zp->avail_out;
+ break;
}
else if (code == Z_BUF_ERROR)
{
fz_warn(stm->ctx, "premature end of data in flate filter");
- return outlen - zp->avail_out;
+ break;
}
else if (code == Z_DATA_ERROR && zp->avail_in == 0)
{
fz_warn(stm->ctx, "ignoring zlib error: %s", zp->msg);
- return outlen - zp->avail_out;
+ break;
}
else if (code == Z_DATA_ERROR && !strcmp(zp->msg, "incorrect data check"))
{
fz_warn(stm->ctx, "ignoring zlib error: %s", zp->msg);
chain->rp = chain->wp;
- return outlen - zp->avail_out;
+ break;
}
else if (code != Z_OK)
{
@@ -69,7 +74,15 @@ read_flated(fz_stream *stm, unsigned char *outbuf, int outlen)
}
}
- return outlen - zp->avail_out;
+ stm->rp = state->buffer;
+ stm->wp = state->buffer + outlen - zp->avail_out;
+ stm->pos += outlen - zp->avail_out;
+ if (stm->rp == stm->wp)
+ {
+ stm->eof = 1;
+ return EOF;
+ }
+ return *stm->rp++;
}
static void
@@ -126,5 +139,5 @@ fz_open_flated(fz_stream *chain)
fz_close(chain);
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_flated, close_flated, rebind_flated);
+ return fz_new_stream(ctx, state, next_flated, close_flated, rebind_flated);
}
diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c
index 592f7ab6..98919dcb 100644
--- a/source/fitz/filter-jbig2.c
+++ b/source/fitz/filter-jbig2.c
@@ -17,6 +17,7 @@ struct fz_jbig2d_s
fz_jbig2_globals *gctx;
Jbig2Image *page;
int idx;
+ unsigned char buffer[4096];
};
static void
@@ -39,15 +40,20 @@ close_jbig2d(fz_context *ctx, void *state_)
}
static int
-read_jbig2d(fz_stream *stm, unsigned char *buf, int len)
+next_jbig2d(fz_stream *stm, int len)
{
fz_jbig2d *state = stm->state;
unsigned char tmp[4096];
+ unsigned char *buf = state->buffer;
unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *ep;
unsigned char *s;
int x, w, n;
+ if (len > sizeof(state->buffer))
+ len = sizeof(state->buffer);
+ ep = buf + len;
+
if (!state->page)
{
while (1)
@@ -72,7 +78,12 @@ read_jbig2d(fz_stream *stm, unsigned char *buf, int len)
*p++ = s[x++] ^ 0xff;
state->idx = x;
- return p - buf;
+ stm->rp = buf;
+ stm->wp = p;
+ if (p == buf)
+ return EOF;
+ stm->pos += p - buf;
+ return *stm->rp++;
}
static fz_stream *
@@ -146,5 +157,5 @@ fz_open_jbig2d(fz_stream *chain, fz_jbig2_globals *globals)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d, rebind_jbig2d);
+ return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d, rebind_jbig2d);
}
diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c
index c78c8c3f..e13b0ef0 100644
--- a/source/fitz/filter-lzw.c
+++ b/source/fitz/filter-lzw.c
@@ -41,15 +41,18 @@ struct fz_lzwd_s
unsigned char bp[MAX_LENGTH];
unsigned char *rp, *wp;
+
+ unsigned char buffer[4096];
};
static int
-read_lzwd(fz_stream *stm, unsigned char *buf, int len)
+next_lzwd(fz_stream *stm, int len)
{
fz_lzwd *lzw = stm->state;
lzw_code *table = lzw->table;
+ unsigned char *buf = lzw->buffer;
unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *ep;
unsigned char *s;
int codelen;
@@ -58,13 +61,17 @@ read_lzwd(fz_stream *stm, unsigned char *buf, int len)
int old_code = lzw->old_code;
int next_code = lzw->next_code;
+ if (len > sizeof(lzw->buffer))
+ len = sizeof(lzw->buffer);
+ ep = buf + len;
+
while (lzw->rp < lzw->wp && p < ep)
*p++ = *lzw->rp++;
while (p < ep)
{
if (lzw->eod)
- return 0;
+ return EOF;
code = fz_read_bits(lzw->chain, code_bits);
@@ -162,7 +169,13 @@ read_lzwd(fz_stream *stm, unsigned char *buf, int len)
lzw->old_code = old_code;
lzw->next_code = next_code;
- return p - buf;
+ stm->rp = buf;
+ stm->wp = p;
+ if (buf == p)
+ return EOF;
+ stm->pos += p - buf;
+
+ return *stm->rp++;
}
static void
@@ -228,5 +241,5 @@ fz_open_lzwd(fz_stream *chain, int early_change)
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, lzw, read_lzwd, close_lzwd, rebind_lzwd);
+ return fz_new_stream(ctx, lzw, next_lzwd, close_lzwd, rebind_lzwd);
}
diff --git a/source/fitz/filter-predict.c b/source/fitz/filter-predict.c
index 66101753..6862f8c9 100644
--- a/source/fitz/filter-predict.c
+++ b/source/fitz/filter-predict.c
@@ -19,6 +19,8 @@ struct fz_predict_s
unsigned char *out;
unsigned char *ref;
unsigned char *rp, *wp;
+
+ unsigned char buffer[4096];
};
static inline int getcomponent(unsigned char *line, int x, int bpc)
@@ -143,14 +145,19 @@ fz_predict_png(fz_predict *state, unsigned char *out, unsigned char *in, int len
}
static int
-read_predict(fz_stream *stm, unsigned char *buf, int len)
+next_predict(fz_stream *stm, int len)
{
fz_predict *state = stm->state;
+ unsigned char *buf = state->buffer;
unsigned char *p = buf;
- unsigned char *ep = buf + len;
+ unsigned char *ep;
int ispng = state->predictor >= 10;
int n;
+ if (len >= sizeof(state->buffer))
+ len = sizeof(state->buffer);
+ ep = buf + len;
+
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
@@ -158,7 +165,7 @@ read_predict(fz_stream *stm, unsigned char *buf, int len)
{
n = fz_read(state->chain, state->in, state->stride + ispng);
if (n == 0)
- return p - buf;
+ break;
if (state->predictor == 1)
memcpy(state->out, state->in, n);
@@ -177,7 +184,13 @@ read_predict(fz_stream *stm, unsigned char *buf, int len)
*p++ = *state->rp++;
}
- return p - buf;
+ stm->rp = buf;
+ stm->wp = p;
+ if (stm->rp == stm->wp)
+ return EOF;
+ stm->pos += p - buf;
+
+ return *stm->rp++;
}
static void
@@ -267,5 +280,5 @@ fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bp
fz_rethrow(ctx);
}
- return fz_new_stream(ctx, state, read_predict, close_predict, rebind_predict);
+ return fz_new_stream(ctx, state, next_predict, close_predict, rebind_predict);
}
diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c
index f336a4e4..3e51e733 100644
--- a/source/fitz/stream-open.c
+++ b/source/fitz/stream-open.c
@@ -12,7 +12,7 @@ void fz_rebind_stream(fz_stream *stm, fz_context *ctx)
fz_stream *
fz_new_stream(fz_context *ctx, void *state,
- fz_stream_read_fn *read,
+ fz_stream_next_fn *next,
fz_stream_close_fn *close,
fz_stream_rebind_fn *rebind)
{
@@ -36,13 +36,11 @@ fz_new_stream(fz_context *ctx, void *state,
stm->bits = 0;
stm->avail = 0;
- stm->bp = stm->buf;
- stm->rp = stm->bp;
- stm->wp = stm->bp;
- stm->ep = stm->buf + sizeof stm->buf;
+ stm->rp = NULL;
+ stm->wp = NULL;
stm->state = state;
- stm->read = read;
+ stm->next = next;
stm->close = close;
stm->seek = NULL;
stm->rebind = rebind;
@@ -75,27 +73,44 @@ fz_close(fz_stream *stm)
/* File stream */
-static int read_file(fz_stream *stm, unsigned char *buf, int len)
+typedef struct fz_file_stream_s
{
- int n = read(*(int*)stm->state, buf, len);
+ int file;
+ unsigned char buffer[4096];
+} fz_file_stream;
+
+static int next_file(fz_stream *stm, int n)
+{
+ fz_file_stream *state = stm->state;
+
+ /* n is only a hint, that we can safely ignore */
+ n = read(state->file, state->buffer, sizeof(state->buffer));
if (n < 0)
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "read error: %s", strerror(errno));
- return n;
+ stm->rp = state->buffer;
+ stm->wp = state->buffer + n;
+ stm->pos += n;
+
+ if (n == 0)
+ return EOF;
+ return *stm->rp++;
}
static void seek_file(fz_stream *stm, int offset, int whence)
{
- int n = lseek(*(int*)stm->state, offset, whence);
+ fz_file_stream *state = stm->state;
+ int n = lseek(state->file, offset, whence);
if (n < 0)
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "cannot lseek: %s", strerror(errno));
stm->pos = n;
- stm->rp = stm->bp;
- stm->wp = stm->bp;
+ stm->rp = state->buffer;
+ stm->wp = state->buffer;
}
-static void close_file(fz_context *ctx, void *state)
+static void close_file(fz_context *ctx, void *state_)
{
- int n = close(*(int*)state);
+ fz_file_stream *state = state_;
+ int n = close(state->file);
if (n < 0)
fz_warn(ctx, "close error: %s", strerror(errno));
fz_free(ctx, state);
@@ -105,14 +120,12 @@ fz_stream *
fz_open_fd(fz_context *ctx, int fd)
{
fz_stream *stm;
- int *state;
-
- state = fz_malloc_struct(ctx, int);
- *state = fd;
+ fz_file_stream *state = fz_malloc_struct(ctx, fz_file_stream);
+ state->file = fd;
fz_try(ctx)
{
- stm = fz_new_stream(ctx, state, read_file, close_file, NULL);
+ stm = fz_new_stream(ctx, state, next_file, close_file, NULL);
}
fz_catch(ctx)
{
@@ -160,21 +173,29 @@ fz_open_file_w(fz_context *ctx, const wchar_t *name)
/* Memory stream */
-static int read_buffer(fz_stream *stm, unsigned char *buf, int len)
+static int next_buffer(fz_stream *stm, int max)
{
- return 0;
+ return EOF;
}
static void seek_buffer(fz_stream *stm, int offset, int whence)
{
- if (whence == 0)
- stm->rp = stm->bp + offset;
+ int pos = stm->pos - (stm->wp - stm->rp);
+ /* Convert to absolute pos */
if (whence == 1)
- stm->rp += offset;
- if (whence == 2)
- stm->rp = stm->ep - offset;
- stm->rp = fz_clampp(stm->rp, stm->bp, stm->ep);
- stm->wp = stm->ep;
+ {
+ offset += pos; /* Was relative to current pos */
+ }
+ else if (whence == 2)
+ {
+ offset += stm->pos; /* Was relative to end */
+ }
+
+ if (offset < 0)
+ offset = 0;
+ if (offset > stm->pos)
+ offset = stm->pos;
+ stm->rp += offset - pos;
}
static void close_buffer(fz_context *ctx, void *state_)
@@ -190,13 +211,11 @@ fz_open_buffer(fz_context *ctx, fz_buffer *buf)
fz_stream *stm;
fz_keep_buffer(ctx, buf);
- stm = fz_new_stream(ctx, buf, read_buffer, close_buffer, NULL);
+ stm = fz_new_stream(ctx, buf, next_buffer, close_buffer, NULL);
stm->seek = seek_buffer;
- stm->bp = buf->data;
stm->rp = buf->data;
stm->wp = buf->data + buf->len;
- stm->ep = buf->data + buf->len;
stm->pos = buf->len;
@@ -208,13 +227,11 @@ fz_open_memory(fz_context *ctx, unsigned char *data, int len)
{
fz_stream *stm;
- stm = fz_new_stream(ctx, NULL, read_buffer, close_buffer, NULL);
+ stm = fz_new_stream(ctx, NULL, next_buffer, close_buffer, NULL);
stm->seek = seek_buffer;
- stm->bp = data;
stm->rp = data;
stm->wp = data + len;
- stm->ep = data + len;
stm->pos = len;
diff --git a/source/fitz/stream-prog.c b/source/fitz/stream-prog.c
index 5ec23823..01f3e5ef 100644
--- a/source/fitz/stream-prog.c
+++ b/source/fitz/stream-prog.c
@@ -24,12 +24,17 @@ typedef struct prog_state
int available;
int bps;
clock_t start_time;
+ unsigned char buffer[4096];
} prog_state;
-static int read_prog(fz_stream *stm, unsigned char *buf, int len)
+static int next_prog(fz_stream *stm, int len)
{
prog_state *ps = (prog_state *)stm->state;
int n;
+ unsigned char *buf = ps->buffer;
+
+ if (len > sizeof(ps->buffer))
+ len = sizeof(ps->buffer);
/* Simulate more data having arrived */
if (ps->available < ps->length)
@@ -53,7 +58,12 @@ static int read_prog(fz_stream *stm, unsigned char *buf, int len)
n = (len > 0 ? read(ps->fd, buf, len) : 0);
if (n < 0)
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "read error: %s", strerror(errno));
- return n;
+ stm->rp = ps->buffer + stm->pos;
+ stm->wp = ps->buffer + stm->pos + n;
+ stm->pos += n;
+ if (n == 0)
+ return EOF;
+ return *stm->rp++;
}
static void seek_prog(fz_stream *stm, int offset, int whence)
@@ -100,8 +110,7 @@ static void seek_prog(fz_stream *stm, int offset, int whence)
if (n < 0)
fz_throw(stm->ctx, FZ_ERROR_GENERIC, "cannot lseek: %s", strerror(errno));
stm->pos = n;
- stm->rp = stm->bp;
- stm->wp = stm->bp;
+ stm->wp = stm->rp;
}
static void close_prog(fz_context *ctx, void *state)
@@ -144,7 +153,7 @@ fz_open_fd_progressive(fz_context *ctx, int fd, int bps)
fz_try(ctx)
{
- stm = fz_new_stream(ctx, state, read_prog, close_prog, NULL);
+ stm = fz_new_stream(ctx, state, next_prog, close_prog, NULL);
}
fz_catch(ctx)
{
diff --git a/source/fitz/stream-read.c b/source/fitz/stream-read.c
index 71ae7666..02f186a0 100644
--- a/source/fitz/stream-read.c
+++ b/source/fitz/stream-read.c
@@ -7,89 +7,26 @@ fz_read(fz_stream *stm, unsigned char *buf, int len)
{
int count, n;
- count = fz_mini(len, stm->wp - stm->rp);
- if (count)
+ count = 0;
+ do
{
- memcpy(buf, stm->rp, count);
- stm->rp += count;
- }
-
- if (count == len || stm->error || stm->eof)
- return count;
-
- assert(stm->rp == stm->wp);
-
- if (len - count < stm->ep - stm->bp)
- {
- n = stm->read(stm, stm->bp, stm->ep - stm->bp);
+ n = fz_available(stm, len);
+ if (n > len)
+ n = len;
if (n == 0)
- {
- stm->eof = 1;
- }
- else if (n > 0)
- {
- stm->rp = stm->bp;
- stm->wp = stm->bp + n;
- stm->pos += n;
- }
+ break;
- n = fz_mini(len - count, stm->wp - stm->rp);
- if (n)
- {
- memcpy(buf + count, stm->rp, n);
- stm->rp += n;
- count += n;
- }
- }
- else
- {
- n = stm->read(stm, buf + count, len - count);
- if (n == 0)
- {
- stm->eof = 1;
- }
- else if (n > 0)
- {
- stm->pos += n;
- count += n;
- }
+ memcpy(buf, stm->rp, n);
+ stm->rp += n;
+ buf += n;
+ count += n;
+ len -= n;
}
+ while (len > 0);
return count;
}
-void
-fz_fill_buffer(fz_stream *stm)
-{
- int n;
-
- assert(stm->rp == stm->wp);
-
- if (stm->error || stm->eof)
- return;
-
- fz_try(stm->ctx)
- {
- n = stm->read(stm, stm->bp, stm->ep - stm->bp);
- if (n == 0)
- {
- stm->eof = 1;
- }
- else if (n > 0)
- {
- stm->rp = stm->bp;
- stm->wp = stm->bp + n;
- stm->pos += n;
- }
- }
- fz_catch(stm->ctx)
- {
- fz_rethrow_if(stm->ctx, FZ_ERROR_TRYLATER);
- fz_warn(stm->ctx, "read error; treating as end of file");
- stm->error = 1;
- }
-}
-
fz_buffer *
fz_read_all(fz_stream *stm, int initial)
{
@@ -196,16 +133,6 @@ fz_seek(fz_stream *stm, int offset, int whence)
offset = fz_tell(stm) + offset;
whence = 0;
}
- if (whence == 0)
- {
- int dist = stm->pos - offset;
- if (dist >= 0 && dist <= stm->wp - stm->bp)
- {
- stm->rp = stm->wp - dist;
- stm->eof = 0;
- return;
- }
- }
stm->seek(stm, offset, whence);
stm->eof = 0;
}
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index f6eda706..0f74667a 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -1741,6 +1741,7 @@ static void pdf_run_BI(pdf_csi *csi, void *state)
int ch;
fz_image *img;
pdf_obj *obj;
+ int found;
obj = pdf_parse_dict(csi->doc, file, &csi->doc->lexbuf.base);
@@ -1768,11 +1769,27 @@ static void pdf_run_BI(pdf_csi *csi, void *state)
fz_drop_image(ctx, img);
/* find EI */
+ found = 0;
ch = fz_read_byte(file);
- while (ch != 'E' && ch != EOF)
- ch = fz_read_byte(file);
- ch = fz_read_byte(file);
- if (ch != 'I')
+ do
+ {
+ while (ch != 'E' && ch != EOF)
+ ch = fz_read_byte(file);
+ if (ch == 'E')
+ {
+ ch = fz_read_byte(file);
+ if (ch == 'I')
+ {
+ ch = fz_peek_byte(file);
+ if (ch == ' ' || ch <= 32 || ch == EOF || ch == '<' || ch == '/')
+ {
+ found = 1;
+ break;
+ }
+ }
+ }
+ } while (ch != EOF);
+ if (!found)
fz_throw(ctx, FZ_ERROR_GENERIC, "syntax error after inline image");
}