X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Flzx_decompress.c;h=cce98e32a96904f850f5da6d3e10c2f11b9f39b5;hp=0907fd8718bf0696d8d4adb0ddfdda6517f38ce2;hb=4ee103c6e2a2988e1fb358bfa2dc38dcb621505a;hpb=eafa4ec57e24f706adf793750b7194031ac50857 diff --git a/src/lzx_decompress.c b/src/lzx_decompress.c index 0907fd87..cce98e32 100644 --- a/src/lzx_decompress.c +++ b/src/lzx_decompress.c @@ -64,7 +64,7 @@ /* These values are chosen for fast decompression. */ #define LZX_MAINCODE_TABLEBITS 11 -#define LZX_LENCODE_TABLEBITS 10 +#define LZX_LENCODE_TABLEBITS 9 #define LZX_PRECODE_TABLEBITS 6 #define LZX_ALIGNEDCODE_TABLEBITS 7 @@ -72,32 +72,42 @@ struct lzx_decompressor { - u16 maincode_decode_table[(1 << LZX_MAINCODE_TABLEBITS) + - (LZX_MAINCODE_MAX_NUM_SYMBOLS * 2)] - _aligned_attribute(DECODE_TABLE_ALIGNMENT); + DECODE_TABLE(maincode_decode_table, LZX_MAINCODE_MAX_NUM_SYMBOLS, + LZX_MAINCODE_TABLEBITS, LZX_MAX_MAIN_CODEWORD_LEN); u8 maincode_lens[LZX_MAINCODE_MAX_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN]; - - u16 lencode_decode_table[(1 << LZX_LENCODE_TABLEBITS) + - (LZX_LENCODE_NUM_SYMBOLS * 2)] - _aligned_attribute(DECODE_TABLE_ALIGNMENT); + DECODE_TABLE(lencode_decode_table, LZX_LENCODE_NUM_SYMBOLS, + LZX_LENCODE_TABLEBITS, LZX_MAX_LEN_CODEWORD_LEN); u8 lencode_lens[LZX_LENCODE_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN]; union { - u16 alignedcode_decode_table[(1 << LZX_ALIGNEDCODE_TABLEBITS) + - (LZX_ALIGNEDCODE_NUM_SYMBOLS * 2)] - _aligned_attribute(DECODE_TABLE_ALIGNMENT); + DECODE_TABLE(alignedcode_decode_table, LZX_ALIGNEDCODE_NUM_SYMBOLS, + LZX_ALIGNEDCODE_TABLEBITS, LZX_MAX_ALIGNED_CODEWORD_LEN); u8 alignedcode_lens[LZX_ALIGNEDCODE_NUM_SYMBOLS]; }; union { - u16 precode_decode_table[(1 << LZX_PRECODE_TABLEBITS) + - (LZX_PRECODE_NUM_SYMBOLS * 2)] - _aligned_attribute(DECODE_TABLE_ALIGNMENT); + DECODE_TABLE(precode_decode_table, LZX_PRECODE_NUM_SYMBOLS, + LZX_PRECODE_TABLEBITS, LZX_MAX_PRE_CODEWORD_LEN); u8 precode_lens[LZX_PRECODE_NUM_SYMBOLS]; u8 extra_offset_bits[LZX_MAX_OFFSET_SLOTS]; }; + union { + DECODE_TABLE_WORKING_SPACE(maincode_working_space, + LZX_MAINCODE_MAX_NUM_SYMBOLS, + LZX_MAX_MAIN_CODEWORD_LEN); + DECODE_TABLE_WORKING_SPACE(lencode_working_space, + LZX_LENCODE_NUM_SYMBOLS, + LZX_MAX_LEN_CODEWORD_LEN); + DECODE_TABLE_WORKING_SPACE(alignedcode_working_space, + LZX_ALIGNEDCODE_NUM_SYMBOLS, + LZX_MAX_ALIGNED_CODEWORD_LEN); + DECODE_TABLE_WORKING_SPACE(precode_working_space, + LZX_PRECODE_NUM_SYMBOLS, + LZX_MAX_PRE_CODEWORD_LEN); + }; + unsigned window_order; unsigned num_main_syms; @@ -162,7 +172,8 @@ lzx_read_codeword_lens(struct lzx_decompressor *d, struct input_bitstream *is, LZX_PRECODE_NUM_SYMBOLS, LZX_PRECODE_TABLEBITS, d->precode_lens, - LZX_MAX_PRE_CODEWORD_LEN)) + LZX_MAX_PRE_CODEWORD_LEN, + d->precode_working_space)) return -1; /* Decode the codeword lengths. */ @@ -338,14 +349,16 @@ lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is, d->num_main_syms, LZX_MAINCODE_TABLEBITS, d->maincode_lens, - LZX_MAX_MAIN_CODEWORD_LEN)) + LZX_MAX_MAIN_CODEWORD_LEN, + d->maincode_working_space)) return -1; if (make_huffman_decode_table(d->lencode_decode_table, LZX_LENCODE_NUM_SYMBOLS, LZX_LENCODE_TABLEBITS, d->lencode_lens, - LZX_MAX_LEN_CODEWORD_LEN)) + LZX_MAX_LEN_CODEWORD_LEN, + d->lencode_working_space)) return -1; if (block_type == LZX_BLOCKTYPE_ALIGNED) { @@ -353,7 +366,8 @@ lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is, LZX_ALIGNEDCODE_NUM_SYMBOLS, LZX_ALIGNEDCODE_TABLEBITS, d->alignedcode_lens, - LZX_MAX_ALIGNED_CODEWORD_LEN)) + LZX_MAX_ALIGNED_CODEWORD_LEN, + d->alignedcode_working_space)) return -1; min_aligned_offset_slot = LZX_MIN_ALIGNED_OFFSET_SLOT; memcpy(d->extra_offset_bits, d->extra_offset_bits_minus_aligned, @@ -414,18 +428,11 @@ lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is, } recent_offsets[0] = offset; - /* Validate the match, then copy it to the current position. */ - - if (unlikely(length > block_end - out_next)) + /* Validate the match and copy it to the current position. */ + if (unlikely(lz_copy(length, offset, out_begin, + out_next, block_end, LZX_MIN_MATCH_LEN))) return -1; - - if (unlikely(offset > out_next - out_begin)) - return -1; - - lz_copy(out_next, length, offset, block_end, LZX_MIN_MATCH_LEN); - out_next += length; - } while (out_next != block_end); return 0;