diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2015-05-24 11:51:24 +0200 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2015-07-29 12:40:29 +0200 |
commit | a414db2d3f579ce6b6b1d55d1c9110b12dd230c3 (patch) | |
tree | b6e6318128a6bb5db4ba7e9224cf1c4eb3c06b56 /source/fitz | |
parent | 9c2c5644c77761b7a065ebdcbbb63b88b182c94b (diff) | |
download | mupdf-a414db2d3f579ce6b6b1d55d1c9110b12dd230c3.tar.xz |
Support LZW codes shorter than 9 bits.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/compressed-buffer.c | 2 | ||||
-rw-r--r-- | source/fitz/filter-lzw.c | 51 | ||||
-rw-r--r-- | source/fitz/load-tiff.c | 2 |
3 files changed, 31 insertions, 24 deletions
diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c index 2c5dd93f..2dbdc694 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); + chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change, 9); 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 257c6c86..ddc11f20 100644 --- a/source/fitz/filter-lzw.c +++ b/source/fitz/filter-lzw.c @@ -2,14 +2,14 @@ /* TODO: error checking */ +#define LZW_CLEAR(lzw) (1 << ((lzw)->min_bits - 1)) +#define LZW_EOD(lzw) (LZW_CLEAR(lzw) + 1) +#define LZW_FIRST(lzw) (LZW_CLEAR(lzw) + 2) + enum { - MIN_BITS = 9, MAX_BITS = 12, NUM_CODES = (1 << MAX_BITS), - LZW_CLEAR = 256, - LZW_EOD = 257, - LZW_FIRST = 258, MAX_LENGTH = 4097 }; @@ -32,6 +32,7 @@ struct fz_lzwd_s int early_change; + int min_bits; /* minimum num bits/code */ int code_bits; /* num bits/code */ int code; /* current code */ int old_code; /* previously recognized code */ @@ -81,22 +82,22 @@ next_lzwd(fz_context *ctx, fz_stream *stm, int len) break; } - if (code == LZW_EOD) + if (code == LZW_EOD(lzw)) { lzw->eod = 1; break; } - if (next_code > NUM_CODES && code != LZW_CLEAR) + if (next_code > NUM_CODES && code != LZW_CLEAR(lzw)) { fz_warn(ctx, "missing clear code in lzw decode"); - code = LZW_CLEAR; + code = LZW_CLEAR(lzw); } - if (code == LZW_CLEAR) + if (code == LZW_CLEAR(lzw)) { - code_bits = MIN_BITS; - next_code = LZW_FIRST; + code_bits = lzw->min_bits; + next_code = LZW_FIRST(lzw); old_code = -1; continue; } @@ -108,7 +109,7 @@ next_lzwd(fz_context *ctx, fz_stream *stm, int len) } else if (next_code == NUM_CODES) { - /* TODO: Ghostscript checks for a following LZW_CLEAR before tolerating */ + /* 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++; } @@ -142,7 +143,7 @@ next_lzwd(fz_context *ctx, fz_stream *stm, int len) } /* code maps to a string, copy to output (in reverse...) */ - if (code > 255) + if (code >= LZW_CLEAR(lzw)) { codelen = table[code].length; lzw->rp = lzw->bp; @@ -195,7 +196,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) +fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits) { fz_lzwd *lzw = NULL; int i; @@ -204,12 +205,25 @@ fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change) fz_try(ctx) { + if (min_bits > MAX_BITS) + { + fz_warn(ctx, "out of range initial lzw code size"); + min_bits = MAX_BITS; + } + lzw = fz_malloc_struct(ctx, fz_lzwd); lzw->chain = chain; lzw->eod = 0; lzw->early_change = early_change; + lzw->min_bits = min_bits; + lzw->code_bits = lzw->min_bits; + lzw->code = -1; + lzw->next_code = LZW_FIRST(lzw); + lzw->old_code = -1; + lzw->rp = lzw->bp; + lzw->wp = lzw->bp; - for (i = 0; i < 256; i++) + for (i = 0; i < LZW_CLEAR(lzw); i++) { lzw->table[i].value = i; lzw->table[i].first_char = i; @@ -217,20 +231,13 @@ fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change) lzw->table[i].prev = -1; } - for (i = 256; i < NUM_CODES; i++) + for (i = LZW_CLEAR(lzw); i < NUM_CODES; i++) { lzw->table[i].value = 0; lzw->table[i].first_char = 0; lzw->table[i].length = 0; lzw->table[i].prev = -1; } - - lzw->code_bits = MIN_BITS; - lzw->code = -1; - lzw->next_code = LZW_FIRST; - lzw->old_code = -1; - lzw->rp = lzw->bp; - lzw->wp = lzw->bp; } fz_catch(ctx) { diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index 054baebe..c2799f7c 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -157,7 +157,7 @@ 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_stream *stm = fz_open_lzwd(ctx, chain, 1); + fz_stream *stm = fz_open_lzwd(ctx, chain, 1, 9); fz_read(ctx, stm, wp, wlen); fz_drop_stream(ctx, stm); } |