/* 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
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;
} _aligned_attribute(DECODE_TABLE_ALIGNMENT);
/* Read a Huffman-encoded symbol using the precode. */
-static inline unsigned
+static forceinline unsigned
read_presym(const struct lzx_decompressor *d, struct input_bitstream *is)
{
return read_huffsym(is, d->precode_decode_table,
}
/* Read a Huffman-encoded symbol using the main code. */
-static inline unsigned
+static forceinline unsigned
read_mainsym(const struct lzx_decompressor *d, struct input_bitstream *is)
{
return read_huffsym(is, d->maincode_decode_table,
}
/* Read a Huffman-encoded symbol using the length code. */
-static inline unsigned
+static forceinline unsigned
read_lensym(const struct lzx_decompressor *d, struct input_bitstream *is)
{
return read_huffsym(is, d->lencode_decode_table,
}
/* Read a Huffman-encoded symbol using the aligned offset code. */
-static inline unsigned
+static forceinline unsigned
read_alignedsym(const struct lzx_decompressor *d, struct input_bitstream *is)
{
return read_huffsym(is, d->alignedcode_decode_table,
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. */
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) {
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,
}
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;