summaryrefslogtreecommitdiff
path: root/vendor/fdeflate
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/fdeflate')
-rw-r--r--vendor/fdeflate/.cargo-checksum.json1
-rw-r--r--vendor/fdeflate/Cargo.toml39
-rw-r--r--vendor/fdeflate/LICENSE-APACHE177
-rw-r--r--vendor/fdeflate/LICENSE-MIT25
-rw-r--r--vendor/fdeflate/README.md26
-rw-r--r--vendor/fdeflate/src/compress.rs327
-rw-r--r--vendor/fdeflate/src/decompress.rs1270
-rw-r--r--vendor/fdeflate/src/lib.rs123
-rw-r--r--vendor/fdeflate/src/tables.rs635
9 files changed, 2623 insertions, 0 deletions
diff --git a/vendor/fdeflate/.cargo-checksum.json b/vendor/fdeflate/.cargo-checksum.json
new file mode 100644
index 0000000..c53afde
--- /dev/null
+++ b/vendor/fdeflate/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"91f15ba802fb134105796f6b935d60ec8ffb4b2ec7882e8cc8c645817841e8ee","LICENSE-APACHE":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT":"c77a4cf9da729987d0fe7ccd811e3bd27393914ddf3d23467c18cc22954513b3","README.md":"6707d3998971b67156f79f414a9032f24977977911e9d74ad251115b0c16203e","src/compress.rs":"2dab44a76819bab3ef22b7d90b9e9e71d0bc83f6f3721aab6bf4eaf28fa5c901","src/decompress.rs":"495c785c85a317caff74eaebd07ee57a75602e32ac4dd4b55d605997225a7b81","src/lib.rs":"c24ffe479bf33436f40b0fabc6dcfd673285558b6adabc523258ebd2f4ba9c9a","src/tables.rs":"5e59a2710471574d83b18c3fcfa6550ad3e6c50fa155fc6ac6a9402d973044c3"},"package":"209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd"} \ No newline at end of file
diff --git a/vendor/fdeflate/Cargo.toml b/vendor/fdeflate/Cargo.toml
new file mode 100644
index 0000000..2ae30f2
--- /dev/null
+++ b/vendor/fdeflate/Cargo.toml
@@ -0,0 +1,39 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.57.0"
+name = "fdeflate"
+version = "0.3.3"
+authors = ["The image-rs Developers"]
+include = [
+ "/src",
+ "README.md",
+ "LICENSE-APACHE",
+ "LICENSE-MIT",
+]
+description = "Fast specialized deflate implementation"
+homepage = "https://github.com/image-rs/fdeflate"
+documentation = "https://docs.rs/fdeflate"
+readme = "README.md"
+categories = ["compression"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/image-rs/fdeflate"
+
+[dependencies.simd-adler32]
+version = "0.3.4"
+
+[dev-dependencies.miniz_oxide]
+version = "0.7.1"
+
+[dev-dependencies.rand]
+version = "0.8.5"
diff --git a/vendor/fdeflate/LICENSE-APACHE b/vendor/fdeflate/LICENSE-APACHE
new file mode 100644
index 0000000..f433b1a
--- /dev/null
+++ b/vendor/fdeflate/LICENSE-APACHE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/vendor/fdeflate/LICENSE-MIT b/vendor/fdeflate/LICENSE-MIT
new file mode 100644
index 0000000..59f49a9
--- /dev/null
+++ b/vendor/fdeflate/LICENSE-MIT
@@ -0,0 +1,25 @@
+MIT License
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/fdeflate/README.md b/vendor/fdeflate/README.md
new file mode 100644
index 0000000..a92a494
--- /dev/null
+++ b/vendor/fdeflate/README.md
@@ -0,0 +1,26 @@
+# fdeflate
+
+[![crates.io](https://img.shields.io/crates/v/fdeflate.svg)](https://crates.io/crates/fdeflate)
+[![Documentation](https://docs.rs/fdeflate/badge.svg)](https://docs.rs/fdeflate)
+[![Build Status](https://img.shields.io/github/actions/workflow/status/image-rs/fdeflate/rust.yml?label=Rust%20CI)](https://github.com/image-rs/fdeflate/actions)
+
+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.
+
+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)
diff --git a/vendor/fdeflate/src/compress.rs b/vendor/fdeflate/src/compress.rs
new file mode 100644
index 0000000..027d0ef
--- /dev/null
+++ b/vendor/fdeflate/src/compress.rs
@@ -0,0 +1,327 @@
+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
new file mode 100644
index 0000000..d38f63b
--- /dev/null
+++ b/vendor/fdeflate/src/decompress.rs
@@ -0,0 +1,1270 @@
+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
new file mode 100644
index 0000000..569c872
--- /dev/null
+++ b/vendor/fdeflate/src/lib.rs
@@ -0,0 +1,123 @@
+//! 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
new file mode 100644
index 0000000..8b233c8
--- /dev/null
+++ b/vendor/fdeflate/src/tables.rs
@@ -0,0 +1,635 @@
+/// 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
+}