X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=include%2Fwimlib%2Fdecompress_common.h;h=856c64117c6cf432cbdb3be761a0ea2f3433f70a;hb=7901ba9cde12d96f6e2dcb612fc5c3b361e988ff;hp=ef7ebe953960cd33c2e91efd341c37f4ba717441;hpb=543d8a6b89049aff65fa7eabf5f4b376a196c8d2;p=wimlib diff --git a/include/wimlib/decompress_common.h b/include/wimlib/decompress_common.h index ef7ebe95..856c6411 100644 --- a/include/wimlib/decompress_common.h +++ b/include/wimlib/decompress_common.h @@ -2,6 +2,9 @@ * decompress_common.h * * Header for decompression code shared by multiple compression formats. + * + * The author dedicates this file to the public domain. + * You can do whatever you want with this file. */ #ifndef _WIMLIB_DECOMPRESS_COMMON_H @@ -12,11 +15,6 @@ #include "wimlib/endianness.h" #include "wimlib/types.h" -#ifndef INPUT_IDX_T_DEFINED -#define INPUT_IDX_T_DEFINED -typedef u32 input_idx_t; -#endif - /* Structure to encapsulate a block of in-memory data that is being interpreted * as a stream of bits. * @@ -36,13 +34,13 @@ struct input_bitstream { const u8 *data; /* Number of bytes of data that are left. */ - input_idx_t data_bytes_left; + u32 data_bytes_left; }; /* Initializes a bitstream to receive its input from @data. */ static inline void init_input_bitstream(struct input_bitstream *istream, - const void *data, input_idx_t num_data_bytes) + const void *data, u32 num_data_bytes) { istream->bitbuf = 0; istream->bitsleft = 0; @@ -56,17 +54,38 @@ init_input_bitstream(struct input_bitstream *istream, * * If the input data is exhausted, any further bits are assumed to be 0. */ static inline void -bitstream_ensure_bits(struct input_bitstream *istream, unsigned num_bits) +bitstream_ensure_bits(struct input_bitstream *istream, const unsigned num_bits) { - for (int nbits = num_bits; (int)istream->bitsleft < nbits; nbits -= 16) { - u16 nextword; - unsigned shift; + u16 nextword; + unsigned shift; + + /* This currently works for at most 17 bits. */ + wimlib_assert2(num_bits <= 17); + + if (istream->bitsleft >= num_bits) + return; + if (unlikely(istream->data_bytes_left < 2)) { + istream->bitsleft = num_bits; + return; + } + + nextword = le16_to_cpu(*(const le16*)istream->data); + shift = sizeof(istream->bitbuf) * 8 - 16 - istream->bitsleft; + istream->bitbuf |= (u32)nextword << shift; + istream->data += 2; + istream->bitsleft += 16; + istream->data_bytes_left -= 2; + + /* Help the compiler: If it's known at compile-time that num_bits <= 16, + * a second word will never be needed. */ + if (!(is_constant(num_bits) && num_bits <= 16) && + unlikely(istream->bitsleft < num_bits)) + { if (unlikely(istream->data_bytes_left < 2)) { istream->bitsleft = num_bits; return; } - nextword = le16_to_cpu(*(const le16*)istream->data); shift = sizeof(istream->bitbuf) * 8 - 16 - istream->bitsleft; istream->bitbuf |= (u32)nextword << shift; @@ -211,7 +230,7 @@ make_huffman_decode_table(u16 decode_table[], unsigned num_syms, * This function won't write any data beyond this position. */ static inline void -lz_copy(u8 *dst, unsigned length, unsigned offset, const u8 *winend) +lz_copy(u8 *dst, u32 length, u32 offset, const u8 *winend) { const u8 *src = dst - offset; #if defined(__x86_64__) || defined(__i386__)