diff options
author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/fdeflate/src | |
parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip |
Deleted vendor folder
Diffstat (limited to 'vendor/fdeflate/src')
-rw-r--r-- | vendor/fdeflate/src/compress.rs | 327 | ||||
-rw-r--r-- | vendor/fdeflate/src/decompress.rs | 1270 | ||||
-rw-r--r-- | vendor/fdeflate/src/lib.rs | 123 | ||||
-rw-r--r-- | vendor/fdeflate/src/tables.rs | 635 |
4 files changed, 0 insertions, 2355 deletions
diff --git a/vendor/fdeflate/src/compress.rs b/vendor/fdeflate/src/compress.rs deleted file mode 100644 index 027d0ef..0000000 --- a/vendor/fdeflate/src/compress.rs +++ /dev/null @@ -1,327 +0,0 @@ -use simd_adler32::Adler32; -use std::{ - convert::TryInto, - io::{self, Seek, SeekFrom, Write}, -}; - -use crate::tables::{ - BITMASKS, HUFFMAN_CODES, HUFFMAN_LENGTHS, LENGTH_TO_LEN_EXTRA, LENGTH_TO_SYMBOL, -}; - -/// Compressor that produces fdeflate compressed streams. -pub struct Compressor<W: Write> { - checksum: Adler32, - buffer: u64, - nbits: u8, - writer: W, -} -impl<W: Write> Compressor<W> { - fn write_bits(&mut self, bits: u64, nbits: u8) -> io::Result<()> { - debug_assert!(nbits <= 64); - - self.buffer |= bits << self.nbits; - self.nbits += nbits; - - if self.nbits >= 64 { - self.writer.write_all(&self.buffer.to_le_bytes())?; - self.nbits -= 64; - self.buffer = bits.checked_shr((nbits - self.nbits) as u32).unwrap_or(0); - } - debug_assert!(self.nbits < 64); - Ok(()) - } - - fn flush(&mut self) -> io::Result<()> { - if self.nbits % 8 != 0 { - self.write_bits(0, 8 - self.nbits % 8)?; - } - if self.nbits > 0 { - self.writer - .write_all(&self.buffer.to_le_bytes()[..self.nbits as usize / 8]) - .unwrap(); - self.buffer = 0; - self.nbits = 0; - } - Ok(()) - } - - fn write_run(&mut self, mut run: u32) -> io::Result<()> { - self.write_bits(HUFFMAN_CODES[0] as u64, HUFFMAN_LENGTHS[0])?; - run -= 1; - - while run >= 258 { - self.write_bits(HUFFMAN_CODES[285] as u64, HUFFMAN_LENGTHS[285] + 1)?; - run -= 258; - } - - if run > 4 { - let sym = LENGTH_TO_SYMBOL[run as usize - 3] as usize; - self.write_bits(HUFFMAN_CODES[sym] as u64, HUFFMAN_LENGTHS[sym])?; - - let len_extra = LENGTH_TO_LEN_EXTRA[run as usize - 3]; - let extra = ((run - 3) & BITMASKS[len_extra as usize]) as u64; - self.write_bits(extra, len_extra + 1)?; - } else { - debug_assert_eq!(HUFFMAN_CODES[0], 0); - self.write_bits(0, run as u8 * HUFFMAN_LENGTHS[0])?; - } - - Ok(()) - } - - /// Create a new Compressor. - pub fn new(writer: W) -> io::Result<Self> { - let mut compressor = Self { - checksum: Adler32::new(), - buffer: 0, - nbits: 0, - writer, - }; - compressor.write_headers()?; - Ok(compressor) - } - - fn write_headers(&mut self) -> io::Result<()> { - self.write_bits(0x0178, 16)?; // zlib header - - self.write_bits(0b1, 1)?; // BFINAL - self.write_bits(0b10, 2)?; // Dynamic Huffman block - - self.write_bits((HUFFMAN_LENGTHS.len() - 257) as u64, 5)?; // # of length / literal codes - self.write_bits(0, 5)?; // 1 distance code - self.write_bits(15, 4)?; // 16 code length codes - - // Write code lengths for code length alphabet - for _ in 0..3 { - self.write_bits(0, 3)?; - } - for _ in 0..16 { - self.write_bits(4, 3)?; - } - - // Write code lengths for length/literal alphabet - for &len in &HUFFMAN_LENGTHS { - self.write_bits((len.reverse_bits() >> 4) as u64, 4)?; - } - - // Write code lengths for distance alphabet - for _ in 0..1 { - self.write_bits(0b1000, 4)?; - } - - Ok(()) - } - - /// Write data to the compressor. - pub fn write_data(&mut self, data: &[u8]) -> io::Result<()> { - self.checksum.write(data); - - let mut run = 0; - let mut chunks = data.chunks_exact(8); - for chunk in &mut chunks { - let ichunk = u64::from_le_bytes(chunk.try_into().unwrap()); - - if ichunk == 0 { - run += 8; - continue; - } else if run > 0 { - let run_extra = ichunk.trailing_zeros() / 8; - self.write_run(run + run_extra)?; - run = 0; - - if run_extra > 0 { - run = ichunk.leading_zeros() / 8; - for &b in &chunk[run_extra as usize..8 - run as usize] { - self.write_bits( - HUFFMAN_CODES[b as usize] as u64, - HUFFMAN_LENGTHS[b as usize], - )?; - } - continue; - } - } - - let run_start = ichunk.leading_zeros() / 8; - if run_start > 0 { - for &b in &chunk[..8 - run_start as usize] { - self.write_bits( - HUFFMAN_CODES[b as usize] as u64, - HUFFMAN_LENGTHS[b as usize], - )?; - } - run = run_start; - continue; - } - - let n0 = HUFFMAN_LENGTHS[chunk[0] as usize]; - let n1 = HUFFMAN_LENGTHS[chunk[1] as usize]; - let n2 = HUFFMAN_LENGTHS[chunk[2] as usize]; - let n3 = HUFFMAN_LENGTHS[chunk[3] as usize]; - let bits = HUFFMAN_CODES[chunk[0] as usize] as u64 - | ((HUFFMAN_CODES[chunk[1] as usize] as u64) << n0) - | ((HUFFMAN_CODES[chunk[2] as usize] as u64) << (n0 + n1)) - | ((HUFFMAN_CODES[chunk[3] as usize] as u64) << (n0 + n1 + n2)); - self.write_bits(bits, n0 + n1 + n2 + n3)?; - - let n4 = HUFFMAN_LENGTHS[chunk[4] as usize]; - let n5 = HUFFMAN_LENGTHS[chunk[5] as usize]; - let n6 = HUFFMAN_LENGTHS[chunk[6] as usize]; - let n7 = HUFFMAN_LENGTHS[chunk[7] as usize]; - let bits2 = HUFFMAN_CODES[chunk[4] as usize] as u64 - | ((HUFFMAN_CODES[chunk[5] as usize] as u64) << n4) - | ((HUFFMAN_CODES[chunk[6] as usize] as u64) << (n4 + n5)) - | ((HUFFMAN_CODES[chunk[7] as usize] as u64) << (n4 + n5 + n6)); - self.write_bits(bits2, n4 + n5 + n6 + n7)?; - } - - if run > 0 { - self.write_run(run)?; - } - - for &b in chunks.remainder() { - self.write_bits( - HUFFMAN_CODES[b as usize] as u64, - HUFFMAN_LENGTHS[b as usize], - )?; - } - - Ok(()) - } - - /// Write the remainder of the stream and return the inner writer. - pub fn finish(mut self) -> io::Result<W> { - // Write end of block - self.write_bits(HUFFMAN_CODES[256] as u64, HUFFMAN_LENGTHS[256])?; - self.flush()?; - - // Write Adler32 checksum - let checksum: u32 = self.checksum.finish(); - self.writer - .write_all(checksum.to_be_bytes().as_ref()) - .unwrap(); - Ok(self.writer) - } -} - -/// Compressor that only writes the stored blocks. -/// -/// This is useful for writing files that are not compressed, but still need to be wrapped in a -/// zlib stream. -pub struct StoredOnlyCompressor<W> { - writer: W, - checksum: Adler32, - block_bytes: u16, -} -impl<W: Write + Seek> StoredOnlyCompressor<W> { - /// Creates a new `StoredOnlyCompressor` that writes to the given writer. - pub fn new(mut writer: W) -> io::Result<Self> { - writer.write_all(&[0x78, 0x01])?; // zlib header - writer.write_all(&[0; 5])?; // placeholder stored block header - - Ok(Self { - writer, - checksum: Adler32::new(), - block_bytes: 0, - }) - } - - fn set_block_header(&mut self, size: u16, last: bool) -> io::Result<()> { - self.writer.seek(SeekFrom::Current(-(size as i64 + 5)))?; - self.writer.write_all(&[ - last as u8, - (size & 0xFF) as u8, - ((size >> 8) & 0xFF) as u8, - (!size & 0xFF) as u8, - ((!size >> 8) & 0xFF) as u8, - ])?; - self.writer.seek(SeekFrom::Current(size as i64))?; - - Ok(()) - } - - /// Writes the given data to the underlying writer. - pub fn write_data(&mut self, mut data: &[u8]) -> io::Result<()> { - self.checksum.write(data); - while !data.is_empty() { - if self.block_bytes == u16::MAX { - self.set_block_header(u16::MAX, false)?; - self.writer.write_all(&[0; 5])?; // placeholder stored block header - self.block_bytes = 0; - } - - let prefix_bytes = data.len().min((u16::MAX - self.block_bytes) as usize); - self.writer.write_all(&data[..prefix_bytes])?; - self.block_bytes += prefix_bytes as u16; - data = &data[prefix_bytes..]; - } - - Ok(()) - } - - /// Finish writing the final block and return the underlying writer. - pub fn finish(mut self) -> io::Result<W> { - self.set_block_header(self.block_bytes, true)?; - - // Write Adler32 checksum - let checksum: u32 = self.checksum.finish(); - self.writer - .write_all(checksum.to_be_bytes().as_ref()) - .unwrap(); - - Ok(self.writer) - } -} -impl<W> StoredOnlyCompressor<W> { - /// Return the number of bytes that will be written to the output stream - /// for the given input size. Because this compressor only writes stored blocks, - /// the output size is always slightly *larger* than the input size. - pub fn compressed_size(raw_size: usize) -> usize { - (raw_size.saturating_sub(1) / u16::MAX as usize) * (u16::MAX as usize + 5) - + (raw_size % u16::MAX as usize + 5) - + 6 - } -} - -/// Compresses the given data. -pub fn compress_to_vec(input: &[u8]) -> Vec<u8> { - let mut compressor = Compressor::new(Vec::with_capacity(input.len() / 4)).unwrap(); - compressor.write_data(input).unwrap(); - compressor.finish().unwrap() -} - -#[cfg(test)] -mod tests { - use super::*; - use rand::Rng; - - fn roundtrip(data: &[u8]) { - let compressed = compress_to_vec(data); - let decompressed = miniz_oxide::inflate::decompress_to_vec_zlib(&compressed).unwrap(); - assert_eq!(&decompressed, data); - } - - #[test] - fn it_works() { - roundtrip(b"Hello world!"); - } - - #[test] - fn constant() { - roundtrip(&vec![0; 2048]); - roundtrip(&vec![5; 2048]); - roundtrip(&vec![128; 2048]); - roundtrip(&vec![254; 2048]); - } - - #[test] - fn random() { - let mut rng = rand::thread_rng(); - let mut data = vec![0; 2048]; - for _ in 0..10 { - for byte in &mut data { - *byte = rng.gen(); - } - roundtrip(&data); - } - } -} diff --git a/vendor/fdeflate/src/decompress.rs b/vendor/fdeflate/src/decompress.rs deleted file mode 100644 index d38f63b..0000000 --- a/vendor/fdeflate/src/decompress.rs +++ /dev/null @@ -1,1270 +0,0 @@ -use std::convert::TryInto; - -use simd_adler32::Adler32; - -use crate::tables::{ - self, CLCL_ORDER, DIST_SYM_TO_DIST_BASE, DIST_SYM_TO_DIST_EXTRA, FDEFLATE_DIST_DECODE_TABLE, - FDEFLATE_LITLEN_DECODE_TABLE, FIXED_CODE_LENGTHS, LEN_SYM_TO_LEN_BASE, LEN_SYM_TO_LEN_EXTRA, -}; - -/// An error encountered while decompressing a deflate stream. -#[derive(Debug, PartialEq)] -pub enum DecompressionError { - /// The zlib header is corrupt. - BadZlibHeader, - /// All input was consumed, but the end of the stream hasn't been reached. - InsufficientInput, - /// A block header specifies an invalid block type. - InvalidBlockType, - /// An uncompressed block's NLEN value is invalid. - InvalidUncompressedBlockLength, - /// Too many literals were specified. - InvalidHlit, - /// Too many distance codes were specified. - InvalidHdist, - /// Attempted to repeat a previous code before reading any codes, or past the end of the code - /// lengths. - InvalidCodeLengthRepeat, - /// The stream doesn't specify a valid huffman tree. - BadCodeLengthHuffmanTree, - /// The stream doesn't specify a valid huffman tree. - BadLiteralLengthHuffmanTree, - /// The stream doesn't specify a valid huffman tree. - BadDistanceHuffmanTree, - /// The stream contains a literal/length code that was not allowed by the header. - InvalidLiteralLengthCode, - /// The stream contains a distance code that was not allowed by the header. - InvalidDistanceCode, - /// The stream contains contains back-reference as the first symbol. - InputStartsWithRun, - /// The stream contains a back-reference that is too far back. - DistanceTooFarBack, - /// The deflate stream checksum is incorrect. - WrongChecksum, - /// Extra input data. - ExtraInput, -} - -struct BlockHeader { - hlit: usize, - hdist: usize, - hclen: usize, - num_lengths_read: usize, - - /// Low 3-bits are code length code length, high 5-bits are code length code. - table: [u8; 128], - code_lengths: [u8; 320], -} - -const LITERAL_ENTRY: u32 = 0x8000; -const EXCEPTIONAL_ENTRY: u32 = 0x4000; -const SECONDARY_TABLE_ENTRY: u32 = 0x2000; - -/// The Decompressor state for a compressed block. -/// -/// The main litlen_table uses a 12-bit input to lookup the meaning of the symbol. The table is -/// split into 4 sections: -/// -/// aaaaaaaa_bbbbbbbb_1000yyyy_0000xxxx x = input_advance_bits, y = output_advance_bytes (literal) -/// 0000000z_zzzzzzzz_00000yyy_0000xxxx x = input_advance_bits, y = extra_bits, z = distance_base (length) -/// 00000000_00000000_01000000_0000xxxx x = input_advance_bits (EOF) -/// 0000xxxx_xxxxxxxx_01100000_00000000 x = secondary_table_index -/// 00000000_00000000_01000000_00000000 invalid code -/// -/// The distance table is a 512-entry table that maps 9 bits of distance symbols to their meaning. -/// -/// 00000000_00000000_00000000_00000000 symbol is more than 9 bits -/// zzzzzzzz_zzzzzzzz_0000yyyy_0000xxxx x = input_advance_bits, y = extra_bits, z = distance_base -#[repr(align(64))] -#[derive(Eq, PartialEq, Debug)] -struct CompressedBlock { - litlen_table: [u32; 4096], - dist_table: [u32; 512], - - dist_symbol_lengths: [u8; 30], - dist_symbol_masks: [u16; 30], - dist_symbol_codes: [u16; 30], - - secondary_table: Vec<u16>, - eof_code: u16, - eof_mask: u16, - eof_bits: u8, -} - -const FDEFLATE_COMPRESSED_BLOCK: CompressedBlock = CompressedBlock { - litlen_table: FDEFLATE_LITLEN_DECODE_TABLE, - dist_table: FDEFLATE_DIST_DECODE_TABLE, - dist_symbol_lengths: [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - dist_symbol_masks: [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - dist_symbol_codes: [ - 0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - ], - secondary_table: Vec::new(), - eof_code: 0x8ff, - eof_mask: 0xfff, - eof_bits: 0xc, -}; - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -enum State { - ZlibHeader, - BlockHeader, - CodeLengthCodes, - CodeLengths, - CompressedData, - UncompressedData, - Checksum, - Done, -} - -/// Decompressor for arbitrary zlib streams. -pub struct Decompressor { - /// State for decoding a compressed block. - compression: CompressedBlock, - // State for decoding a block header. - header: BlockHeader, - // Number of bytes left for uncompressed block. - uncompressed_bytes_left: u16, - - buffer: u64, - nbits: u8, - - queued_rle: Option<(u8, usize)>, - queued_backref: Option<(usize, usize)>, - last_block: bool, - - state: State, - checksum: Adler32, - ignore_adler32: bool, -} - -impl Default for Decompressor { - fn default() -> Self { - Self::new() - } -} - -impl Decompressor { - /// Create a new decompressor. - pub fn new() -> Self { - Self { - buffer: 0, - nbits: 0, - compression: CompressedBlock { - litlen_table: [0; 4096], - dist_table: [0; 512], - secondary_table: Vec::new(), - dist_symbol_lengths: [0; 30], - dist_symbol_masks: [0; 30], - dist_symbol_codes: [0xffff; 30], - eof_code: 0, - eof_mask: 0, - eof_bits: 0, - }, - header: BlockHeader { - hlit: 0, - hdist: 0, - hclen: 0, - table: [0; 128], - num_lengths_read: 0, - code_lengths: [0; 320], - }, - uncompressed_bytes_left: 0, - queued_rle: None, - queued_backref: None, - checksum: Adler32::new(), - state: State::ZlibHeader, - last_block: false, - ignore_adler32: false, - } - } - - /// Ignore the checksum at the end of the stream. - pub fn ignore_adler32(&mut self) { - self.ignore_adler32 = true; - } - - fn fill_buffer(&mut self, input: &mut &[u8]) { - if input.len() >= 8 { - self.buffer |= u64::from_le_bytes(input[..8].try_into().unwrap()) << self.nbits; - *input = &mut &input[(63 - self.nbits as usize) / 8..]; - self.nbits |= 56; - } else { - let nbytes = input.len().min((63 - self.nbits as usize) / 8); - let mut input_data = [0; 8]; - input_data[..nbytes].copy_from_slice(&input[..nbytes]); - self.buffer |= u64::from_le_bytes(input_data) - .checked_shl(self.nbits as u32) - .unwrap_or(0); - self.nbits += nbytes as u8 * 8; - *input = &mut &input[nbytes..]; - } - } - - fn peak_bits(&mut self, nbits: u8) -> u64 { - debug_assert!(nbits <= 56 && nbits <= self.nbits); - self.buffer & ((1u64 << nbits) - 1) - } - fn consume_bits(&mut self, nbits: u8) { - debug_assert!(self.nbits >= nbits); - self.buffer >>= nbits; - self.nbits -= nbits; - } - - fn read_block_header(&mut self, remaining_input: &mut &[u8]) -> Result<(), DecompressionError> { - self.fill_buffer(remaining_input); - if self.nbits < 3 { - return Ok(()); - } - - let start = self.peak_bits(3); - self.last_block = start & 1 != 0; - match start >> 1 { - 0b00 => { - let align_bits = (self.nbits - 3) % 8; - let header_bits = 3 + 32 + align_bits; - if self.nbits < header_bits { - return Ok(()); - } - - let len = (self.peak_bits(align_bits + 19) >> (align_bits + 3)) as u16; - let nlen = (self.peak_bits(header_bits) >> (align_bits + 19)) as u16; - if nlen != !len { - return Err(DecompressionError::InvalidUncompressedBlockLength); - } - - self.state = State::UncompressedData; - self.uncompressed_bytes_left = len; - self.consume_bits(header_bits); - Ok(()) - } - 0b01 => { - self.consume_bits(3); - // TODO: Do this statically rather than every time. - Self::build_tables(288, &FIXED_CODE_LENGTHS, &mut self.compression, 6)?; - self.state = State::CompressedData; - Ok(()) - } - 0b10 => { - if self.nbits < 17 { - return Ok(()); - } - - self.header.hlit = (self.peak_bits(8) >> 3) as usize + 257; - self.header.hdist = (self.peak_bits(13) >> 8) as usize + 1; - self.header.hclen = (self.peak_bits(17) >> 13) as usize + 4; - if self.header.hlit > 286 { - return Err(DecompressionError::InvalidHlit); - } - if self.header.hdist > 30 { - return Err(DecompressionError::InvalidHdist); - } - - self.consume_bits(17); - self.state = State::CodeLengthCodes; - Ok(()) - } - 0b11 => Err(DecompressionError::InvalidBlockType), - _ => unreachable!(), - } - } - - fn read_code_length_codes( - &mut self, - remaining_input: &mut &[u8], - ) -> Result<(), DecompressionError> { - self.fill_buffer(remaining_input); - if self.nbits as usize + remaining_input.len() * 8 < 3 * self.header.hclen { - return Ok(()); - } - - let mut code_length_lengths = [0; 19]; - for i in 0..self.header.hclen { - code_length_lengths[CLCL_ORDER[i]] = self.peak_bits(3) as u8; - self.consume_bits(3); - - // We need to refill the buffer after reading 3 * 18 = 54 bits since the buffer holds - // between 56 and 63 bits total. - if i == 17 { - self.fill_buffer(remaining_input); - } - } - let code_length_codes: [u16; 19] = crate::compute_codes(&code_length_lengths) - .ok_or(DecompressionError::BadCodeLengthHuffmanTree)?; - - self.header.table = [255; 128]; - for i in 0..19 { - let length = code_length_lengths[i]; - if length > 0 { - let mut j = code_length_codes[i]; - while j < 128 { - self.header.table[j as usize] = ((i as u8) << 3) | length; - j += 1 << length; - } - } - } - - self.state = State::CodeLengths; - self.header.num_lengths_read = 0; - Ok(()) - } - - fn read_code_lengths(&mut self, remaining_input: &mut &[u8]) -> Result<(), DecompressionError> { - let total_lengths = self.header.hlit + self.header.hdist; - while self.header.num_lengths_read < total_lengths { - self.fill_buffer(remaining_input); - if self.nbits < 7 { - return Ok(()); - } - - let code = self.peak_bits(7); - let entry = self.header.table[code as usize]; - let length = entry & 0x7; - let symbol = entry >> 3; - - debug_assert!(length != 0); - match symbol { - 0..=15 => { - self.header.code_lengths[self.header.num_lengths_read] = symbol; - self.header.num_lengths_read += 1; - self.consume_bits(length); - } - 16..=18 => { - let (base_repeat, extra_bits) = match symbol { - 16 => (3, 2), - 17 => (3, 3), - 18 => (11, 7), - _ => unreachable!(), - }; - - if self.nbits < length + extra_bits { - return Ok(()); - } - - let value = match symbol { - 16 => { - self.header.code_lengths[self - .header - .num_lengths_read - .checked_sub(1) - .ok_or(DecompressionError::InvalidCodeLengthRepeat)?] - // TODO: is this right? - } - 17 => 0, - 18 => 0, - _ => unreachable!(), - }; - - let repeat = - (self.peak_bits(length + extra_bits) >> length) as usize + base_repeat; - if self.header.num_lengths_read + repeat > total_lengths { - return Err(DecompressionError::InvalidCodeLengthRepeat); - } - - for i in 0..repeat { - self.header.code_lengths[self.header.num_lengths_read + i] = value; - } - self.header.num_lengths_read += repeat; - self.consume_bits(length + extra_bits); - } - _ => unreachable!(), - } - } - - self.header - .code_lengths - .copy_within(self.header.hlit..total_lengths, 288); - for i in self.header.hlit..288 { - self.header.code_lengths[i] = 0; - } - for i in 288 + self.header.hdist..320 { - self.header.code_lengths[i] = 0; - } - - if self.header.hdist == 1 - && self.header.code_lengths[..286] == tables::HUFFMAN_LENGTHS - && self.header.code_lengths[288] == 1 - { - self.compression = FDEFLATE_COMPRESSED_BLOCK; - } else { - Self::build_tables( - self.header.hlit, - &self.header.code_lengths, - &mut self.compression, - 6, - )?; - } - self.state = State::CompressedData; - Ok(()) - } - - fn build_tables( - hlit: usize, - code_lengths: &[u8], - compression: &mut CompressedBlock, - max_search_bits: u8, - ) -> Result<(), DecompressionError> { - // Build the literal/length code table. - let lengths = &code_lengths[..288]; - let codes: [u16; 288] = crate::compute_codes(&lengths.try_into().unwrap()) - .ok_or(DecompressionError::BadLiteralLengthHuffmanTree)?; - - let table_bits = lengths.iter().cloned().max().unwrap().min(12).max(6); - let table_size = 1 << table_bits; - - for i in 0..256 { - let code = codes[i]; - let length = lengths[i]; - let mut j = code; - - while j < table_size && length != 0 && length <= 12 { - compression.litlen_table[j as usize] = - ((i as u32) << 16) | LITERAL_ENTRY | (1 << 8) | length as u32; - j += 1 << length; - } - - if length > 0 && length <= max_search_bits { - for ii in 0..256 { - let code2 = codes[ii]; - let length2 = lengths[ii]; - if length2 != 0 && length + length2 <= table_bits { - let mut j = code | (code2 << length); - - while j < table_size { - compression.litlen_table[j as usize] = (ii as u32) << 24 - | (i as u32) << 16 - | LITERAL_ENTRY - | (2 << 8) - | ((length + length2) as u32); - j += 1 << (length + length2); - } - } - } - } - } - - if lengths[256] != 0 && lengths[256] <= 12 { - let mut j = codes[256]; - while j < table_size { - compression.litlen_table[j as usize] = EXCEPTIONAL_ENTRY | lengths[256] as u32; - j += 1 << lengths[256]; - } - } - - let table_size = table_size as usize; - for i in (table_size..4096).step_by(table_size) { - compression.litlen_table.copy_within(0..table_size, i); - } - - compression.eof_code = codes[256]; - compression.eof_mask = (1 << lengths[256]) - 1; - compression.eof_bits = lengths[256]; - - for i in 257..hlit { - let code = codes[i]; - let length = lengths[i]; - if length != 0 && length <= 12 { - let mut j = code; - while j < 4096 { - compression.litlen_table[j as usize] = if i < 286 { - (LEN_SYM_TO_LEN_BASE[i - 257] as u32) << 16 - | (LEN_SYM_TO_LEN_EXTRA[i - 257] as u32) << 8 - | length as u32 - } else { - EXCEPTIONAL_ENTRY - }; - j += 1 << length; - } - } - } - - for i in 0..hlit { - if lengths[i] > 12 { - compression.litlen_table[(codes[i] & 0xfff) as usize] = u32::MAX; - } - } - - let mut secondary_table_len = 0; - for i in 0..hlit { - if lengths[i] > 12 { - let j = (codes[i] & 0xfff) as usize; - if compression.litlen_table[j] == u32::MAX { - compression.litlen_table[j] = - (secondary_table_len << 16) | EXCEPTIONAL_ENTRY | SECONDARY_TABLE_ENTRY; - secondary_table_len += 8; - } - } - } - assert!(secondary_table_len <= 0x7ff); - compression.secondary_table = vec![0; secondary_table_len as usize]; - for i in 0..hlit { - let code = codes[i]; - let length = lengths[i]; - if length > 12 { - let j = (codes[i] & 0xfff) as usize; - let k = (compression.litlen_table[j] >> 16) as usize; - - let mut s = code >> 12; - while s < 8 { - debug_assert_eq!(compression.secondary_table[k + s as usize], 0); - compression.secondary_table[k + s as usize] = - ((i as u16) << 4) | (length as u16); - s += 1 << (length - 12); - } - } - } - debug_assert!(compression - .secondary_table - .iter() - .all(|&x| x != 0 && (x & 0xf) > 12)); - - // Build the distance code table. - let lengths = &code_lengths[288..320]; - if lengths == [0; 32] { - compression.dist_symbol_masks = [0; 30]; - compression.dist_symbol_codes = [0xffff; 30]; - compression.dist_table.fill(0); - } else { - let codes: [u16; 32] = match crate::compute_codes(&lengths.try_into().unwrap()) { - Some(codes) => codes, - None => { - if lengths.iter().filter(|&&l| l != 0).count() != 1 { - return Err(DecompressionError::BadDistanceHuffmanTree); - } - [0; 32] - } - }; - - compression.dist_symbol_codes.copy_from_slice(&codes[..30]); - compression - .dist_symbol_lengths - .copy_from_slice(&lengths[..30]); - compression.dist_table.fill(0); - for i in 0..30 { - let length = lengths[i]; - let code = codes[i]; - if length == 0 { - compression.dist_symbol_masks[i] = 0; - compression.dist_symbol_codes[i] = 0xffff; - } else { - compression.dist_symbol_masks[i] = (1 << lengths[i]) - 1; - if lengths[i] <= 9 { - let mut j = code; - while j < 512 { - compression.dist_table[j as usize] = (DIST_SYM_TO_DIST_BASE[i] as u32) - << 16 - | (DIST_SYM_TO_DIST_EXTRA[i] as u32) << 8 - | length as u32; - j += 1 << lengths[i]; - } - } - } - } - } - - Ok(()) - } - - fn read_compressed( - &mut self, - remaining_input: &mut &[u8], - output: &mut [u8], - mut output_index: usize, - ) -> Result<usize, DecompressionError> { - while let State::CompressedData = self.state { - self.fill_buffer(remaining_input); - if output_index == output.len() { - break; - } - - let mut bits = self.buffer; - let litlen_entry = self.compression.litlen_table[(bits & 0xfff) as usize]; - let litlen_code_bits = litlen_entry as u8; - - if litlen_entry & LITERAL_ENTRY != 0 { - // Ultra-fast path: do 3 more consecutive table lookups and bail if any of them need the slow path. - if self.nbits >= 48 { - let litlen_entry2 = - self.compression.litlen_table[(bits >> litlen_code_bits & 0xfff) as usize]; - let litlen_code_bits2 = litlen_entry2 as u8; - let litlen_entry3 = self.compression.litlen_table - [(bits >> (litlen_code_bits + litlen_code_bits2) & 0xfff) as usize]; - let litlen_code_bits3 = litlen_entry3 as u8; - let litlen_entry4 = self.compression.litlen_table[(bits - >> (litlen_code_bits + litlen_code_bits2 + litlen_code_bits3) - & 0xfff) - as usize]; - let litlen_code_bits4 = litlen_entry4 as u8; - if litlen_entry2 & litlen_entry3 & litlen_entry4 & LITERAL_ENTRY != 0 { - let advance_output_bytes = ((litlen_entry & 0xf00) >> 8) as usize; - let advance_output_bytes2 = ((litlen_entry2 & 0xf00) >> 8) as usize; - let advance_output_bytes3 = ((litlen_entry3 & 0xf00) >> 8) as usize; - let advance_output_bytes4 = ((litlen_entry4 & 0xf00) >> 8) as usize; - if output_index - + advance_output_bytes - + advance_output_bytes2 - + advance_output_bytes3 - + advance_output_bytes4 - < output.len() - { - self.consume_bits( - litlen_code_bits - + litlen_code_bits2 - + litlen_code_bits3 - + litlen_code_bits4, - ); - - output[output_index] = (litlen_entry >> 16) as u8; - output[output_index + 1] = (litlen_entry >> 24) as u8; - output_index += advance_output_bytes; - output[output_index] = (litlen_entry2 >> 16) as u8; - output[output_index + 1] = (litlen_entry2 >> 24) as u8; - output_index += advance_output_bytes2; - output[output_index] = (litlen_entry3 >> 16) as u8; - output[output_index + 1] = (litlen_entry3 >> 24) as u8; - output_index += advance_output_bytes3; - output[output_index] = (litlen_entry4 >> 16) as u8; - output[output_index + 1] = (litlen_entry4 >> 24) as u8; - output_index += advance_output_bytes4; - continue; - } - } - } - - // Fast path: the next symbol is <= 12 bits and a literal, the table specifies the - // output bytes and we can directly write them to the output buffer. - let advance_output_bytes = ((litlen_entry & 0xf00) >> 8) as usize; - - // match advance_output_bytes { - // 1 => println!("[{output_index}] LIT1 {}", litlen_entry >> 16), - // 2 => println!( - // "[{output_index}] LIT2 {} {} {}", - // (litlen_entry >> 16) as u8, - // litlen_entry >> 24, - // bits & 0xfff - // ), - // n => println!( - // "[{output_index}] LIT{n} {} {}", - // (litlen_entry >> 16) as u8, - // litlen_entry >> 24, - // ), - // } - - if self.nbits < litlen_code_bits { - break; - } else if output_index + 1 < output.len() { - output[output_index] = (litlen_entry >> 16) as u8; - output[output_index + 1] = (litlen_entry >> 24) as u8; - output_index += advance_output_bytes; - self.consume_bits(litlen_code_bits); - continue; - } else if output_index + advance_output_bytes == output.len() { - debug_assert_eq!(advance_output_bytes, 1); - output[output_index] = (litlen_entry >> 16) as u8; - output_index += 1; - self.consume_bits(litlen_code_bits); - break; - } else { - debug_assert_eq!(advance_output_bytes, 2); - output[output_index] = (litlen_entry >> 16) as u8; - self.queued_rle = Some(((litlen_entry >> 24) as u8, 1)); - output_index += 1; - self.consume_bits(litlen_code_bits); - break; - } - } - - let (length_base, length_extra_bits, litlen_code_bits) = - if litlen_entry & EXCEPTIONAL_ENTRY == 0 { - ( - litlen_entry >> 16, - (litlen_entry >> 8) as u8, - litlen_code_bits, - ) - } else if litlen_entry & SECONDARY_TABLE_ENTRY != 0 { - let secondary_index = litlen_entry >> 16; - let secondary_entry = self.compression.secondary_table - [secondary_index as usize + ((bits >> 12) & 0x7) as usize]; - let litlen_symbol = secondary_entry >> 4; - let litlen_code_bits = (secondary_entry & 0xf) as u8; - - if self.nbits < litlen_code_bits { - break; - } else if litlen_symbol < 256 { - // println!("[{output_index}] LIT1b {} (val={:04x})", litlen_symbol, self.peak_bits(15)); - - self.consume_bits(litlen_code_bits); - output[output_index] = litlen_symbol as u8; - output_index += 1; - continue; - } else if litlen_symbol == 256 { - // println!("[{output_index}] EOF"); - self.consume_bits(litlen_code_bits); - self.state = match self.last_block { - true => State::Checksum, - false => State::BlockHeader, - }; - break; - } - - ( - LEN_SYM_TO_LEN_BASE[litlen_symbol as usize - 257] as u32, - LEN_SYM_TO_LEN_EXTRA[litlen_symbol as usize - 257], - litlen_code_bits, - ) - } else if litlen_code_bits == 0 { - return Err(DecompressionError::InvalidLiteralLengthCode); - } else { - if self.nbits < litlen_code_bits { - break; - } - // println!("[{output_index}] EOF"); - self.consume_bits(litlen_code_bits); - self.state = match self.last_block { - true => State::Checksum, - false => State::BlockHeader, - }; - break; - }; - bits >>= litlen_code_bits; - - let length_extra_mask = (1 << length_extra_bits) - 1; - let length = length_base as usize + (bits & length_extra_mask) as usize; - bits >>= length_extra_bits; - - let dist_entry = self.compression.dist_table[(bits & 0x1ff) as usize]; - let (dist_base, dist_extra_bits, dist_code_bits) = if dist_entry != 0 { - ( - (dist_entry >> 16) as u16, - (dist_entry >> 8) as u8, - dist_entry as u8, - ) - } else { - let mut dist_extra_bits = 0; - let mut dist_base = 0; - let mut dist_advance_bits = 0; - for i in 0..self.compression.dist_symbol_lengths.len() { - if bits as u16 & self.compression.dist_symbol_masks[i] - == self.compression.dist_symbol_codes[i] - { - dist_extra_bits = DIST_SYM_TO_DIST_EXTRA[i]; - dist_base = DIST_SYM_TO_DIST_BASE[i]; - dist_advance_bits = self.compression.dist_symbol_lengths[i]; - break; - } - } - if dist_advance_bits == 0 { - return Err(DecompressionError::InvalidDistanceCode); - } - (dist_base, dist_extra_bits, dist_advance_bits) - }; - bits >>= dist_code_bits; - - let dist = dist_base as usize + (bits & ((1 << dist_extra_bits) - 1)) as usize; - let total_bits = - litlen_code_bits + length_extra_bits + dist_code_bits + dist_extra_bits; - - if self.nbits < total_bits { - break; - } else if dist > output_index { - return Err(DecompressionError::DistanceTooFarBack); - } - - // println!("[{output_index}] BACKREF len={} dist={} {:x}", length, dist, dist_entry); - self.consume_bits(total_bits); - - let copy_length = length.min(output.len() - output_index); - if dist == 1 { - let last = output[output_index - 1]; - output[output_index..][..copy_length].fill(last); - - if copy_length < length { - self.queued_rle = Some((last, length - copy_length)); - output_index = output.len(); - break; - } - } else if output_index + length + 15 <= output.len() { - let start = output_index - dist; - output.copy_within(start..start + 16, output_index); - - if length > 16 || dist < 16 { - for i in (0..length).step_by(dist.min(16)).skip(1) { - output.copy_within(start + i..start + i + 16, output_index + i); - } - } - } else { - if dist < copy_length { - for i in 0..copy_length { - output[output_index + i] = output[output_index + i - dist]; - } - } else { - output.copy_within( - output_index - dist..output_index + copy_length - dist, - output_index, - ) - } - - if copy_length < length { - self.queued_backref = Some((dist, length - copy_length)); - output_index = output.len(); - break; - } - } - output_index += copy_length; - } - - if self.state == State::CompressedData - && self.queued_backref.is_none() - && self.queued_rle.is_none() - && self.nbits >= 15 - && self.peak_bits(15) as u16 & self.compression.eof_mask == self.compression.eof_code - { - self.consume_bits(self.compression.eof_bits); - self.state = match self.last_block { - true => State::Checksum, - false => State::BlockHeader, - }; - } - - Ok(output_index) - } - - /// Decompresses a chunk of data. - /// - /// Returns the number of bytes read from `input` and the number of bytes written to `output`, - /// or an error if the deflate stream is not valid. `input` is the compressed data. `output` is - /// the buffer to write the decompressed data to, starting at index `output_position`. - /// `end_of_input` indicates whether more data may be available in the future. - /// - /// The contents of `output` after `output_position` are ignored. However, this function may - /// write additional data to `output` past what is indicated by the return value. - /// - /// When this function returns `Ok`, at least one of the following is true: - /// - The input is fully consumed. - /// - The output is full but there are more bytes to output. - /// - The deflate stream is complete (and `is_done` will return true). - /// - /// # Panics - /// - /// This function will panic if `output_position` is out of bounds. - pub fn read( - &mut self, - input: &[u8], - output: &mut [u8], - output_position: usize, - end_of_input: bool, - ) -> Result<(usize, usize), DecompressionError> { - if let State::Done = self.state { - return Ok((0, 0)); - } - - assert!(output_position <= output.len()); - - let mut remaining_input = input; - let mut output_index = output_position; - - if let Some((data, len)) = self.queued_rle.take() { - let n = len.min(output.len() - output_index); - output[output_index..][..n].fill(data); - output_index += n; - if n < len { - self.queued_rle = Some((data, len - n)); - return Ok((0, n)); - } - } - if let Some((dist, len)) = self.queued_backref.take() { - let n = len.min(output.len() - output_index); - for i in 0..n { - output[output_index + i] = output[output_index + i - dist]; - } - output_index += n; - if n < len { - self.queued_backref = Some((dist, len - n)); - return Ok((0, n)); - } - } - - // Main decoding state machine. - let mut last_state = None; - while last_state != Some(self.state) { - last_state = Some(self.state); - match self.state { - State::ZlibHeader => { - self.fill_buffer(&mut remaining_input); - if self.nbits < 16 { - break; - } - - let input0 = self.peak_bits(8); - let input1 = self.peak_bits(16) >> 8 & 0xff; - if input0 & 0x0f != 0x08 - || (input0 & 0xf0) > 0x70 - || input1 & 0x20 != 0 - || (input0 << 8 | input1) % 31 != 0 - { - return Err(DecompressionError::BadZlibHeader); - } - - self.consume_bits(16); - self.state = State::BlockHeader; - } - State::BlockHeader => { - self.read_block_header(&mut remaining_input)?; - } - State::CodeLengthCodes => { - self.read_code_length_codes(&mut remaining_input)?; - } - State::CodeLengths => { - self.read_code_lengths(&mut remaining_input)?; - } - State::CompressedData => { - output_index = - self.read_compressed(&mut remaining_input, output, output_index)? - } - State::UncompressedData => { - // Drain any bytes from our buffer. - debug_assert_eq!(self.nbits % 8, 0); - while self.nbits > 0 - && self.uncompressed_bytes_left > 0 - && output_index < output.len() - { - output[output_index] = self.peak_bits(8) as u8; - self.consume_bits(8); - output_index += 1; - self.uncompressed_bytes_left -= 1; - } - // Buffer may contain one additional byte. Clear it to avoid confusion. - if self.nbits == 0 { - self.buffer = 0; - } - - // Copy subsequent bytes directly from the input. - let copy_bytes = (self.uncompressed_bytes_left as usize) - .min(remaining_input.len()) - .min(output.len() - output_index); - output[output_index..][..copy_bytes] - .copy_from_slice(&remaining_input[..copy_bytes]); - remaining_input = &remaining_input[copy_bytes..]; - output_index += copy_bytes; - self.uncompressed_bytes_left -= copy_bytes as u16; - - if self.uncompressed_bytes_left == 0 { - self.state = if self.last_block { - State::Checksum - } else { - State::BlockHeader - }; - } - } - State::Checksum => { - self.fill_buffer(&mut remaining_input); - - let align_bits = self.nbits % 8; - if self.nbits >= 32 + align_bits { - self.checksum.write(&output[output_position..output_index]); - if align_bits != 0 { - self.consume_bits(align_bits); - } - #[cfg(not(fuzzing))] - if !self.ignore_adler32 - && (self.peak_bits(32) as u32).swap_bytes() != self.checksum.finish() - { - return Err(DecompressionError::WrongChecksum); - } - self.state = State::Done; - self.consume_bits(32); - break; - } - } - State::Done => unreachable!(), - } - } - - if !self.ignore_adler32 && self.state != State::Done { - self.checksum.write(&output[output_position..output_index]); - } - - if self.state == State::Done || !end_of_input || output_index >= output.len() - 1 { - let input_left = remaining_input.len(); - Ok((input.len() - input_left, output_index - output_position)) - } else { - Err(DecompressionError::InsufficientInput) - } - } - - /// Returns true if the decompressor has finished decompressing the input. - pub fn is_done(&self) -> bool { - self.state == State::Done - } -} - -/// Decompress the given data. -pub fn decompress_to_vec(input: &[u8]) -> Result<Vec<u8>, DecompressionError> { - match decompress_to_vec_bounded(input, usize::MAX) { - Ok(output) => Ok(output), - Err(BoundedDecompressionError::DecompressionError { inner }) => Err(inner), - Err(BoundedDecompressionError::OutputTooLarge { .. }) => { - unreachable!("Impossible to allocate more than isize::MAX bytes") - } - } -} - -/// An error encountered while decompressing a deflate stream given a bounded maximum output. -pub enum BoundedDecompressionError { - /// The input is not a valid deflate stream. - DecompressionError { - /// The underlying error. - inner: DecompressionError, - }, - - /// The output is too large. - OutputTooLarge { - /// The output decoded so far. - partial_output: Vec<u8>, - }, -} -impl From<DecompressionError> for BoundedDecompressionError { - fn from(inner: DecompressionError) -> Self { - BoundedDecompressionError::DecompressionError { inner } - } -} - -/// Decompress the given data, returning an error if the output is larger than -/// `maxlen` bytes. -pub fn decompress_to_vec_bounded( - input: &[u8], - maxlen: usize, -) -> Result<Vec<u8>, BoundedDecompressionError> { - let mut decoder = Decompressor::new(); - let mut output = vec![0; 1024.min(maxlen)]; - let mut input_index = 0; - let mut output_index = 0; - loop { - let (consumed, produced) = - decoder.read(&input[input_index..], &mut output, output_index, true)?; - input_index += consumed; - output_index += produced; - if decoder.is_done() || output_index == maxlen { - break; - } - output.resize((output_index + 32 * 1024).min(maxlen), 0); - } - output.resize(output_index, 0); - - if decoder.is_done() { - Ok(output) - } else { - Err(BoundedDecompressionError::OutputTooLarge { - partial_output: output, - }) - } -} - -#[cfg(test)] -mod tests { - use crate::tables::{self, LENGTH_TO_LEN_EXTRA, LENGTH_TO_SYMBOL}; - - use super::*; - use rand::Rng; - - fn roundtrip(data: &[u8]) { - let compressed = crate::compress_to_vec(data); - let decompressed = decompress_to_vec(&compressed).unwrap(); - assert_eq!(&decompressed, data); - } - - fn roundtrip_miniz_oxide(data: &[u8]) { - let compressed = miniz_oxide::deflate::compress_to_vec_zlib(data, 3); - let decompressed = decompress_to_vec(&compressed).unwrap(); - assert_eq!(decompressed.len(), data.len()); - for (i, (a, b)) in decompressed.chunks(1).zip(data.chunks(1)).enumerate() { - assert_eq!(a, b, "chunk {}..{}", i * 1, i * 1 + 1); - } - assert_eq!(&decompressed, data); - } - - #[allow(unused)] - fn compare_decompression(data: &[u8]) { - // let decompressed0 = flate2::read::ZlibDecoder::new(std::io::Cursor::new(&data)) - // .bytes() - // .collect::<Result<Vec<_>, _>>() - // .unwrap(); - let decompressed = decompress_to_vec(&data).unwrap(); - let decompressed2 = miniz_oxide::inflate::decompress_to_vec_zlib(&data).unwrap(); - for i in 0..decompressed.len().min(decompressed2.len()) { - if decompressed[i] != decompressed2[i] { - panic!( - "mismatch at index {} {:?} {:?}", - i, - &decompressed[i.saturating_sub(1)..(i + 16).min(decompressed.len())], - &decompressed2[i.saturating_sub(1)..(i + 16).min(decompressed2.len())] - ); - } - } - if decompressed != decompressed2 { - panic!( - "length mismatch {} {} {:x?}", - decompressed.len(), - decompressed2.len(), - &decompressed2[decompressed.len()..][..16] - ); - } - //assert_eq!(decompressed, decompressed2); - } - - #[test] - fn tables() { - for (i, &bits) in LEN_SYM_TO_LEN_EXTRA.iter().enumerate() { - let len_base = LEN_SYM_TO_LEN_BASE[i]; - for j in 0..(1 << bits) { - if i == 27 && j == 31 { - continue; - } - assert_eq!(LENGTH_TO_LEN_EXTRA[len_base + j - 3], bits, "{} {}", i, j); - assert_eq!( - LENGTH_TO_SYMBOL[len_base + j - 3], - i as u16 + 257, - "{} {}", - i, - j - ); - } - } - } - - #[test] - fn fdeflate_table() { - let mut compression = CompressedBlock { - litlen_table: [0; 4096], - dist_table: [0; 512], - dist_symbol_lengths: [0; 30], - dist_symbol_masks: [0; 30], - dist_symbol_codes: [0; 30], - secondary_table: Vec::new(), - eof_code: 0, - eof_mask: 0, - eof_bits: 0, - }; - let mut lengths = tables::HUFFMAN_LENGTHS.to_vec(); - lengths.resize(288, 0); - lengths.push(1); - lengths.resize(320, 0); - Decompressor::build_tables(286, &lengths, &mut compression, 11).unwrap(); - - assert_eq!( - compression, FDEFLATE_COMPRESSED_BLOCK, - "{:#x?}", - compression - ); - } - - #[test] - fn it_works() { - roundtrip(b"Hello world!"); - } - - #[test] - fn constant() { - roundtrip_miniz_oxide(&vec![0; 50]); - roundtrip_miniz_oxide(&vec![5; 2048]); - roundtrip_miniz_oxide(&vec![128; 2048]); - roundtrip_miniz_oxide(&vec![254; 2048]); - } - - #[test] - fn random() { - let mut rng = rand::thread_rng(); - let mut data = vec![0; 50000]; - for _ in 0..10 { - for byte in &mut data { - *byte = rng.gen::<u8>() % 5; - } - println!("Random data: {:?}", data); - roundtrip_miniz_oxide(&data); - } - } - - #[test] - fn ignore_adler32() { - let mut compressed = crate::compress_to_vec(b"Hello world!"); - let last_byte = compressed.len() - 1; - compressed[last_byte] = compressed[last_byte].wrapping_add(1); - - match decompress_to_vec(&compressed) { - Err(DecompressionError::WrongChecksum) => {} - r => panic!("expected WrongChecksum, got {:?}", r), - } - - let mut decompressor = Decompressor::new(); - decompressor.ignore_adler32(); - let mut decompressed = vec![0; 1024]; - let decompressed_len = decompressor - .read(&compressed, &mut decompressed, 0, true) - .unwrap() - .1; - assert_eq!(&decompressed[..decompressed_len], b"Hello world!"); - } - - #[test] - fn checksum_after_eof() { - let input = b"Hello world!"; - let compressed = crate::compress_to_vec(input); - - let mut decompressor = Decompressor::new(); - let mut decompressed = vec![0; 1024]; - let (input_consumed, output_written) = decompressor - .read( - &compressed[..compressed.len() - 1], - &mut decompressed, - 0, - false, - ) - .unwrap(); - assert_eq!(output_written, input.len()); - assert_eq!(input_consumed, compressed.len() - 1); - - let (input_consumed, output_written) = decompressor - .read( - &compressed[input_consumed..], - &mut decompressed[..output_written], - output_written, - true, - ) - .unwrap(); - assert!(decompressor.is_done()); - assert_eq!(input_consumed, 1); - assert_eq!(output_written, 0); - - assert_eq!(&decompressed[..input.len()], input); - } - - #[test] - fn zero_length() { - let mut compressed = crate::compress_to_vec(b"").to_vec(); - - // Splice in zero-length non-compressed blocks. - for _ in 0..10 { - println!("compressed len: {}", compressed.len()); - compressed.splice(2..2, [0u8, 0, 0, 0xff, 0xff].into_iter()); - } - - // Ensure that the full input is decompressed, regardless of whether - // `end_of_input` is set. - for end_of_input in [true, false] { - let mut decompressor = Decompressor::new(); - let (input_consumed, output_written) = decompressor - .read(&compressed, &mut [], 0, end_of_input) - .unwrap(); - - assert!(decompressor.is_done()); - assert_eq!(input_consumed, compressed.len()); - assert_eq!(output_written, 0); - } - } -} diff --git a/vendor/fdeflate/src/lib.rs b/vendor/fdeflate/src/lib.rs deleted file mode 100644 index 569c872..0000000 --- a/vendor/fdeflate/src/lib.rs +++ /dev/null @@ -1,123 +0,0 @@ -//! A fast deflate implementation. -//! -//! This crate contains an optimized implementation of the deflate algorithm tuned to compress PNG -//! images. It is compatible with standard zlib, but make a bunch of simplifying assumptions that -//! drastically improve encoding performance: -//! -//! - Exactly one block per deflate stream. -//! - No distance codes except for run length encoding of zeros. -//! - A single fixed huffman tree trained on a large corpus of PNG images. -//! - All huffman codes are 12 bits or less. -//! -//! It also contains a fast decompressor that supports arbitrary zlib streams but does especially -//! well on streams that meet the above assumptions. -//! -//! # Inspiration -//! -//! The algorithms in this crate take inspiration from multiple sources: -//! * [fpnge](https://github.com/veluca93/fpnge) -//! * [zune-inflate](https://github.com/etemesi254/zune-image/tree/main/zune-inflate) -//! * [RealTime Data Compression blog](https://fastcompression.blogspot.com/2015/10/huffman-revisited-part-4-multi-bytes.html) -#![forbid(unsafe_code)] -#![warn(missing_docs)] - -mod compress; -mod decompress; -mod tables; - -pub use compress::{compress_to_vec, Compressor, StoredOnlyCompressor}; -pub use decompress::{ - decompress_to_vec, decompress_to_vec_bounded, BoundedDecompressionError, DecompressionError, - Decompressor, -}; - -/// Build a length limited huffman tree. -/// -/// Dynamic programming algorithm from fpnge. -#[doc(hidden)] -pub fn compute_code_lengths( - freqs: &[u64], - min_limit: &[u8], - max_limit: &[u8], - calculated_nbits: &mut [u8], -) { - debug_assert_eq!(freqs.len(), min_limit.len()); - debug_assert_eq!(freqs.len(), max_limit.len()); - debug_assert_eq!(freqs.len(), calculated_nbits.len()); - let len = freqs.len(); - - for i in 0..len { - debug_assert!(min_limit[i] >= 1); - debug_assert!(min_limit[i] <= max_limit[i]); - } - - let precision = *max_limit.iter().max().unwrap(); - let num_patterns = 1 << precision; - - let mut dynp = vec![u64::MAX; (num_patterns + 1) * (len + 1)]; - let index = |sym: usize, off: usize| sym * (num_patterns + 1) + off; - - dynp[index(0, 0)] = 0; - for sym in 0..len { - for bits in min_limit[sym]..=max_limit[sym] { - let off_delta = 1 << (precision - bits); - for off in 0..=num_patterns.saturating_sub(off_delta) { - dynp[index(sym + 1, off + off_delta)] = dynp[index(sym, off)] - .saturating_add(freqs[sym] * u64::from(bits)) - .min(dynp[index(sym + 1, off + off_delta)]); - } - } - } - - let mut sym = len; - let mut off = num_patterns; - - while sym > 0 { - sym -= 1; - assert!(off > 0); - - for bits in min_limit[sym]..=max_limit[sym] { - let off_delta = 1 << (precision - bits); - if off_delta <= off - && dynp[index(sym + 1, off)] - == dynp[index(sym, off - off_delta)] - .saturating_add(freqs[sym] * u64::from(bits)) - { - off -= off_delta; - calculated_nbits[sym] = bits; - break; - } - } - } - - for i in 0..len { - debug_assert!(calculated_nbits[i] >= min_limit[i]); - debug_assert!(calculated_nbits[i] <= max_limit[i]); - } -} - -const fn compute_codes<const NSYMS: usize>(lengths: &[u8; NSYMS]) -> Option<[u16; NSYMS]> { - let mut codes = [0u16; NSYMS]; - - let mut code = 0u32; - - let mut len = 1; - while len <= 16 { - let mut i = 0; - while i < lengths.len() { - if lengths[i] == len { - codes[i] = (code as u16).reverse_bits() >> (16 - len); - code += 1; - } - i += 1; - } - code <<= 1; - len += 1; - } - - if code == 2 << 16 { - Some(codes) - } else { - None - } -} diff --git a/vendor/fdeflate/src/tables.rs b/vendor/fdeflate/src/tables.rs deleted file mode 100644 index 8b233c8..0000000 --- a/vendor/fdeflate/src/tables.rs +++ /dev/null @@ -1,635 +0,0 @@ -/// Hard-coded Huffman codes used regardless of the input. -/// -/// These values work well for PNGs with some form of filtering enabled, but will likely make most -/// other inputs worse. -pub(crate) const HUFFMAN_LENGTHS: [u8; 286] = [ - 2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 8, 8, 7, - 7, 7, 6, 6, 6, 5, 4, 3, 12, 12, 12, 9, 9, 11, 10, 11, 11, 10, 11, 11, 11, 11, 11, 11, 12, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, -]; - -pub(crate) const HUFFMAN_CODES: [u16; 286] = match crate::compute_codes(&HUFFMAN_LENGTHS) { - Some(codes) => codes, - None => panic!("HUFFMAN_LENGTHS is invalid"), -}; - -/// Length code for length values (derived from deflate spec). -pub(crate) const LENGTH_TO_SYMBOL: [u16; 256] = [ - 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, - 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, 273, 273, 273, 273, 273, 273, - 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, - 276, 276, 276, 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 285, -]; - -/// Number of extra bits for length values (derived from deflate spec). -pub(crate) const LENGTH_TO_LEN_EXTRA: [u8; 256] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, -]; - -pub(crate) const BITMASKS: [u32; 17] = [ - 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, - 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, -]; - -/// Order of the length code length alphabet (derived from deflate spec). -pub(crate) const CLCL_ORDER: [usize; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, -]; - -/// Number of extra bits for each length code (derived from deflate spec). -pub(crate) const LEN_SYM_TO_LEN_EXTRA: [u8; 29] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, -]; - -/// The base length for each length code (derived from deflate spec). -pub(crate) const LEN_SYM_TO_LEN_BASE: [usize; 29] = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, - 163, 195, 227, 258, -]; - -/// Number of extra bits for each distance code (derived from deflate spec.) -pub(crate) const DIST_SYM_TO_DIST_EXTRA: [u8; 30] = [ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, - 13, -]; - -/// The base distance for each distance code (derived from deflate spec). -pub(crate) const DIST_SYM_TO_DIST_BASE: [u16; 30] = [ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, - 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, -]; - -pub(crate) const FDEFLATE_LITLEN_DECODE_TABLE: [u32; 4096] = [ - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf4820a, 0x1008205, - 0xfe8206, 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0xb010a, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xee820b, 0xff008205, 0x2fe8208, - 0xfa018209, 0xa820a, 0xf400820a, 0x58208, 0xfaff8209, 0x65810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0x2038209, 0xff8205, 0x11820b, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, - 0x9008209, 0x2fd8209, 0x3ff8208, 0x17020b, 0x8204, 0xfa02820a, 0xff018206, 0x78209, 0xfd008207, - 0x2048209, 0xffff8206, 0x1a820c, 0xff008205, 0xfafe820a, 0xf401820b, 0xe820a, 0x8102, 0x68208, - 0xf4ff820b, 0xa5810c, 0x8204, 0x28206, 0x18205, 0x2fa820a, 0x2008206, 0x1038208, 0xff8205, - 0xf6820a, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, 0xfeff8207, - 0xd8810b, 0x8204, 0x3028209, 0x1018206, 0x2fc820a, 0x4008207, 0x1048208, 0x1ff8206, 0x60009, - 0xff008205, 0x3fe8209, 0x901820a, 0xc820a, 0xee00820b, 0x205820a, 0x9ff820a, 0x85810c, 0x8204, - 0xff028207, 0x18205, 0x2fb820a, 0xfe008206, 0xfa03820b, 0xff8205, 0x15820b, 0x1008205, - 0xfffe8207, 0xfd018208, 0xf98209, 0xa00820a, 0xfafd820b, 0xfdff8208, 0x45810c, 0x8204, - 0xf402820c, 0xff018206, 0x88209, 0x5008208, 0xfa04820b, 0xffff8206, 0xe4820c, 0xff008205, - 0xf4fe820c, 0x18103, 0xf2820a, 0x8102, 0x206820a, 0xff8103, 0xc5810c, 0x8204, 0x28206, 0x18205, - 0x1fa8209, 0x2008206, 0x38207, 0xff8205, 0xf5820a, 0x1008205, 0xfe8206, 0x2018207, 0x209820b, - 0xfb008208, 0xfd8207, 0x2ff8207, 0x25810b, 0x8204, 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, - 0x48207, 0x1ff8206, 0xf1820b, 0xff008205, 0xfefe8208, 0xfc018209, 0xb820a, 0x1100820b, - 0x1058209, 0xfcff8209, 0x75810c, 0x8204, 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x303820a, - 0xff8205, 0x13820b, 0x1008205, 0x1fe8207, 0x4018208, 0x2f8820b, 0xf8008209, 0x3fd820a, - 0x4ff8208, 0x35810c, 0x8204, 0x902820b, 0xff018206, 0x207820b, 0xfd008207, 0x304820a, - 0xffff8206, 0x1e820c, 0xff008205, 0x9fe820b, 0xee01820c, 0xf0820a, 0x8102, 0x1068209, - 0xeeff820c, 0xb5810c, 0x8204, 0x28206, 0x18205, 0xfafa820c, 0x2008206, 0xff038208, 0xff8205, - 0xf820b, 0x1008205, 0xfe8206, 0xfe018207, 0x2f7820b, 0x7008209, 0xfffd8208, 0xfeff8207, - 0xe1810b, 0x8204, 0xfd028209, 0x1018206, 0xfafc820c, 0x4008207, 0xff048208, 0x1ff8206, - 0x16820c, 0xff008205, 0xfdfe8209, 0xa01820b, 0xd820a, 0x1a00820c, 0xfa05820c, 0xaff820b, - 0x95810c, 0x8204, 0xff028207, 0x18205, 0xfafb820c, 0xfe008206, 0x38105, 0xff8205, 0xec820b, - 0x1008205, 0xfffe8207, 0x5018209, 0x2f9820b, 0xe00820a, 0xfd8105, 0x5ff8209, 0x55810c, 0x8204, - 0x28104, 0xff018206, 0x208820b, 0x6008208, 0x48105, 0xffff8206, 0xe8820c, 0xff008205, 0xfe8104, - 0x18103, 0xf3820a, 0x8102, 0xfa06820c, 0xff8103, 0xd5810c, 0x8204, 0x28206, 0x18205, 0xfa8208, - 0x2008206, 0x38207, 0xff8205, 0x2f4820c, 0x1008205, 0xfe8206, 0x2018207, 0x109820a, 0xfa008208, - 0xfd8207, 0x2ff8207, 0x21810b, 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, - 0x1ff8206, 0xef820b, 0xff008205, 0x2fe8208, 0xfb018209, 0x20a820c, 0xf600820a, 0x58208, - 0xfbff8209, 0x6d810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, - 0x12820b, 0x1008205, 0x1fe8207, 0x3018208, 0x1f8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, - 0x2d810c, 0x8204, 0xfc02820a, 0xff018206, 0x107820a, 0xfd008207, 0xfe048209, 0xffff8206, - 0x1c820c, 0xff008205, 0xfcfe820a, 0x1101820c, 0x20e820c, 0x8102, 0x68208, 0x11ff820c, 0xad810c, - 0x8204, 0x28206, 0x18205, 0x3fa820b, 0x2008206, 0x1038208, 0xff8205, 0x2f6820c, 0x1008205, - 0xfe8206, 0xfe018207, 0x1f7820a, 0xfc008208, 0x1fd8208, 0xfeff8207, 0xdc810b, 0x8204, - 0x4028209, 0x1018206, 0x3fc820b, 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, - 0x4fe8209, 0xf801820a, 0x20c820c, 0x8102, 0x305820b, 0xf8ff820a, 0x8d810c, 0x8204, 0xff028207, - 0x18205, 0x3fb820b, 0xfe008206, 0x903820c, 0xff8205, 0xeb820b, 0x1008205, 0xfffe8207, - 0xfd018208, 0x1f9820a, 0xc00820a, 0x9fd820c, 0xfdff8208, 0x4d810c, 0x8204, 0x28104, 0xff018206, - 0x108820a, 0x5008208, 0x904820c, 0xffff8206, 0xe6820c, 0xff008205, 0xfe8104, 0x18103, - 0x2f2820c, 0x8102, 0x306820b, 0xff8103, 0xcd810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, - 0x2008206, 0x38207, 0xff8205, 0x2f5820c, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, - 0xfd8207, 0x2ff8207, 0x29810b, 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, - 0x1ff8206, 0x50009, 0xff008205, 0xfefe8208, 0x701820a, 0x20b820c, 0x1500820b, 0xff058209, - 0x7ff820a, 0x7d810c, 0x8204, 0x1028207, 0x18205, 0xfffb8209, 0xfe008206, 0xfd03820a, 0xff8205, - 0x14820b, 0x1008205, 0x1fe8207, 0x4018208, 0xf88107, 0xf9008209, 0xfdfd820a, 0x4ff8208, - 0x3d810c, 0x8204, 0xa02820c, 0xff018206, 0x78107, 0xfd008207, 0xfd04820a, 0xffff8206, 0xe2820c, - 0xff008205, 0xafe820c, 0x18103, 0x2f0820c, 0x8102, 0xff068209, 0xff8103, 0xbd810c, 0x8204, - 0x28206, 0x18205, 0xfa8106, 0x2008206, 0xff038208, 0xff8205, 0x10820b, 0x1008205, 0xfe8206, - 0xfe018207, 0xf78107, 0x8008209, 0xfffd8208, 0xfeff8207, 0xd010b, 0x8204, 0x502820a, 0x1018206, - 0xfc8106, 0x4008207, 0xff048208, 0x1ff8206, 0x18820c, 0xff008205, 0x5fe820a, 0xe01820b, - 0x20d820c, 0xe400820c, 0x58106, 0xeff820b, 0x9d810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, - 0xfe008206, 0x38105, 0xff8205, 0xed820b, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, - 0xf200820a, 0xfd8105, 0x6ff8209, 0x5d810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, - 0x48105, 0xffff8206, 0xea820c, 0xff008205, 0xfe8104, 0x18103, 0x2f3820c, 0x8102, 0x68106, - 0xff8103, 0x43040c, 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, - 0x1f4820b, 0x1008205, 0xfe8206, 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0x1f810b, - 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xee8109, 0xff008205, - 0x2fe8208, 0xfa018209, 0x10a820b, 0xf500820a, 0x58208, 0xfaff8209, 0x69810c, 0x8204, 0x1028207, - 0x18205, 0xfb8208, 0xfe008206, 0x2038209, 0xff8205, 0x118109, 0x1008205, 0x1fe8207, 0x3018208, - 0xf88209, 0x9008209, 0x2fd8209, 0x3ff8208, 0x23030b, 0x8204, 0xfb02820a, 0xff018206, 0x78209, - 0xfd008207, 0x2048209, 0xffff8206, 0x1b820c, 0xff008205, 0xfbfe820a, 0xf601820b, 0x10e820b, - 0x8102, 0x68208, 0xf6ff820b, 0xa9810c, 0x8204, 0x28206, 0x18205, 0xfefa820a, 0x2008206, - 0x1038208, 0xff8205, 0x1f6820b, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, - 0x1fd8208, 0xfeff8207, 0xda810b, 0x8204, 0x3028209, 0x1018206, 0xfefc820a, 0x4008207, - 0x1048208, 0x1ff8206, 0x60009, 0xff008205, 0x3fe8209, 0xf701820a, 0x10c820b, 0xf100820b, - 0xfe05820a, 0xf7ff820a, 0x89810c, 0x8204, 0xff028207, 0x18205, 0xfefb820a, 0xfe008206, - 0xfc03820b, 0xff8205, 0x158109, 0x1008205, 0xfffe8207, 0xfd018208, 0xf98209, 0xb00820a, - 0xfcfd820b, 0xfdff8208, 0x49810c, 0x8204, 0x28104, 0xff018206, 0x88209, 0x5008208, 0xfc04820b, - 0xffff8206, 0xe5820c, 0xff008205, 0xfe8104, 0x18103, 0x1f2820b, 0x8102, 0xfe06820a, 0xff8103, - 0xc9810c, 0x8204, 0x28206, 0x18205, 0x1fa8209, 0x2008206, 0x38207, 0xff8205, 0x1f5820b, - 0x1008205, 0xfe8206, 0x2018207, 0x309820c, 0xfb008208, 0xfd8207, 0x2ff8207, 0x27810b, 0x8204, - 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, 0x48207, 0x1ff8206, 0xf18109, 0xff008205, - 0xfefe8208, 0xfc018209, 0x10b820b, 0x1300820b, 0x1058209, 0xfcff8209, 0x79810c, 0x8204, - 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x403820a, 0xff8205, 0x138109, 0x1008205, 0x1fe8207, - 0x4018208, 0x3f8820c, 0xf8008209, 0x4fd820a, 0x4ff8208, 0x39810c, 0x8204, 0xf802820b, - 0xff018206, 0x307820c, 0xfd008207, 0x404820a, 0xffff8206, 0xe0820c, 0xff008205, 0xf8fe820b, - 0x18103, 0x1f0820b, 0x8102, 0x1068209, 0xff8103, 0xb9810c, 0x8204, 0x28206, 0x18205, 0xfa8106, - 0x2008206, 0xff038208, 0xff8205, 0xf8109, 0x1008205, 0xfe8206, 0xfe018207, 0x3f7820c, - 0x7008209, 0xfffd8208, 0xfeff8207, 0x9000b, 0x8204, 0xfd028209, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x17820c, 0xff008205, 0xfdfe8209, 0xc01820b, 0x10d820b, 0x1e00820c, - 0x58106, 0xcff820b, 0x99810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xec8109, 0x1008205, 0xfffe8207, 0x5018209, 0x3f9820c, 0xf000820a, 0xfd8105, - 0x5ff8209, 0x59810c, 0x8204, 0x28104, 0xff018206, 0x308820c, 0x6008208, 0x48105, 0xffff8206, - 0xe9820c, 0xff008205, 0xfe8104, 0x18103, 0x1f3820b, 0x8102, 0x68106, 0xff8103, 0x1f020c, - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf48108, 0x1008205, - 0xfe8206, 0x2018207, 0xff09820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x23810b, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xef8109, 0xff008205, 0x2fe8208, - 0xfb018209, 0xa8108, 0xf00820b, 0x58208, 0xfbff8209, 0x71810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0x128109, 0x1008205, 0x1fe8207, 0x3018208, - 0xfff8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x31810c, 0x8204, 0x702820b, 0xff018206, - 0xff07820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1d820c, 0xff008205, 0x7fe820b, 0x1501820c, - 0xe8108, 0x8102, 0x68208, 0x15ff820c, 0xb1810c, 0x8204, 0x28206, 0x18205, 0xfdfa820b, - 0x2008206, 0x1038208, 0xff8205, 0xf68108, 0x1008205, 0xfe8206, 0xfe018207, 0xfff7820a, - 0xfc008208, 0x1fd8208, 0xfeff8207, 0xde810b, 0x8204, 0x4028209, 0x1018206, 0xfdfc820b, - 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf901820a, 0xc8108, - 0x1600820c, 0xfd05820b, 0xf9ff820a, 0x91810c, 0x8204, 0xff028207, 0x18205, 0xfdfb820b, - 0xfe008206, 0x38105, 0xff8205, 0xeb8109, 0x1008205, 0xfffe8207, 0xfd018208, 0xfff9820a, - 0xd00820a, 0xfd8105, 0xfdff8208, 0x51810c, 0x8204, 0x28104, 0xff018206, 0xff08820a, 0x5008208, - 0x48105, 0xffff8206, 0xe7820c, 0xff008205, 0xfe8104, 0x18103, 0xf28108, 0x8102, 0xfd06820b, - 0xff8103, 0xd1810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, - 0xf58108, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0xd6810b, - 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, - 0xfefe8208, 0x801820a, 0xb8108, 0xec00820b, 0xff058209, 0x8ff820a, 0x81810c, 0x8204, 0x1028207, - 0x18205, 0xfffb8209, 0xfe008206, 0x503820b, 0xff8205, 0x148109, 0x1008205, 0x1fe8207, - 0x4018208, 0xf88107, 0xf9008209, 0x5fd820b, 0x4ff8208, 0x41810c, 0x8204, 0xe02820c, 0xff018206, - 0x78107, 0xfd008207, 0x504820b, 0xffff8206, 0xe3820c, 0xff008205, 0xefe820c, 0x18103, 0xf08108, - 0x8102, 0xff068209, 0xff8103, 0xc1810c, 0x8204, 0x28206, 0x18205, 0xfa8106, 0x2008206, - 0xff038208, 0xff8205, 0x108109, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, 0x8008209, - 0xfffd8208, 0xfeff8207, 0x11010b, 0x8204, 0x602820a, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x19820c, 0xff008205, 0x6fe820a, 0xf201820b, 0xd8108, 0xe800820c, - 0x58106, 0xf2ff820b, 0xa1810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xed8109, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, 0xf300820a, 0xfd8105, - 0x6ff8209, 0x61810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, - 0x8000a, 0xff008205, 0xfe8104, 0x18103, 0xf38108, 0x8102, 0x68106, 0xff8103, 0x83050c, 0x8204, - 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf4820a, 0x1008205, 0xfe8206, - 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0xb010a, 0x8204, 0x2028208, 0x1018206, - 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0x1ee820c, 0xff008205, 0x2fe8208, 0xfa018209, 0xa820a, - 0xf400820a, 0x58208, 0xfaff8209, 0x67810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, 0xfe008206, - 0x2038209, 0xff8205, 0x111820c, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, 0x9008209, - 0x2fd8209, 0x3ff8208, 0x1b020b, 0x8204, 0xfa02820a, 0xff018206, 0x78209, 0xfd008207, 0x2048209, - 0xffff8206, 0x1a810a, 0xff008205, 0xfafe820a, 0xf501820b, 0xe820a, 0x8102, 0x68208, 0xf5ff820b, - 0xa7810c, 0x8204, 0x28206, 0x18205, 0x2fa820a, 0x2008206, 0x1038208, 0xff8205, 0xf6820a, - 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, 0xfeff8207, 0xd9810b, 0x8204, - 0x3028209, 0x1018206, 0x2fc820a, 0x4008207, 0x1048208, 0x1ff8206, 0x60009, 0xff008205, - 0x3fe8209, 0x901820a, 0xc820a, 0xef00820b, 0x205820a, 0x9ff820a, 0x87810c, 0x8204, 0xff028207, - 0x18205, 0x2fb820a, 0xfe008206, 0xfb03820b, 0xff8205, 0x115820c, 0x1008205, 0xfffe8207, - 0xfd018208, 0xf98209, 0xa00820a, 0xfbfd820b, 0xfdff8208, 0x47810c, 0x8204, 0xf602820c, - 0xff018206, 0x88209, 0x5008208, 0xfb04820b, 0xffff8206, 0xe4810a, 0xff008205, 0xf6fe820c, - 0x18103, 0xf2820a, 0x8102, 0x206820a, 0xff8103, 0xc7810c, 0x8204, 0x28206, 0x18205, 0x1fa8209, - 0x2008206, 0x38207, 0xff8205, 0xf5820a, 0x1008205, 0xfe8206, 0x2018207, 0xfe09820b, 0xfb008208, - 0xfd8207, 0x2ff8207, 0x26810b, 0x8204, 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, 0x48207, - 0x1ff8206, 0x1f1820c, 0xff008205, 0xfefe8208, 0xfc018209, 0xb820a, 0x1200820b, 0x1058209, - 0xfcff8209, 0x77810c, 0x8204, 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x303820a, 0xff8205, - 0x113820c, 0x1008205, 0x1fe8207, 0x4018208, 0xfef8820b, 0xf8008209, 0x3fd820a, 0x4ff8208, - 0x37810c, 0x8204, 0xf702820b, 0xff018206, 0xfe07820b, 0xfd008207, 0x304820a, 0xffff8206, - 0x1e810a, 0xff008205, 0xf7fe820b, 0xf101820c, 0xf0820a, 0x8102, 0x1068209, 0xf1ff820c, - 0xb7810c, 0x8204, 0x28206, 0x18205, 0xfcfa820c, 0x2008206, 0xff038208, 0xff8205, 0x10f820c, - 0x1008205, 0xfe8206, 0xfe018207, 0xfef7820b, 0x7008209, 0xfffd8208, 0xfeff8207, 0x7000b, - 0x8204, 0xfd028209, 0x1018206, 0xfcfc820c, 0x4008207, 0xff048208, 0x1ff8206, 0x16810a, - 0xff008205, 0xfdfe8209, 0xb01820b, 0xd820a, 0x1c00820c, 0xfc05820c, 0xbff820b, 0x97810c, - 0x8204, 0xff028207, 0x18205, 0xfcfb820c, 0xfe008206, 0x38105, 0xff8205, 0x1ec820c, 0x1008205, - 0xfffe8207, 0x5018209, 0xfef9820b, 0xe00820a, 0xfd8105, 0x5ff8209, 0x57810c, 0x8204, 0x28104, - 0xff018206, 0xfe08820b, 0x6008208, 0x48105, 0xffff8206, 0xe8810a, 0xff008205, 0xfe8104, - 0x18103, 0xf3820a, 0x8102, 0xfc06820c, 0xff8103, 0x3000c, 0x8204, 0x28206, 0x18205, 0xfa8208, - 0x2008206, 0x38207, 0xff8205, 0xf48108, 0x1008205, 0xfe8206, 0x2018207, 0x109820a, 0xfa008208, - 0xfd8207, 0x2ff8207, 0x22810b, 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, - 0x1ff8206, 0x1ef820c, 0xff008205, 0x2fe8208, 0xfb018209, 0xa8108, 0xf600820a, 0x58208, - 0xfbff8209, 0x6f810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, - 0x112820c, 0x1008205, 0x1fe8207, 0x3018208, 0x1f8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, - 0x2f810c, 0x8204, 0xfc02820a, 0xff018206, 0x107820a, 0xfd008207, 0xfe048209, 0xffff8206, - 0x1c810a, 0xff008205, 0xfcfe820a, 0x1301820c, 0xe8108, 0x8102, 0x68208, 0x13ff820c, 0xaf810c, - 0x8204, 0x28206, 0x18205, 0x4fa820b, 0x2008206, 0x1038208, 0xff8205, 0xf68108, 0x1008205, - 0xfe8206, 0xfe018207, 0x1f7820a, 0xfc008208, 0x1fd8208, 0xfeff8207, 0xdd810b, 0x8204, - 0x4028209, 0x1018206, 0x4fc820b, 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, - 0x4fe8209, 0xf801820a, 0xc8108, 0x8102, 0x405820b, 0xf8ff820a, 0x8f810c, 0x8204, 0xff028207, - 0x18205, 0x4fb820b, 0xfe008206, 0xf803820c, 0xff8205, 0x1eb820c, 0x1008205, 0xfffe8207, - 0xfd018208, 0x1f9820a, 0xc00820a, 0xf8fd820c, 0xfdff8208, 0x4f810c, 0x8204, 0x28104, - 0xff018206, 0x108820a, 0x5008208, 0xf804820c, 0xffff8206, 0xe6810a, 0xff008205, 0xfe8104, - 0x18103, 0xf28108, 0x8102, 0x406820b, 0xff8103, 0xcf810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, - 0x2008206, 0x38207, 0xff8205, 0xf58108, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, - 0xfd8207, 0x2ff8207, 0x2a810b, 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, - 0x1ff8206, 0x50009, 0xff008205, 0xfefe8208, 0x701820a, 0xb8108, 0xeb00820b, 0xff058209, - 0x7ff820a, 0x7f810c, 0x8204, 0x1028207, 0x18205, 0xfffb8209, 0xfe008206, 0xfd03820a, 0xff8205, - 0x114820c, 0x1008205, 0x1fe8207, 0x4018208, 0xf88107, 0xf9008209, 0xfdfd820a, 0x4ff8208, - 0x3f810c, 0x8204, 0xc02820c, 0xff018206, 0x78107, 0xfd008207, 0xfd04820a, 0xffff8206, 0xe2810a, - 0xff008205, 0xcfe820c, 0x18103, 0xf08108, 0x8102, 0xff068209, 0xff8103, 0xbf810c, 0x8204, - 0x28206, 0x18205, 0xfa8106, 0x2008206, 0xff038208, 0xff8205, 0x110820c, 0x1008205, 0xfe8206, - 0xfe018207, 0xf78107, 0x8008209, 0xfffd8208, 0xfeff8207, 0xf010b, 0x8204, 0x502820a, 0x1018206, - 0xfc8106, 0x4008207, 0xff048208, 0x1ff8206, 0x18810a, 0xff008205, 0x5fe820a, 0xf001820b, - 0xd8108, 0xe600820c, 0x58106, 0xf0ff820b, 0x9f810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, - 0xfe008206, 0x38105, 0xff8205, 0x1ed820c, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, - 0xf200820a, 0xfd8105, 0x6ff8209, 0x5f810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, - 0x48105, 0xffff8206, 0xea810a, 0xff008205, 0xfe8104, 0x18103, 0xf38108, 0x8102, 0x68106, - 0xff8103, 0x63040c, 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, - 0xfff4820b, 0x1008205, 0xfe8206, 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0x20810b, - 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xee8109, 0xff008205, - 0x2fe8208, 0xfa018209, 0xff0a820b, 0xf500820a, 0x58208, 0xfaff8209, 0x6b810c, 0x8204, - 0x1028207, 0x18205, 0xfb8208, 0xfe008206, 0x2038209, 0xff8205, 0x118109, 0x1008205, 0x1fe8207, - 0x3018208, 0xf88209, 0x9008209, 0x2fd8209, 0x3ff8208, 0x2b810c, 0x8204, 0xfb02820a, 0xff018206, - 0x78209, 0xfd008207, 0x2048209, 0xffff8206, 0x1b810a, 0xff008205, 0xfbfe820a, 0xf01820c, - 0xff0e820b, 0x8102, 0x68208, 0xfff820c, 0xab810c, 0x8204, 0x28206, 0x18205, 0xfefa820a, - 0x2008206, 0x1038208, 0xff8205, 0xfff6820b, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, - 0xfc008208, 0x1fd8208, 0xfeff8207, 0xdb810b, 0x8204, 0x3028209, 0x1018206, 0xfefc820a, - 0x4008207, 0x1048208, 0x1ff8206, 0x60009, 0xff008205, 0x3fe8209, 0xf701820a, 0xff0c820b, - 0x8102, 0xfe05820a, 0xf7ff820a, 0x8b810c, 0x8204, 0xff028207, 0x18205, 0xfefb820a, 0xfe008206, - 0x703820c, 0xff8205, 0x158109, 0x1008205, 0xfffe8207, 0xfd018208, 0xf98209, 0xb00820a, - 0x7fd820c, 0xfdff8208, 0x4b810c, 0x8204, 0x28104, 0xff018206, 0x88209, 0x5008208, 0x704820c, - 0xffff8206, 0xe5810a, 0xff008205, 0xfe8104, 0x18103, 0xfff2820b, 0x8102, 0xfe06820a, 0xff8103, - 0xcb810c, 0x8204, 0x28206, 0x18205, 0x1fa8209, 0x2008206, 0x38207, 0xff8205, 0xfff5820b, - 0x1008205, 0xfe8206, 0x2018207, 0xfd09820c, 0xfb008208, 0xfd8207, 0x2ff8207, 0x28810b, 0x8204, - 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, 0x48207, 0x1ff8206, 0xf18109, 0xff008205, - 0xfefe8208, 0xfc018209, 0xff0b820b, 0x1400820b, 0x1058209, 0xfcff8209, 0x7b810c, 0x8204, - 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x403820a, 0xff8205, 0x138109, 0x1008205, 0x1fe8207, - 0x4018208, 0xfdf8820c, 0xf8008209, 0x4fd820a, 0x4ff8208, 0x3b810c, 0x8204, 0xf902820b, - 0xff018206, 0xfd07820c, 0xfd008207, 0x404820a, 0xffff8206, 0xe0810a, 0xff008205, 0xf9fe820b, - 0x18103, 0xfff0820b, 0x8102, 0x1068209, 0xff8103, 0xbb810c, 0x8204, 0x28206, 0x18205, 0xfa8106, - 0x2008206, 0xff038208, 0xff8205, 0xf8109, 0x1008205, 0xfe8206, 0xfe018207, 0xfdf7820c, - 0x7008209, 0xfffd8208, 0xfeff8207, 0xa000b, 0x8204, 0xfd028209, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x17810a, 0xff008205, 0xfdfe8209, 0xd01820b, 0xff0d820b, 0xe200820c, - 0x58106, 0xdff820b, 0x9b810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xec8109, 0x1008205, 0xfffe8207, 0x5018209, 0xfdf9820c, 0xf000820a, 0xfd8105, - 0x5ff8209, 0x5b810c, 0x8204, 0x28104, 0xff018206, 0xfd08820c, 0x6008208, 0x48105, 0xffff8206, - 0xe9810a, 0xff008205, 0xfe8104, 0x18103, 0xfff3820b, 0x8102, 0x68106, 0xff8103, 0x33030c, - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf48108, 0x1008205, - 0xfe8206, 0x2018207, 0xff09820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x24810b, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xef8109, 0xff008205, 0x2fe8208, - 0xfb018209, 0xa8108, 0x1000820b, 0x58208, 0xfbff8209, 0x73810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0x128109, 0x1008205, 0x1fe8207, 0x3018208, - 0xfff8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x33810c, 0x8204, 0x802820b, 0xff018206, - 0xff07820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1d810a, 0xff008205, 0x8fe820b, 0xec01820c, - 0xe8108, 0x8102, 0x68208, 0xecff820c, 0xb3810c, 0x8204, 0x28206, 0x18205, 0x5fa820c, 0x2008206, - 0x1038208, 0xff8205, 0xf68108, 0x1008205, 0xfe8206, 0xfe018207, 0xfff7820a, 0xfc008208, - 0x1fd8208, 0xfeff8207, 0xdf810b, 0x8204, 0x4028209, 0x1018206, 0x5fc820c, 0x4008207, 0x1048208, - 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf901820a, 0xc8108, 0x1800820c, 0x505820c, - 0xf9ff820a, 0x93810c, 0x8204, 0xff028207, 0x18205, 0x5fb820c, 0xfe008206, 0x38105, 0xff8205, - 0xeb8109, 0x1008205, 0xfffe8207, 0xfd018208, 0xfff9820a, 0xd00820a, 0xfd8105, 0xfdff8208, - 0x53810c, 0x8204, 0x28104, 0xff018206, 0xff08820a, 0x5008208, 0x48105, 0xffff8206, 0xe7810a, - 0xff008205, 0xfe8104, 0x18103, 0xf28108, 0x8102, 0x506820c, 0xff8103, 0xd3810c, 0x8204, - 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, 0xf58108, 0x1008205, 0xfe8206, - 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0xd7810b, 0x8204, 0xfe028208, 0x1018206, - 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, 0xfefe8208, 0x801820a, 0xb8108, - 0xed00820b, 0xff058209, 0x8ff820a, 0x83810c, 0x8204, 0x1028207, 0x18205, 0xfffb8209, - 0xfe008206, 0x603820b, 0xff8205, 0x148109, 0x1008205, 0x1fe8207, 0x4018208, 0xf88107, - 0xf9008209, 0x6fd820b, 0x4ff8208, 0x43810c, 0x8204, 0xf202820c, 0xff018206, 0x78107, - 0xfd008207, 0x604820b, 0xffff8206, 0xe3810a, 0xff008205, 0xf2fe820c, 0x18103, 0xf08108, 0x8102, - 0xff068209, 0xff8103, 0xc3810c, 0x8204, 0x28206, 0x18205, 0xfa8106, 0x2008206, 0xff038208, - 0xff8205, 0x108109, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, 0x8008209, 0xfffd8208, - 0xfeff8207, 0x13020b, 0x8204, 0x602820a, 0x1018206, 0xfc8106, 0x4008207, 0xff048208, 0x1ff8206, - 0x19810a, 0xff008205, 0x6fe820a, 0xf301820b, 0xd8108, 0xea00820c, 0x58106, 0xf3ff820b, - 0xa3810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, 0xff8205, 0xed8109, - 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, 0xf300820a, 0xfd8105, 0x6ff8209, 0x63810c, 0x8204, - 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, 0x8000a, 0xff008205, 0xfe8104, - 0x18103, 0xf38108, 0x8102, 0x68106, 0xff8103, 0xc3050c, 0x8204, 0x28206, 0x18205, 0xfa8208, - 0x2008206, 0x38207, 0xff8205, 0xf4820a, 0x1008205, 0xfe8206, 0x2018207, 0x98209, 0xfa008208, - 0xfd8207, 0x2ff8207, 0xb010a, 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, - 0x1ff8206, 0xee820b, 0xff008205, 0x2fe8208, 0xfa018209, 0xa820a, 0xf400820a, 0x58208, - 0xfaff8209, 0x66810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, 0xfe008206, 0x2038209, 0xff8205, - 0x11820b, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, 0x9008209, 0x2fd8209, 0x3ff8208, 0x17020b, - 0x8204, 0xfa02820a, 0xff018206, 0x78209, 0xfd008207, 0x2048209, 0xffff8206, 0x1a810a, - 0xff008205, 0xfafe820a, 0xf401820b, 0xe820a, 0x8102, 0x68208, 0xf4ff820b, 0xa6810c, 0x8204, - 0x28206, 0x18205, 0x2fa820a, 0x2008206, 0x1038208, 0xff8205, 0xf6820a, 0x1008205, 0xfe8206, - 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, 0xfeff8207, 0xd8810b, 0x8204, 0x3028209, - 0x1018206, 0x2fc820a, 0x4008207, 0x1048208, 0x1ff8206, 0x60009, 0xff008205, 0x3fe8209, - 0x901820a, 0xc820a, 0xee00820b, 0x205820a, 0x9ff820a, 0x86810c, 0x8204, 0xff028207, 0x18205, - 0x2fb820a, 0xfe008206, 0xfa03820b, 0xff8205, 0x15820b, 0x1008205, 0xfffe8207, 0xfd018208, - 0xf98209, 0xa00820a, 0xfafd820b, 0xfdff8208, 0x46810c, 0x8204, 0xf502820c, 0xff018206, 0x88209, - 0x5008208, 0xfa04820b, 0xffff8206, 0xe4810a, 0xff008205, 0xf5fe820c, 0x18103, 0xf2820a, 0x8102, - 0x206820a, 0xff8103, 0xc6810c, 0x8204, 0x28206, 0x18205, 0x1fa8209, 0x2008206, 0x38207, - 0xff8205, 0xf5820a, 0x1008205, 0xfe8206, 0x2018207, 0x209820b, 0xfb008208, 0xfd8207, 0x2ff8207, - 0x25810b, 0x8204, 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, 0x48207, 0x1ff8206, 0xf1820b, - 0xff008205, 0xfefe8208, 0xfc018209, 0xb820a, 0x1100820b, 0x1058209, 0xfcff8209, 0x76810c, - 0x8204, 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x303820a, 0xff8205, 0x13820b, 0x1008205, - 0x1fe8207, 0x4018208, 0x2f8820b, 0xf8008209, 0x3fd820a, 0x4ff8208, 0x36810c, 0x8204, 0x902820b, - 0xff018206, 0x207820b, 0xfd008207, 0x304820a, 0xffff8206, 0x1e810a, 0xff008205, 0x9fe820b, - 0xef01820c, 0xf0820a, 0x8102, 0x1068209, 0xefff820c, 0xb6810c, 0x8204, 0x28206, 0x18205, - 0xfbfa820c, 0x2008206, 0xff038208, 0xff8205, 0xf820b, 0x1008205, 0xfe8206, 0xfe018207, - 0x2f7820b, 0x7008209, 0xfffd8208, 0xfeff8207, 0xe1810b, 0x8204, 0xfd028209, 0x1018206, - 0xfbfc820c, 0x4008207, 0xff048208, 0x1ff8206, 0x16810a, 0xff008205, 0xfdfe8209, 0xa01820b, - 0xd820a, 0x1b00820c, 0xfb05820c, 0xaff820b, 0x96810c, 0x8204, 0xff028207, 0x18205, 0xfbfb820c, - 0xfe008206, 0x38105, 0xff8205, 0xec820b, 0x1008205, 0xfffe8207, 0x5018209, 0x2f9820b, - 0xe00820a, 0xfd8105, 0x5ff8209, 0x56810c, 0x8204, 0x28104, 0xff018206, 0x208820b, 0x6008208, - 0x48105, 0xffff8206, 0xe8810a, 0xff008205, 0xfe8104, 0x18103, 0xf3820a, 0x8102, 0xfb06820c, - 0xff8103, 0x400c, 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xfef4820c, - 0x1008205, 0xfe8206, 0x2018207, 0x109820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x21810b, 0x8204, - 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xef820b, 0xff008205, 0x2fe8208, - 0xfb018209, 0xfe0a820c, 0xf600820a, 0x58208, 0xfbff8209, 0x6e810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0x12820b, 0x1008205, 0x1fe8207, 0x3018208, - 0x1f8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x2e810c, 0x8204, 0xfc02820a, 0xff018206, - 0x107820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1c810a, 0xff008205, 0xfcfe820a, 0x1201820c, - 0xfe0e820c, 0x8102, 0x68208, 0x12ff820c, 0xae810c, 0x8204, 0x28206, 0x18205, 0x3fa820b, - 0x2008206, 0x1038208, 0xff8205, 0xfef6820c, 0x1008205, 0xfe8206, 0xfe018207, 0x1f7820a, - 0xfc008208, 0x1fd8208, 0xfeff8207, 0xdc810b, 0x8204, 0x4028209, 0x1018206, 0x3fc820b, - 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf801820a, 0xfe0c820c, - 0x8102, 0x305820b, 0xf8ff820a, 0x8e810c, 0x8204, 0xff028207, 0x18205, 0x3fb820b, 0xfe008206, - 0xf703820c, 0xff8205, 0xeb820b, 0x1008205, 0xfffe8207, 0xfd018208, 0x1f9820a, 0xc00820a, - 0xf7fd820c, 0xfdff8208, 0x4e810c, 0x8204, 0x28104, 0xff018206, 0x108820a, 0x5008208, - 0xf704820c, 0xffff8206, 0xe6810a, 0xff008205, 0xfe8104, 0x18103, 0xfef2820c, 0x8102, 0x306820b, - 0xff8103, 0xce810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, - 0xfef5820c, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0x29810b, - 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, - 0xfefe8208, 0x701820a, 0xfe0b820c, 0x1500820b, 0xff058209, 0x7ff820a, 0x7e810c, 0x8204, - 0x1028207, 0x18205, 0xfffb8209, 0xfe008206, 0xfd03820a, 0xff8205, 0x14820b, 0x1008205, - 0x1fe8207, 0x4018208, 0xf88107, 0xf9008209, 0xfdfd820a, 0x4ff8208, 0x3e810c, 0x8204, 0xb02820c, - 0xff018206, 0x78107, 0xfd008207, 0xfd04820a, 0xffff8206, 0xe2810a, 0xff008205, 0xbfe820c, - 0x18103, 0xfef0820c, 0x8102, 0xff068209, 0xff8103, 0xbe810c, 0x8204, 0x28206, 0x18205, - 0xfa8106, 0x2008206, 0xff038208, 0xff8205, 0x10820b, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, - 0x8008209, 0xfffd8208, 0xfeff8207, 0xd010b, 0x8204, 0x502820a, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x18810a, 0xff008205, 0x5fe820a, 0xe01820b, 0xfe0d820c, 0xe500820c, - 0x58106, 0xeff820b, 0x9e810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xed820b, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, 0xf200820a, 0xfd8105, - 0x6ff8209, 0x5e810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, - 0xea810a, 0xff008205, 0xfe8104, 0x18103, 0xfef3820c, 0x8102, 0x68106, 0xff8103, 0x53040c, - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0x1f4820b, 0x1008205, - 0xfe8206, 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0x1f810b, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xee8109, 0xff008205, 0x2fe8208, - 0xfa018209, 0x10a820b, 0xf500820a, 0x58208, 0xfaff8209, 0x6a810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0x2038209, 0xff8205, 0x118109, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, - 0x9008209, 0x2fd8209, 0x3ff8208, 0x23030b, 0x8204, 0xfb02820a, 0xff018206, 0x78209, 0xfd008207, - 0x2048209, 0xffff8206, 0x1b810a, 0xff008205, 0xfbfe820a, 0xf601820b, 0x10e820b, 0x8102, - 0x68208, 0xf6ff820b, 0xaa810c, 0x8204, 0x28206, 0x18205, 0xfefa820a, 0x2008206, 0x1038208, - 0xff8205, 0x1f6820b, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, - 0xfeff8207, 0xda810b, 0x8204, 0x3028209, 0x1018206, 0xfefc820a, 0x4008207, 0x1048208, - 0x1ff8206, 0x60009, 0xff008205, 0x3fe8209, 0xf701820a, 0x10c820b, 0xf100820b, 0xfe05820a, - 0xf7ff820a, 0x8a810c, 0x8204, 0xff028207, 0x18205, 0xfefb820a, 0xfe008206, 0xfc03820b, - 0xff8205, 0x158109, 0x1008205, 0xfffe8207, 0xfd018208, 0xf98209, 0xb00820a, 0xfcfd820b, - 0xfdff8208, 0x4a810c, 0x8204, 0x28104, 0xff018206, 0x88209, 0x5008208, 0xfc04820b, 0xffff8206, - 0xe5810a, 0xff008205, 0xfe8104, 0x18103, 0x1f2820b, 0x8102, 0xfe06820a, 0xff8103, 0xca810c, - 0x8204, 0x28206, 0x18205, 0x1fa8209, 0x2008206, 0x38207, 0xff8205, 0x1f5820b, 0x1008205, - 0xfe8206, 0x2018207, 0x409820c, 0xfb008208, 0xfd8207, 0x2ff8207, 0x27810b, 0x8204, 0xfe028208, - 0x1018206, 0x1fc8209, 0x3008207, 0x48207, 0x1ff8206, 0xf18109, 0xff008205, 0xfefe8208, - 0xfc018209, 0x10b820b, 0x1300820b, 0x1058209, 0xfcff8209, 0x7a810c, 0x8204, 0x1028207, 0x18205, - 0x1fb8209, 0xfe008206, 0x403820a, 0xff8205, 0x138109, 0x1008205, 0x1fe8207, 0x4018208, - 0x4f8820c, 0xf8008209, 0x4fd820a, 0x4ff8208, 0x3a810c, 0x8204, 0xf802820b, 0xff018206, - 0x407820c, 0xfd008207, 0x404820a, 0xffff8206, 0xe0810a, 0xff008205, 0xf8fe820b, 0x18103, - 0x1f0820b, 0x8102, 0x1068209, 0xff8103, 0xba810c, 0x8204, 0x28206, 0x18205, 0xfa8106, - 0x2008206, 0xff038208, 0xff8205, 0xf8109, 0x1008205, 0xfe8206, 0xfe018207, 0x4f7820c, - 0x7008209, 0xfffd8208, 0xfeff8207, 0x9000b, 0x8204, 0xfd028209, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x17810a, 0xff008205, 0xfdfe8209, 0xc01820b, 0x10d820b, 0xe000820c, - 0x58106, 0xcff820b, 0x9a810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xec8109, 0x1008205, 0xfffe8207, 0x5018209, 0x4f9820c, 0xf000820a, 0xfd8105, - 0x5ff8209, 0x5a810c, 0x8204, 0x28104, 0xff018206, 0x408820c, 0x6008208, 0x48105, 0xffff8206, - 0xe9810a, 0xff008205, 0xfe8104, 0x18103, 0x1f3820b, 0x8102, 0x68106, 0xff8103, 0x2b030c, - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf48108, 0x1008205, - 0xfe8206, 0x2018207, 0xff09820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x23810b, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xef8109, 0xff008205, 0x2fe8208, - 0xfb018209, 0xa8108, 0xf00820b, 0x58208, 0xfbff8209, 0x72810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0x128109, 0x1008205, 0x1fe8207, 0x3018208, - 0xfff8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x32810c, 0x8204, 0x702820b, 0xff018206, - 0xff07820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1d810a, 0xff008205, 0x7fe820b, 0xeb01820c, - 0xe8108, 0x8102, 0x68208, 0xebff820c, 0xb2810c, 0x8204, 0x28206, 0x18205, 0xfdfa820b, - 0x2008206, 0x1038208, 0xff8205, 0xf68108, 0x1008205, 0xfe8206, 0xfe018207, 0xfff7820a, - 0xfc008208, 0x1fd8208, 0xfeff8207, 0xde810b, 0x8204, 0x4028209, 0x1018206, 0xfdfc820b, - 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf901820a, 0xc8108, - 0x1700820c, 0xfd05820b, 0xf9ff820a, 0x92810c, 0x8204, 0xff028207, 0x18205, 0xfdfb820b, - 0xfe008206, 0x38105, 0xff8205, 0xeb8109, 0x1008205, 0xfffe8207, 0xfd018208, 0xfff9820a, - 0xd00820a, 0xfd8105, 0xfdff8208, 0x52810c, 0x8204, 0x28104, 0xff018206, 0xff08820a, 0x5008208, - 0x48105, 0xffff8206, 0xe7810a, 0xff008205, 0xfe8104, 0x18103, 0xf28108, 0x8102, 0xfd06820b, - 0xff8103, 0xd2810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, - 0xf58108, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0xd6810b, - 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, - 0xfefe8208, 0x801820a, 0xb8108, 0xec00820b, 0xff058209, 0x8ff820a, 0x82810c, 0x8204, 0x1028207, - 0x18205, 0xfffb8209, 0xfe008206, 0x503820b, 0xff8205, 0x148109, 0x1008205, 0x1fe8207, - 0x4018208, 0xf88107, 0xf9008209, 0x5fd820b, 0x4ff8208, 0x42810c, 0x8204, 0xf002820c, - 0xff018206, 0x78107, 0xfd008207, 0x504820b, 0xffff8206, 0xe3810a, 0xff008205, 0xf0fe820c, - 0x18103, 0xf08108, 0x8102, 0xff068209, 0xff8103, 0xc2810c, 0x8204, 0x28206, 0x18205, 0xfa8106, - 0x2008206, 0xff038208, 0xff8205, 0x108109, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, - 0x8008209, 0xfffd8208, 0xfeff8207, 0x11010b, 0x8204, 0x602820a, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x19810a, 0xff008205, 0x6fe820a, 0xf201820b, 0xd8108, 0xe900820c, - 0x58106, 0xf2ff820b, 0xa2810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xed8109, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, 0xf300820a, 0xfd8105, - 0x6ff8209, 0x62810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, - 0x8000a, 0xff008205, 0xfe8104, 0x18103, 0xf38108, 0x8102, 0x68106, 0xff8103, 0xa3050c, 0x8204, - 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf4820a, 0x1008205, 0xfe8206, - 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0xb010a, 0x8204, 0x2028208, 0x1018206, - 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xffee820c, 0xff008205, 0x2fe8208, 0xfa018209, - 0xa820a, 0xf400820a, 0x58208, 0xfaff8209, 0x68810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, - 0xfe008206, 0x2038209, 0xff8205, 0xff11820c, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, - 0x9008209, 0x2fd8209, 0x3ff8208, 0x1b020b, 0x8204, 0xfa02820a, 0xff018206, 0x78209, 0xfd008207, - 0x2048209, 0xffff8206, 0x1a810a, 0xff008205, 0xfafe820a, 0xf501820b, 0xe820a, 0x8102, 0x68208, - 0xf5ff820b, 0xa8810c, 0x8204, 0x28206, 0x18205, 0x2fa820a, 0x2008206, 0x1038208, 0xff8205, - 0xf6820a, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, 0xfeff8207, - 0xd9810b, 0x8204, 0x3028209, 0x1018206, 0x2fc820a, 0x4008207, 0x1048208, 0x1ff8206, 0x60009, - 0xff008205, 0x3fe8209, 0x901820a, 0xc820a, 0xef00820b, 0x205820a, 0x9ff820a, 0x88810c, 0x8204, - 0xff028207, 0x18205, 0x2fb820a, 0xfe008206, 0xfb03820b, 0xff8205, 0xff15820c, 0x1008205, - 0xfffe8207, 0xfd018208, 0xf98209, 0xa00820a, 0xfbfd820b, 0xfdff8208, 0x48810c, 0x8204, 0x28104, - 0xff018206, 0x88209, 0x5008208, 0xfb04820b, 0xffff8206, 0xe4810a, 0xff008205, 0xfe8104, - 0x18103, 0xf2820a, 0x8102, 0x206820a, 0xff8103, 0xc8810c, 0x8204, 0x28206, 0x18205, 0x1fa8209, - 0x2008206, 0x38207, 0xff8205, 0xf5820a, 0x1008205, 0xfe8206, 0x2018207, 0xfe09820b, 0xfb008208, - 0xfd8207, 0x2ff8207, 0x26810b, 0x8204, 0xfe028208, 0x1018206, 0x1fc8209, 0x3008207, 0x48207, - 0x1ff8206, 0xfff1820c, 0xff008205, 0xfefe8208, 0xfc018209, 0xb820a, 0x1200820b, 0x1058209, - 0xfcff8209, 0x78810c, 0x8204, 0x1028207, 0x18205, 0x1fb8209, 0xfe008206, 0x303820a, 0xff8205, - 0xff13820c, 0x1008205, 0x1fe8207, 0x4018208, 0xfef8820b, 0xf8008209, 0x3fd820a, 0x4ff8208, - 0x38810c, 0x8204, 0xf702820b, 0xff018206, 0xfe07820b, 0xfd008207, 0x304820a, 0xffff8206, - 0x1e810a, 0xff008205, 0xf7fe820b, 0x18103, 0xf0820a, 0x8102, 0x1068209, 0xff8103, 0xb8810c, - 0x8204, 0x28206, 0x18205, 0xfa8106, 0x2008206, 0xff038208, 0xff8205, 0xff0f820c, 0x1008205, - 0xfe8206, 0xfe018207, 0xfef7820b, 0x7008209, 0xfffd8208, 0xfeff8207, 0x7000b, 0x8204, - 0xfd028209, 0x1018206, 0xfc8106, 0x4008207, 0xff048208, 0x1ff8206, 0x16810a, 0xff008205, - 0xfdfe8209, 0xb01820b, 0xd820a, 0x1d00820c, 0x58106, 0xbff820b, 0x98810c, 0x8204, 0xff028207, - 0x18205, 0xfb8106, 0xfe008206, 0x38105, 0xff8205, 0xffec820c, 0x1008205, 0xfffe8207, 0x5018209, - 0xfef9820b, 0xe00820a, 0xfd8105, 0x5ff8209, 0x58810c, 0x8204, 0x28104, 0xff018206, 0xfe08820b, - 0x6008208, 0x48105, 0xffff8206, 0xe8810a, 0xff008205, 0xfe8104, 0x18103, 0xf3820a, 0x8102, - 0x68106, 0xff8103, 0x4000c, 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, - 0xf48108, 0x1008205, 0xfe8206, 0x2018207, 0x109820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x22810b, - 0x8204, 0x2028208, 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xffef820c, 0xff008205, - 0x2fe8208, 0xfb018209, 0xa8108, 0xf600820a, 0x58208, 0xfbff8209, 0x70810c, 0x8204, 0x1028207, - 0x18205, 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0xff12820c, 0x1008205, 0x1fe8207, - 0x3018208, 0x1f8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x30810c, 0x8204, 0xfc02820a, - 0xff018206, 0x107820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1c810a, 0xff008205, 0xfcfe820a, - 0x1401820c, 0xe8108, 0x8102, 0x68208, 0x14ff820c, 0xb0810c, 0x8204, 0x28206, 0x18205, - 0x4fa820b, 0x2008206, 0x1038208, 0xff8205, 0xf68108, 0x1008205, 0xfe8206, 0xfe018207, - 0x1f7820a, 0xfc008208, 0x1fd8208, 0xfeff8207, 0xdd810b, 0x8204, 0x4028209, 0x1018206, - 0x4fc820b, 0x4008207, 0x1048208, 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf801820a, - 0xc8108, 0x8102, 0x405820b, 0xf8ff820a, 0x90810c, 0x8204, 0xff028207, 0x18205, 0x4fb820b, - 0xfe008206, 0xf903820c, 0xff8205, 0xffeb820c, 0x1008205, 0xfffe8207, 0xfd018208, 0x1f9820a, - 0xc00820a, 0xf9fd820c, 0xfdff8208, 0x50810c, 0x8204, 0x28104, 0xff018206, 0x108820a, 0x5008208, - 0xf904820c, 0xffff8206, 0xe6810a, 0xff008205, 0xfe8104, 0x18103, 0xf28108, 0x8102, 0x406820b, - 0xff8103, 0xd0810c, 0x8204, 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, - 0xf58108, 0x1008205, 0xfe8206, 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0x2a810b, - 0x8204, 0xfe028208, 0x1018206, 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, - 0xfefe8208, 0x701820a, 0xb8108, 0xeb00820b, 0xff058209, 0x7ff820a, 0x80810c, 0x8204, 0x1028207, - 0x18205, 0xfffb8209, 0xfe008206, 0xfd03820a, 0xff8205, 0xff14820c, 0x1008205, 0x1fe8207, - 0x4018208, 0xf88107, 0xf9008209, 0xfdfd820a, 0x4ff8208, 0x40810c, 0x8204, 0xd02820c, - 0xff018206, 0x78107, 0xfd008207, 0xfd04820a, 0xffff8206, 0xe2810a, 0xff008205, 0xdfe820c, - 0x18103, 0xf08108, 0x8102, 0xff068209, 0xff8103, 0xc0810c, 0x8204, 0x28206, 0x18205, 0xfa8106, - 0x2008206, 0xff038208, 0xff8205, 0xff10820c, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, - 0x8008209, 0xfffd8208, 0xfeff8207, 0xf010b, 0x8204, 0x502820a, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x18810a, 0xff008205, 0x5fe820a, 0xf001820b, 0xd8108, 0xe700820c, - 0x58106, 0xf0ff820b, 0xa0810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xffed820c, 0x1008205, 0xfffe8207, 0x6018209, 0xf98107, 0xf200820a, 0xfd8105, - 0x6ff8209, 0x60810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, - 0xea810a, 0xff008205, 0xfe8104, 0x18103, 0xf38108, 0x8102, 0x68106, 0xff8103, 0x73040c, 0x8204, - 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xfff4820b, 0x1008205, 0xfe8206, - 0x2018207, 0x98209, 0xfa008208, 0xfd8207, 0x2ff8207, 0x20810b, 0x8204, 0x2028208, 0x1018206, - 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xee8109, 0xff008205, 0x2fe8208, 0xfa018209, - 0xff0a820b, 0xf500820a, 0x58208, 0xfaff8209, 0x6c810c, 0x8204, 0x1028207, 0x18205, 0xfb8208, - 0xfe008206, 0x2038209, 0xff8205, 0x118109, 0x1008205, 0x1fe8207, 0x3018208, 0xf88209, - 0x9008209, 0x2fd8209, 0x3ff8208, 0x2c810c, 0x8204, 0xfb02820a, 0xff018206, 0x78209, 0xfd008207, - 0x2048209, 0xffff8206, 0x1b810a, 0xff008205, 0xfbfe820a, 0x1001820c, 0xff0e820b, 0x8102, - 0x68208, 0x10ff820c, 0xac810c, 0x8204, 0x28206, 0x18205, 0xfefa820a, 0x2008206, 0x1038208, - 0xff8205, 0xfff6820b, 0x1008205, 0xfe8206, 0xfe018207, 0xf78209, 0xfc008208, 0x1fd8208, - 0xfeff8207, 0xdb810b, 0x8204, 0x3028209, 0x1018206, 0xfefc820a, 0x4008207, 0x1048208, - 0x1ff8206, 0x60009, 0xff008205, 0x3fe8209, 0xf701820a, 0xff0c820b, 0x8102, 0xfe05820a, - 0xf7ff820a, 0x8c810c, 0x8204, 0xff028207, 0x18205, 0xfefb820a, 0xfe008206, 0x803820c, 0xff8205, - 0x158109, 0x1008205, 0xfffe8207, 0xfd018208, 0xf98209, 0xb00820a, 0x8fd820c, 0xfdff8208, - 0x4c810c, 0x8204, 0x28104, 0xff018206, 0x88209, 0x5008208, 0x804820c, 0xffff8206, 0xe5810a, - 0xff008205, 0xfe8104, 0x18103, 0xfff2820b, 0x8102, 0xfe06820a, 0xff8103, 0xcc810c, 0x8204, - 0x28206, 0x18205, 0x1fa8209, 0x2008206, 0x38207, 0xff8205, 0xfff5820b, 0x1008205, 0xfe8206, - 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0x28810b, 0x8204, 0xfe028208, 0x1018206, - 0x1fc8209, 0x3008207, 0x48207, 0x1ff8206, 0xf18109, 0xff008205, 0xfefe8208, 0xfc018209, - 0xff0b820b, 0x1400820b, 0x1058209, 0xfcff8209, 0x7c810c, 0x8204, 0x1028207, 0x18205, 0x1fb8209, - 0xfe008206, 0x403820a, 0xff8205, 0x138109, 0x1008205, 0x1fe8207, 0x4018208, 0xf88107, - 0xf8008209, 0x4fd820a, 0x4ff8208, 0x3c810c, 0x8204, 0xf902820b, 0xff018206, 0x78107, - 0xfd008207, 0x404820a, 0xffff8206, 0xe0810a, 0xff008205, 0xf9fe820b, 0x18103, 0xfff0820b, - 0x8102, 0x1068209, 0xff8103, 0xbc810c, 0x8204, 0x28206, 0x18205, 0xfa8106, 0x2008206, - 0xff038208, 0xff8205, 0xf8109, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, 0x7008209, - 0xfffd8208, 0xfeff8207, 0xa000b, 0x8204, 0xfd028209, 0x1018206, 0xfc8106, 0x4008207, - 0xff048208, 0x1ff8206, 0x17810a, 0xff008205, 0xfdfe8209, 0xd01820b, 0xff0d820b, 0xe300820c, - 0x58106, 0xdff820b, 0x9c810c, 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, - 0xff8205, 0xec8109, 0x1008205, 0xfffe8207, 0x5018209, 0xf98107, 0xf000820a, 0xfd8105, - 0x5ff8209, 0x5c810c, 0x8204, 0x28104, 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, - 0xe9810a, 0xff008205, 0xfe8104, 0x18103, 0xfff3820b, 0x8102, 0x68106, 0xff8103, 0x3b030c, - 0x8204, 0x28206, 0x18205, 0xfa8208, 0x2008206, 0x38207, 0xff8205, 0xf48108, 0x1008205, - 0xfe8206, 0x2018207, 0xff09820a, 0xfa008208, 0xfd8207, 0x2ff8207, 0x24810b, 0x8204, 0x2028208, - 0x1018206, 0xfc8208, 0x3008207, 0x48207, 0x1ff8206, 0xef8109, 0xff008205, 0x2fe8208, - 0xfb018209, 0xa8108, 0x1000820b, 0x58208, 0xfbff8209, 0x74810c, 0x8204, 0x1028207, 0x18205, - 0xfb8208, 0xfe008206, 0xfe038209, 0xff8205, 0x128109, 0x1008205, 0x1fe8207, 0x3018208, - 0xfff8820a, 0xf7008209, 0xfefd8209, 0x3ff8208, 0x34810c, 0x8204, 0x802820b, 0xff018206, - 0xff07820a, 0xfd008207, 0xfe048209, 0xffff8206, 0x1d810a, 0xff008205, 0x8fe820b, 0xed01820c, - 0xe8108, 0x8102, 0x68208, 0xedff820c, 0xb4810c, 0x8204, 0x28206, 0x18205, 0x6fa820c, 0x2008206, - 0x1038208, 0xff8205, 0xf68108, 0x1008205, 0xfe8206, 0xfe018207, 0xfff7820a, 0xfc008208, - 0x1fd8208, 0xfeff8207, 0xdf810b, 0x8204, 0x4028209, 0x1018206, 0x6fc820c, 0x4008207, 0x1048208, - 0x1ff8206, 0x1020009, 0xff008205, 0x4fe8209, 0xf901820a, 0xc8108, 0x1900820c, 0x605820c, - 0xf9ff820a, 0x94810c, 0x8204, 0xff028207, 0x18205, 0x6fb820c, 0xfe008206, 0x38105, 0xff8205, - 0xeb8109, 0x1008205, 0xfffe8207, 0xfd018208, 0xfff9820a, 0xd00820a, 0xfd8105, 0xfdff8208, - 0x54810c, 0x8204, 0x28104, 0xff018206, 0xff08820a, 0x5008208, 0x48105, 0xffff8206, 0xe7810a, - 0xff008205, 0xfe8104, 0x18103, 0xf28108, 0x8102, 0x606820c, 0xff8103, 0xd4810c, 0x8204, - 0x28206, 0x18205, 0xfffa8209, 0x2008206, 0x38207, 0xff8205, 0xf58108, 0x1008205, 0xfe8206, - 0x2018207, 0x98107, 0xfb008208, 0xfd8207, 0x2ff8207, 0xd7810b, 0x8204, 0xfe028208, 0x1018206, - 0xfffc8209, 0x3008207, 0x48207, 0x1ff8206, 0x50009, 0xff008205, 0xfefe8208, 0x801820a, 0xb8108, - 0xed00820b, 0xff058209, 0x8ff820a, 0x84810c, 0x8204, 0x1028207, 0x18205, 0xfffb8209, - 0xfe008206, 0x603820b, 0xff8205, 0x148109, 0x1008205, 0x1fe8207, 0x4018208, 0xf88107, - 0xf9008209, 0x6fd820b, 0x4ff8208, 0x44810c, 0x8204, 0xf302820c, 0xff018206, 0x78107, - 0xfd008207, 0x604820b, 0xffff8206, 0xe3810a, 0xff008205, 0xf3fe820c, 0x18103, 0xf08108, 0x8102, - 0xff068209, 0xff8103, 0xc4810c, 0x8204, 0x28206, 0x18205, 0xfa8106, 0x2008206, 0xff038208, - 0xff8205, 0x108109, 0x1008205, 0xfe8206, 0xfe018207, 0xf78107, 0x8008209, 0xfffd8208, - 0xfeff8207, 0x13020b, 0x8204, 0x602820a, 0x1018206, 0xfc8106, 0x4008207, 0xff048208, 0x1ff8206, - 0x19810a, 0xff008205, 0x6fe820a, 0xf301820b, 0xd8108, 0x8102, 0x58106, 0xf3ff820b, 0xa4810c, - 0x8204, 0xff028207, 0x18205, 0xfb8106, 0xfe008206, 0x38105, 0xff8205, 0xed8109, 0x1008205, - 0xfffe8207, 0x6018209, 0xf98107, 0xf300820a, 0xfd8105, 0x6ff8209, 0x64810c, 0x8204, 0x28104, - 0xff018206, 0x88107, 0x6008208, 0x48105, 0xffff8206, 0x8000a, 0xff008205, 0xfe8104, 0x18103, - 0xf38108, 0x8102, 0x68106, 0xff8103, 0xe3050c, -]; - -pub(crate) const FDEFLATE_DIST_DECODE_TABLE: [u32; 512] = [ - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, - 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, 0x0, 0x10001, - 0x0, 0x10001, 0x0, 0x10001, 0x0, -]; - -pub(crate) const FIXED_CODE_LENGTHS: [u8; 320] = make_fixed_code_lengths(); -const fn make_fixed_code_lengths() -> [u8; 320] { - let mut i = 0; - let mut lengths = [0; 320]; - while i < 144 { - lengths[i] = 8; - i += 1; - } - while i < 256 { - lengths[i] = 9; - i += 1; - } - while i < 280 { - lengths[i] = 7; - i += 1; - } - while i < 288 { - lengths[i] = 8; - i += 1; - } - while i < 320 { - lengths[i] = 5; - i += 1; - } - lengths -} |