From c0759acc6e5bd8167ab4983fc51eb1212da6a216 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Sat, 11 Jun 2016 16:01:53 +0100 Subject: 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. --- source/fitz/compressed-buffer.c | 2 +- source/fitz/filter-lzw.c | 14 +++++++++----- source/fitz/load-gif.c | 2 +- source/fitz/load-tiff.c | 6 +++--- 4 files changed, 14 insertions(+), 10 deletions(-) (limited to 'source') 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"); -- cgit v1.2.3