]> wimlib.net Git - wimlib/blobdiff - src/decompress.c
Decompression optimizations
[wimlib] / src / decompress.c
index 47ce9943b23cb90bc263f33fad25588d727ba143..68ab495dac0cabc3aeb60844b55da40aa2f4b3dd 100644 (file)
@@ -31,7 +31,7 @@
 int bitstream_read_bytes(struct input_bitstream *stream, size_t n, void *dest)
 {
        /* Precondition:  The bitstream is 16-byte aligned. */
-       wimlib_assert(stream->bitsleft % 16 == 0);
+       wimlib_assert2(stream->bitsleft % 16 == 0);
 
        u8 *p = dest;
 
@@ -68,34 +68,6 @@ int bitstream_read_bytes(struct input_bitstream *stream, size_t n, void *dest)
        return 0;
 }
 
-/* Aligns the bitstream on a 16-bit boundary.
- *
- * Note: M$'s idea of "alignment" means that for some reason, a 16-bit word
- * should be skipped over if the buffer happens to already be aligned on such a
- * boundary.  This only applies for realigning the stream after the blocktype
- * and length fields of an uncompressed block, however; it does not apply when
- * realigning the stream after the end of the uncompressed block.
- */
-int align_input_bitstream(struct input_bitstream *stream,
-                         bool skip_word_if_aligned)
-{
-       int ret;
-       if (stream->bitsleft % 16 != 0) {
-               bitstream_remove_bits(stream, stream->bitsleft % 16);
-       } else if (skip_word_if_aligned) {
-               if (stream->bitsleft == 0) {
-                       ret = bitstream_ensure_bits(stream, 16);
-                       if (ret != 0) {
-                               ERROR("Unexpected end of input when "
-                                     "aligning bitstream");
-                               return ret;
-                       }
-               }
-               bitstream_remove_bits(stream, 16);
-       }
-       return 0;
-}
-
 /*
  * Builds a fast huffman decoding table from a canonical huffman code lengths
  * table.  Based on code written by David Tritscher.
@@ -154,9 +126,9 @@ int align_input_bitstream(struct input_bitstream *stream,
  * entries from pointers by the fact that values less than @num_syms must be
  * symbol values.
  */
-int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
-                             uint num_bits, const u8 lens[],
-                             uint max_code_len)
+int make_huffman_decode_table(u16 decode_table[],  unsigned num_syms,
+                             unsigned num_bits, const u8 lens[],
+                             unsigned max_code_len)
 {
        /* Number of entries in the decode table. */
        u32 table_num_entries = 1 << num_bits;
@@ -173,7 +145,7 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
         * array, and both symbols have the same code length, then we know that
         * the code for A numerically precedes the code for B.
         * */
-       for (uint code_len = 1; code_len <= num_bits; code_len++) {
+       for (unsigned code_len = 1; code_len <= num_bits; code_len++) {
 
                /* Number of entries that a code of length @code_length would
                 * need.  */
@@ -182,7 +154,7 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
                /* For each symbol of length @code_len, fill in its entries in
                 * the decode table. */
-               for (uint sym = 0; sym < num_syms; sym++) {
+               for (unsigned sym = 0; sym < num_syms; sym++) {
 
                        if (lens[sym] != code_len)
                                continue;
@@ -200,7 +172,7 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
                        /* Fill all possible lookups of this symbol with
                         * the symbol itself. */
-                       for (uint i = 0; i < code_num_entries; i++)
+                       for (unsigned i = 0; i < code_num_entries; i++)
                                decode_table[decode_table_pos + i] = sym;
 
                        /* Increment the position in the decode table by
@@ -222,7 +194,7 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
        /* First, zero out the rest of the entries; this is necessary so
         * that the entries appear as "unallocated" in the next part.  */
-       for (uint i = decode_table_pos; i < table_num_entries; i++)
+       for (unsigned i = decode_table_pos; i < table_num_entries; i++)
                decode_table[i] = 0;
 
        /* Assert that 2**num_bits is at least num_syms.  If this wasn't the
@@ -232,30 +204,30 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
 
        /* The current Huffman code.  */
-       uint current_code = decode_table_pos;
+       unsigned current_code = decode_table_pos;
 
        /* The tree nodes are allocated starting at
         * decode_table[table_num_entries].  Remember that the full size of the
         * table, including the extra space for the tree nodes, is actually
         * 2**num_bits + 2 * num_syms slots, while table_num_entries is only
         * 2**num_bits. */
-       uint next_free_tree_slot = table_num_entries;
+       unsigned next_free_tree_slot = table_num_entries;
 
        /* Go through every codeword of length greater than @num_bits.  Note:
         * the LZX format guarantees that the codeword length can be at most 16
         * bits. */
-       for (uint code_len = num_bits + 1; code_len <= max_code_len;
+       for (unsigned code_len = num_bits + 1; code_len <= max_code_len;
                                                        code_len++)
        {
                current_code <<= 1;
-               for (uint sym = 0; sym < num_syms; sym++) {
+               for (unsigned sym = 0; sym < num_syms; sym++) {
                        if (lens[sym] != code_len)
                                continue;
 
 
                        /* i is the index of the current node; find it from the
                         * prefix of the current Huffman code. */
-                       uint i = current_code >> (code_len - num_bits);
+                       unsigned i = current_code >> (code_len - num_bits);
 
                        if (i >= (1 << num_bits)) {
                                ERROR("Invalid canonical Huffman code");
@@ -314,7 +286,7 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
        if (decode_table_pos != table_num_entries) {
 
-               for (uint i = 0; i < num_syms; i++) {
+               for (unsigned i = 0; i < num_syms; i++) {
                        if (lens[i] != 0) {
                                ERROR("Lengths do not form a valid canonical "
                                      "Huffman tree (only filled %u of %u "
@@ -329,15 +301,15 @@ int make_huffman_decode_table(u16 decode_table[],  uint num_syms,
 
 /* Reads a Huffman-encoded symbol when it is known there are less than
  * MAX_CODE_LEN bits remaining in the bitstream. */
-static int read_huffsym_near_end_of_input(struct input_bitstream *istream,
-                                         const u16 decode_table[],
-                                         const u8 lens[],
-                                         uint num_syms,
-                                         uint table_bits,
-                                         uint *n)
+int read_huffsym_near_end_of_input(struct input_bitstream *istream,
+                                  const u16 decode_table[],
+                                  const u8 lens[],
+                                  unsigned num_syms,
+                                  unsigned table_bits,
+                                  unsigned *n)
 {
-       uint bitsleft = istream->bitsleft;
-       uint key_size;
+       unsigned bitsleft = istream->bitsleft;
+       unsigned key_size;
        u16 sym;
        u16 key_bits;
 
@@ -370,65 +342,3 @@ static int read_huffsym_near_end_of_input(struct input_bitstream *istream,
        *n = sym;
        return 0;
 }
-
-/*
- * Reads a Huffman-encoded symbol from a bitstream.
- *
- * This function may be called hundreds of millions of times when extracting a
- * large WIM file.  I'm not sure it could be made much faster that it is,
- * especially since there isn't enough time to make a big table that allows
- * decoding multiple symbols per lookup.  But if extracting files to a hard
- * disk, the IO will be the bottleneck anyway.
- *
- * @buf:       The input buffer from which the symbol will be read.
- * @decode_table:      The fast Huffman decoding table for the Huffman tree.
- * @lengths:           The table that gives the length of the code for each
- *                             symbol.
- * @num_symbols:       The number of symbols in the Huffman code.
- * @table_bits:                Huffman codes this length or less can be looked up
- *                             directory in the decode_table, as the
- *                             decode_table contains 2**table_bits entries.
- */
-int read_huffsym(struct input_bitstream *stream,
-                const u16 decode_table[],
-                const u8 lengths[],
-                unsigned num_symbols,
-                unsigned table_bits,
-                uint *n,
-                unsigned max_codeword_len)
-{
-       /* In the most common case, there are at least max_codeword_len bits
-        * remaining in the stream. */
-       if (bitstream_ensure_bits(stream, max_codeword_len) == 0) {
-
-               /* Use the next table_bits of the input as an index into the
-                * decode_table. */
-               u16 key_bits = bitstream_peek_bits(stream, table_bits);
-
-               u16 sym = decode_table[key_bits];
-
-               /* If the entry in the decode table is not a valid symbol, it is
-                * the offset of the root of its Huffman subtree. */
-               if (sym >= num_symbols) {
-                       bitstream_remove_bits(stream, table_bits);
-                       do {
-                               key_bits = sym + bitstream_peek_bits(stream, 1);
-                               bitstream_remove_bits(stream, 1);
-
-                               wimlib_assert(key_bits < num_symbols * 2 +
-                                                       (1 << table_bits));
-                       } while ((sym = decode_table[key_bits]) >= num_symbols);
-               } else {
-                       wimlib_assert(lengths[sym] <= table_bits);
-                       bitstream_remove_bits(stream, lengths[sym]);
-               }
-               *n = sym;
-               return 0;
-       } else {
-               /* Otherwise, we must be careful to use only the bits that are
-                * actually remaining.  */
-               return read_huffsym_near_end_of_input(stream, decode_table,
-                                                     lengths, num_symbols,
-                                                     table_bits, n);
-       }
-}