]> wimlib.net Git - wimlib/blob - src/lzx_decompress.c
lzx_decompress: decompressor cleanup
[wimlib] / src / lzx_decompress.c
1 /*
2  * lzx_decompress.c
3  *
4  * A decompressor for the LZX compression format, as used in WIM files.
5  */
6
7 /*
8  * Copyright (C) 2012-2016 Eric Biggers
9  *
10  * This file is free software; you can redistribute it and/or modify it under
11  * the terms of the GNU Lesser General Public License as published by the Free
12  * Software Foundation; either version 3 of the License, or (at your option) any
13  * later version.
14  *
15  * This file is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this file; if not, see http://www.gnu.org/licenses/.
22  */
23
24 /*
25  * LZX is an LZ77 and Huffman-code based compression format that has many
26  * similarities to DEFLATE (the format used by zlib/gzip).  The compression
27  * ratio is as good or better than DEFLATE.  See lzx_compress.c for a format
28  * overview, and see https://en.wikipedia.org/wiki/LZX_(algorithm) for a
29  * historical overview.  Here I make some pragmatic notes.
30  *
31  * The old specification for LZX is the document "Microsoft LZX Data Compression
32  * Format" (1997).  It defines the LZX format as used in cabinet files.  Allowed
33  * window sizes are 2^n where 15 <= n <= 21.  However, this document contains
34  * several errors, so don't read too much into it...
35  *
36  * The new specification for LZX is the document "[MS-PATCH]: LZX DELTA
37  * Compression and Decompression" (2014).  It defines the LZX format as used by
38  * Microsoft's binary patcher.  It corrects several errors in the 1997 document
39  * and extends the format in several ways --- namely, optional reference data,
40  * up to 2^25 byte windows, and longer match lengths.
41  *
42  * WIM files use a more restricted form of LZX.  No LZX DELTA extensions are
43  * present, the window is not "sliding", E8 preprocessing is done
44  * unconditionally with a fixed file size, and the maximum window size is always
45  * 2^15 bytes (equal to the size of each "chunk" in a compressed WIM resource).
46  * This code is primarily intended to implement this form of LZX.  But although
47  * not compatible with WIMGAPI, this code also supports maximum window sizes up
48  * to 2^21 bytes.
49  *
50  * TODO: Add support for window sizes up to 2^25 bytes.
51  */
52
53 #ifdef HAVE_CONFIG_H
54 #  include "config.h"
55 #endif
56
57 #include <string.h>
58
59 #include "wimlib/decompressor_ops.h"
60 #include "wimlib/decompress_common.h"
61 #include "wimlib/error.h"
62 #include "wimlib/lzx_common.h"
63 #include "wimlib/util.h"
64
65 /* These values are chosen for fast decompression.  */
66 #define LZX_MAINCODE_TABLEBITS          11
67 #define LZX_LENCODE_TABLEBITS           10
68 #define LZX_PRECODE_TABLEBITS           6
69 #define LZX_ALIGNEDCODE_TABLEBITS       7
70
71 #define LZX_READ_LENS_MAX_OVERRUN 50
72
73 struct lzx_decompressor {
74
75         u16 maincode_decode_table[(1 << LZX_MAINCODE_TABLEBITS) +
76                                         (LZX_MAINCODE_MAX_NUM_SYMBOLS * 2)]
77                                         _aligned_attribute(DECODE_TABLE_ALIGNMENT);
78         u8 maincode_lens[LZX_MAINCODE_MAX_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN];
79
80
81         u16 lencode_decode_table[(1 << LZX_LENCODE_TABLEBITS) +
82                                         (LZX_LENCODE_NUM_SYMBOLS * 2)]
83                                         _aligned_attribute(DECODE_TABLE_ALIGNMENT);
84         u8 lencode_lens[LZX_LENCODE_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN];
85
86         union {
87                 u16 alignedcode_decode_table[(1 << LZX_ALIGNEDCODE_TABLEBITS) +
88                                                 (LZX_ALIGNEDCODE_NUM_SYMBOLS * 2)]
89                                                 _aligned_attribute(DECODE_TABLE_ALIGNMENT);
90                 u8 alignedcode_lens[LZX_ALIGNEDCODE_NUM_SYMBOLS];
91         };
92
93         union {
94                 u16 precode_decode_table[(1 << LZX_PRECODE_TABLEBITS) +
95                                          (LZX_PRECODE_NUM_SYMBOLS * 2)]
96                                                 _aligned_attribute(DECODE_TABLE_ALIGNMENT);
97                 u8 precode_lens[LZX_PRECODE_NUM_SYMBOLS];
98         };
99
100         unsigned window_order;
101         unsigned num_main_syms;
102 } _aligned_attribute(DECODE_TABLE_ALIGNMENT);
103
104 /* Read a Huffman-encoded symbol using the precode. */
105 static inline unsigned
106 read_presym(const struct lzx_decompressor *d, struct input_bitstream *is)
107 {
108         return read_huffsym(is, d->precode_decode_table,
109                             LZX_PRECODE_TABLEBITS, LZX_MAX_PRE_CODEWORD_LEN);
110 }
111
112 /* Read a Huffman-encoded symbol using the main code. */
113 static inline unsigned
114 read_mainsym(const struct lzx_decompressor *d, struct input_bitstream *is)
115 {
116         return read_huffsym(is, d->maincode_decode_table,
117                             LZX_MAINCODE_TABLEBITS, LZX_MAX_MAIN_CODEWORD_LEN);
118 }
119
120 /* Read a Huffman-encoded symbol using the length code. */
121 static inline unsigned
122 read_lensym(const struct lzx_decompressor *d, struct input_bitstream *is)
123 {
124         return read_huffsym(is, d->lencode_decode_table,
125                             LZX_LENCODE_TABLEBITS, LZX_MAX_LEN_CODEWORD_LEN);
126 }
127
128 /* Read a Huffman-encoded symbol using the aligned offset code. */
129 static inline unsigned
130 read_alignedsym(const struct lzx_decompressor *d, struct input_bitstream *is)
131 {
132         return read_huffsym(is, d->alignedcode_decode_table,
133                             LZX_ALIGNEDCODE_TABLEBITS, LZX_MAX_ALIGNED_CODEWORD_LEN);
134 }
135
136 /*
137  * Read a precode from the compressed input bitstream, then use it to decode
138  * @num_lens codeword length values and write them to @lens.
139  */
140 static int
141 lzx_read_codeword_lens(struct lzx_decompressor *d, struct input_bitstream *is,
142                        u8 *lens, unsigned num_lens)
143 {
144         u8 *len_ptr = lens;
145         u8 *lens_end = lens + num_lens;
146
147         /* Read the lengths of the precode codewords.  These are stored
148          * explicitly. */
149         for (int i = 0; i < LZX_PRECODE_NUM_SYMBOLS; i++) {
150                 d->precode_lens[i] =
151                         bitstream_read_bits(is, LZX_PRECODE_ELEMENT_SIZE);
152         }
153
154         /* Build the decoding table for the precode. */
155         if (make_huffman_decode_table(d->precode_decode_table,
156                                       LZX_PRECODE_NUM_SYMBOLS,
157                                       LZX_PRECODE_TABLEBITS,
158                                       d->precode_lens,
159                                       LZX_MAX_PRE_CODEWORD_LEN))
160                 return -1;
161
162         /* Decode the codeword lengths.  */
163         do {
164                 unsigned presym;
165                 u8 len;
166
167                 /* Read the next precode symbol.  */
168                 presym = read_presym(d, is);
169                 if (presym < 17) {
170                         /* Difference from old length  */
171                         len = *len_ptr - presym;
172                         if ((s8)len < 0)
173                                 len += 17;
174                         *len_ptr++ = len;
175                 } else {
176                         /* Special RLE values  */
177
178                         unsigned run_len;
179
180                         if (presym == 17) {
181                                 /* Run of 0's  */
182                                 run_len = 4 + bitstream_read_bits(is, 4);
183                                 len = 0;
184                         } else if (presym == 18) {
185                                 /* Longer run of 0's  */
186                                 run_len = 20 + bitstream_read_bits(is, 5);
187                                 len = 0;
188                         } else {
189                                 /* Run of identical lengths  */
190                                 run_len = 4 + bitstream_read_bits(is, 1);
191                                 presym = read_presym(d, is);
192                                 if (unlikely(presym > 17))
193                                         return -1;
194                                 len = *len_ptr - presym;
195                                 if ((s8)len < 0)
196                                         len += 17;
197                         }
198
199                         do {
200                                 *len_ptr++ = len;
201                         } while (--run_len);
202                         /*
203                          * The worst case overrun is when presym == 18,
204                          * run_len == 20 + 31, and only 1 length was remaining.
205                          * So LZX_READ_LENS_MAX_OVERRUN == 50.
206                          *
207                          * Overrun while reading the first half of maincode_lens
208                          * can corrupt the previous values in the second half.
209                          * This doesn't really matter because the resulting
210                          * lengths will still be in range, and data that
211                          * generates overruns is invalid anyway.
212                          */
213                 }
214         } while (len_ptr < lens_end);
215
216         return 0;
217 }
218
219 /*
220  * Read the header of an LZX block.  For all block types, the block type and
221  * size is saved in *block_type_ret and *block_size_ret, respectively.  For
222  * compressed blocks, the codeword lengths are also saved.  For uncompressed
223  * blocks, the recent offsets queue is also updated.
224  */
225 static int
226 lzx_read_block_header(struct lzx_decompressor *d, struct input_bitstream *is,
227                       u32 recent_offsets[], int *block_type_ret,
228                       u32 *block_size_ret)
229 {
230         int block_type;
231         u32 block_size;
232
233         bitstream_ensure_bits(is, 4);
234
235         /* Read the block type. */
236         block_type = bitstream_pop_bits(is, 3);
237
238         /* Read the block size. */
239         if (bitstream_pop_bits(is, 1)) {
240                 block_size = LZX_DEFAULT_BLOCK_SIZE;
241         } else {
242                 block_size = bitstream_read_bits(is, 16);
243                 if (d->window_order >= 16) {
244                         block_size <<= 8;
245                         block_size |= bitstream_read_bits(is, 8);
246                 }
247         }
248
249         switch (block_type) {
250
251         case LZX_BLOCKTYPE_ALIGNED:
252
253                 /* Read the aligned offset codeword lengths. */
254
255                 for (int i = 0; i < LZX_ALIGNEDCODE_NUM_SYMBOLS; i++) {
256                         d->alignedcode_lens[i] =
257                                 bitstream_read_bits(is,
258                                                     LZX_ALIGNEDCODE_ELEMENT_SIZE);
259                 }
260
261                 /* Fall though, since the rest of the header for aligned offset
262                  * blocks is the same as that for verbatim blocks.  */
263
264         case LZX_BLOCKTYPE_VERBATIM:
265
266                 /* Read the main codeword lengths, which are divided into two
267                  * parts: literal symbols and match headers. */
268
269                 if (lzx_read_codeword_lens(d, is, d->maincode_lens,
270                                            LZX_NUM_CHARS))
271                         return -1;
272
273                 if (lzx_read_codeword_lens(d, is, d->maincode_lens + LZX_NUM_CHARS,
274                                            d->num_main_syms - LZX_NUM_CHARS))
275                         return -1;
276
277
278                 /* Read the length codeword lengths. */
279
280                 if (lzx_read_codeword_lens(d, is, d->lencode_lens,
281                                            LZX_LENCODE_NUM_SYMBOLS))
282                         return -1;
283
284                 break;
285
286         case LZX_BLOCKTYPE_UNCOMPRESSED:
287                 /*
288                  * The header of an uncompressed block contains new values for
289                  * the recent offsets queue, starting on the next 16-bit
290                  * boundary in the bitstream.  Careful: if the stream is
291                  * *already* aligned, the correct thing to do is to throw away
292                  * the next 16 bits (this is probably a mistake in the format).
293                  */
294                 bitstream_ensure_bits(is, 1);
295                 bitstream_align(is);
296                 recent_offsets[0] = bitstream_read_u32(is);
297                 recent_offsets[1] = bitstream_read_u32(is);
298                 recent_offsets[2] = bitstream_read_u32(is);
299
300                 /* Offsets of 0 are invalid.  */
301                 if (recent_offsets[0] == 0 || recent_offsets[1] == 0 ||
302                     recent_offsets[2] == 0)
303                         return -1;
304                 break;
305
306         default:
307                 /* Unrecognized block type.  */
308                 return -1;
309         }
310
311         *block_type_ret = block_type;
312         *block_size_ret = block_size;
313         return 0;
314 }
315
316 /* Decompress a block of LZX-compressed data. */
317 static int
318 lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is,
319                      int block_type, u32 block_size,
320                      u8 * const out_begin, u8 *out_next, u32 recent_offsets[])
321 {
322         u8 * const block_end = out_next + block_size;
323         unsigned min_aligned_offset_slot;
324
325         /*
326          * Build the Huffman decode tables.  We always need to build the main
327          * and length decode tables.  For aligned blocks we additionally need to
328          * build the aligned offset decode table.
329          */
330
331         if (make_huffman_decode_table(d->maincode_decode_table,
332                                       d->num_main_syms,
333                                       LZX_MAINCODE_TABLEBITS,
334                                       d->maincode_lens,
335                                       LZX_MAX_MAIN_CODEWORD_LEN))
336                 return -1;
337
338         if (make_huffman_decode_table(d->lencode_decode_table,
339                                       LZX_LENCODE_NUM_SYMBOLS,
340                                       LZX_LENCODE_TABLEBITS,
341                                       d->lencode_lens,
342                                       LZX_MAX_LEN_CODEWORD_LEN))
343                 return -1;
344
345         if (block_type == LZX_BLOCKTYPE_ALIGNED) {
346                 if (make_huffman_decode_table(d->alignedcode_decode_table,
347                                               LZX_ALIGNEDCODE_NUM_SYMBOLS,
348                                               LZX_ALIGNEDCODE_TABLEBITS,
349                                               d->alignedcode_lens,
350                                               LZX_MAX_ALIGNED_CODEWORD_LEN))
351                         return -1;
352                 min_aligned_offset_slot = 8;
353         } else {
354                 min_aligned_offset_slot = LZX_MAX_OFFSET_SLOTS;
355         }
356
357         /* Decode the literals and matches. */
358
359         do {
360                 unsigned mainsym;
361                 unsigned length;
362                 u32 offset;
363                 unsigned offset_slot;
364                 unsigned num_extra_bits;
365
366                 mainsym = read_mainsym(d, is);
367                 if (mainsym < LZX_NUM_CHARS) {
368                         /* Literal */
369                         *out_next++ = mainsym;
370                         continue;
371                 }
372
373                 /* Match */
374
375                 /* Decode the length header and offset slot.  */
376                 STATIC_ASSERT(LZX_NUM_CHARS % LZX_NUM_LEN_HEADERS == 0);
377                 length = mainsym % LZX_NUM_LEN_HEADERS;
378                 offset_slot = (mainsym - LZX_NUM_CHARS) / LZX_NUM_LEN_HEADERS;
379
380                 /* If needed, read a length symbol to decode the full length. */
381                 if (length == LZX_NUM_PRIMARY_LENS)
382                         length += read_lensym(d, is);
383                 length += LZX_MIN_MATCH_LEN;
384
385                 if (offset_slot < LZX_NUM_RECENT_OFFSETS) {
386                         /* Repeat offset  */
387
388                         /* Note: This isn't a real LRU queue, since using the R2
389                          * offset doesn't bump the R1 offset down to R2. */
390                         offset = recent_offsets[offset_slot];
391                         recent_offsets[offset_slot] = recent_offsets[0];
392                 } else {
393                         /* Explicit offset  */
394
395                         /* Look up the number of extra bits that need to be read
396                          * to decode offsets with this offset slot.  */
397                         num_extra_bits = lzx_extra_offset_bits[offset_slot];
398
399                         /* Start with the offset slot base value.  */
400                         offset = lzx_offset_slot_base[offset_slot];
401
402                         /* In aligned offset blocks, the low-order 3 bits of
403                          * each offset are encoded using the aligned offset
404                          * code.  Otherwise, all the extra bits are literal.  */
405
406                         if (offset_slot >= min_aligned_offset_slot) {
407                                 offset +=
408                                         bitstream_read_bits(is,
409                                                             num_extra_bits -
410                                                                 LZX_NUM_ALIGNED_OFFSET_BITS)
411                                                         << LZX_NUM_ALIGNED_OFFSET_BITS;
412                                 offset += read_alignedsym(d, is);
413                         } else {
414                                 offset += bitstream_read_bits(is, num_extra_bits);
415                         }
416
417                         /* Adjust the offset.  */
418                         offset -= LZX_OFFSET_ADJUSTMENT;
419
420                         /* Update the match offset LRU queue.  */
421                         STATIC_ASSERT(LZX_NUM_RECENT_OFFSETS == 3);
422                         recent_offsets[2] = recent_offsets[1];
423                         recent_offsets[1] = recent_offsets[0];
424                 }
425                 recent_offsets[0] = offset;
426
427                 /* Validate the match, then copy it to the current position.  */
428
429                 if (unlikely(length > block_end - out_next))
430                         return -1;
431
432                 if (unlikely(offset > out_next - out_begin))
433                         return -1;
434
435                 lz_copy(out_next, length, offset, block_end, LZX_MIN_MATCH_LEN);
436
437                 out_next += length;
438
439         } while (out_next != block_end);
440
441         return 0;
442 }
443
444 static int
445 lzx_decompress(const void *restrict compressed_data, size_t compressed_size,
446                void *restrict uncompressed_data, size_t uncompressed_size,
447                void *restrict _d)
448 {
449         struct lzx_decompressor *d = _d;
450         u8 * const out_begin = uncompressed_data;
451         u8 *out_next = out_begin;
452         u8 * const out_end = out_begin + uncompressed_size;
453         struct input_bitstream is;
454         STATIC_ASSERT(LZX_NUM_RECENT_OFFSETS == 3);
455         u32 recent_offsets[LZX_NUM_RECENT_OFFSETS] = {1, 1, 1};
456         unsigned may_have_e8_byte = 0;
457
458         init_input_bitstream(&is, compressed_data, compressed_size);
459
460         /* Codeword lengths begin as all 0's for delta encoding purposes. */
461         memset(d->maincode_lens, 0, d->num_main_syms);
462         memset(d->lencode_lens, 0, LZX_LENCODE_NUM_SYMBOLS);
463
464         /* Decompress blocks until we have all the uncompressed data. */
465
466         while (out_next != out_end) {
467                 int block_type;
468                 u32 block_size;
469
470                 if (lzx_read_block_header(d, &is, recent_offsets,
471                                           &block_type, &block_size))
472                         return -1;
473
474                 if (block_size < 1 || block_size > out_end - out_next)
475                         return -1;
476
477                 if (likely(block_type != LZX_BLOCKTYPE_UNCOMPRESSED)) {
478
479                         /* Compressed block */
480                         if (lzx_decompress_block(d, &is, block_type, block_size,
481                                                  out_begin, out_next,
482                                                  recent_offsets))
483                                 return -1;
484
485                         /* If the first E8 byte was in this block, then it must
486                          * have been encoded as a literal using mainsym E8. */
487                         may_have_e8_byte |= d->maincode_lens[0xE8];
488                 } else {
489
490                         /* Uncompressed block */
491                         if (bitstream_read_bytes(&is, out_next, block_size))
492                                 return -1;
493
494                         /* Re-align the bitstream if needed. */
495                         if (block_size & 1)
496                                 bitstream_read_byte(&is);
497
498                         /* There may have been an E8 byte in the block. */
499                         may_have_e8_byte = 1;
500                 }
501                 out_next += block_size;
502         }
503
504         /* Postprocess the data unless it cannot possibly contain E8 bytes. */
505         if (may_have_e8_byte)
506                 lzx_postprocess(uncompressed_data, uncompressed_size);
507
508         return 0;
509 }
510
511 static int
512 lzx_create_decompressor(size_t max_block_size, void **d_ret)
513 {
514         unsigned window_order;
515         struct lzx_decompressor *d;
516
517         window_order = lzx_get_window_order(max_block_size);
518         if (window_order == 0)
519                 return WIMLIB_ERR_INVALID_PARAM;
520
521         d = ALIGNED_MALLOC(sizeof(*d), DECODE_TABLE_ALIGNMENT);
522         if (!d)
523                 return WIMLIB_ERR_NOMEM;
524
525         d->window_order = window_order;
526         d->num_main_syms = lzx_get_num_main_syms(window_order);
527
528         *d_ret = d;
529         return 0;
530 }
531
532 static void
533 lzx_free_decompressor(void *_d)
534 {
535         ALIGNED_FREE(_d);
536 }
537
538 const struct decompressor_ops lzx_decompressor_ops = {
539         .create_decompressor = lzx_create_decompressor,
540         .decompress          = lzx_decompress,
541         .free_decompressor   = lzx_free_decompressor,
542 };