keramics_compression/
bzip2.rs

1/* Copyright 2024-2025 Joachim Metz <joachim.metz@gmail.com>
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may
5 * obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 * License for the specific language governing permissions and limitations
11 * under the License.
12 */
13
14//! Bzip2 decompression.
15//!
16//! Provides decompression support for bzip2 compressed data.
17
18use std::cmp::max;
19
20use keramics_checksums::Crc32Context;
21use keramics_core::ErrorTrace;
22use keramics_core::formatters::debug_format_array;
23use keramics_core::mediator::{Mediator, MediatorReference};
24use keramics_layout_map::LayoutMap;
25
26use super::huffman::HuffmanTree;
27use super::traits::Bitstream;
28
29/// Bzip2 data header signature.
30pub(super) const BZIP2_DATA_HEADER_SIGNATURE: [u8; 2] = [0x42, 0x5a]; // BZ
31
32/// Bzip2 block size;
33pub(super) const BZIP2_BLOCK_SIZE: usize = 100000;
34
35/// Bitstream for bzip2 compressed data.
36pub(super) struct Bzip2Bitstream<'a> {
37    /// Byte steam.
38    data: &'a [u8],
39
40    /// Current offset in the byte stream.
41    pub data_offset: usize,
42
43    /// Size of the byte stream in bytes.
44    pub data_size: usize,
45
46    /// Bits buffer.
47    bits: u32,
48
49    /// Number of bits in the bits buffer.
50    pub number_of_bits: usize,
51}
52
53impl<'a> Bzip2Bitstream<'a> {
54    /// Creates a new bitstream.
55    pub fn new(data: &'a [u8], data_offset: usize) -> Self {
56        let data_size: usize = data.len();
57        Self {
58            data: data,
59            data_offset: data_offset,
60            data_size: data_size,
61            bits: 0,
62            number_of_bits: 0,
63        }
64    }
65
66    /// Reads input data forwards into the bits buffer in big-endian byte order.
67    #[inline(always)]
68    fn read_data(&mut self, number_of_bits: usize) {
69        while number_of_bits > self.number_of_bits {
70            self.bits <<= 8;
71
72            // If the bit stream overflows fill the bit buffer with 0 byte values.
73            if self.data_offset < self.data_size {
74                self.bits |= self.data[self.data_offset] as u32;
75                self.data_offset += 1;
76            }
77            self.number_of_bits += 8;
78        }
79    }
80}
81
82impl<'a> Bitstream for Bzip2Bitstream<'a> {
83    /// Retrieves a bit value.
84    fn get_value(&mut self, number_of_bits: usize) -> u32 {
85        // Note that this does not check if number_of_bits <= 32
86        let mut bit_value: u32 = 0;
87
88        let mut bit_offset: usize = 0;
89        while bit_offset < number_of_bits {
90            let mut read_size: usize = number_of_bits - bit_offset;
91            if read_size > 24 {
92                read_size = 24;
93            }
94            if self.number_of_bits < read_size {
95                self.read_data(read_size);
96            }
97            let mut value_32bit: u32 = self.bits;
98
99            self.number_of_bits -= read_size;
100
101            if self.number_of_bits == 0 {
102                self.bits = 0;
103            } else {
104                self.bits &= 0xffffffff >> (32 - self.number_of_bits);
105
106                value_32bit >>= self.number_of_bits;
107            }
108            if bit_offset > 0 {
109                bit_value <<= read_size;
110            }
111            bit_value |= value_32bit;
112            bit_offset += read_size;
113        }
114        bit_value
115    }
116
117    /// Skips a number of bits.
118    fn skip_bits(&mut self, number_of_bits: usize) {
119        // Note that this does not check if number_of_bits <= 32
120        let mut bit_offset: usize = 0;
121        while bit_offset < number_of_bits {
122            let mut read_size: usize = number_of_bits - bit_offset;
123            if read_size > 24 {
124                read_size = 24;
125            }
126            if self.number_of_bits < read_size {
127                self.read_data(read_size);
128            }
129            self.number_of_bits -= read_size;
130
131            if self.number_of_bits == 0 {
132                self.bits = 0;
133            } else {
134                self.bits &= 0xffffffff >> (32 - self.number_of_bits);
135            }
136            bit_offset += read_size;
137        }
138    }
139}
140
141#[derive(LayoutMap)]
142#[layout_map(
143    structure(
144        byte_order = "little",
145        field(name = "signature", data_type = "[u8; 2]", format = "char"),
146        field(name = "format_version", data_type = "u8"),
147        field(name = "compression_level", data_type = "u8", format = "char"),
148    ),
149    method(name = "debug_read_data")
150)]
151/// Stream header used by bzip2 compressed data.
152struct Bzip2StreamHeader {}
153
154impl Bzip2StreamHeader {
155    /// Creates a new stream header.
156    pub fn new() -> Self {
157        Self {}
158    }
159
160    /// Reads the stream header.
161    pub fn read_data(&mut self, data: &[u8]) -> Result<(), ErrorTrace> {
162        if data.len() < 4 {
163            return Err(keramics_core::error_trace_new!(
164                "Unsupported bzip2 stream header data size"
165            ));
166        }
167        if data[0..2] != BZIP2_DATA_HEADER_SIGNATURE {
168            return Err(keramics_core::error_trace_new!(
169                "Unsupported bzip2 header signature"
170            ));
171        }
172        let compression_level: u8 = data[3];
173
174        if compression_level < 0x31 || compression_level > 0x39 {
175            return Err(keramics_core::error_trace_new!(format!(
176                "Unsupported compression level: {}",
177                compression_level as char
178            )));
179        }
180        Ok(())
181    }
182}
183
184/// Block header used by bzip2 compressed data.
185struct Bzip2BlockHeader {
186    /// Signature.
187    pub signature: u64,
188
189    /// Checksum.
190    pub checksum: u32,
191
192    pub randomized_flag: u32,
193
194    /// Origin pointer.
195    pub origin_pointer: u32,
196}
197
198impl Bzip2BlockHeader {
199    /// Creates a new block header.
200    pub fn new() -> Self {
201        Self {
202            signature: 0,
203            checksum: 0,
204            randomized_flag: 0,
205            origin_pointer: 0,
206        }
207    }
208
209    /// Reads the block header from a bitstream.
210    pub fn read_from_bitstream(
211        &mut self,
212        bitstream: &mut Bzip2Bitstream,
213    ) -> Result<(), ErrorTrace> {
214        self.signature = ((bitstream.get_value(24) as u64) << 24) | bitstream.get_value(24) as u64;
215
216        if self.signature == 0x177245385090 {
217            self.checksum = bitstream.get_value(32);
218            self.randomized_flag = 0;
219            self.origin_pointer = 0;
220        } else if self.signature == 0x314159265359 {
221            self.checksum = bitstream.get_value(32);
222            self.randomized_flag = bitstream.get_value(1);
223            self.origin_pointer = bitstream.get_value(24);
224        } else {
225            return Err(keramics_core::error_trace_new!(format!(
226                "Unsupported bzip2 signature: 0x{:12x}",
227                self.signature
228            )));
229        }
230        let mediator = Mediator::current();
231        if mediator.debug_output {
232            let mut string_parts: Vec<String> = Vec::new();
233            string_parts.push(format!("Bzip2BlockHeader {{\n"));
234            string_parts.push(format!("    signature: 0x{:012x},\n", self.signature));
235            string_parts.push(format!("    checksum: 0x{:08x},\n", self.checksum));
236
237            if self.signature == 0x314159265359 {
238                string_parts.push(format!("    randomized_flag: {},\n", self.randomized_flag));
239                string_parts.push(format!(
240                    "    origin_pointer: 0x{:06x},\n",
241                    self.origin_pointer
242                ));
243            }
244            string_parts.push(format!("}}\n\n"));
245
246            mediator.debug_print(string_parts.join(""));
247        }
248        Ok(())
249    }
250}
251
252/// Context for decompressing bzip2 compressed data.
253pub struct Bzip2Context {
254    /// Mediator.
255    mediator: MediatorReference,
256
257    /// Uncompressed data size.
258    pub uncompressed_data_size: usize,
259}
260
261impl Bzip2Context {
262    /// Creates a new context.
263    pub fn new() -> Self {
264        Self {
265            mediator: Mediator::current(),
266            uncompressed_data_size: 0,
267        }
268    }
269
270    /// Decompress data.
271    pub fn decompress(
272        &mut self,
273        compressed_data: &[u8],
274        uncompressed_data: &mut [u8],
275    ) -> Result<(), ErrorTrace> {
276        let compressed_data_size: usize = compressed_data.len();
277
278        if compressed_data_size < 14 {
279            return Err(keramics_core::error_trace_new!(
280                "Invalid compressed data value too small"
281            ));
282        }
283        let mut data_header: Bzip2StreamHeader = Bzip2StreamHeader::new();
284
285        if self.mediator.debug_output {
286            let header_size: usize = if compressed_data[0] & 0x20 == 0 { 2 } else { 6 };
287
288            self.mediator.debug_print(format!(
289                "Bzip2StreamHeader data of size: {} at offset: 0 (0x00000000)\n",
290                header_size,
291            ));
292            self.mediator.debug_print_data(compressed_data, true);
293            self.mediator
294                .debug_print(Bzip2StreamHeader::debug_read_data(compressed_data));
295        }
296        data_header.read_data(compressed_data)?;
297
298        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&compressed_data, 4);
299        self.decompress_bitstream(&mut bitstream, uncompressed_data)?;
300
301        Ok(())
302    }
303
304    /// Decompress a bitstream.
305    pub(super) fn decompress_bitstream(
306        &mut self,
307        bitstream: &mut Bzip2Bitstream,
308        uncompressed_data: &mut [u8],
309    ) -> Result<(), ErrorTrace> {
310        let mut block_data: [u8; BZIP2_BLOCK_SIZE] = [0; BZIP2_BLOCK_SIZE];
311        let mut selectors: [u8; 32769] = [0; 32769]; // ( 1 << 15 ) + 1 = 32769
312        let mut symbol_stack: [u8; 256] = [0; 256];
313        let mut uncompressed_data_offset: usize = 0;
314        let uncompressed_data_size: usize = uncompressed_data.len();
315
316        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
317        while bitstream.data_offset < bitstream.data_size {
318            block_header.read_from_bitstream(bitstream)?;
319
320            if block_header.signature == 0x177245385090 {
321                break;
322            }
323            if (block_header.origin_pointer as usize) >= BZIP2_BLOCK_SIZE {
324                return Err(keramics_core::error_trace_new!(format!(
325                    "Invalid origin pointer: 0x{:06x} value out of bounds",
326                    block_header.origin_pointer
327                )));
328            }
329            let number_of_symbols: usize = self.read_symbol_stack(bitstream, &mut symbol_stack)?;
330            let number_of_trees: u32 = bitstream.get_value(3);
331            let number_of_selectors: u32 = bitstream.get_value(15);
332
333            if self.mediator.debug_output {
334                self.mediator.debug_print(format!("Bzip2Bitstream {{\n",));
335                self.mediator
336                    .debug_print(format!("    number_of_symbols: {}\n", number_of_symbols));
337                self.mediator
338                    .debug_print(format!("    number_of_trees: {}\n", number_of_trees));
339                self.mediator.debug_print(format!(
340                    "    number_of_selectors: {}\n",
341                    number_of_selectors
342                ));
343                self.mediator.debug_print(format!("}}\n\n",));
344            }
345            self.read_selectors(
346                bitstream,
347                &mut selectors,
348                number_of_selectors as usize,
349                number_of_trees as usize,
350            )?;
351            let mut huffman_trees: Vec<HuffmanTree> = Vec::new();
352
353            for _ in 0..number_of_trees {
354                let mut huffman_tree: HuffmanTree = HuffmanTree::new(number_of_symbols, 20);
355
356                self.read_huffman_tree(bitstream, &mut huffman_tree, number_of_symbols)?;
357
358                huffman_trees.push(huffman_tree);
359            }
360            let block_data_size: usize = self.read_block_data(
361                bitstream,
362                &huffman_trees,
363                number_of_trees as usize,
364                &selectors,
365                number_of_selectors as usize,
366                &mut symbol_stack,
367                number_of_symbols,
368                &mut block_data,
369            )?;
370            self.reverse_burrows_wheeler_transform(
371                &block_data,
372                block_data_size,
373                block_header.origin_pointer,
374                uncompressed_data,
375                &mut uncompressed_data_offset,
376                uncompressed_data_size,
377            )?;
378        }
379        let mut crc32_context: Crc32Context = Crc32Context::new(0x04c11db7, 0);
380        crc32_context.update(&uncompressed_data[0..uncompressed_data_offset]);
381        let calculated_checksum: u32 = crc32_context.finalize();
382
383        if block_header.checksum != calculated_checksum {
384            return Err(keramics_core::error_trace_new!(format!(
385                "Mismatch between stored: 0x{:08x} and calculated: 0x{:08x} bzip2 block checksums",
386                block_header.checksum, calculated_checksum
387            )));
388        }
389        self.uncompressed_data_size = uncompressed_data_offset;
390
391        Ok(())
392    }
393
394    /// Reads block data from a bitstream.
395    fn read_block_data(
396        &self,
397        bitstream: &mut Bzip2Bitstream,
398        huffman_trees: &[HuffmanTree],
399        number_of_trees: usize,
400        selectors: &[u8],
401        number_of_selectors: usize,
402        symbol_stack: &mut [u8],
403        number_of_symbols: usize,
404        block_data: &mut [u8],
405    ) -> Result<usize, ErrorTrace> {
406        let end_of_block_symbol: u16 = (number_of_symbols - 1) as u16;
407        let mut block_data_offset: usize = 0;
408        let mut number_of_run_length_symbols: u64 = 0;
409        let mut run_length_value: u64 = 0;
410        let mut symbol_index: usize = 0;
411        let mut tree_index: usize = selectors[0] as usize;
412
413        if self.mediator.debug_output {
414            self.mediator.debug_print(format!("Bzip2BlockData {{\n",));
415        }
416        loop {
417            if tree_index >= number_of_trees {
418                return Err(keramics_core::error_trace_new!(format!(
419                    "Invalid tree index: {} value out of bounds",
420                    tree_index
421                )));
422            }
423            let huffman_tree: &HuffmanTree = &huffman_trees[tree_index];
424            let symbol: u16 = huffman_tree.decode_symbol(bitstream)?;
425
426            if number_of_run_length_symbols != 0 && symbol > 1 {
427                let mut run_length: u64 =
428                    ((1 << number_of_run_length_symbols) | run_length_value) - 1;
429
430                if self.mediator.debug_output {
431                    self.mediator
432                        .debug_print(format!("    0-byte run-length: {}\n", run_length,));
433                }
434                if (run_length as usize) > BZIP2_BLOCK_SIZE - block_data_offset {
435                    return Err(keramics_core::error_trace_new!(format!(
436                        "Invalid run length: {} value out of bounds",
437                        run_length
438                    )));
439                }
440                number_of_run_length_symbols = 0;
441                run_length_value = 0;
442
443                while run_length > 0 {
444                    // Inverse move-to-front transform.
445                    // Note that 0 is already at the front of the stack hence the stack does not need to be reordered.
446                    block_data[block_data_offset] = symbol_stack[0];
447
448                    block_data_offset += 1;
449                    run_length -= 1;
450                }
451            }
452            if symbol == end_of_block_symbol {
453                if self.mediator.debug_output {
454                    self.mediator
455                        .debug_print(format!("    symbol: {}\n", symbol));
456                }
457                break;
458            }
459            if symbol == 0 || symbol == 1 {
460                run_length_value |= (symbol as u64) << (number_of_run_length_symbols as u64);
461                number_of_run_length_symbols += 1;
462
463                if self.mediator.debug_output {
464                    self.mediator
465                        .debug_print(format!("    symbol: {} (run-length)\n", symbol));
466                }
467            } else if symbol < end_of_block_symbol {
468                // Inverse move-to-front transform.
469                let stack_value_index: usize = (symbol as usize) - 1;
470
471                let stack_value: u8 = symbol_stack[stack_value_index];
472
473                for stack_index in (0..stack_value_index).rev() {
474                    symbol_stack[stack_index + 1] = symbol_stack[stack_index];
475                }
476                symbol_stack[0] = stack_value;
477
478                if self.mediator.debug_output {
479                    self.mediator
480                        .debug_print(format!("    symbol: {} (MTF: {})\n", symbol, stack_value));
481                }
482                if block_data_offset >= BZIP2_BLOCK_SIZE {
483                    return Err(keramics_core::error_trace_new!(format!(
484                        "Invalid block data offset: {} value out of bounds",
485                        block_data_offset
486                    )));
487                }
488                block_data[block_data_offset] = stack_value;
489
490                block_data_offset += 1;
491            } else {
492                return Err(keramics_core::error_trace_new!(format!(
493                    "Invalid symbol: {} value out of bounds",
494                    symbol
495                )));
496            }
497            symbol_index += 1;
498
499            if symbol_index % 50 == 0 {
500                let selector_index: usize = symbol_index / 50;
501
502                if selector_index > number_of_selectors {
503                    return Err(keramics_core::error_trace_new!(format!(
504                        "Invalid selector index: {} value out of bounds",
505                        selector_index
506                    )));
507                }
508                tree_index = selectors[selector_index] as usize;
509            }
510        }
511        if self.mediator.debug_output {
512            self.mediator.debug_print(format!("}}\n\n",));
513        }
514        Ok(block_data_offset)
515    }
516
517    /// Reads a Huffman tree from a bitstream.
518    fn read_huffman_tree(
519        &self,
520        bitstream: &mut Bzip2Bitstream,
521        huffman_tree: &mut HuffmanTree,
522        number_of_symbols: usize,
523    ) -> Result<(), ErrorTrace> {
524        let mut code_size: u32 = bitstream.get_value(5);
525        let mut code_size_array: [u8; 258] = [0; 258];
526        let mut largest_code_size: u32 = code_size;
527
528        for symbol_index in 0..number_of_symbols {
529            while code_size < 20 {
530                let value_32bit: u32 = bitstream.get_value(1);
531                if value_32bit == 0 {
532                    break;
533                }
534                let value_32bit: u32 = bitstream.get_value(1);
535                if value_32bit == 0 {
536                    code_size += 1;
537                } else {
538                    code_size -= 1;
539                }
540            }
541            if code_size >= 20 {
542                return Err(keramics_core::error_trace_new!(format!(
543                    "Invalid code size: {} value out of bounds",
544                    code_size
545                )));
546            }
547            code_size_array[symbol_index] = code_size as u8;
548
549            largest_code_size = max(code_size, largest_code_size);
550        }
551        if largest_code_size > 32 {
552            return Err(keramics_core::error_trace_new!(format!(
553                "Invalid largest code size: {} value out of bounds",
554                largest_code_size
555            )));
556        }
557        let mut check_value: u32 = 1 << largest_code_size;
558
559        for symbol_index in 0..number_of_symbols {
560            code_size = code_size_array[symbol_index] as u32;
561            check_value -= 1 << (largest_code_size - code_size);
562        }
563        if check_value != 0 {
564            return Err(keramics_core::error_trace_new!(format!(
565                "Invalid check value: {} value out of bounds",
566                check_value
567            )));
568        }
569        huffman_tree.build(&code_size_array[0..number_of_symbols])
570    }
571
572    /// Reads the selectors from a bitstream.
573    fn read_selectors(
574        &self,
575        bitstream: &mut Bzip2Bitstream,
576        selectors: &mut [u8],
577        number_of_selectors: usize,
578        number_of_trees: usize,
579    ) -> Result<(), ErrorTrace> {
580        let mut selector_index: usize = 0;
581        let mut stack: [u8; 7] = [0, 1, 2, 3, 4, 5, 6];
582
583        while selector_index < number_of_selectors {
584            let mut tree_index: usize = 0;
585
586            while tree_index < number_of_trees {
587                let value_32bit: u32 = bitstream.get_value(1);
588                if value_32bit == 0 {
589                    break;
590                }
591                tree_index += 1;
592            }
593            if tree_index >= number_of_trees {
594                return Err(keramics_core::error_trace_new!(format!(
595                    "Invalid tree index: {} value out of bounds",
596                    tree_index
597                )));
598            }
599            // Inverse move-to-front transform.
600            let selector_value: u8 = stack[tree_index];
601
602            selectors[selector_index] = selector_value;
603
604            for stack_index in (0..tree_index).rev() {
605                stack[stack_index + 1] = stack[stack_index];
606            }
607            stack[0] = selector_value;
608
609            selector_index += 1;
610        }
611        if self.mediator.debug_output {
612            self.mediator.debug_print(format!("Bzip2Selectors {{\n",));
613
614            let array_parts: Vec<String> = selectors
615                .iter()
616                .map(|&element| element.to_string())
617                .collect();
618            self.mediator.debug_print(format!(
619                "    selectors: {},",
620                debug_format_array(&array_parts),
621            ));
622            self.mediator.debug_print(format!("}}\n\n",));
623        }
624        Ok(())
625    }
626
627    /// Reads the symbol stack from a bitstream.
628    fn read_symbol_stack(
629        &self,
630        bitstream: &mut Bzip2Bitstream,
631        symbol_stack: &mut [u8],
632    ) -> Result<usize, ErrorTrace> {
633        let level1_value: u32 = bitstream.get_value(16);
634        let mut level1_bitmask: u32 = 0x00008000;
635        let mut symbol_index: usize = 0;
636
637        if self.mediator.debug_output {
638            self.mediator.debug_print(format!("Bzip2SymbolStack {{\n",));
639            self.mediator
640                .debug_print(format!("    level1_value: 0x{:04x},\n", level1_value,));
641            self.mediator.debug_print(format!("    level2_values: [",));
642        }
643        for level1_bit_index in 0..16 {
644            if level1_value & level1_bitmask != 0 {
645                let level2_value: u32 = bitstream.get_value(16);
646                let mut level2_bitmask: u32 = 0x00008000;
647
648                if self.mediator.debug_output {
649                    if level1_bit_index > 0 {
650                        self.mediator.debug_print(format!(", "));
651                    }
652                    self.mediator.debug_print(format!("0x{:04x}", level2_value));
653                }
654                for level2_bit_index in 0..16 {
655                    if level2_value & level2_bitmask != 0 {
656                        if symbol_index > 256 {
657                            return Err(keramics_core::error_trace_new!(format!(
658                                "Invalid symbol index: {} value out of bounds",
659                                symbol_index
660                            )));
661                        }
662                        symbol_stack[symbol_index] = (16 * level1_bit_index) + level2_bit_index;
663
664                        symbol_index += 1;
665                    }
666                    level2_bitmask >>= 1;
667                }
668            }
669            level1_bitmask >>= 1;
670        }
671        if self.mediator.debug_output {
672            self.mediator.debug_print(format!("],\n",));
673            // TODO: move to a debug_format_array like function.
674            self.mediator
675                .debug_print(format!("    symbols: [0x{:02x}", symbol_stack[0]));
676            for symbol in &symbol_stack[1..symbol_index] {
677                self.mediator.debug_print(format!(", 0x{:02x}", symbol));
678            }
679            self.mediator.debug_print(format!("],\n",));
680            self.mediator.debug_print(format!("}}\n\n",));
681        }
682        Ok(symbol_index + 2)
683    }
684
685    /// Performs a Burrows-Wheeler transform
686    fn reverse_burrows_wheeler_transform(
687        &self,
688        block_data: &[u8],
689        block_data_size: usize,
690        origin_pointer: u32,
691        uncompressed_data: &mut [u8],
692        uncompressed_data_offset: &mut usize,
693        uncompressed_data_size: usize,
694    ) -> Result<(), ErrorTrace> {
695        let mut data_offset: usize = *uncompressed_data_offset;
696        let mut distribution_value: usize = 0;
697        let mut distributions: [usize; 256] = [0; 256];
698        let mut last_byte_value: u8 = 0;
699        let mut number_of_last_byte_values: u8 = 0;
700        let mut permutations: [usize; BZIP2_BLOCK_SIZE] = [0; BZIP2_BLOCK_SIZE];
701
702        for block_data_offset in 0..block_data_size {
703            let byte_value: u8 = block_data[block_data_offset];
704            distributions[byte_value as usize] += 1;
705        }
706        for byte_value in 0..256 {
707            let number_of_values: usize = distributions[byte_value as usize];
708            distributions[byte_value] = distribution_value;
709            distribution_value += number_of_values;
710        }
711        for block_data_offset in 0..block_data_size {
712            let byte_value: u8 = block_data[block_data_offset];
713            distribution_value = distributions[byte_value as usize];
714            permutations[distribution_value] = block_data_offset;
715            distributions[byte_value as usize] += 1;
716        }
717        let mut permutation_value: usize = permutations[origin_pointer as usize];
718
719        for _ in 0..block_data_size {
720            let mut byte_value: u8 = block_data[permutation_value];
721
722            if number_of_last_byte_values == 4 {
723                if byte_value as usize > uncompressed_data_size - data_offset {
724                    return Err(keramics_core::error_trace_new!(
725                        "Invalid uncompressed data value too small"
726                    ));
727                }
728                while byte_value > 0 {
729                    uncompressed_data[data_offset] = last_byte_value;
730
731                    data_offset += 1;
732                    byte_value -= 1;
733                }
734                last_byte_value = 0;
735                number_of_last_byte_values = 0;
736            } else {
737                if byte_value != last_byte_value {
738                    number_of_last_byte_values = 0;
739                }
740                last_byte_value = byte_value;
741                number_of_last_byte_values += 1;
742
743                if data_offset >= uncompressed_data_size {
744                    return Err(keramics_core::error_trace_new!(
745                        "Invalid uncompressed data value too small"
746                    ));
747                }
748                uncompressed_data[data_offset] = byte_value;
749
750                data_offset += 1;
751            }
752            permutation_value = permutations[permutation_value];
753        }
754        *uncompressed_data_offset = data_offset;
755
756        Ok(())
757    }
758}
759
760#[cfg(test)]
761mod tests {
762    use super::*;
763
764    fn get_test_data() -> Vec<u8> {
765        return vec![
766            0x42, 0x5a, 0x68, 0x31, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x5a, 0x55, 0xc4, 0x1e,
767            0x00, 0x00, 0x0c, 0x5f, 0x80, 0x20, 0x00, 0x40, 0x84, 0x00, 0x00, 0x80, 0x20, 0x40,
768            0x00, 0x2f, 0x6c, 0xdc, 0x80, 0x20, 0x00, 0x48, 0x4a, 0x9a, 0x4c, 0xd5, 0x53, 0xfc,
769            0x69, 0xa5, 0x53, 0xff, 0x55, 0x3f, 0x69, 0x50, 0x15, 0x48, 0x95, 0x4f, 0xff, 0x55,
770            0x51, 0xff, 0xaa, 0xa0, 0xff, 0xf5, 0x55, 0x31, 0xff, 0xaa, 0xa7, 0xfb, 0x4b, 0x34,
771            0xc9, 0xb8, 0x38, 0xff, 0x16, 0x14, 0x56, 0x5a, 0xe2, 0x8b, 0x9d, 0x50, 0xb9, 0x00,
772            0x81, 0x1a, 0x91, 0xfa, 0x25, 0x4f, 0x08, 0x5f, 0x4b, 0x5f, 0x53, 0x92, 0x4b, 0x11,
773            0xc5, 0x22, 0x92, 0xd9, 0x50, 0x56, 0x6b, 0x6f, 0x9e, 0x17, 0x72, 0x45, 0x38, 0x50,
774            0x90, 0x5a, 0x55, 0xc4, 0x1e,
775        ];
776    }
777
778    #[test]
779    fn test_bitstream_get_value() {
780        let test_data: Vec<u8> = get_test_data();
781
782        let mut test_bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
783
784        let test_value: u32 = test_bitstream.get_value(0);
785        assert_eq!(test_value, 0);
786
787        let test_value: u32 = test_bitstream.get_value(4);
788        assert_eq!(test_value, 0x00000003);
789
790        let test_value: u32 = test_bitstream.get_value(12);
791        assert_eq!(test_value, 0x00000141);
792
793        let test_value: u32 = test_bitstream.get_value(32);
794        assert_eq!(test_value, 0x59265359);
795
796        let mut test_bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
797
798        let test_value: u32 = test_bitstream.get_value(12);
799        assert_eq!(test_value, 0x00000314);
800
801        let test_value: u32 = test_bitstream.get_value(32);
802        assert_eq!(test_value, 0x15926535);
803    }
804
805    #[test]
806    fn test_bitstream_skip_bits() {
807        let test_data: Vec<u8> = get_test_data();
808
809        let mut test_bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
810
811        test_bitstream.skip_bits(4);
812        let test_value: u32 = test_bitstream.get_value(12);
813        assert_eq!(test_value, 0x00000141);
814    }
815
816    #[test]
817    fn test_read_stream_header() -> Result<(), ErrorTrace> {
818        let mut stream_header: Bzip2StreamHeader = Bzip2StreamHeader::new();
819
820        let test_data: Vec<u8> = get_test_data();
821        stream_header.read_data(&test_data)?;
822
823        Ok(())
824    }
825
826    #[test]
827    fn test_read_block_header() -> Result<(), ErrorTrace> {
828        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
829
830        let test_data: Vec<u8> = get_test_data();
831        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
832        block_header.read_from_bitstream(&mut bitstream)?;
833
834        assert_eq!(block_header.signature, 0x314159265359);
835        assert_eq!(block_header.checksum, 0x5a55c41e);
836        assert_eq!(block_header.randomized_flag, 0);
837        assert_eq!(block_header.origin_pointer, 0x000018);
838
839        Ok(())
840    }
841
842    #[test]
843    fn test_read_symbol_stack() -> Result<(), ErrorTrace> {
844        let test_data: Vec<u8> = get_test_data();
845
846        let test_context: Bzip2Context = Bzip2Context::new();
847
848        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
849        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
850        block_header.read_from_bitstream(&mut bitstream)?;
851
852        let mut symbol_stack: [u8; 256] = [0; 256];
853        let number_of_symbols: usize =
854            test_context.read_symbol_stack(&mut bitstream, &mut symbol_stack)?;
855
856        let expected_symbol_stack: [u8; 24] = [
857            1, 32, 39, 44, 63, 73, 80, 97, 99, 100, 101, 102, 104, 105, 107, 108, 111, 112, 114,
858            115, 116, 119, 0, 0,
859        ];
860        assert_eq!(number_of_symbols, 24);
861        assert_eq!(&symbol_stack[0..24], &expected_symbol_stack);
862
863        Ok(())
864    }
865
866    #[test]
867    fn test_read_selectors() -> Result<(), ErrorTrace> {
868        let test_data: Vec<u8> = get_test_data();
869
870        let test_context: Bzip2Context = Bzip2Context::new();
871
872        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
873        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
874        block_header.read_from_bitstream(&mut bitstream)?;
875
876        let mut symbol_stack: [u8; 256] = [0; 256];
877        test_context.read_symbol_stack(&mut bitstream, &mut symbol_stack)?;
878
879        let number_of_trees: u32 = bitstream.get_value(3);
880        let number_of_selectors: u32 = bitstream.get_value(15);
881
882        let mut selectors: [u8; 32769] = [0; 32769];
883        test_context.read_selectors(
884            &mut bitstream,
885            &mut selectors,
886            number_of_selectors as usize,
887            number_of_trees as usize,
888        )?;
889        let expected_selectors: [u8; 2] = [0, 1];
890        assert_eq!(&selectors[0..2], &expected_selectors);
891
892        Ok(())
893    }
894
895    #[test]
896    fn test_read_huffman_tree() -> Result<(), ErrorTrace> {
897        let test_data: Vec<u8> = get_test_data();
898
899        let test_context: Bzip2Context = Bzip2Context::new();
900
901        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
902        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
903        block_header.read_from_bitstream(&mut bitstream)?;
904
905        let mut symbol_stack: [u8; 256] = [0; 256];
906        let number_of_symbols: usize =
907            test_context.read_symbol_stack(&mut bitstream, &mut symbol_stack)?;
908        let number_of_trees: u32 = bitstream.get_value(3);
909        let number_of_selectors: u32 = bitstream.get_value(15);
910
911        let mut selectors: [u8; 32769] = [0; 32769];
912        test_context.read_selectors(
913            &mut bitstream,
914            &mut selectors,
915            number_of_selectors as usize,
916            number_of_trees as usize,
917        )?;
918
919        let mut huffman_tree: HuffmanTree = HuffmanTree::new(number_of_symbols, 20);
920        test_context.read_huffman_tree(&mut bitstream, &mut huffman_tree, number_of_symbols)?;
921
922        Ok(())
923    }
924
925    #[test]
926    fn test_read_block_data() -> Result<(), ErrorTrace> {
927        let test_data: Vec<u8> = get_test_data();
928
929        let test_context: Bzip2Context = Bzip2Context::new();
930
931        let mut block_header: Bzip2BlockHeader = Bzip2BlockHeader::new();
932        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
933        block_header.read_from_bitstream(&mut bitstream)?;
934
935        let mut symbol_stack: [u8; 256] = [0; 256];
936        let number_of_symbols: usize =
937            test_context.read_symbol_stack(&mut bitstream, &mut symbol_stack)?;
938        let number_of_trees: u32 = bitstream.get_value(3);
939        let number_of_selectors: u32 = bitstream.get_value(15);
940
941        let mut selectors: [u8; 32769] = [0; 32769];
942        test_context.read_selectors(
943            &mut bitstream,
944            &mut selectors,
945            number_of_selectors as usize,
946            number_of_trees as usize,
947        )?;
948        let mut huffman_trees: Vec<HuffmanTree> = Vec::new();
949
950        for _ in 0..number_of_trees {
951            let mut huffman_tree: HuffmanTree = HuffmanTree::new(number_of_symbols, 20);
952
953            test_context.read_huffman_tree(&mut bitstream, &mut huffman_tree, number_of_symbols)?;
954
955            huffman_trees.push(huffman_tree);
956        }
957        let mut block_data: [u8; BZIP2_BLOCK_SIZE] = [0; BZIP2_BLOCK_SIZE];
958        let block_data_size: usize = test_context.read_block_data(
959            &mut bitstream,
960            &huffman_trees,
961            number_of_trees as usize,
962            &selectors,
963            number_of_selectors as usize,
964            &mut symbol_stack,
965            number_of_symbols,
966            &mut block_data,
967        )?;
968        let expected_block_data: [u8; 108] = [
969            0x3f, 0x66, 0x73, 0x72, 0x72, 0x64, 0x6b, 0x6b, 0x65, 0x61, 0x64, 0x64, 0x72, 0x72,
970            0x66, 0x66, 0x73, 0x2c, 0x65, 0x73, 0x3f, 0x3f, 0x3f, 0x64, 0x01, 0x20, 0x20, 0x20,
971            0x20, 0x20, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, 0x65, 0x65, 0x65, 0x65, 0x68, 0x72,
972            0x70, 0x70, 0x6b, 0x6c, 0x6c, 0x6b, 0x70, 0x70, 0x74, 0x74, 0x70, 0x70, 0x68, 0x70,
973            0x70, 0x50, 0x50, 0x49, 0x6f, 0x6f, 0x74, 0x77, 0x70, 0x70, 0x70, 0x70, 0x50, 0x50,
974            0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
975            0x69, 0x69, 0x70, 0x70, 0x20, 0x20, 0x20, 0x20, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
976            0x65, 0x65, 0x65, 0x72, 0x27, 0x72, 0x65, 0x65, 0x20, 0x20,
977        ];
978        assert_eq!(block_data_size, 108);
979        assert_eq!(&block_data[0..108], &expected_block_data);
980
981        Ok(())
982    }
983
984    #[test]
985    fn test_reverse_burrows_wheeler_transform() -> Result<(), ErrorTrace> {
986        let test_context: Bzip2Context = Bzip2Context::new();
987
988        let block_data: [u8; 35] = [
989            0x73, 0x73, 0x65, 0x65, 0x79, 0x65, 0x65, 0x20, 0x68, 0x68, 0x73, 0x73, 0x68, 0x73,
990            0x72, 0x74, 0x73, 0x73, 0x73, 0x65, 0x65, 0x6c, 0x6c, 0x68, 0x6f, 0x6c, 0x6c, 0x20,
991            0x20, 0x20, 0x65, 0x61, 0x61, 0x20, 0x62,
992        ];
993        let mut uncompressed_data: [u8; 35] = [0; 35];
994        let mut uncompressed_data_offset: usize = 0;
995        test_context.reverse_burrows_wheeler_transform(
996            &block_data,
997            35,
998            30,
999            &mut uncompressed_data,
1000            &mut uncompressed_data_offset,
1001            35,
1002        )?;
1003        let expected_uncompressed_data: [u8; 35] = [
1004            0x73, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x73, 0x65, 0x61, 0x73,
1005            0x68, 0x65, 0x6c, 0x6c, 0x73, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
1006            0x65, 0x61, 0x73, 0x68, 0x6f, 0x72, 0x65,
1007        ];
1008        assert_eq!(uncompressed_data_offset, 35);
1009        assert_eq!(&uncompressed_data, &expected_uncompressed_data);
1010
1011        Ok(())
1012    }
1013
1014    #[test]
1015    fn test_decompress_bitstream() -> Result<(), ErrorTrace> {
1016        let test_data: Vec<u8> = get_test_data();
1017
1018        let mut test_context: Bzip2Context = Bzip2Context::new();
1019
1020        let mut bitstream: Bzip2Bitstream = Bzip2Bitstream::new(&test_data, 4);
1021        let mut uncompressed_data: Vec<u8> = vec![0; 512];
1022        test_context.decompress_bitstream(&mut bitstream, &mut uncompressed_data)?;
1023
1024        let expected_uncompressed_data: [u8; 108] = [
1025            0x49, 0x66, 0x20, 0x50, 0x65, 0x74, 0x65, 0x72, 0x20, 0x50, 0x69, 0x70, 0x65, 0x72,
1026            0x20, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x20, 0x70, 0x65, 0x63, 0x6b,
1027            0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x64, 0x20, 0x70, 0x65,
1028            0x70, 0x70, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x27, 0x73,
1029            0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x63, 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x70,
1030            0x69, 0x63, 0x6b, 0x6c, 0x65, 0x64, 0x20, 0x70, 0x65, 0x70, 0x70, 0x65, 0x72, 0x73,
1031            0x20, 0x50, 0x65, 0x74, 0x65, 0x72, 0x20, 0x50, 0x69, 0x70, 0x65, 0x72, 0x20, 0x70,
1032            0x69, 0x63, 0x6b, 0x65, 0x64, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
1033        ];
1034        assert_eq!(
1035            &uncompressed_data[0..test_context.uncompressed_data_size],
1036            expected_uncompressed_data
1037        );
1038
1039        Ok(())
1040    }
1041
1042    #[test]
1043    fn test1_decompress() -> Result<(), ErrorTrace> {
1044        let mut test_context: Bzip2Context = Bzip2Context::new();
1045
1046        let test_data: Vec<u8> = get_test_data();
1047        let mut uncompressed_data: Vec<u8> = vec![0; 512];
1048        test_context.decompress(&test_data, &mut uncompressed_data)?;
1049        assert_eq!(test_context.uncompressed_data_size, 108);
1050
1051        let expected_uncompressed_data: [u8; 108] = [
1052            0x49, 0x66, 0x20, 0x50, 0x65, 0x74, 0x65, 0x72, 0x20, 0x50, 0x69, 0x70, 0x65, 0x72,
1053            0x20, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x20, 0x70, 0x65, 0x63, 0x6b,
1054            0x20, 0x6f, 0x66, 0x20, 0x70, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x64, 0x20, 0x70, 0x65,
1055            0x70, 0x70, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x27, 0x73,
1056            0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x63, 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x70,
1057            0x69, 0x63, 0x6b, 0x6c, 0x65, 0x64, 0x20, 0x70, 0x65, 0x70, 0x70, 0x65, 0x72, 0x73,
1058            0x20, 0x50, 0x65, 0x74, 0x65, 0x72, 0x20, 0x50, 0x69, 0x70, 0x65, 0x72, 0x20, 0x70,
1059            0x69, 0x63, 0x6b, 0x65, 0x64, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
1060        ];
1061        assert_eq!(
1062            &uncompressed_data[0..test_context.uncompressed_data_size],
1063            expected_uncompressed_data
1064        );
1065        Ok(())
1066    }
1067
1068    #[test]
1069    fn test2_decompress() -> Result<(), ErrorTrace> {
1070        let mut test_context: Bzip2Context = Bzip2Context::new();
1071
1072        let test_data: [u8; 122] = [
1073            0x42, 0x5a, 0x68, 0x31, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xef, 0x2d, 0xfa, 0x16,
1074            0x00, 0x00, 0x21, 0xfe, 0x57, 0xf8, 0x00, 0x00, 0xc2, 0xda, 0x00, 0x00, 0x30, 0x23,
1075            0x30, 0x54, 0x04, 0x49, 0x89, 0x68, 0x40, 0x05, 0x00, 0x01, 0x01, 0x00, 0x40, 0x00,
1076            0x09, 0xa0, 0x00, 0x54, 0x61, 0xa1, 0xa3, 0x26, 0x20, 0xc2, 0x1a, 0x06, 0x20, 0xf2,
1077            0x83, 0x45, 0x06, 0x80, 0x1a, 0x00, 0xd1, 0xa1, 0x90, 0xc8, 0x20, 0xe4, 0x11, 0x4d,
1078            0x1b, 0xf8, 0x40, 0x2d, 0x15, 0x01, 0x98, 0x51, 0x82, 0x01, 0x06, 0x0b, 0x63, 0x21,
1079            0xd1, 0xad, 0xa9, 0xf9, 0xeb, 0x4b, 0xb3, 0xc9, 0xac, 0xf1, 0xcc, 0x68, 0xf3, 0x2f,
1080            0x19, 0x0a, 0x3e, 0x96, 0x3e, 0x82, 0x0a, 0x03, 0xa8, 0x0a, 0x0b, 0x35, 0x44, 0xfc,
1081            0x5d, 0xc9, 0x14, 0xe1, 0x42, 0x43, 0xbc, 0xb7, 0xe8, 0x58,
1082        ];
1083        let mut uncompressed_data: Vec<u8> = vec![0; 512];
1084        test_context.decompress(&test_data, &mut uncompressed_data)?;
1085        assert_eq!(test_context.uncompressed_data_size, 512);
1086
1087        let expected_uncompressed_data: [u8; 512] = [
1088            0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, 0x00, 0x00, 0x01, 0x00, 0x5c, 0x00,
1089            0x00, 0x00, 0x17, 0xc4, 0x17, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1090            0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00,
1091            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092            0x87, 0x3a, 0xd6, 0x8e, 0x83, 0x17, 0xfe, 0x4a, 0x8b, 0xa3, 0x18, 0x39, 0xc6, 0x23,
1093            0x25, 0x86, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
1094            0x80, 0x00, 0x00, 0x00, 0xe8, 0xa8, 0x45, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1099            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1111            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1113            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1114            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1115            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1116            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1117            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1119            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1121            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1122            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1123            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1124            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125        ];
1126        assert_eq!(
1127            &uncompressed_data[0..test_context.uncompressed_data_size],
1128            expected_uncompressed_data
1129        );
1130
1131        Ok(())
1132    }
1133}