summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-06-11 16:01:53 +0100
committerRobin Watts <robin.watts@artifex.com>2016-06-14 12:53:03 +0100
commitc0759acc6e5bd8167ab4983fc51eb1212da6a216 (patch)
treeb46f6a783f5e6dd8e09fc7c0ca318ac34b88fb81 /source
parent60edbbde3a384401cbefe338e55e7a5f52cad5f4 (diff)
downloadmupdf-c0759acc6e5bd8167ab4983fc51eb1212da6a216.tar.xz
Update TIFF LZW decode.
TIFF 5.0 uses a slightly laxer set of rules for TIFF decode. Specifically, when we hit the maximum code, we are not required to send a clear code immediately, but it can overrrun. We don't bother storing codes > 12 bits, because they can never be used. This avoids the need to extend the table.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/compressed-buffer.c2
-rw-r--r--source/fitz/filter-lzw.c14
-rw-r--r--source/fitz/load-gif.c2
-rw-r--r--source/fitz/load-tiff.c6
4 files changed, 14 insertions, 10 deletions
diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c
index e2ced271..8c9b7e56 100644
--- a/source/fitz/compressed-buffer.c
+++ b/source/fitz/compressed-buffer.c
@@ -54,7 +54,7 @@ fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_pa
chain = fz_open_predict(ctx, chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc);
return chain;
case FZ_IMAGE_LZW:
- chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change, 9, 0);
+ chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change, 9, 0, 0);
if (params->u.lzw.predictor > 1)
chain = fz_open_predict(ctx, chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc);
return chain;
diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c
index ff655c9e..cb977772 100644
--- a/source/fitz/filter-lzw.c
+++ b/source/fitz/filter-lzw.c
@@ -33,6 +33,7 @@ struct fz_lzwd_s
int early_change;
int reverse_bits;
+ int old_tiff;
int min_bits; /* minimum num bits/code */
int code_bits; /* num bits/code */
int code; /* current code */
@@ -92,7 +93,9 @@ next_lzwd(fz_context *ctx, fz_stream *stm, int len)
break;
}
- if (next_code > NUM_CODES && code != LZW_CLEAR(lzw))
+ /* Old Tiffs are allowed to NOT send the clear code, and to
+ * overrun at the end. */
+ if (!lzw->old_tiff && next_code > NUM_CODES && code != LZW_CLEAR(lzw))
{
fz_warn(ctx, "missing clear code in lzw decode");
code = LZW_CLEAR(lzw);
@@ -111,17 +114,17 @@ next_lzwd(fz_context *ctx, fz_stream *stm, int len)
{
old_code = code;
}
- else if (next_code == NUM_CODES)
+ else if (!lzw->old_tiff && next_code == NUM_CODES)
{
/* TODO: Ghostscript checks for a following clear code before tolerating */
fz_warn(ctx, "tolerating a single out of range code in lzw decode");
next_code++;
}
- else if (code > next_code || next_code >= NUM_CODES)
+ else if (code > next_code || (!lzw->old_tiff && next_code >= NUM_CODES))
{
fz_warn(ctx, "out of range code encountered in lzw decode");
}
- else
+ else if (next_code < NUM_CODES)
{
/* add new entry to the code table */
table[next_code].prev = old_code;
@@ -200,7 +203,7 @@ close_lzwd(fz_context *ctx, void *state_)
/* Default: early_change = 1 */
fz_stream *
-fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits)
+fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff)
{
fz_lzwd *lzw = NULL;
int i;
@@ -220,6 +223,7 @@ fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits,
lzw->eod = 0;
lzw->early_change = early_change;
lzw->reverse_bits = reverse_bits;
+ lzw->old_tiff = old_tiff;
lzw->min_bits = min_bits;
lzw->code_bits = lzw->min_bits;
lzw->code = -1;
diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c
index d31dee09..06f353f3 100644
--- a/source/fitz/load-gif.c
+++ b/source/fitz/load-gif.c
@@ -245,7 +245,7 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, unsigned
p = gif_read_subblocks(ctx, info, p + 1, end, compressed);
stm = fz_open_buffer(ctx, compressed);
- lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1);
+ lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1, 0);
uncompressed = fz_read_all(ctx, lzwstm, info->width * info->height);
sp = uncompressed->data;
diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
index f7661a8d..3df9f7c8 100644
--- a/source/fitz/load-tiff.c
+++ b/source/fitz/load-tiff.c
@@ -155,9 +155,9 @@ fz_decode_tiff_packbits(fz_context *ctx, struct tiff *tiff, fz_stream *chain, un
}
static void
-fz_decode_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen)
+fz_decode_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int old_tiff)
{
- fz_stream *stm = fz_open_lzwd(ctx, chain, 1, 9, 0);
+ fz_stream *stm = fz_open_lzwd(ctx, chain, old_tiff ? 0 : 1, 9, old_tiff ? 1 : 0, old_tiff);
fz_read(ctx, stm, wp, wlen);
fz_drop_stream(ctx, stm);
}
@@ -457,7 +457,7 @@ fz_decode_tiff_strips(fz_context *ctx, struct tiff *tiff)
fz_decode_tiff_fax(ctx, tiff, 4, stm, wp, wlen);
break;
case 5:
- fz_decode_tiff_lzw(ctx, tiff, stm, wp, wlen);
+ fz_decode_tiff_lzw(ctx, tiff, stm, wp, wlen, (rp[0] == 0 && rp[1] & 1));
break;
case 6:
fz_warn(ctx, "deprecated JPEG in TIFF compression not fully supported");