]> wimlib.net Git - wimlib/blobdiff - include/wimlib/decompress_common.h
Merge branch 'wimboot_fast'
[wimlib] / include / wimlib / decompress_common.h
index ef7ebe953960cd33c2e91efd341c37f4ba717441..856c64117c6cf432cbdb3be761a0ea2f3433f70a 100644 (file)
@@ -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
 #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__)