keramics_compression/
lzfse.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//! LZFSE decompression.
15//!
16//! Provides decompression support for LZFSE compressed data.
17
18use std::cmp::min;
19
20use keramics_core::ErrorTrace;
21use keramics_core::mediator::{Mediator, MediatorReference};
22use keramics_layout_map::LayoutMap;
23use keramics_types::{bytes_to_i32_le, bytes_to_u16_le, bytes_to_u32_le, bytes_to_u64_le};
24
25use super::lzvn::LzvnContext;
26use super::traits::Bitstream;
27
28const LZFSE_END_OF_STREAM_BLOCK_MARKER: u32 = 0x24787662;
29const LZFSE_UNCOMPRESSED_BLOCK_MARKER: u32 = 0x2d787662;
30const LZFSE_COMPRESSED_BLOCK_V1_MARKER: u32 = 0x31787662;
31const LZFSE_COMPRESSED_BLOCK_V2_MARKER: u32 = 0x32787662;
32const LZFSE_COMPRESSED_BLOCK_LZVN_MARKER: u32 = 0x6e787662;
33
34const LZFSE_NUMBER_OF_LITERAL_STATES: i16 = 1024;
35const LZFSE_NUMBER_OF_LITERAL_SYMBOLS: i16 = 256;
36
37const LZFSE_NUMBER_OF_L_VALUE_STATES: i16 = 64;
38const LZFSE_NUMBER_OF_L_VALUE_SYMBOLS: i16 = 20;
39
40const LZFSE_NUMBER_OF_M_VALUE_STATES: i16 = 64;
41const LZFSE_NUMBER_OF_M_VALUE_SYMBOLS: i16 = 20;
42
43const LZFSE_NUMBER_OF_D_VALUE_STATES: i16 = 256;
44const LZFSE_NUMBER_OF_D_VALUE_SYMBOLS: i16 = 64;
45
46// const LZFSE_MATCHES_PER_BLOCK: usize = 10000;
47// const LZFSE_LITERALS_PER_BLOCK: usize = 40000; // 4 * LZFSE_MATCHES_PER_BLOCK;
48const LZFSE_MAXIMUM_NUMBER_OF_LITERALS: usize = 40064; // LZFSE_LITERALS_PER_BLOCK + 64
49
50const LZFSE_FREQUENCY_NUMBER_OF_BITS_TABLE: [u8; 32] = [
51    2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14, 2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2,
52    14,
53];
54
55const LZFSE_FREQUENCY_VALUE_TABLE: [u16; 32] = [
56    0, 2, 1, 4, 0, 3, 1, 0xffff, 0, 2, 1, 5, 0, 3, 1, 0xffff, 0, 2, 1, 6, 0, 3, 1, 0xffff, 0, 2, 1,
57    7, 0, 3, 1, 0xffff,
58];
59
60const LZFSE_D_VALUE_BITS_TABLE: [u8; 64] = [
61    0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
62    8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14,
63    14, 14, 15, 15, 15, 15,
64];
65
66const LZFSE_D_VALUE_BASE_TABLE: [i32; 64] = [
67    0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 36, 44, 52, 60, 76, 92, 108, 124, 156, 188, 220,
68    252, 316, 380, 444, 508, 636, 764, 892, 1020, 1276, 1532, 1788, 2044, 2556, 3068, 3580, 4092,
69    5116, 6140, 7164, 8188, 10236, 12284, 14332, 16380, 20476, 24572, 28668, 32764, 40956, 49148,
70    57340, 65532, 81916, 98300, 114684, 131068, 163836, 196604, 229372,
71];
72
73const LZFSE_L_VALUE_BITS_TABLE: [u8; 20] =
74    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 8];
75
76const LZFSE_L_VALUE_BASE_TABLE: [i32; 20] = [
77    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 28, 60,
78];
79
80const LZFSE_M_VALUE_BITS_TABLE: [u8; 20] =
81    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11];
82
83const LZFSE_M_VALUE_BASE_TABLE: [i32; 20] = [
84    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 56, 312,
85];
86
87/// Bitstream for LZFSE compressed data.
88pub(super) struct LzfseBitstream<'a> {
89    /// Byte steam.
90    data: &'a [u8],
91
92    /// Current offset in the byte stream.
93    pub data_offset: usize,
94
95    /// Size of the byte stream in bytes.
96    pub data_size: usize,
97
98    /// Bits buffer.
99    bits: u32,
100
101    /// Number of bits in the bits buffer.
102    pub number_of_bits: usize,
103}
104
105impl<'a> LzfseBitstream<'a> {
106    /// Creates a new bitstream.
107    pub fn new(data: &'a [u8], data_offset: usize) -> Self {
108        let data_size: usize = data.len();
109        Self {
110            data: data,
111            data_offset: data_offset,
112            data_size: data_size,
113            bits: 0,
114            number_of_bits: 0,
115        }
116    }
117
118    /// Reads input data backwards into the bits buffer in big-endian byte order.
119    #[inline(always)]
120    fn read_data(&mut self, number_of_bits: usize) {
121        while number_of_bits > self.number_of_bits {
122            self.bits <<= 8;
123
124            // If the bit stream overflows fill the bit buffer with 0 byte values.
125            if self.data_offset > 0 {
126                self.data_offset -= 1;
127                self.bits |= self.data[self.data_offset] as u32;
128            }
129            self.number_of_bits += 8;
130        }
131    }
132}
133
134impl<'a> Bitstream for LzfseBitstream<'a> {
135    /// Retrieves a bit value.
136    fn get_value(&mut self, number_of_bits: usize) -> u32 {
137        // Note that this does not check if number_of_bits <= 32
138        let mut bit_value: u32 = 0;
139
140        let mut bit_offset: usize = 0;
141        while bit_offset < number_of_bits {
142            let mut read_size: usize = number_of_bits - bit_offset;
143            if read_size > 24 {
144                read_size = 24;
145            }
146            if self.number_of_bits < read_size {
147                self.read_data(read_size);
148            }
149            let mut value_32bit: u32 = self.bits;
150
151            self.number_of_bits -= read_size;
152
153            if self.number_of_bits == 0 {
154                self.bits = 0;
155            } else {
156                self.bits &= 0xffffffff >> (32 - self.number_of_bits);
157
158                value_32bit >>= self.number_of_bits;
159            }
160            if bit_offset > 0 {
161                bit_value <<= read_size;
162            }
163            bit_value |= value_32bit;
164            bit_offset += read_size;
165        }
166        bit_value
167    }
168
169    /// Skips a number of bits.
170    fn skip_bits(&mut self, number_of_bits: usize) {
171        // Note that this does not check if number_of_bits <= 32
172        let mut bit_offset: usize = 0;
173        while bit_offset < number_of_bits {
174            let mut read_size: usize = number_of_bits - bit_offset;
175            if read_size > 24 {
176                read_size = 24;
177            }
178            if self.number_of_bits < read_size {
179                self.read_data(read_size);
180            }
181            self.number_of_bits -= read_size;
182
183            if self.number_of_bits == 0 {
184                self.bits = 0;
185            } else {
186                self.bits &= 0xffffffff >> (32 - self.number_of_bits);
187            }
188            bit_offset += read_size;
189        }
190    }
191}
192
193#[derive(LayoutMap)]
194#[layout_map(
195    structure(
196        byte_order = "little",
197        field(name = "compressed_block_size", data_type = "u32"),
198        field(name = "number_of_literals", data_type = "u32"),
199        field(name = "number_of_lmd_values", data_type = "u32"),
200        field(name = "literals_data_size", data_type = "u32"),
201        field(name = "lmd_values_data_size", data_type = "u32"),
202        field(name = "literal_bits", data_type = "i32"),
203        field(name = "literal_states", data_type = "[u16; 4]"),
204        field(name = "lmd_values_bits", data_type = "i32"),
205        field(name = "l_value_state", data_type = "u16"),
206        field(name = "m_value_state", data_type = "u16"),
207        field(name = "d_value_state", data_type = "u16"),
208    ),
209    method(name = "debug_read_data")
210)]
211/// LZFSE version 1 block header.
212struct LzfseBlockV1Header {}
213
214impl LzfseBlockV1Header {
215    /// Creates a new block header.
216    pub fn new() -> Self {
217        Self {}
218    }
219
220    /// Reads the block header from a buffer.
221    pub fn read_data(&mut self, data: &[u8], decoder: &mut LzfseDecoder) -> Result<(), ErrorTrace> {
222        if data.len() != 42 {
223            return Err(keramics_core::error_trace_new!(
224                "Unsupported LZFSE version 1 block header data size"
225            ));
226        }
227        decoder.number_of_literals = bytes_to_u32_le!(data, 4);
228        decoder.number_of_lmd_values = bytes_to_u32_le!(data, 8);
229        decoder.literals_data_size = bytes_to_u32_le!(data, 12);
230        decoder.lmd_values_data_size = bytes_to_u32_le!(data, 16);
231        decoder.literal_bits = bytes_to_i32_le!(data, 20);
232
233        let mut data_offset: usize = 24;
234        for literal_state_index in 0..4 {
235            decoder.literal_states[literal_state_index] = bytes_to_u16_le!(data, data_offset);
236            data_offset += 2;
237        }
238        decoder.lmd_values_bits = bytes_to_i32_le!(data, 32);
239        decoder.l_value_state = bytes_to_u16_le!(data, 36);
240        decoder.m_value_state = bytes_to_u16_le!(data, 38);
241        decoder.d_value_state = bytes_to_u16_le!(data, 40);
242
243        Ok(())
244    }
245}
246
247#[derive(LayoutMap)]
248#[layout_map(
249    structure(
250        byte_order = "little",
251        field(name = "number_of_literals", data_type = "BitField64<20>"),
252        field(name = "literals_data_size", data_type = "BitField64<20>"),
253        field(name = "number_of_lmd_values", data_type = "BitField64<20>"),
254        field(name = "literal_bits", data_type = "BitField64<3>", modifier = "- 7"),
255        field(name = "unknown1", data_type = "BitField64<1>"),
256        field(name = "literal_state1", data_type = "BitField64<10>"),
257        field(name = "literal_state2", data_type = "BitField64<10>"),
258        field(name = "literal_state3", data_type = "BitField64<10>"),
259        field(name = "literal_state4", data_type = "BitField64<10>"),
260        field(name = "lmd_values_data_size", data_type = "BitField64<20>"),
261        field(
262            name = "lmd_values_bits",
263            data_type = "BitField64<3>",
264            modifier = "- 7"
265        ),
266        field(name = "unknown2", data_type = "BitField64<1>"),
267        field(name = "header_size", data_type = "BitField64<32>"),
268        field(name = "l_value_state", data_type = "BitField64<10>"),
269        field(name = "m_value_state", data_type = "BitField64<10>"),
270        field(name = "d_value_state", data_type = "BitField64<10>"),
271        field(name = "unknown3", data_type = "BitField64<2>"),
272    ),
273    method(name = "debug_read_data")
274)]
275/// LZFSE version 2 block header.
276struct LzfseBlockV2Header {
277    header_size: u32,
278}
279
280impl LzfseBlockV2Header {
281    /// Creates a new block header.
282    pub fn new() -> Self {
283        Self { header_size: 0 }
284    }
285
286    /// Reads the block header from a buffer.
287    pub fn read_data(&mut self, data: &[u8], decoder: &mut LzfseDecoder) -> Result<(), ErrorTrace> {
288        if data.len() < 24 {
289            return Err(keramics_core::error_trace_new!(
290                "Unsupported LZFSE version 2 block header data size"
291            ));
292        }
293        let bit_fields1: u64 = bytes_to_u64_le!(data, 0);
294        let bit_fields2: u64 = bytes_to_u64_le!(data, 8);
295        let bit_fields3: u64 = bytes_to_u64_le!(data, 16);
296
297        self.header_size = (bit_fields3 & 0xffffffff) as u32;
298
299        decoder.number_of_literals = (bit_fields1 & 0x000fffff) as u32;
300        decoder.literals_data_size = ((bit_fields1 >> 20) & 0x000fffff) as u32;
301        decoder.number_of_lmd_values = ((bit_fields1 >> 40) & 0x000fffff) as u32;
302        decoder.literal_bits = (((bit_fields1 >> 60) & 0x00000007) as i32) - 7;
303
304        decoder.literal_states[0] = (bit_fields2 & 0x000003ff) as u16;
305        decoder.literal_states[1] = ((bit_fields2 >> 10) & 0x000003ff) as u16;
306        decoder.literal_states[2] = ((bit_fields2 >> 20) & 0x000003ff) as u16;
307        decoder.literal_states[3] = ((bit_fields2 >> 30) & 0x000003ff) as u16;
308        decoder.lmd_values_data_size = ((bit_fields2 >> 40) & 0x000fffff) as u32;
309        decoder.lmd_values_bits = (((bit_fields2 >> 60) & 0x00000007) as i32) - 7;
310
311        decoder.l_value_state = ((bit_fields3 >> 32) & 0x000003ff) as u16;
312        decoder.m_value_state = ((bit_fields3 >> 42) & 0x000003ff) as u16;
313        decoder.d_value_state = ((bit_fields3 >> 52) & 0x000003ff) as u16;
314
315        if self.header_size < 32 || self.header_size > 720 {
316            return Err(keramics_core::error_trace_new!(format!(
317                "Invalid header size: {} value out of bounds",
318                self.header_size
319            )));
320        }
321        Ok(())
322    }
323}
324
325/// Decoder entry for decompressing LZFSE compressed data.
326struct LzfseDecoderEntry {
327    /// The number of bits.
328    pub number_of_bits: i8,
329
330    /// The symbol.
331    pub symbol: u8,
332
333    /// The delta to compute the next state.
334    pub delta: i16,
335}
336
337impl LzfseDecoderEntry {
338    /// Creates a new decoder entry.
339    pub fn new() -> Self {
340        Self {
341            number_of_bits: 0,
342            symbol: 0,
343            delta: 0,
344        }
345    }
346}
347
348/// Value decoder entry for decompressing LZFSE compressed data.
349struct LzfseValueDecoderEntry {
350    /// The (total) number of bits.
351    pub number_of_bits: u8,
352
353    /// The value bits.
354    pub value_bits: u8,
355
356    /// The delta.
357    pub delta: i16,
358
359    /// The value base.
360    pub value_base: i32,
361
362    /// The value bitmask.
363    pub value_bitmask: u32,
364}
365
366impl LzfseValueDecoderEntry {
367    /// Creates a new value decoder entry.
368    pub fn new() -> Self {
369        Self {
370            number_of_bits: 0,
371            value_bits: 0,
372            delta: 0,
373            value_base: 0,
374            value_bitmask: 0,
375        }
376    }
377}
378
379/// Decoder for decompressing LZFSE compressed data.
380struct LzfseDecoder {
381    /// The number of literals.
382    pub number_of_literals: u32,
383
384    /// The number of L, M and D values.
385    pub number_of_lmd_values: u32,
386
387    /// The literals data size.
388    pub literals_data_size: u32,
389
390    /// The L, M and D values data size.
391    pub lmd_values_data_size: u32,
392
393    /// The literal states.
394    pub literal_states: [u16; 4],
395
396    /// The L value states.
397    pub l_value_state: u16,
398
399    /// The M value states.
400    pub m_value_state: u16,
401
402    /// The D value states.
403    pub d_value_state: u16,
404
405    /// The literal number of bits.
406    pub literal_bits: i32,
407
408    /// The L, M and D values number of bits.
409    pub lmd_values_bits: i32,
410
411    /// The literal decoder table.
412    pub literal_decoder_table: Vec<LzfseDecoderEntry>,
413
414    /// The L value decoder table.
415    pub l_value_decoder_table: Vec<LzfseValueDecoderEntry>,
416
417    /// The M value decoder table.
418    pub m_value_decoder_table: Vec<LzfseValueDecoderEntry>,
419
420    /// The D value decoder table.
421    pub d_value_decoder_table: Vec<LzfseValueDecoderEntry>,
422}
423
424impl LzfseDecoder {
425    /// Creates a new decoder.
426    pub fn new() -> Self {
427        Self {
428            number_of_literals: 0,
429            number_of_lmd_values: 0,
430            literals_data_size: 0,
431            lmd_values_data_size: 0,
432            literal_states: [0; 4],
433            l_value_state: 0,
434            m_value_state: 0,
435            d_value_state: 0,
436            literal_bits: 0,
437            lmd_values_bits: 0,
438            literal_decoder_table: Vec::new(),
439            l_value_decoder_table: Vec::new(),
440            m_value_decoder_table: Vec::new(),
441            d_value_decoder_table: Vec::new(),
442        }
443    }
444}
445
446/// Context for decompressing LZFSE compressed data.
447pub struct LzfseContext {
448    /// Mediator.
449    mediator: MediatorReference,
450
451    /// Context for decompressing LZVN compressed data.
452    lzvn_context: LzvnContext,
453
454    /// Uncompressed data size.
455    pub uncompressed_data_size: usize,
456}
457
458impl LzfseContext {
459    /// Creates a new context.
460    pub fn new() -> Self {
461        Self {
462            mediator: Mediator::current(),
463            lzvn_context: LzvnContext::new(),
464            uncompressed_data_size: 0,
465        }
466    }
467
468    /// Builds a decoder table.
469    fn build_decoder_table(
470        &self,
471        number_of_states: i16,
472        number_of_symbols: i16,
473        frequency_table: &[u16],
474        decoder_table: &mut Vec<LzfseDecoderEntry>,
475    ) -> Result<(), ErrorTrace> {
476        if number_of_symbols > 256 {
477            return Err(keramics_core::error_trace_new!(format!(
478                "Invalid number of symbols: {} value out of bounds",
479                number_of_symbols,
480            )));
481        }
482        let number_of_leading_zeros: u32 = number_of_states.leading_zeros();
483        let mut sum_of_frequencies: i16 = 0;
484
485        for symbol in 0..number_of_symbols {
486            // Frequency contains the number of occurrences of the symbol.
487            let frequency: u16 = frequency_table[symbol as usize];
488
489            if frequency == 0 {
490                continue;
491            }
492            sum_of_frequencies += frequency as i16;
493
494            if sum_of_frequencies > number_of_states {
495                return Err(keramics_core::error_trace_new!(format!(
496                    "Invalid sum of frequencies: {} value out of bounds",
497                    sum_of_frequencies,
498                )));
499            }
500            let number_of_bits: u32 = frequency.leading_zeros() - number_of_leading_zeros;
501            let base_decoder_weight: i16 =
502                ((2 * number_of_states) >> number_of_bits) - frequency as i16;
503
504            for decoder_weight in 0..frequency {
505                let mut decoder_entry: LzfseDecoderEntry = LzfseDecoderEntry::new();
506
507                decoder_entry.number_of_bits = number_of_bits as i8;
508                decoder_entry.symbol = symbol as u8;
509                decoder_entry.delta = if (decoder_weight as i16) < base_decoder_weight {
510                    ((frequency as i16 + decoder_weight as i16) << number_of_bits)
511                        - number_of_states
512                } else {
513                    decoder_entry.number_of_bits -= 1;
514
515                    (decoder_weight as i16 - base_decoder_weight) << (number_of_bits - 1)
516                };
517                decoder_table.push(decoder_entry);
518            }
519        }
520        Ok(())
521    }
522
523    /// Builds a value decoder table.
524    fn build_value_decoder_table(
525        &self,
526        number_of_states: i16,
527        number_of_symbols: i16,
528        frequency_table: &[u16],
529        value_bits_table: &[u8],
530        value_base_table: &[i32],
531        value_decoder_table: &mut Vec<LzfseValueDecoderEntry>,
532    ) -> Result<(), ErrorTrace> {
533        if number_of_symbols > 256 {
534            return Err(keramics_core::error_trace_new!(format!(
535                "Invalid number of symbols: {} value out of bounds",
536                number_of_symbols,
537            )));
538        }
539        let number_of_leading_zeros: u32 = number_of_states.leading_zeros();
540        let mut sum_of_frequencies: i16 = 0;
541
542        for symbol in 0..number_of_symbols {
543            // Frequency contains the number of occurrences of the symbol.
544            let frequency: u16 = frequency_table[symbol as usize];
545
546            if frequency == 0 {
547                continue;
548            }
549            sum_of_frequencies += frequency as i16;
550
551            if sum_of_frequencies > number_of_states {
552                return Err(keramics_core::error_trace_new!(format!(
553                    "Invalid sum of frequencies: {} value out of bounds",
554                    sum_of_frequencies,
555                )));
556            }
557            let number_of_bits: u32 = frequency.leading_zeros() - number_of_leading_zeros;
558            let base_decoder_weight: i16 =
559                ((2 * number_of_states) >> number_of_bits) - frequency as i16;
560
561            let value_bits: u8 = value_bits_table[symbol as usize];
562            let value_base: i32 = value_base_table[symbol as usize];
563
564            for decoder_weight in 0..frequency {
565                let mut value_decoder_entry: LzfseValueDecoderEntry = LzfseValueDecoderEntry::new();
566
567                value_decoder_entry.value_bits = value_bits;
568                value_decoder_entry.value_base = value_base;
569                value_decoder_entry.value_bitmask = (1 << value_bits) - 1;
570                value_decoder_entry.number_of_bits = number_of_bits as u8 + value_bits;
571                value_decoder_entry.delta = if (decoder_weight as i16) < base_decoder_weight {
572                    ((frequency as i16 + decoder_weight as i16) << number_of_bits)
573                        - number_of_states
574                } else {
575                    value_decoder_entry.number_of_bits -= 1;
576
577                    (decoder_weight as i16 - base_decoder_weight) << (number_of_bits - 1)
578                };
579                value_decoder_table.push(value_decoder_entry);
580            }
581        }
582        Ok(())
583    }
584
585    /// Decompress data.
586    pub fn decompress(
587        &mut self,
588        compressed_data: &[u8],
589        uncompressed_data: &mut [u8],
590    ) -> Result<(), ErrorTrace> {
591        let mut frequency_table: [u16; 360] = [0; 360];
592
593        let mut compressed_data_offset: usize = 0;
594        let compressed_data_size: usize = compressed_data.len();
595
596        let mut uncompressed_data_offset: usize = 0;
597        let uncompressed_data_size: usize = uncompressed_data.len();
598
599        while compressed_data_offset < compressed_data_size {
600            if uncompressed_data_offset >= uncompressed_data_size {
601                break;
602            }
603            if 4 > compressed_data_size - compressed_data_offset {
604                return Err(keramics_core::error_trace_new!(
605                    "Invalid compressed data value too small"
606                ));
607            }
608            let block_marker: u32 = bytes_to_u32_le!(compressed_data, compressed_data_offset);
609
610            match block_marker {
611                LZFSE_END_OF_STREAM_BLOCK_MARKER => {
612                    if self.mediator.debug_output {
613                        self.mediator.debug_print(format!(
614                            "    block_marker: {}{}{}{} (end-of-stream)\n",
615                            compressed_data[compressed_data_offset] as char,
616                            compressed_data[compressed_data_offset + 1] as char,
617                            compressed_data[compressed_data_offset + 2] as char,
618                            compressed_data[compressed_data_offset + 3] as char,
619                        ));
620                    }
621                    break;
622                }
623                LZFSE_UNCOMPRESSED_BLOCK_MARKER => {
624                    if self.mediator.debug_output {
625                        self.mediator.debug_print(format!(
626                            "    block_marker: {}{}{}{} (uncompressed)\n",
627                            compressed_data[compressed_data_offset] as char,
628                            compressed_data[compressed_data_offset + 1] as char,
629                            compressed_data[compressed_data_offset + 2] as char,
630                            compressed_data[compressed_data_offset + 3] as char,
631                        ));
632                    }
633                }
634                LZFSE_COMPRESSED_BLOCK_V1_MARKER => {
635                    if self.mediator.debug_output {
636                        self.mediator.debug_print(format!(
637                            "    block_marker: {}{}{}{} (compressed version 1)\n",
638                            compressed_data[compressed_data_offset] as char,
639                            compressed_data[compressed_data_offset + 1] as char,
640                            compressed_data[compressed_data_offset + 2] as char,
641                            compressed_data[compressed_data_offset + 3] as char,
642                        ));
643                    }
644                }
645                LZFSE_COMPRESSED_BLOCK_V2_MARKER => {
646                    if self.mediator.debug_output {
647                        self.mediator.debug_print(format!(
648                            "    block_marker: {}{}{}{} (compressed version 2)\n",
649                            compressed_data[compressed_data_offset] as char,
650                            compressed_data[compressed_data_offset + 1] as char,
651                            compressed_data[compressed_data_offset + 2] as char,
652                            compressed_data[compressed_data_offset + 3] as char,
653                        ));
654                    }
655                }
656                LZFSE_COMPRESSED_BLOCK_LZVN_MARKER => {
657                    if self.mediator.debug_output {
658                        self.mediator.debug_print(format!(
659                            "    block_marker: {}{}{}{} (compressed LZVN)\n",
660                            compressed_data[compressed_data_offset] as char,
661                            compressed_data[compressed_data_offset + 1] as char,
662                            compressed_data[compressed_data_offset + 2] as char,
663                            compressed_data[compressed_data_offset + 3] as char,
664                        ));
665                    }
666                }
667                _ => {
668                    if self.mediator.debug_output {
669                        self.mediator
670                            .debug_print(format!("    block_marker: 0x{:08x}\n", block_marker));
671                    }
672                    return Err(keramics_core::error_trace_new!(format!(
673                        "Unsupported block marker: 0x{:08x}",
674                        block_marker
675                    )));
676                }
677            };
678            compressed_data_offset += 4;
679
680            if 4 > compressed_data_size - compressed_data_offset {
681                return Err(keramics_core::error_trace_new!(
682                    "Invalid compressed data value too small"
683                ));
684            }
685            let uncompressed_block_size: u32 =
686                bytes_to_u32_le!(compressed_data, compressed_data_offset);
687            compressed_data_offset += 4;
688
689            if self.mediator.debug_output {
690                self.mediator.debug_print(format!(
691                    "    uncompressed_block_size: {}\n",
692                    uncompressed_block_size
693                ));
694            }
695            if uncompressed_block_size as usize > uncompressed_data_size - uncompressed_data_offset
696            {
697                return Err(keramics_core::error_trace_new!(
698                    "Invalid uncompressed data value too small"
699                ));
700            }
701            match block_marker {
702                LZFSE_UNCOMPRESSED_BLOCK_MARKER => {
703                    if uncompressed_block_size as usize
704                        > compressed_data_size - compressed_data_offset
705                    {
706                        return Err(keramics_core::error_trace_new!(
707                            "Invalid compressed data value too small"
708                        ));
709                    }
710                    let compressed_data_end_offset: usize =
711                        compressed_data_offset + uncompressed_block_size as usize;
712                    let uncompressed_data_end_offset: usize =
713                        uncompressed_data_offset + uncompressed_block_size as usize;
714
715                    if self.mediator.debug_output {
716                        self.mediator
717                            .debug_print(format!("    uncompressed block data:\n"));
718                        self.mediator.debug_print_data(
719                            &compressed_data[compressed_data_offset..compressed_data_end_offset],
720                            true,
721                        );
722                    }
723                    uncompressed_data[uncompressed_data_offset..uncompressed_data_end_offset]
724                        .copy_from_slice(
725                            &compressed_data[compressed_data_offset..compressed_data_end_offset],
726                        );
727
728                    compressed_data_offset = compressed_data_end_offset;
729                    uncompressed_data_offset = uncompressed_data_end_offset;
730                }
731                LZFSE_COMPRESSED_BLOCK_V1_MARKER | LZFSE_COMPRESSED_BLOCK_V2_MARKER => {
732                    let mut decoder: LzfseDecoder = LzfseDecoder::new();
733
734                    if block_marker == LZFSE_COMPRESSED_BLOCK_V1_MARKER {
735                        self.read_block_v1_header(
736                            compressed_data,
737                            &mut compressed_data_offset,
738                            compressed_data_size,
739                            &mut decoder,
740                            &mut frequency_table,
741                        )?;
742                    } else {
743                        self.read_block_v2_header(
744                            compressed_data,
745                            &mut compressed_data_offset,
746                            compressed_data_size,
747                            &mut decoder,
748                            &mut frequency_table,
749                        )?;
750                    }
751                    self.build_value_decoder_table(
752                        LZFSE_NUMBER_OF_L_VALUE_STATES,
753                        LZFSE_NUMBER_OF_L_VALUE_SYMBOLS,
754                        &frequency_table[0..20],
755                        &LZFSE_L_VALUE_BITS_TABLE,
756                        &LZFSE_L_VALUE_BASE_TABLE,
757                        &mut decoder.l_value_decoder_table,
758                    )?;
759                    self.build_value_decoder_table(
760                        LZFSE_NUMBER_OF_M_VALUE_STATES,
761                        LZFSE_NUMBER_OF_M_VALUE_SYMBOLS,
762                        &frequency_table[20..40],
763                        &LZFSE_M_VALUE_BITS_TABLE,
764                        &LZFSE_M_VALUE_BASE_TABLE,
765                        &mut decoder.m_value_decoder_table,
766                    )?;
767                    self.build_value_decoder_table(
768                        LZFSE_NUMBER_OF_D_VALUE_STATES,
769                        LZFSE_NUMBER_OF_D_VALUE_SYMBOLS,
770                        &frequency_table[40..104],
771                        &LZFSE_D_VALUE_BITS_TABLE,
772                        &LZFSE_D_VALUE_BASE_TABLE,
773                        &mut decoder.d_value_decoder_table,
774                    )?;
775                    self.build_decoder_table(
776                        LZFSE_NUMBER_OF_LITERAL_STATES,
777                        LZFSE_NUMBER_OF_LITERAL_SYMBOLS,
778                        &frequency_table[104..360],
779                        &mut decoder.literal_decoder_table,
780                    )?;
781                    self.decompress_block(
782                        &decoder,
783                        compressed_data,
784                        &mut compressed_data_offset,
785                        compressed_data_size,
786                        uncompressed_data,
787                        &mut uncompressed_data_offset,
788                        uncompressed_data_size,
789                    )?;
790                }
791                LZFSE_COMPRESSED_BLOCK_LZVN_MARKER => {
792                    if 4 > compressed_data_size - compressed_data_offset {
793                        return Err(keramics_core::error_trace_new!(
794                            "Invalid compressed data value too small"
795                        ));
796                    }
797                    let compressed_block_size: u32 =
798                        bytes_to_u32_le!(compressed_data, compressed_data_offset);
799                    compressed_data_offset += 4;
800
801                    if compressed_block_size as usize
802                        > compressed_data_size - compressed_data_offset
803                    {
804                        return Err(keramics_core::error_trace_new!(
805                            "Invalid compressed data value too small"
806                        ));
807                    }
808                    let compressed_data_end_offset: usize =
809                        compressed_data_offset + compressed_block_size as usize;
810                    let uncompressed_data_end_offset: usize =
811                        uncompressed_data_offset + uncompressed_block_size as usize;
812
813                    self.lzvn_context.decompress(
814                        &compressed_data[compressed_data_offset..compressed_data_end_offset],
815                        &mut uncompressed_data
816                            [uncompressed_data_offset..uncompressed_data_end_offset],
817                    )?;
818
819                    compressed_data_offset = compressed_data_end_offset;
820                    uncompressed_data_offset = uncompressed_data_end_offset;
821                }
822                _ => {}
823            };
824        }
825        self.uncompressed_data_size = uncompressed_data_offset;
826
827        Ok(())
828    }
829
830    /// Decompress a LZFSE compressed block.
831    fn decompress_block(
832        &self,
833        decoder: &LzfseDecoder,
834        compressed_data: &[u8],
835        compressed_data_offset: &mut usize,
836        compressed_data_size: usize,
837        uncompressed_data: &mut [u8],
838        uncompressed_data_offset: &mut usize,
839        uncompressed_data_size: usize,
840    ) -> Result<(), ErrorTrace> {
841        let mut data_offset: usize = *compressed_data_offset;
842
843        if decoder.literals_data_size as usize > compressed_data_size - data_offset {
844            return Err(keramics_core::error_trace_new!(
845                "Invalid compressed data value too small"
846            ));
847        }
848        let data_end_offset: usize = data_offset + decoder.literals_data_size as usize;
849        let mut bitstream: LzfseBitstream = LzfseBitstream::new(compressed_data, data_end_offset);
850
851        let mut literal_values: [u8; LZFSE_MAXIMUM_NUMBER_OF_LITERALS] =
852            [0; LZFSE_MAXIMUM_NUMBER_OF_LITERALS];
853        self.read_literal_values(decoder, &mut bitstream, &mut literal_values)?;
854
855        data_offset = data_end_offset;
856
857        if decoder.lmd_values_data_size as usize > compressed_data_size - data_offset {
858            return Err(keramics_core::error_trace_new!(
859                "Invalid compressed data value too small"
860            ));
861        }
862        let data_end_offset: usize = data_offset + decoder.lmd_values_data_size as usize;
863        let mut bitstream: LzfseBitstream = LzfseBitstream::new(compressed_data, data_end_offset);
864
865        self.read_lmd_values(
866            decoder,
867            &mut bitstream,
868            &literal_values,
869            uncompressed_data,
870            uncompressed_data_offset,
871            uncompressed_data_size,
872        )?;
873        *compressed_data_offset = data_end_offset;
874
875        Ok(())
876    }
877
878    /// Read a LZFSE block version 1 header.
879    fn read_block_v1_header(
880        &self,
881        compressed_data: &[u8],
882        compressed_data_offset: &mut usize,
883        compressed_data_size: usize,
884        decoder: &mut LzfseDecoder,
885        frequency_table: &mut [u16],
886    ) -> Result<(), ErrorTrace> {
887        let mut data_offset: usize = *compressed_data_offset;
888
889        if 762 > compressed_data_size - data_offset {
890            return Err(keramics_core::error_trace_new!(
891                "Invalid compressed data value too small"
892            ));
893        }
894        let mut block_header: LzfseBlockV1Header = LzfseBlockV1Header::new();
895        let data_end_offset: usize = data_offset + 42;
896
897        if self.mediator.debug_output {
898            self.mediator.debug_print(format!(
899                "LzfseBlockV1Header data of size: 42 at offset: {} (0x{:08x})\n",
900                data_offset, data_offset
901            ));
902            self.mediator
903                .debug_print_data(&compressed_data[data_offset..data_end_offset], true);
904            self.mediator
905                .debug_print(LzfseBlockV1Header::debug_read_data(
906                    &compressed_data[data_offset..data_end_offset],
907                ));
908        }
909        block_header.read_data(&compressed_data[data_offset..data_end_offset], decoder)?;
910        data_offset = data_end_offset;
911
912        let data_end_offset: usize = data_offset + 720;
913
914        if self.mediator.debug_output {
915            self.mediator.debug_print(format!(
916                "LzfseFrequencyTable data of size: 720 at offset: {} (0x{:08x})\n",
917                data_offset, data_offset
918            ));
919            self.mediator
920                .debug_print_data(&compressed_data[data_offset..data_end_offset], true);
921            self.mediator
922                .debug_print(format!("LzfseFrequencyTable {{\n"));
923            self.mediator.debug_print(format!("    values: [\n"));
924        }
925        let mut data_offset: usize = 42;
926        for frequency_table_index in 0..360 {
927            let frequency_value: u16 = bytes_to_u16_le!(compressed_data, data_offset);
928            data_offset += 2;
929
930            if self.mediator.debug_output {
931                if frequency_table_index % 16 == 0 {
932                    self.mediator
933                        .debug_print(format!("    {}", frequency_value));
934                } else if frequency_table_index % 16 == 15 {
935                    self.mediator
936                        .debug_print(format!(", {},\n", frequency_value));
937                } else {
938                    self.mediator.debug_print(format!(", {}", frequency_value));
939                }
940            }
941            frequency_table[frequency_table_index] = frequency_value;
942        }
943        if self.mediator.debug_output {
944            self.mediator.debug_print(format!("    ],\n"));
945            self.mediator.debug_print(format!("}}\n"));
946        }
947        *compressed_data_offset = data_offset;
948
949        Ok(())
950    }
951
952    /// Read a LZFSE block version 2 header.
953    fn read_block_v2_header(
954        &self,
955        compressed_data: &[u8],
956        compressed_data_offset: &mut usize,
957        compressed_data_size: usize,
958        decoder: &mut LzfseDecoder,
959        frequency_table: &mut [u16],
960    ) -> Result<(), ErrorTrace> {
961        let mut data_offset: usize = *compressed_data_offset;
962
963        let mut block_header: LzfseBlockV2Header = LzfseBlockV2Header::new();
964        let mut data_end_offset: usize = data_offset + 24;
965
966        if data_end_offset > compressed_data_size {
967            return Err(keramics_core::error_trace_new!(
968                "Invalid compressed data value too small"
969            ));
970        }
971        if self.mediator.debug_output {
972            self.mediator.debug_print(format!(
973                "LzfseBlockV2Header data of size: 24 at offset: {} (0x{:08x})\n",
974                data_offset, data_offset
975            ));
976            self.mediator
977                .debug_print_data(&compressed_data[data_offset..data_end_offset], true);
978            self.mediator
979                .debug_print(LzfseBlockV2Header::debug_read_data(
980                    &compressed_data[data_offset..data_end_offset],
981                ));
982        }
983        block_header.read_data(&compressed_data[data_offset..data_end_offset], decoder)?;
984        if block_header.header_size as usize > compressed_data_size - data_offset {
985            return Err(keramics_core::error_trace_new!(
986                "Invalid compressed data value too small"
987            ));
988        }
989        data_offset = data_end_offset;
990
991        if block_header.header_size > 32 {
992            let compressed_data_size: usize = block_header.header_size as usize - 32;
993            data_end_offset += compressed_data_size;
994
995            if self.mediator.debug_output {
996                self.mediator.debug_print(format!(
997                    "LzfseCompressedFrequencyTable data of size: {} at offset: {} (0x{:08x})\n",
998                    compressed_data_size, data_offset, data_offset
999                ));
1000                self.mediator
1001                    .debug_print_data(&compressed_data[data_offset..data_end_offset], true);
1002                self.mediator
1003                    .debug_print(format!("LzfseFrequencyTable {{\n"));
1004                self.mediator.debug_print(format!("    values: [\n"));
1005            }
1006            // TODO: use bitstream to read compressed data
1007            let mut number_of_bits: usize = 0;
1008            let mut value_32bit: u32 = 0;
1009            for frequency_table_index in 0..360 {
1010                while number_of_bits <= 24 && data_offset < data_end_offset {
1011                    value_32bit |= (compressed_data[data_offset] as u32) << number_of_bits;
1012                    data_offset += 1;
1013                    number_of_bits += 8;
1014                }
1015                let table_index: u32 = value_32bit & 0x0000001f;
1016                let frequency_value_size: u8 =
1017                    LZFSE_FREQUENCY_NUMBER_OF_BITS_TABLE[table_index as usize];
1018
1019                let frequency_value: u16 = match frequency_value_size {
1020                    8 => (((value_32bit >> 4) & 0x0000000f) + 8) as u16,
1021                    14 => (((value_32bit >> 4) & 0x000003ff) + 24) as u16,
1022                    _ => LZFSE_FREQUENCY_VALUE_TABLE[table_index as usize],
1023                };
1024                if self.mediator.debug_output {
1025                    if frequency_table_index % 16 == 0 {
1026                        self.mediator
1027                            .debug_print(format!("        {}", frequency_value));
1028                    } else if frequency_table_index % 16 == 15 {
1029                        self.mediator
1030                            .debug_print(format!(", {},\n", frequency_value));
1031                    } else {
1032                        self.mediator.debug_print(format!(", {}", frequency_value));
1033                    }
1034                }
1035                frequency_table[frequency_table_index] = frequency_value;
1036
1037                value_32bit >>= frequency_value_size;
1038                number_of_bits -= frequency_value_size as usize;
1039            }
1040            if self.mediator.debug_output {
1041                self.mediator.debug_print(format!("\n    ],\n"));
1042                self.mediator.debug_print(format!("}}\n"));
1043            }
1044        }
1045        *compressed_data_offset = data_offset;
1046
1047        Ok(())
1048    }
1049
1050    /// Read literal values.
1051    fn read_literal_values(
1052        &self,
1053        decoder: &LzfseDecoder,
1054        bitstream: &mut LzfseBitstream,
1055        literal_values: &mut [u8],
1056    ) -> Result<(), ErrorTrace> {
1057        if decoder.number_of_literals as usize > LZFSE_MAXIMUM_NUMBER_OF_LITERALS {
1058            return Err(keramics_core::error_trace_new!(format!(
1059                "Invalid number of literals: {} value out of bounds",
1060                decoder.number_of_literals,
1061            )));
1062        }
1063        if decoder.literal_bits < -32 || decoder.literal_bits > 0 {
1064            return Err(keramics_core::error_trace_new!(format!(
1065                "Invalid literal bits: {} value out of bounds",
1066                decoder.literal_bits,
1067            )));
1068        }
1069        let mut literal_states: [u16; 4] = [0; 4];
1070        literal_states.copy_from_slice(&decoder.literal_states);
1071
1072        let number_of_bits: i32 = -1 * decoder.literal_bits;
1073        let _ = bitstream.get_value(number_of_bits as usize);
1074
1075        for literal_index in (0..decoder.number_of_literals).step_by(4) {
1076            for literal_states_index in 0..4 {
1077                let literal_state: u16 = literal_states[literal_states_index];
1078
1079                // TODO: refactor to decoder.get_literal?
1080                if literal_state > LZFSE_NUMBER_OF_LITERAL_STATES as u16 {
1081                    return Err(keramics_core::error_trace_new!(format!(
1082                        "Invalid literal state: {} value out of bounds",
1083                        literal_state,
1084                    )));
1085                }
1086                let decoder_entry: &LzfseDecoderEntry =
1087                    match decoder.literal_decoder_table.get(literal_state as usize) {
1088                        Some(value) => value,
1089                        None => {
1090                            return Err(keramics_core::error_trace_new!(format!(
1091                                "Missing decoder entry for literal state: {}",
1092                                literal_state
1093                            )));
1094                        }
1095                    };
1096                let value: u32 = bitstream.get_value(decoder_entry.number_of_bits as usize);
1097                let literal_state: i32 = (decoder_entry.delta as i32) + (value as i32);
1098                let literal_values_index: usize = literal_index as usize + literal_states_index;
1099
1100                if self.mediator.debug_output {
1101                    self.mediator
1102                        .debug_print(format!("    value: 0x{:02x}\n", value));
1103                    self.mediator.debug_print(format!(
1104                        "    literal_values[{}]: 0x{:02x}\n",
1105                        literal_values_index, decoder_entry.symbol
1106                    ));
1107                    self.mediator.debug_print(format!(
1108                        "    literal_states[{}]: {}\n",
1109                        literal_states_index, literal_state
1110                    ));
1111                }
1112                literal_values[literal_values_index] = decoder_entry.symbol;
1113                literal_states[literal_states_index] = literal_state as u16;
1114            }
1115        }
1116        if self.mediator.debug_output {
1117            self.mediator.debug_print(format!("\n"));
1118        }
1119        Ok(())
1120    }
1121
1122    /// Read L, M and D values.
1123    fn read_lmd_values(
1124        &self,
1125        decoder: &LzfseDecoder,
1126        bitstream: &mut LzfseBitstream,
1127        literal_values: &[u8],
1128        uncompressed_data: &mut [u8],
1129        uncompressed_data_offset: &mut usize,
1130        uncompressed_data_size: usize,
1131    ) -> Result<(), ErrorTrace> {
1132        if decoder.lmd_values_bits < -32 || decoder.lmd_values_bits > 0 {
1133            return Err(keramics_core::error_trace_new!(format!(
1134                "Invalid L, M and D values bits: {} value out of bounds",
1135                decoder.lmd_values_bits,
1136            )));
1137        }
1138        let mut data_offset: usize = *uncompressed_data_offset;
1139        let mut remaining_data_size: usize = uncompressed_data_size - data_offset;
1140
1141        let mut active_d_value: i32 = 0;
1142        let mut literal_value_index: i32 = 0;
1143
1144        let mut l_value_state: i32 = decoder.l_value_state as i32;
1145        let mut m_value_state: i32 = decoder.m_value_state as i32;
1146        let mut d_value_state: i32 = decoder.d_value_state as i32;
1147
1148        let number_of_bits: i32 = -1 * decoder.lmd_values_bits;
1149        let _ = bitstream.get_value(number_of_bits as usize);
1150
1151        for _ in 0..decoder.number_of_lmd_values {
1152            // TODO: refactor to decoder.get_l_value?
1153            if l_value_state > LZFSE_NUMBER_OF_L_VALUE_STATES as i32 {
1154                return Err(keramics_core::error_trace_new!(format!(
1155                    "Invalid L value state: {} value out of bounds",
1156                    l_value_state,
1157                )));
1158            }
1159            let value_decoder_entry: &LzfseValueDecoderEntry =
1160                match decoder.l_value_decoder_table.get(l_value_state as usize) {
1161                    Some(value) => value,
1162                    None => {
1163                        return Err(keramics_core::error_trace_new!(format!(
1164                            "Missing value decoder entry for L value state: {}",
1165                            l_value_state,
1166                        )));
1167                    }
1168                };
1169            let value: u32 = bitstream.get_value(value_decoder_entry.number_of_bits as usize);
1170            let l_value: i32 =
1171                value_decoder_entry.value_base + (value & value_decoder_entry.value_bitmask) as i32;
1172            l_value_state = (value_decoder_entry.delta as i32)
1173                + (value >> (value_decoder_entry.value_bits as u32)) as i32;
1174
1175            if self.mediator.debug_output {
1176                self.mediator
1177                    .debug_print(format!("    l_value: {}\n", l_value));
1178                self.mediator
1179                    .debug_print(format!("    l_value_state: {}\n", l_value_state));
1180            }
1181            // TODO: refactor to decoder.get_m_value?
1182            if m_value_state > LZFSE_NUMBER_OF_M_VALUE_STATES as i32 {
1183                return Err(keramics_core::error_trace_new!(format!(
1184                    "Invalid M value state: {} value out of bounds",
1185                    m_value_state,
1186                )));
1187            }
1188            let value_decoder_entry: &LzfseValueDecoderEntry =
1189                match decoder.m_value_decoder_table.get(m_value_state as usize) {
1190                    Some(value) => value,
1191                    None => {
1192                        return Err(keramics_core::error_trace_new!(format!(
1193                            "Missing value decoder entry for M value state: {}",
1194                            m_value_state,
1195                        )));
1196                    }
1197                };
1198            let value: u32 = bitstream.get_value(value_decoder_entry.number_of_bits as usize);
1199            let m_value: i32 =
1200                value_decoder_entry.value_base + (value & value_decoder_entry.value_bitmask) as i32;
1201            m_value_state = (value_decoder_entry.delta as i32)
1202                + (value >> (value_decoder_entry.value_bits as u32)) as i32;
1203
1204            if self.mediator.debug_output {
1205                self.mediator
1206                    .debug_print(format!("    m_value: {}\n", m_value));
1207                self.mediator
1208                    .debug_print(format!("    m_value_state: {}\n", m_value_state));
1209            }
1210            // TODO: refactor to decoder.get_d_value?
1211            if d_value_state > LZFSE_NUMBER_OF_D_VALUE_STATES as i32 {
1212                return Err(keramics_core::error_trace_new!(format!(
1213                    "Invalid D value state: {} value out of bounds",
1214                    d_value_state,
1215                )));
1216            }
1217            let value_decoder_entry: &LzfseValueDecoderEntry =
1218                match decoder.d_value_decoder_table.get(d_value_state as usize) {
1219                    Some(value) => value,
1220                    None => {
1221                        return Err(keramics_core::error_trace_new!(format!(
1222                            "Missing value decoder entry for D value state: {}",
1223                            d_value_state,
1224                        )));
1225                    }
1226                };
1227            let value: u32 = bitstream.get_value(value_decoder_entry.number_of_bits as usize);
1228            let d_value: i32 =
1229                value_decoder_entry.value_base + (value & value_decoder_entry.value_bitmask) as i32;
1230            d_value_state = (value_decoder_entry.delta as i32)
1231                + (value >> (value_decoder_entry.value_bits as u32)) as i32;
1232
1233            if self.mediator.debug_output {
1234                self.mediator
1235                    .debug_print(format!("    d_value: {}\n", d_value));
1236                self.mediator
1237                    .debug_print(format!("    d_value_state: {}\n", d_value_state));
1238            }
1239            if d_value != 0 {
1240                active_d_value = d_value;
1241            }
1242            let maximum_l_value: usize =
1243                min(LZFSE_MAXIMUM_NUMBER_OF_LITERALS - 1, remaining_data_size);
1244            if l_value < 0
1245                || l_value as usize > maximum_l_value
1246                || literal_value_index > (LZFSE_MAXIMUM_NUMBER_OF_LITERALS as i32) - l_value
1247            {
1248                return Err(keramics_core::error_trace_new!(format!(
1249                    "Invalid L value: {} value out of bounds",
1250                    l_value
1251                )));
1252            }
1253            for _ in 0..l_value {
1254                uncompressed_data[data_offset] = literal_values[literal_value_index as usize];
1255
1256                data_offset += 1;
1257                literal_value_index += 1;
1258            }
1259            remaining_data_size -= l_value as usize;
1260
1261            if m_value < 0 || m_value > remaining_data_size as i32 {
1262                return Err(keramics_core::error_trace_new!(format!(
1263                    "Invalid M value: {} value out of bounds",
1264                    m_value
1265                )));
1266            }
1267            if active_d_value < 0 || active_d_value as usize > data_offset {
1268                return Err(keramics_core::error_trace_new!(format!(
1269                    "Invalid D value: {} value out of bounds",
1270                    active_d_value
1271                )));
1272            }
1273            let mut compression_offset: usize = data_offset - active_d_value as usize;
1274
1275            for _ in 0..m_value {
1276                uncompressed_data[data_offset] = uncompressed_data[compression_offset];
1277
1278                data_offset += 1;
1279                compression_offset += 1;
1280            }
1281            remaining_data_size -= m_value as usize;
1282        }
1283        if self.mediator.debug_output {
1284            self.mediator.debug_print(format!("\n"));
1285        }
1286        *uncompressed_data_offset = data_offset;
1287
1288        Ok(())
1289    }
1290}
1291
1292#[cfg(test)]
1293mod tests {
1294    use super::*;
1295
1296    fn get_test_data() -> Vec<u8> {
1297        return vec![
1298            0x62, 0x76, 0x78, 0x32, 0x00, 0x10, 0x00, 0x00, 0x44, 0x00, 0x30, 0x02, 0x00, 0x05,
1299            0x00, 0x40, 0xe4, 0x8b, 0xd9, 0xa2, 0xc9, 0x0f, 0x00, 0x50, 0xa5, 0x00, 0x00, 0x00,
1300            0x39, 0x58, 0x30, 0x0d, 0x47, 0x70, 0x05, 0x70, 0x05, 0x00, 0x70, 0x75, 0xc5, 0x15,
1301            0x00, 0x57, 0x00, 0x70, 0x05, 0xc0, 0x07, 0xf0, 0xb5, 0xfc, 0x06, 0x00, 0x00, 0x00,
1302            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x72,
1303            0x01, 0xdc, 0x01, 0x00, 0xc0, 0xdd, 0x1b, 0x00, 0x00, 0xdc, 0x01, 0x70, 0x77, 0x07,
1304            0x00, 0xdc, 0x01, 0x00, 0x77, 0x70, 0x77, 0x07, 0x00, 0x00, 0x00, 0x77, 0x00, 0xdc,
1305            0xdd, 0x01, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x70, 0x07, 0x77, 0x5f, 0x01, 0x77, 0xbc,
1306            0x01, 0x77, 0x77, 0xdc, 0x01, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 0x00,
1307            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1b, 0xc0, 0x1d, 0x00, 0x00, 0x77, 0x00,
1308            0xdc, 0x01, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xdd, 0xdd, 0x01, 0xdc, 0x01,
1309            0x00, 0x70, 0x07, 0x70, 0x07, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1c,
1310            0x68, 0xbd, 0xc5, 0xd0, 0xc4, 0x3c, 0x8c, 0xb7, 0xbe, 0x86, 0x9b, 0xeb, 0x76, 0x65,
1311            0xd2, 0x38, 0x3e, 0x26, 0x5c, 0x31, 0x96, 0xe7, 0x57, 0xc5, 0x31, 0xd3, 0x83, 0xb0,
1312            0x45, 0x9f, 0xa7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd3,
1313            0xfc, 0x7f, 0x9c, 0x51, 0x03, 0x62, 0x76, 0x78, 0x24,
1314        ];
1315    }
1316
1317    #[test]
1318    fn test_bitstream_get_value() {
1319        let test_data: Vec<u8> = get_test_data();
1320
1321        let mut test_bitstream: LzfseBitstream = LzfseBitstream::new(&test_data, 198);
1322
1323        let test_value: u32 = test_bitstream.get_value(0);
1324        assert_eq!(test_value, 0);
1325
1326        let test_value: u32 = test_bitstream.get_value(4);
1327        assert_eq!(test_value, 0x00000009);
1328
1329        let test_value: u32 = test_bitstream.get_value(12);
1330        assert_eq!(test_value, 0x00000f45);
1331
1332        let test_value: u32 = test_bitstream.get_value(24);
1333        assert_eq!(test_value, 0x00b083d3);
1334    }
1335
1336    #[test]
1337    fn test_bitstream_skip_bits() {
1338        let test_data: Vec<u8> = get_test_data();
1339
1340        let mut test_bitstream: LzfseBitstream = LzfseBitstream::new(&test_data, 198);
1341
1342        test_bitstream.skip_bits(4);
1343        let test_value: u32 = test_bitstream.get_value(12);
1344        assert_eq!(test_value, 0x00000f45);
1345    }
1346
1347    #[test]
1348    fn test_decompress() -> Result<(), ErrorTrace> {
1349        let test_data: Vec<u8> = get_test_data();
1350        let mut test_context: LzfseContext = LzfseContext::new();
1351
1352        let expected_data: [u8; 4096] = [
1353            0xef, 0x57, 0x34, 0x7c, 0x00, 0x00, 0xaa, 0x11, 0xaa, 0x11, 0x00, 0x30, 0x65, 0x43,
1354            0xec, 0xac, 0x65, 0xf0, 0x4a, 0xdd, 0xc4, 0xe7, 0x19, 0x49, 0xbc, 0x05, 0xd6, 0x6a,
1355            0xb6, 0x33, 0x10, 0xd8, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x1f,
1356            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1357            0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6d, 0x00,
1358            0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1369            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1370            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1371            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1374            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1378            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1384            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1387            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1388            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1390            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1391            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1395            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1396            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1402            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1403            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1406            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1407            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1409            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1413            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1414            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1418            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1419            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1422            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1425            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1426            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1432            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1435            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1438            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1441            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1442            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1443            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1444            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1445            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1446            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1448            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1449            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1452            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1457            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1460            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1461            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1466            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1467            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1468            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1469            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1470            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1471            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1473            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1474            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1475            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1477            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1478            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1481            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1482            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1484            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1485            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1486            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1488            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1491            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1492            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1493            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1494            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1496            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1498            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1499            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1500            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1501            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1502            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1503            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1504            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1505            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1506            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1507            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1508            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1509            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1510            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1511            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1512            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1513            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1514            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1515            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1516            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1517            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1518            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1519            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1521            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1522            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1523            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1524            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1525            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1526            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1527            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1528            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1529            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1530            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1531            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1532            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1533            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1534            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1535            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1536            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1537            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1538            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1539            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1540            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1541            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1542            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1543            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1544            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1545            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1546            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1547            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1548            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1549            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1550            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1551            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1552            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1553            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1554            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1555            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1556            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1557            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1558            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1559            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1560            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1561            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1562            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1563            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1564            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1565            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1566            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1567            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1568            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1569            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1570            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1571            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1573            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1574            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1575            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1576            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1579            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1580            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1581            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1582            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1583            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1584            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1585            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1586            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1587            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1588            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1589            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1591            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1592            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1593            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1594            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1595            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1596            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1597            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1598            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1599            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1600            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1601            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1604            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1605            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1606            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1607            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1608            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1609            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1610            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1611            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1612            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1613            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1614            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1615            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1616            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1617            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1618            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1620            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1621            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1622            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1623            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1624            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1625            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1629            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1630            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1631            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1632            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1633            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1638            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1639            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646        ];
1647        let mut uncompressed_data: Vec<u8> = vec![0; 4096];
1648        test_context.decompress(&test_data, &mut uncompressed_data)?;
1649        assert_eq!(uncompressed_data, expected_data);
1650
1651        Ok(())
1652    }
1653}