]> wimlib.net Git - wimlib/blobdiff - src/xpress-decompress.c
xpress-decompress.c: Store 'len_hdr' and 'offset_bsr' in unsigned ints
[wimlib] / src / xpress-decompress.c
index b71f6be23e1c6f8a502564fda9b29e966d33a5fa..855f2cb311ccb156db1ecd9e00600c86255e458a 100644 (file)
  *
  * Also, a caveat--- according to Microsoft's documentation for XPRESS,
  *
- *     "Some implementation of the decompression algorithm expect an extra
- *     symbol to mark the end of the data.  Specifically, some implementations
- *     fail during decompression if the Huffman symbol 256 is not found after
- *     the actual data."
+ *     "Some implementation of the decompression algorithm expect an extra
+ *     symbol to mark the end of the data.  Specifically, some implementations
+ *     fail during decompression if the Huffman symbol 256 is not found after
+ *     the actual data."
  *
  * This is the case for the implementation in WIMGAPI.  However, wimlib's
  * decompressor in this file currently does not care if this extra symbol is
@@ -70,7 +70,8 @@
 #endif
 
 #include "wimlib.h"
-#include "wimlib/decompress.h"
+#include "wimlib/decompressor_ops.h"
+#include "wimlib/decompress_common.h"
 #include "wimlib/xpress.h"
 
 /*
@@ -89,9 +90,8 @@ xpress_decode_match(unsigned sym, input_idx_t window_pos,
                    struct input_bitstream * restrict istream)
 {
 
-       u8 len_hdr;
-       u8 offset_bsr;
-       int ret;
+       unsigned len_hdr;
+       unsigned offset_bsr;
        u8 *match_dest;
        u8 *match_src;
        unsigned i;
@@ -102,27 +102,15 @@ xpress_decode_match(unsigned sym, input_idx_t window_pos,
        len_hdr = sym & 0xf;
        offset_bsr = sym >> 4;
 
-       if (bitstream_ensure_bits(istream, 16))
-               return -1;
+       bitstream_ensure_bits(istream, 16);
 
        match_offset = (1U << offset_bsr) | bitstream_pop_bits(istream, offset_bsr);
 
        if (len_hdr == 0xf) {
-               ret = bitstream_read_byte(istream);
-               if (ret < 0)
-                       return ret;
-               match_len = ret;
+               match_len = bitstream_read_byte(istream);
                if (unlikely(match_len == 0xff)) {
-                       ret = bitstream_read_byte(istream);
-                       if (ret < 0)
-                               return ret;
-                       match_len = ret;
-
-                       ret = bitstream_read_byte(istream);
-                       if (ret < 0)
-                               return ret;
-
-                       match_len |= (ret << 8);
+                       match_len = bitstream_read_byte(istream);
+                       match_len |= (unsigned)bitstream_read_byte(istream) << 8;
                } else {
                        match_len += 0xf;
                }
@@ -132,7 +120,7 @@ xpress_decode_match(unsigned sym, input_idx_t window_pos,
        match_len += XPRESS_MIN_MATCH_LEN;
 
 
-       /* Verify the match is in bounds, then copy its data to the the current
+       /* Verify the match is in bounds, then copy its data to the current
         * position.  */
 
        if (window_pos + match_len > window_len)
@@ -156,7 +144,6 @@ static int
 xpress_lz_decode(struct input_bitstream * restrict istream,
                 u8 uncompressed_data[restrict],
                 unsigned uncompressed_len,
-                const u8 lens[restrict],
                 const u16 decode_table[restrict])
 {
        input_idx_t curpos;
@@ -166,14 +153,10 @@ xpress_lz_decode(struct input_bitstream * restrict istream,
                unsigned sym;
                int ret;
 
-               if (unlikely(bitstream_ensure_bits(istream, 16)))
-                       return -1;
-
-               if (unlikely(read_huffsym(istream, decode_table, lens,
-                                         XPRESS_NUM_SYMBOLS, XPRESS_TABLEBITS,
-                                         &sym, XPRESS_MAX_CODEWORD_LEN)))
-                       return -1;
+               bitstream_ensure_bits(istream, 16);
 
+               sym = read_huffsym(istream, decode_table,
+                                  XPRESS_TABLEBITS, XPRESS_MAX_CODEWORD_LEN);
                if (sym < XPRESS_NUM_CHARS) {
                        /* Literal  */
                        uncompressed_data[curpos] = sym;
@@ -194,14 +177,11 @@ xpress_lz_decode(struct input_bitstream * restrict istream,
 }
 
 
-/* API function documented in wimlib.h  */
-WIMLIBAPI int
-wimlib_xpress_decompress(const void * const restrict _compressed_data,
-                        const unsigned compressed_len,
-                        void * const restrict uncompressed_data,
-                        const unsigned uncompressed_len)
+static int
+xpress_decompress(const void *compressed_data, size_t compressed_size,
+                 void *uncompressed_data, size_t uncompressed_size, void *_ctx)
 {
-       const u8 *compressed_data = _compressed_data;
+       const u8 *cdata = compressed_data;
        u8 lens[XPRESS_NUM_SYMBOLS];
        u8 *lens_p;
        u16 decode_table[(1 << XPRESS_TABLEBITS) + 2 * XPRESS_NUM_SYMBOLS]
@@ -211,13 +191,13 @@ wimlib_xpress_decompress(const void * const restrict _compressed_data,
        /* XPRESS uses only one Huffman code.  It contains 512 symbols, and the
         * code lengths of these symbols are given literally as 4-bit integers
         * in the first 256 bytes of the compressed data.  */
-       if (compressed_len < XPRESS_NUM_SYMBOLS / 2)
+       if (compressed_size < XPRESS_NUM_SYMBOLS / 2)
                return -1;
 
        lens_p = lens;
        for (unsigned i = 0; i < XPRESS_NUM_SYMBOLS / 2; i++) {
-               *lens_p++ = compressed_data[i] & 0xf;
-               *lens_p++ = compressed_data[i] >> 4;
+               *lens_p++ = cdata[i] & 0xf;
+               *lens_p++ = cdata[i] >> 4;
        }
 
        if (make_huffman_decode_table(decode_table, XPRESS_NUM_SYMBOLS,
@@ -225,9 +205,13 @@ wimlib_xpress_decompress(const void * const restrict _compressed_data,
                                      XPRESS_MAX_CODEWORD_LEN))
                return -1;
 
-       init_input_bitstream(&istream, compressed_data + XPRESS_NUM_SYMBOLS / 2,
-                            compressed_len - XPRESS_NUM_SYMBOLS / 2);
+       init_input_bitstream(&istream, cdata + XPRESS_NUM_SYMBOLS / 2,
+                            compressed_size - XPRESS_NUM_SYMBOLS / 2);
 
        return xpress_lz_decode(&istream, uncompressed_data,
-                               uncompressed_len, lens, decode_table);
+                               uncompressed_size, decode_table);
 }
+
+const struct decompressor_ops xpress_decompressor_ops = {
+       .decompress = xpress_decompress,
+};