From d3243651cb142e3e04f3e4bc037b9e985878f444 Mon Sep 17 00:00:00 2001 From: 101arrowz Date: Tue, 6 Feb 2024 19:29:14 -0500 Subject: [PATCH] improve demo, prepare for publish --- README.md | 17 +- demo/components/code-box/stream-adapter.ts | 57 ++ demo/components/code-box/stream-adapter.tsx | 17 - package.json | 2 +- rs/fflate-wasm/Cargo.toml | 19 - rs/fflate-wasm/src/lib.rs | 43 -- rs/fflate/Cargo.toml | 37 -- rs/fflate/src/genlib.rs | 493 ----------------- rs/fflate/src/lib.rs | 460 ---------------- rs/fflate/src/main.rs | 20 - rs/fflate/src/newlib.rs | 559 -------------------- rs/fflate/src/oldlib.rs | 507 ------------------ 12 files changed, 65 insertions(+), 2166 deletions(-) create mode 100644 demo/components/code-box/stream-adapter.ts delete mode 100644 demo/components/code-box/stream-adapter.tsx delete mode 100644 rs/fflate-wasm/Cargo.toml delete mode 100644 rs/fflate-wasm/src/lib.rs delete mode 100644 rs/fflate/Cargo.toml delete mode 100644 rs/fflate/src/genlib.rs delete mode 100644 rs/fflate/src/lib.rs delete mode 100644 rs/fflate/src/main.rs delete mode 100644 rs/fflate/src/newlib.rs delete mode 100644 rs/fflate/src/oldlib.rs diff --git a/README.md b/README.md index 2dd3adc..c4be595 100644 --- a/README.md +++ b/README.md @@ -60,13 +60,13 @@ Note that tree shaking is completely unsupported from the CDN. If you want a small build without build tools, please ask me and I will make one manually with only the features you need. This build is about 31kB, or 11.5kB gzipped. --> - - + + ``` @@ -75,8 +75,8 @@ If you are using Deno: // Don't use the ?dts Skypack flag; it isn't necessary for Deno support // The @deno-types comment adds TypeScript typings -// @deno-types="https://cdn.skypack.dev/fflate@0.8.0/lib/index.d.ts" -import * as fflate from 'https://cdn.skypack.dev/fflate@0.8.0?min'; +// @deno-types="https://cdn.skypack.dev/fflate@0.8.2/lib/index.d.ts" +import * as fflate from 'https://cdn.skypack.dev/fflate@0.8.2?min'; ``` @@ -376,9 +376,9 @@ unzipper.push(zipChunk2); unzipper.push(zipChunk3, true); ``` -As you may have guessed, there is an asynchronous version of every method as well. Unlike most libraries, this will cause the compression or decompression run in a separate thread entirely and automatically by using Web (or Node) Workers (as of now, Deno is unsupported). This means that the processing will not block the main thread at all. +As you may have guessed, there is an asynchronous version of every method as well. Unlike most libraries, this will cause the compression or decompression run in a separate thread entirely and automatically by using Web (or Node) Workers. This means that the processing will not block the main thread at all. -Note that there is a significant initial overhead to using workers of about 70ms for each asynchronous function. For instance, if you call `unzip` ten times, the overhead only applies for the first call, but if you call `unzip` and `zlib`, they will each cause the 70ms delay. Therefore, it's best to avoid the asynchronous API unless necessary. However, if you're compressing multiple large files at once, or the synchronous API causes the main thread to hang for too long, the callback APIs are an order of magnitude better. +Note that there is a significant initial overhead to using workers of about 50ms for each asynchronous function. For instance, if you call `unzip` ten times, the overhead only applies for the first call, but if you call `unzip` and `zlib`, they will each cause the 50ms delay. For small (under about 50kB) payloads, the asynchronous APIs will be much slower. However, if you're compressing larger files/multiple files at once, or if the synchronous API causes the main thread to hang for too long, the callback APIs are an order of magnitude better. ```js import { gzip, zlib, AsyncGzip, zip, unzip, strFromU8, @@ -386,9 +386,6 @@ import { } from 'fflate'; // Workers will work in almost any browser (even IE11!) -// However, they fail below Node v12 without the --experimental-worker -// CLI flag, and will fail entirely on Node below v10. - // All of the async APIs use a node-style callback as so: const terminate = gzip(aMassiveFile, (err, data) => { if (err) { diff --git a/demo/components/code-box/stream-adapter.ts b/demo/components/code-box/stream-adapter.ts new file mode 100644 index 0000000..3ed1b5b --- /dev/null +++ b/demo/components/code-box/stream-adapter.ts @@ -0,0 +1,57 @@ +import { AsyncDeflate } from '../../..'; + +export default (stream: AsyncDeflate, highWaterMark = 65536) => { + // whether backpressure was observed on readable stream + let backpressure = false; + let resolveBackpressure: () => void = () => {}; + + // fflate has built-in buffering; don't use WHATWG highWaterMark implementation + const writable = new WritableStream({ + async write(dat: Uint8Array) { + stream.push(dat); + + const blockers: Promise[] = []; + + if (stream.queuedSize >= highWaterMark) { + blockers.push(new Promise(resolve => { + stream.ondrain = () => { + if (stream.queuedSize < highWaterMark) resolve(); + } + })); + } + + if (backpressure) { + blockers.push(new Promise(resolve => { + resolveBackpressure = resolve; + })); + } + + await Promise.all(blockers); + }, + close() { + stream.push(new Uint8Array(0), true); + } + }); + + const readable = new ReadableStream({ + start(controller: ReadableStreamDefaultController) { + stream.ondata = (err, chunk, final) => { + if (err) writable.abort(err.message); + controller.enqueue(chunk); + if (controller.desiredSize != null && controller.desiredSize <= 0) { + backpressure = true; + } else { + backpressure = false; + resolveBackpressure(); + } + if (final) controller.close(); + } + }, + pull() { + backpressure = false; + resolveBackpressure(); + } + }); + + return { readable, writable }; +} \ No newline at end of file diff --git a/demo/components/code-box/stream-adapter.tsx b/demo/components/code-box/stream-adapter.tsx deleted file mode 100644 index a97d2ed..0000000 --- a/demo/components/code-box/stream-adapter.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { AsyncDeflate } from '../../..'; -export default (stream: AsyncDeflate) => { - const writable = new WritableStream({ - write(dat: Uint8Array) { stream.push(dat); }, - close() { stream.push(new Uint8Array(0), true); } - }); - const readable = new ReadableStream({ - start(controller: ReadableStreamDefaultController) { - stream.ondata = (err, chunk, final) => { - if (err) writable.abort(err.message); - controller.enqueue(chunk); - if (final) controller.close(); - } - } - }); - return { readable, writable }; -} \ No newline at end of file diff --git a/package.json b/package.json index c2f0559..a1e415e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fflate", - "version": "0.8.1", + "version": "0.8.2", "description": "High performance (de)compression in an 8kB package", "main": "./lib/index.cjs", "module": "./esm/browser.js", diff --git a/rs/fflate-wasm/Cargo.toml b/rs/fflate-wasm/Cargo.toml deleted file mode 100644 index 77751e0..0000000 --- a/rs/fflate-wasm/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "fflate-wasm" -version = "0.0.1" -authors = ["Arjun Barrett "] -edition = "2018" - -[dependencies] -fflate = { path = "../fflate", features = ["std"] } -wasm-bindgen = "0.2" - -[profile.release] -opt-level = "s" -lto = true - -[package.metadata.wasm-pack.profile.release] -wasm-opt = ["-Oz", "--enable-mutable-globals"] - -[lib] -crate-type = ["cdylib", "rlib"] \ No newline at end of file diff --git a/rs/fflate-wasm/src/lib.rs b/rs/fflate-wasm/src/lib.rs deleted file mode 100644 index 95e1dac..0000000 --- a/rs/fflate-wasm/src/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -use wasm_bindgen::prelude::*; -use fflate; - -#[wasm_bindgen] -pub fn inflate(dat: &[u8]) -> Vec { - let mut v = Vec::new(); - fflate::inflate(dat, &mut v); - v -} - -// use std::io::prelude::*; -// use std::env; -// use std::fs::read; -// use std::time; -// use flate2::Compression; -// use flate2::write::DeflateEncoder; -// use flate2::write::DeflateDecoder; -// use libflate::deflate::Decoder; -// mod lib; - - - -// fn main() { -// let args: Vec = env::args().collect(); -// let buf = read(&args[1]).unwrap(); -// let mut e = DeflateEncoder::new(Vec::new(), Compression::default()); -// e.write_all(&buf).unwrap(); -// let cmpr = e.finish().unwrap(); -// let t = time::Instant::now(); -// let mut infld = Vec::new(); -// let decmpr = lib::inflate(&cmpr, &mut infld); -// println!("fflate time: {:?}", t.elapsed()); -// let t2 = time::Instant::now(); -// let mut dec = DeflateDecoder::new(Vec::new()); -// dec.write_all(&cmpr).unwrap(); -// let decmpr2 = dec.finish().unwrap(); -// println!("flate2 time: {:?}", t2.elapsed()); -// let t3 = time::Instant::now(); -// let mut dec = Decoder::new(&*cmpr); -// let mut decmpr3 = Vec::new(); -// dec.read_to_end(&mut decmpr3).unwrap(); -// println!("libflate time: {:?}", t3.elapsed()); -// } \ No newline at end of file diff --git a/rs/fflate/Cargo.toml b/rs/fflate/Cargo.toml deleted file mode 100644 index afc9639..0000000 --- a/rs/fflate/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "fflate" -version = "0.0.1" -authors = ["Arjun Barrett "] -description = "A fast, efficient, pure Rust compression library" -repository = "https://github.com/101arrowz/fflate" -license = "MIT" -keywords = [ - "compression", - "decompression", - "deflate", - "inflate", - "gzip", - "gunzip", - "zlib", - "zip", - "libflate", - "flate2" -] -edition = "2018" - -[dependencies] -lazy_static = "1.4" -# TO REMOVE -miniz_oxide = "*" - -[profile.release] -opt-level = 3 -lto = true -# TO FIX -# debug = true - -[features] -std = [] - -[lib] -crate-type = ["cdylib", "rlib"] \ No newline at end of file diff --git a/rs/fflate/src/genlib.rs b/rs/fflate/src/genlib.rs deleted file mode 100644 index 9c70765..0000000 --- a/rs/fflate/src/genlib.rs +++ /dev/null @@ -1,493 +0,0 @@ -//! fflate - a fast, efficient, pure compression library -//! -//! - -// Instead of trying to read this code, check out the TypeScript version - -#![allow(non_upper_case_globals)] -// #![cfg_attr(not(feature = "std"), no_std)] -use lazy_static::lazy_static; - -// #[cfg(feature = "std")] -use std::{vec::Vec, io::{Read, Write, Error, ErrorKind}, ops::Range}; - -const fleb: [usize; 32] = [ - 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, 0, 0, 0, -]; - -const fl: [u16; 32] = [ - 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, 0, 0, 0, -]; - -// in theory, this could be computed, but embedding it at compile time is faster. -const flt: [u8; 288] = [ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, -]; - -const fdeb: [usize; 32] = [ - 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, 0, 0, -]; - -const fd: [u16; 32] = [ - 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, 0, 0, -]; - -const fdt: [u8; 31] = [5u8; 31]; - -const clim: [usize; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, -]; - -const et: [u8; 0] = []; - -fn freb(b: &[u16], r: &mut [u32]) { - for i in 1..30 { - let base = b[i]; - for j in base..b[i + 1] { - r[j as usize] = ((j - base) << 5) as u32 | i as u32; - } - } -} - -// hmap base -fn hmb(cd: &[u8], mb: u8, le: &mut [u16]) { - let t = (mb + 1) as usize; - le.iter_mut().for_each(|v| *v = 0); - for &cl in cd { - if cl != 0 { - le[cl as usize] += 1; - } - } - let mut v = 0; - for i in 1..t { - let val = le[i]; - le[i] = v; - v = (v + val) << 1; - } -} - -fn hmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - for i in 0..cd.len() { - let cl = cd[i] as usize; - let v = rev[le[cl] as usize] >> (15 - cl); - le[cl] += 1; - co[i] = v as u16; - } -} - -fn hrmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - let rvb = 15 - mb; - let mbu = mb as usize; - for i in 0..cd.len() { - let cl = cd[i] as usize; - if cl != 0 { - let r = mbu - cl; - let v = (le[cl] << r) as usize; - le[cl] += 1; - let m = v + (1 << r); - let sv = ((i as u16) << 4) | cl as u16; - rev[v..m].iter().for_each(|i| co[i >> rvb] = sv); - } - } -} - -lazy_static! { - static ref revfl: [u32; 261] = { - let mut v = [0u32; 261]; - freb(&fl, &mut v); - v[258] = 28; - v - }; - static ref revfd: [u32; 32769] = { - let mut v = [0u32; 32769]; - freb(&fd, &mut v); - v - }; - static ref rev: [usize; 32768] = { - let mut v = [0usize; 32768]; - for i in 0..32768 { - let mut el = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1); - el = ((el & 0xCCCC) >> 2) | ((el & 0x3333) << 2); - el = ((el & 0xF0F0) >> 4) | ((el & 0x0F0F) << 4); - v[i] = (((el & 0xFF00) >> 8) | ((el & 0x00FF) << 8)) >> 1; - } - v - }; - static ref flm: [u16; 288] = { - let mut v = [0u16; 288]; - hmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref flrm: [u16; 512] = { - let mut v = [0u16; 512]; - hrmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref fdm: [u16; 32] = { - let mut v = [0u16; 32]; - hmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; - static ref fdrm: [u16; 32] = { - let mut v = [0u16; 32]; - hrmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; -} - -#[inline(always)] -unsafe fn bits(dat: &[u8], pos: usize, mask: u8) -> u8 { - let b = pos >> 3; - ((*dat.get_unchecked(b) as u16 | ((*dat.get_unchecked(b + 1) as u16) << 8)) >> (pos & 7)) as u8 & mask -} - -#[inline(always)] -unsafe fn bits16(dat: &[u8], pos: usize, mask: u16) -> u16 { - let b = pos >> 3; - ((*dat.get_unchecked(b) as u32 - | ((*dat.get_unchecked(b + 1) as u32) << 8) - | ((*dat.get_unchecked(b + 2) as u32) << 16)) - >> (pos & 7)) as u16 - & mask -} - -#[inline(always)] -fn shft(pos: usize) -> usize { - (pos >> 3) + (pos & 7 != 0) as usize -} - - -struct InflateState { - lmap: [u16; 32768], - dmap: [u16; 32768], - clmap: [u16; 128], - le: [u16; 16], - ldt: [u8; 320], - clt: [u8; 19], - lbits: u8, - dbits: u8, - bfinal: bool, - pos: usize, - last: bool, - head: bool, -} - -impl InflateState { - #[inline(always)] - pub fn new() -> Self { - Default::default() - } -} - -impl Default for InflateState { - fn default() -> Self { - InflateState { - lmap: [0; 32768], - dmap: [0; 32768], - clmap: [0; 128], - le: [0; 16], - ldt: [0; 320], - clt: [0; 19], - lbits: 0, - dbits: 0, - bfinal: false, - pos: 0, - last: false, - head: true - } - } -} - -pub enum InflateError { - UnexpectedEOF, - InvalidBlockType, - InvalidLengthOrLiteral, - InvalidDistance -} - -// #[cfg(feature = "std")] -impl From for Error { - fn from(error: InflateError) -> Self { - Error::new(match error { - InflateError::UnexpectedEOF => ErrorKind::UnexpectedEof, - _ => ErrorKind::Other - }, match error { - InflateError::UnexpectedEOF => "unexpected EOF", - InflateError::InvalidBlockType => "invalid block type", - InflateError::InvalidLengthOrLiteral => "invalid length/literal", - InflateError::InvalidDistance => "invalid distance" - }) - } -} - -fn max(dat: &[u8]) -> u8 { - let mut m = 0; - for &v in dat { - if v > m { - m = v; - } - } - m -} - -pub trait OutputBuffer { - fn write(&mut self, value: u8); - fn write_all(&mut self, slice: &[u8]) { - for &value in slice { - self.write(value); - } - } - fn pre_alloc(&mut self, extra_bytes: usize); - fn copy_back(&mut self, back: usize, len: usize); -} - -// #[cfg(feature = "std")] -impl OutputBuffer for Vec { - #[inline(always)] - fn write(&mut self, value: u8) { - self.push(value); - } - #[inline(always)] - fn write_all(&mut self, slice: &[u8]) { - self.extend_from_slice(slice) - } - #[inline(always)] - fn pre_alloc(&mut self, extra_bytes: usize) { - self.reserve(extra_bytes); - } - #[inline(always)] - fn copy_back(&mut self, back: usize, len: usize) { - let l = self.len(); - let st = l - back; - self.reserve(len); - unsafe { - self.set_len(l + len); - } - if len > back { - for i in 0..len { - self[l + i] = self[st + i]; - } - } else { - self.copy_within(st..st + len, l); - } - } -} - -// pub struct SliceOutputBuffer<'a > { -// buf: &'a mut [u8], -// byte: usize -// } - -// impl<'a> SliceOutputBuffer<'a> { -// #[inline(always)] -// pub fn new(slice: &'a mut [u8]) -> SliceOutputBuffer<'a> { -// SliceOutputBuffer { -// buf: slice, -// byte: 0 -// } -// } -// } - -// impl<'a> OutputBuffer for SliceOutputBuffer<'a> { -// #[inline(always)] -// fn write(&mut self, value: u8) { -// if self.byte < self.buf.len() { -// self.buf[self.byte] = value; -// } -// self.byte += 1; -// } -// #[inline(always)] -// fn write_all(&mut self, slice: &[u8]) { -// let sl = slice.len(); -// let end = self.byte + sl; -// if end <= self.buf.len() { -// self.buf[self.byte..end].copy_from_slice(slice); -// } -// self.byte = end; -// } -// #[inline(always)] -// fn pre_alloc(&mut self, _eb: usize) {} -// fn copy_back(&mut self, back: usize, mut len: usize) { -// if len > back { -// while len != 0 { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..std::cmp::min(st + len as usize, self.byte)]); -// len -= back; -// } -// } else { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..st + len]) -// } -// } - -// } - -unsafe fn inflt(dat: &[u8], buf: &mut dyn OutputBuffer, st: &mut InflateState) -> Result<(), InflateError> { - let mut pos = st.pos; - let sl = dat.len(); - if sl == 0 || (st.head && sl < 5) { return Ok(()); } - let tbts = sl << 3; - loop { - if st.head { - st.bfinal = bits(dat, pos, 1) != 0; - let btype = bits(dat, pos + 1, 3); - pos += 3; - match btype { - 0 => { - let s = shft(pos) + 4; - let t = s + (dat[s - 4] as u16 | ((dat[s - 3] as u16) << 8)) as usize; - if t > dat.len() { - if st.last { - return Err(InflateError::UnexpectedEOF); - } - break; - } - buf.write_all(&dat[s..t]); - continue; - } - 1 => { - st.lmap[..512].copy_from_slice(&*flrm); - st.dmap[..32].copy_from_slice(&*fdrm); - st.lbits = 9; - st.dbits = 5; - } - 2 => { - let hlit = bits(dat, pos, 31) as usize + 257; - let hclen = (bits(dat, pos + 10, 15) + 4) as usize; - let tl = hlit + (bits(dat, pos + 5, 31) + 1) as usize; - pos += 14; - for i in 0..hclen { - st.clt[clim[i]] = bits(dat, pos + (i * 3) as usize, 7); - } - pos += hclen * 3; - for i in hclen..19 { - st.clt[clim[i]] = 0; - } - let clb = max(&st.clt); - let clbmsk = (1 << clb) - 1; - if !st.last && pos + tl * (clb + 7) as usize > tbts { - break; - } - hrmap(&st.clt, clb, &mut st.clmap, &mut st.le); - let mut i = 0; - loop { - let r = st.clmap[bits(dat, pos, clbmsk) as usize]; - pos += (r & 15) as usize; - let s = (r >> 4) as u8; - if s < 16 { - st.ldt[i] = s; - i += 1; - } else { - let mut c = 0; - let mut n = 0; - if s == 16 { - n = 3 + bits(dat, pos, 3); - pos += 2; - c = st.ldt[i - 1]; - } - else if s == 17 { - n = 3 + bits(dat, pos, 7); - pos += 3; - } - else if s == 18 { - n = 11 + bits(dat, pos, 127); - pos += 7; - } - let mut un = n as usize; - i += un; - while un > 0 { - st.ldt[i - un] = c; - un -= 1; - } - } - if i >= tl { - break; - } - } - let lt = &st.ldt[0..hlit]; - let dt = &st.ldt[hlit..tl]; - st.lbits = max(lt); - st.dbits = max(dt); - hrmap(lt, st.lbits, &mut st.lmap, &mut st.le); - hrmap(dt, st.dbits, &mut st.dmap, &mut st.le); - } - _ => { - return Err(InflateError::InvalidBlockType); - } - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - } - st.head = false; - let lms = (1u16 << st.lbits) - 1; - let dms = (1u16 << st.dbits) - 1; - let top = tbts - (st.lbits + st.dbits + 18) as usize; - while st.last || pos < top { - let c = st.lmap[ - bits16(dat, pos, lms) as usize - ]; - pos += (c & 15) as usize; - let sym = c >> 4; - if (sym & 256) == 0 { - buf.write(sym as u8); - } else if sym == 256 { - st.head = true; - break; - } else { - let mut add = sym - 254; - if add > 10 { - let i = add as usize - 3; - let b = fleb[i]; - add = bits(dat, pos, (1 << b) - 1) as u16 + fl[i]; - pos += b; - } - let d = st.dmap[ - bits16(dat, pos, dms) as usize - ]; - if d == 0 { - return Err(InflateError::InvalidDistance); - } - pos += (d & 15) as usize; - let dsym = (d >> 4) as usize; - let mut dt = fd[dsym] as usize; - if dsym > 3 { - let b = fdeb[dsym]; - dt += bits16(dat, pos, (1 << b) - 1) as usize; - pos += b; - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - buf.copy_back(dt, add as usize); - } - } - st.pos = pos; - if !st.head || st.bfinal { - break; - } - } - Ok(()) -} - -pub fn inflate(dat: &[u8], out: &mut dyn OutputBuffer) -> Result<(), InflateError> { - let mut st = InflateState::new(); - st.last = true; - unsafe { - inflt(dat, out, &mut st)?; - } - Ok(()) -} \ No newline at end of file diff --git a/rs/fflate/src/lib.rs b/rs/fflate/src/lib.rs deleted file mode 100644 index f90d6f6..0000000 --- a/rs/fflate/src/lib.rs +++ /dev/null @@ -1,460 +0,0 @@ -//! fflate - a fast, efficient, pure compression library -//! -//! - -// Instead of trying to read this code, check out the TypeScript version - -#![allow(non_upper_case_globals)] -// #![cfg_attr(not(feature = "std"), no_std)] -use lazy_static::lazy_static; - -// #[cfg(feature = "std")] -use std::{convert::TryInto, io::{Read, Write, Error, ErrorKind}, ops::Range, vec::Vec}; - -const fleb: [usize; 32] = [ - 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, 0, 0, 0, -]; - -const fl: [usize; 32] = [ - 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, 0, 0, 0, -]; - -// in theory, this could be computed, but embedding it at compile time is faster. -const flt: [u8; 288] = [ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, -]; - -const fdeb: [usize; 32] = [ - 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, 0, 0, -]; - -const fd: [usize; 32] = [ - 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, 0, 0, -]; - -const fdt: [u8; 31] = [5u8; 31]; - -const clim: [usize; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, -]; - -const et: [u8; 0] = []; - -fn freb(b: &[usize], r: &mut [u32]) { - for i in 1..30 { - let base = b[i]; - for j in base..b[i + 1] { - r[j as usize] = ((j - base) << 5) as u32 | i as u32; - } - } -} - -// hmap base -fn hmb(cd: &[u8], mb: u8, le: &mut [u16]) { - let t = (mb + 1) as usize; - le.iter_mut().for_each(|v| *v = 0); - for &cl in cd { - if cl != 0 { - le[cl as usize] += 1; - } - } - let mut v = 0; - for i in 1..t { - let val = le[i]; - le[i] = v; - v = (v + val) << 1; - } -} - -fn hmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - for i in 0..cd.len() { - let cl = cd[i] as usize; - let v = rev[le[cl] as usize] >> (15 - cl); - le[cl] += 1; - co[i] = v as u16; - } -} - -fn hrmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - let rvb = 15 - mb; - let mbu = mb as usize; - for i in 0..cd.len() { - let cl = cd[i] as usize; - if cl != 0 { - let r = mbu - cl; - let v = (le[cl] << r) as usize; - le[cl] += 1; - let m = v + (1 << r); - let sv = ((i as u16) << 4) | cl as u16; - rev[v..m].iter().for_each(|i| co[i >> rvb] = sv); - } - } -} - -lazy_static! { - static ref revfl: [u32; 261] = { - let mut v = [0u32; 261]; - freb(&fl, &mut v); - v[258] = 28; - v - }; - static ref revfd: [u32; 32769] = { - let mut v = [0u32; 32769]; - freb(&fd, &mut v); - v - }; - static ref rev: [usize; 32768] = { - let mut v = [0usize; 32768]; - for i in 0..32768 { - let mut el = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1); - el = ((el & 0xCCCC) >> 2) | ((el & 0x3333) << 2); - el = ((el & 0xF0F0) >> 4) | ((el & 0x0F0F) << 4); - v[i] = (((el & 0xFF00) >> 8) | ((el & 0x00FF) << 8)) >> 1; - } - v - }; - static ref flm: [u16; 288] = { - let mut v = [0u16; 288]; - hmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref flrm: [u16; 512] = { - let mut v = [0u16; 512]; - hrmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref fdm: [u16; 32] = { - let mut v = [0u16; 32]; - hmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; - static ref fdrm: [u16; 32] = { - let mut v = [0u16; 32]; - hrmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; -} - -#[inline(always)] -fn read_u16(buf: &[u8], bt: usize) -> u16 { - u16::from_le_bytes(buf[bt..bt + 2].try_into().unwrap()) -} - -#[inline(always)] -fn read_u32(buf: &[u8], bt: usize) -> u32 { - u32::from_le_bytes(buf[bt..bt + 4].try_into().unwrap()) -} - -#[inline(always)] -fn shft(pos: usize) -> usize { - (pos >> 3) + (pos & 7 != 0) as usize -} - - -struct InflateState { - lmap: [u16; 32768], - dmap: [u16; 32768], - clmap: [u16; 128], - le: [u16; 16], - ldt: [u8; 320], - clt: [u8; 19], - lbits: u8, - dbits: u8, - bfinal: bool, - pos: usize, - last: bool, - head: bool, -} - -impl InflateState { - #[inline(always)] - pub fn new() -> Self { - Default::default() - } -} - -impl Default for InflateState { - fn default() -> Self { - InflateState { - lmap: [0; 32768], - dmap: [0; 32768], - clmap: [0; 128], - le: [0; 16], - ldt: [0; 320], - clt: [0; 19], - lbits: 0, - dbits: 0, - bfinal: false, - pos: 0, - last: false, - head: true - } - } -} - -pub enum InflateError { - UnexpectedEOF, - InvalidBlockType, - InvalidLengthOrLiteral, - InvalidDistance -} - -// #[cfg(feature = "std")] -impl From for Error { - fn from(error: InflateError) -> Self { - Error::new(match error { - InflateError::UnexpectedEOF => ErrorKind::UnexpectedEof, - _ => ErrorKind::Other - }, match error { - InflateError::UnexpectedEOF => "unexpected EOF", - InflateError::InvalidBlockType => "invalid block type", - InflateError::InvalidLengthOrLiteral => "invalid length/literal", - InflateError::InvalidDistance => "invalid distance" - }) - } -} - -fn max(dat: &[u8]) -> u8 { - let mut m = 0; - for &v in dat { - if v > m { - m = v; - } - } - m -} - -// pub struct SliceOutputBuffer<'a > { -// buf: &'a mut [u8], -// byte: usize -// } - -// impl<'a> SliceOutputBuffer<'a> { -// #[inline(always)] -// pub fn new(slice: &'a mut [u8]) -> SliceOutputBuffer<'a> { -// SliceOutputBuffer { -// buf: slice, -// byte: 0 -// } -// } -// } - -// impl<'a> OutputBuffer for SliceOutputBuffer<'a> { -// #[inline(always)] -// fn write(&mut self, value: u8) { -// if self.byte < self.buf.len() { -// self.buf[self.byte] = value; -// } -// self.byte += 1; -// } -// #[inline(always)] -// fn write_all(&mut self, slice: &[u8]) { -// let sl = slice.len(); -// let end = self.byte + sl; -// if end <= self.buf.len() { -// self.buf[self.byte..end].copy_from_slice(slice); -// } -// self.byte = end; -// } -// #[inline(always)] -// fn pre_alloc(&mut self, _eb: usize) {} -// fn copy_back(&mut self, back: usize, mut len: usize) { -// if len > back { -// while len != 0 { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..std::cmp::min(st + len as usize, self.byte)]); -// len -= back; -// } -// } else { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..st + len]) -// } -// } - -// } - -unsafe fn inflt(dat: &[u8], buf: &mut Vec, st: &mut InflateState) -> Result<(), InflateError> { - let mut pos = st.pos; - let mut bb: u32; - let sl = dat.len(); - if sl == 0 || (st.head && sl < 5) { return Ok(()); } - let tbts = sl << 3; - loop { - if st.head { - bb = if (pos >> 3) + 4 > sl { read_u16(buf, pos >> 3) as u32 } else { read_u32(buf, pos >> 3) }; - let off = pos & 7; - st.bfinal = (bb >> off) & 1 != 0; - let btype = (bb >> (off + 1)) & 3; - pos += 3; - match btype { - 0 => { - let s = shft(pos) + 4; - let t = s + read_u16(dat, s) as usize; - if t > dat.len() { - if st.last { - return Err(InflateError::UnexpectedEOF); - } - break; - } - buf.extend_from_slice(&dat[s..t]); - continue; - } - 1 => { - st.lmap[..512].copy_from_slice(&*flrm); - st.dmap[..32].copy_from_slice(&*fdrm); - st.lbits = 9; - st.dbits = 5; - } - 2 => { - let hlit = bits(dat, pos, 31) as usize + 257; - let hclen = (bits(dat, pos + 10, 15) + 4) as usize; - let tl = hlit + (bits(dat, pos + 5, 31) + 1) as usize; - pos += 14; - for i in 0..hclen { - st.clt[clim[i]] = bits(dat, pos + (i * 3) as usize, 7); - } - pos += hclen * 3; - for i in hclen..19 { - st.clt[clim[i]] = 0; - } - let clb = max(&st.clt); - let clbmsk = (1 << clb) - 1; - if !st.last && pos + tl * (clb + 7) as usize > tbts { - break; - } - hrmap(&st.clt, clb, &mut st.clmap, &mut st.le); - let mut i = 0; - loop { - let r = st.clmap[bits(dat, pos, clbmsk) as usize]; - pos += (r & 15) as usize; - let s = (r >> 4) as u8; - if s < 16 { - st.ldt[i] = s; - i += 1; - } else { - let mut c = 0; - let mut n = 0; - if s == 16 { - n = 3 + bits(dat, pos, 3); - pos += 2; - c = st.ldt[i - 1]; - } - else if s == 17 { - n = 3 + bits(dat, pos, 7); - pos += 3; - } - else if s == 18 { - n = 11 + bits(dat, pos, 127); - pos += 7; - } - let mut un = n as usize; - i += un; - while un > 0 { - st.ldt[i - un] = c; - un -= 1; - } - } - if i >= tl { - break; - } - } - let lt = &st.ldt[0..hlit]; - let dt = &st.ldt[hlit..tl]; - st.lbits = max(lt); - st.dbits = max(dt); - hrmap(lt, st.lbits, &mut st.lmap, &mut st.le); - hrmap(dt, st.dbits, &mut st.dmap, &mut st.le); - } - _ => { - return Err(InflateError::InvalidBlockType); - } - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - } - st.head = false; - let lms = (1usize << st.lbits) - 1; - let dms = (1usize << st.dbits) - 1; - let top = tbts - (st.lbits + st.dbits + 18) as usize; - let lm = st.lmap; - let dm = st.dmap; - let lst = st.last; - while lst || pos < top { - let c = lm[gbits16(dat, pos, lms)]; - if c == 0 { - return Err(InflateError::InvalidLengthOrLiteral); - } - pos += (c & 15) as usize; - let sym = c >> 4; - if (sym & 256) == 0 { - buf.push(sym as u8); - } else if sym == 256 { - st.head = true; - break; - } else { - let mut add = (sym as usize) - 254; - if add > 10 { - let i = add - 3; - let b = fleb[i]; - add = bits(dat, pos, (1 << b) - 1) as usize + fl[i]; - pos += b; - } - let d = dm[gbits16(dat, pos, dms)]; - if d == 0 { - return Err(InflateError::InvalidDistance); - } - pos += (d & 15) as usize; - let dsym = (d >> 4) as usize; - let mut dt = fd[dsym] as usize; - if dsym > 3 { - let b = fdeb[dsym]; - dt += bits16(dat, pos, (1 << b) - 1) as usize; - pos += b; - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - let len = add as usize; - let l = buf.len(); - let st = l - dt; - buf.reserve(len); - buf.set_len(l + len); - if len > dt { - for i in 0..len { - buf[l + i] = buf[st + i]; - } - } else { - buf.copy_within(st..st + len, l); - } - } - } - st.pos = pos; - if !st.head || st.bfinal { - break; - } - } - Ok(()) -} - -pub fn inflate(dat: &[u8], out: &mut Vec) -> Result<(), InflateError> { - let mut st = InflateState::new(); - st.last = true; - unsafe { - inflt(dat, out, &mut st)?; - } - Ok(()) -} \ No newline at end of file diff --git a/rs/fflate/src/main.rs b/rs/fflate/src/main.rs deleted file mode 100644 index ea8b014..0000000 --- a/rs/fflate/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::fs; -use std::env; -use std::time; -use std::string; -extern crate miniz_oxide; -mod lib; - - -fn main() { - let args = env::args().collect::>(); - let fp = args.get(1).unwrap(); - let dat = fs::read(fp).unwrap(); - let mut out = Vec::new(); - let ts = time::Instant::now(); - lib::inflate(&dat, &mut out); - println!("{:?} {}", ts.elapsed(), out.len()); - let ts = time::Instant::now(); - let o2 = miniz_oxide::inflate::decompress_to_vec(&dat).unwrap(); - println!("{:?}", ts.elapsed()); -} \ No newline at end of file diff --git a/rs/fflate/src/newlib.rs b/rs/fflate/src/newlib.rs deleted file mode 100644 index a6569fd..0000000 --- a/rs/fflate/src/newlib.rs +++ /dev/null @@ -1,559 +0,0 @@ -//! fflate - a fast, efficient, pure compression library -//! -//! - -// Instead of trying to read this code, check out the TypeScript version - -#![allow(non_upper_case_globals)] -// #![cfg_attr(not(feature = "std"), no_std)] -use lazy_static::lazy_static; - -// #[cfg(feature = "std")] -use std::{vec::Vec, io::{Read, Write, Error, ErrorKind}, ops::Range}; - -const fleb: [usize; 32] = [ - 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, 0, 0, 0, -]; - -const fl: [u16; 32] = [ - 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, 0, 0, 0, -]; - -// in theory, this could be computed, but embedding it at compile time is faster. -const flt: [u8; 288] = [ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, -]; - -const fdeb: [usize; 32] = [ - 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, 0, 0, -]; - -const fd: [u16; 32] = [ - 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, 0, 0, -]; - -const fdt: [u8; 31] = [5u8; 31]; - -const clim: [usize; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, -]; - -const et: [u8; 0] = []; - -fn freb(b: &[u16], r: &mut [u32]) { - for i in 1..30 { - let base = b[i]; - for j in base..b[i + 1] { - r[j as usize] = ((j - base) << 5) as u32 | i as u32; - } - } -} - -// hmap base -fn hmb(cd: &[u8], mb: u8, le: &mut [u16]) { - let t = (mb + 1) as usize; - le.iter_mut().for_each(|v| *v = 0); - for &cl in cd { - if cl != 0 { - le[cl as usize] += 1; - } - } - let mut v = 0; - for i in 1..t { - let val = le[i]; - le[i] = v; - v = (v + val) << 1; - } -} - -fn hmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - for i in 0..cd.len() { - let cl = cd[i] as usize; - let v = rev[le[cl] as usize] >> (15 - cl); - le[cl] += 1; - co[i] = v as u16; - } -} - -fn hrmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - let rvb = 15 - mb; - let mbu = mb as usize; - for i in 0..cd.len() { - let cl = cd[i] as usize; - if cl != 0 { - let r = mbu - cl; - let v = (le[cl] << r) as usize; - le[cl] += 1; - let m = v + (1 << r); - let sv = ((i as u16) << 4) | cl as u16; - for j in v..m { - co[rev[j] >> rvb] = sv; - } - } - } -} - -lazy_static! { - static ref revfl: [u32; 261] = { - let mut v = [0u32; 261]; - freb(&fl, &mut v); - v[258] = 28; - v - }; - static ref revfd: [u32; 32769] = { - let mut v = [0u32; 32769]; - freb(&fd, &mut v); - v - }; - static ref rev: [usize; 32768] = { - let mut v = [0usize; 32768]; - for i in 0..32768 { - let mut el = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1); - el = ((el & 0xCCCC) >> 2) | ((el & 0x3333) << 2); - el = ((el & 0xF0F0) >> 4) | ((el & 0x0F0F) << 4); - v[i] = (((el & 0xFF00) >> 8) | ((el & 0x00FF) << 8)) >> 1; - } - v - }; - static ref flm: [u16; 288] = { - let mut v = [0u16; 288]; - hmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref flrm: [u16; 512] = { - let mut v = [0u16; 512]; - hrmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref fdm: [u16; 32] = { - let mut v = [0u16; 32]; - hmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; - static ref fdrm: [u16; 32] = { - let mut v = [0u16; 32]; - hrmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; -} - -#[inline(always)] -fn mbits(dat: &[u8], pos: usize, mask: u8) -> u8 { - (dat[pos >> 3] >> (pos & 7)) & mask -} - -fn mbits16(dat: &[u8], pos: usize, mask: u16) -> u16 { - let b = pos >> 3; - ((dat[b] as u16 | ((dat[b + 1] as u16) << 8)) >> (pos & 7)) & mask -} - -#[inline(always)] -fn bits(dat: &[u8], pos: usize, mask: u8) -> u8 { - let b = pos >> 3; - ((dat[b] as u16 | ((dat[b + 1] as u16) << 8)) >> (pos & 7)) as u8 & mask -} - -#[inline(always)] -fn bits16(dat: &[u8], pos: usize, mask: u16) -> u16 { - let b = pos >> 3; - ((dat[b] as u32 - | ((dat[b + 1] as u32) << 8) - | ((dat[b + 2] as u32) << 16)) - >> (pos & 7)) as u16 - & mask -} - -#[inline(always)] -fn shft(pos: usize) -> usize { - (pos >> 3) + (pos & 7 != 0) as usize -} - - -struct InflateState { - lmap: [u16; 32768], - dmap: [u16; 32768], - clmap: [u16; 128], - le: [u16; 16], - ldt: [u8; 320], - clt: [u8; 19], - lbits: u8, - dbits: u8, - bfinal: bool, - pos: usize, - last: bool, - head: bool, -} - -impl InflateState { - #[inline(always)] - pub fn new() -> Self { - Default::default() - } -} - -impl Default for InflateState { - fn default() -> Self { - InflateState { - lmap: [0; 32768], - dmap: [0; 32768], - clmap: [0; 128], - le: [0; 16], - ldt: [0; 320], - clt: [0; 19], - lbits: 0, - dbits: 0, - bfinal: false, - pos: 0, - last: false, - head: true - } - } -} - -pub enum InflateError { - UnexpectedEOF, - InvalidBlockType, - InvalidLengthOrLiteral, - InvalidDistance -} - -// #[cfg(feature = "std")] -impl From for Error { - fn from(error: InflateError) -> Self { - Error::new(match error { - InflateError::UnexpectedEOF => ErrorKind::UnexpectedEof, - _ => ErrorKind::Other - }, match error { - InflateError::UnexpectedEOF => "unexpected EOF", - InflateError::InvalidBlockType => "invalid block type", - InflateError::InvalidLengthOrLiteral => "invalid length/literal", - InflateError::InvalidDistance => "invalid distance" - }) - } -} - -fn max(dat: &[u8]) -> u8 { - let mut m = 0; - for &v in dat { - if v > m { - m = v; - } - } - m -} - -pub trait OutputBuffer { - fn write(&mut self, value: u8); - fn write_all(&mut self, slice: &[u8]) { - for &value in slice { - self.write(value); - } - } - fn pre_alloc(&mut self, extra_bytes: usize); - fn back(&self, back: usize) -> u8; -} - -// #[cfg(feature = "std")] -impl OutputBuffer for Vec { - #[inline(always)] - fn write(&mut self, value: u8) { - self.push(value); - } - #[inline(always)] - fn write_all(&mut self, slice: &[u8]) { - self.extend(slice.iter()); - } - #[inline(always)] - fn pre_alloc(&mut self, extra_bytes: usize) { - self.reserve(extra_bytes); - } - #[inline(always)] - fn back(&self, back: usize) -> u8 { - self[self.len() - back] - } -} - -pub struct SliceOutputBuffer<'a > { - buf: &'a mut [u8], - byte: usize -} - -impl<'a> SliceOutputBuffer<'a> { - #[inline(always)] - pub fn new(slice: &'a mut [u8]) -> SliceOutputBuffer<'a> { - SliceOutputBuffer { - buf: slice, - byte: 0 - } - } -} - -impl<'a> OutputBuffer for SliceOutputBuffer<'a> { - #[inline(always)] - fn write(&mut self, value: u8) { - if self.byte < self.buf.len() { - self.buf[self.byte] = value; - } - self.byte += 1; - } - #[inline(always)] - fn write_all(&mut self, slice: &[u8]) { - let sl = slice.len(); - let end = self.byte + sl; - if end <= self.buf.len() { - self.buf[self.byte..end].copy_from_slice(slice); - } - self.byte = end; - } - #[inline(always)] - fn pre_alloc(&mut self, _eb: usize) {} - #[inline(always)] - fn back(&self, back: usize) -> u8 { - self.buf[self.byte - back] - } -} - -fn inflt(dat: &[u8], buf: &mut dyn OutputBuffer, st: &mut InflateState) -> Result<(), InflateError> { - let mut pos = st.pos; - let sl = dat.len(); - if sl == 0 || (st.head && sl < 5) { return Ok(()); } - let tbts = sl << 3; - let tbts1 = tbts - 8; - let tbts2 = tbts1 - 8; - loop { - if st.head { - st.bfinal = bits(dat, pos, 1) != 0; - let btype = bits(dat, pos + 1, 3); - pos += 3; - match btype { - 0 => { - let s = shft(pos) + 4; - let t = s + (dat[s - 4] as u16 | ((dat[s - 3] as u16) << 8)) as usize; - if t > dat.len() { - if st.last { - return Err(InflateError::UnexpectedEOF); - } - break; - } - buf.write_all(&dat[s..t]); - continue; - } - 1 => { - st.lmap[..512].copy_from_slice(&*flrm); - st.dmap[..32].copy_from_slice(&*fdrm); - st.lbits = 9; - st.dbits = 5; - } - 2 => { - let hlit = bits(dat, pos, 31) as usize + 257; - let hclen = (bits(dat, pos + 10, 15) + 4) as usize; - let tl = hlit + (bits(dat, pos + 5, 31) + 1) as usize; - pos += 14; - for i in 0..hclen { - st.clt[clim[i]] = bits(dat, pos + (i * 3) as usize, 7); - } - pos += hclen * 3; - for i in hclen..19 { - st.clt[clim[i]] = 0; - } - let clb = max(&st.clt); - let clbmsk = (1 << clb) - 1; - if !st.last && pos + tl * (clb + 7) as usize > tbts { - break; - } - hrmap(&st.clt, clb, &mut st.clmap, &mut st.le); - let mut i = 0; - loop { - let r = st.clmap[bits(dat, pos, clbmsk) as usize]; - pos += (r & 15) as usize; - let s = (r >> 4) as u8; - if s < 16 { - st.ldt[i] = s; - i += 1; - } else { - let mut c = 0; - let mut n = 0; - if s == 16 { - n = 3 + bits(dat, pos, 3); - pos += 2; - c = st.ldt[i - 1]; - } - else if s == 17 { - n = 3 + bits(dat, pos, 7); - pos += 3; - } - else if s == 18 { - n = 11 + bits(dat, pos, 127); - pos += 7; - } - let mut un = n as usize; - i += un; - while un > 0 { - st.ldt[i - un] = c; - un -= 1; - } - } - if i >= tl { - break; - } - } - let lt = &st.ldt[0..hlit]; - let dt = &st.ldt[hlit..tl]; - st.lbits = max(lt); - st.dbits = max(dt); - hrmap(lt, st.lbits, &mut st.lmap, &mut st.le); - hrmap(dt, st.dbits, &mut st.dmap, &mut st.le); - } - _ => { - return Err(InflateError::InvalidBlockType); - } - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - } - st.head = false; - let lms = (1u16 << st.lbits) - 1; - let lms8 = lms as u8; - let dms = (1u16 << st.dbits) - 1; - let dms8 = dms as u8; - let topl = tbts - st.lbits as usize; - let topd = tbts - st.dbits as usize; - let top = tbts - (st.lbits + st.dbits + 18) as usize; - while st.last || pos < top { - let c = st.lmap[ - if pos > topl { - return Err(InflateError::UnexpectedEOF); - } else if st.lbits < 10 { - if pos > tbts1 { - mbits(dat, pos, lms8) as usize - } else { - bits(dat, pos, lms8) as usize - } - } else { - if pos > tbts2 { - mbits16(dat, pos, lms) as usize - } else { - bits16(dat, pos, lms) as usize - } - } - ]; - pos += (c & 15) as usize; - if c == 0 { - return Err(InflateError::InvalidLengthOrLiteral); - } - let sym = c >> 4; - if (sym >> 8) == 0 { - buf.write(sym as u8); - } else if sym == 256 { - st.head = true; - break; - } else { - let mut add = sym - 254; - if add > 10 { - let i = add as usize - 3; - let b = fleb[i]; - add = bits(dat, pos, (1 << b) - 1) as u16 + fl[i]; - pos += b; - } - let d = st.dmap[ - if pos > topd { - return Err(InflateError::UnexpectedEOF); - } else if st.dbits < 10 { - if pos > tbts1 { - mbits(dat, pos, dms8) as usize - } else { - bits(dat, pos, dms8) as usize - } - } else { - if pos > tbts2 { - mbits16(dat, pos, dms) as usize - } else { - bits16(dat, pos, dms) as usize - } - } - ]; - if d == 0 { - return Err(InflateError::InvalidDistance); - } - pos += (d & 15) as usize; - let dsym = (d >> 4) as usize; - let mut dt = fd[dsym] as usize; - if dsym > 3 { - let b = fdeb[dsym]; - dt += bits16(dat, pos, (1 << b) - 1) as usize; - pos += b; - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - while add != 0 { - buf.write(buf.back(dt)); - add -= 1; - } - } - } - st.pos = pos; - if !st.head || st.bfinal { - break; - } - } - Ok(()) -} - -pub fn inflate(dat: &[u8], out: &mut dyn OutputBuffer) -> Result<(), InflateError> { - let mut st = InflateState::new(); - st.last = true; - inflt(dat, out, &mut st)?; - Ok(()) -} - -// // pub struct Inflate<'a> { -// // pub sink: &'a mut dyn OutputBuffer, -// // state: InflateState -// // } - -// // impl<'a> Inflate<'a> { -// // pub fn push(&mut self, data: &[u8]) -> Result { -// // inflt(data, self.sink, &mut self.state)?; -// // let bytes = self.state.pos >> 3; -// // self.state.pos &= 7; -// // Ok(bytes) -// // } -// // pub fn end(&mut self) -> Result<(), InflateError> { -// // self.state.last = true; -// // self.push(&et)?; -// // Ok(()) -// // } -// // pub fn new(sink: &'a mut dyn OutputBuffer) -> Inflate<'a> { -// // Inflate { -// // state: InflateState::new(), -// // sink: sink -// // } -// // } -// // } - -// #[cfg(feature = "std")] -// impl<'a> Write for Inflate<'a> { -// #[inline(always)] -// fn write(&mut self, data: &[u8]) -> Result { -// Ok(self.push(data)?) -// } -// #[inline(always)] -// fn flush(&mut self) -> Result<(), Error> { -// Ok(self.end()?) -// } -// } \ No newline at end of file diff --git a/rs/fflate/src/oldlib.rs b/rs/fflate/src/oldlib.rs deleted file mode 100644 index 0169288..0000000 --- a/rs/fflate/src/oldlib.rs +++ /dev/null @@ -1,507 +0,0 @@ -//! fflate - a fast, efficient, pure compression library -//! -//! - -// Instead of trying to read this code, check out the TypeScript version - -#![allow(non_upper_case_globals)] -// #![cfg_attr(not(feature = "std"), no_std)] -use lazy_static::lazy_static; - -// #[cfg(feature = "std")] -use std::{vec::Vec, io::{Read, Write, Error, ErrorKind}, ops::Range}; - -const fleb: [usize; 32] = [ - 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, 0, 0, 0, -]; - -const fl: [u16; 32] = [ - 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, 0, 0, 0, -]; - -// in theory, this could be computed, but embedding it at compile time is faster. -const flt: [u8; 288] = [ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, -]; - -const fdeb: [usize; 32] = [ - 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, 0, 0, -]; - -const fd: [u16; 32] = [ - 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, 0, 0, -]; - -const fdt: [u8; 31] = [5u8; 31]; - -const clim: [usize; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, -]; - -const et: [u8; 0] = []; - -fn freb(b: &[u16], r: &mut [u32]) { - for i in 1..30 { - let base = b[i]; - for j in base..b[i + 1] { - r[j as usize] = ((j - base) << 5) as u32 | i as u32; - } - } -} - -// hmap base -fn hmb(cd: &[u8], mb: u8, le: &mut [u16]) { - let t = (mb + 1) as usize; - le.iter_mut().for_each(|v| *v = 0); - for &cl in cd { - if cl != 0 { - le[cl as usize] += 1; - } - } - let mut v = 0; - for i in 1..t { - let val = le[i]; - le[i] = v; - v = (v + val) << 1; - } -} - -fn hmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - for i in 0..cd.len() { - let cl = cd[i] as usize; - let v = rev[le[cl] as usize] >> (15 - cl); - le[cl] += 1; - co[i] = v as u16; - } -} - -fn hrmap(cd: &[u8], mb: u8, co: &mut [u16], le: &mut [u16]) { - hmb(cd, mb, le); - let rvb = 15 - mb; - let mbu = mb as usize; - for i in 0..cd.len() { - let cl = cd[i] as usize; - if cl != 0 { - let r = mbu - cl; - let v = (le[cl] << r) as usize; - le[cl] += 1; - let m = v + (1 << r); - let sv = ((i as u16) << 4) | cl as u16; - rev[v..m].iter().for_each(|i| co[i >> rvb] = sv); - } - } -} - -lazy_static! { - static ref revfl: [u32; 261] = { - let mut v = [0u32; 261]; - freb(&fl, &mut v); - v[258] = 28; - v - }; - static ref revfd: [u32; 32769] = { - let mut v = [0u32; 32769]; - freb(&fd, &mut v); - v - }; - static ref rev: [usize; 32768] = { - let mut v = [0usize; 32768]; - for i in 0..32768 { - let mut el = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1); - el = ((el & 0xCCCC) >> 2) | ((el & 0x3333) << 2); - el = ((el & 0xF0F0) >> 4) | ((el & 0x0F0F) << 4); - v[i] = (((el & 0xFF00) >> 8) | ((el & 0x00FF) << 8)) >> 1; - } - v - }; - static ref flm: [u16; 288] = { - let mut v = [0u16; 288]; - hmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref flrm: [u16; 512] = { - let mut v = [0u16; 512]; - hrmap(&flt, 9, &mut v, &mut [0u16; 16]); - v - }; - static ref fdm: [u16; 32] = { - let mut v = [0u16; 32]; - hmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; - static ref fdrm: [u16; 32] = { - let mut v = [0u16; 32]; - hrmap(&fdt, 5, &mut v, &mut [0u16; 16]); - v - }; -} - -#[inline(always)] -fn mbits(dat: &[u8], pos: usize, mask: u8) -> u8 { - (dat[pos >> 3] >> (pos & 7)) & mask -} - -fn mbits16(dat: &[u8], pos: usize, mask: u16) -> u16 { - let b = pos >> 3; - ((dat[b] as u16 | ((dat[b + 1] as u16) << 8)) >> (pos & 7)) & mask -} - -#[inline(always)] -fn bits(dat: &[u8], pos: usize, mask: u8) -> u8 { - let b = pos >> 3; - ((dat[b] as u16 | ((dat[b + 1] as u16) << 8)) >> (pos & 7)) as u8 & mask -} - -#[inline(always)] -fn bits16(dat: &[u8], pos: usize, mask: u16) -> u16 { - let b = pos >> 3; - ((dat[b] as u32 - | ((dat[b + 1] as u32) << 8) - | ((dat[b + 2] as u32) << 16)) - >> (pos & 7)) as u16 - & mask -} - -#[inline(always)] -fn shft(pos: usize) -> usize { - (pos >> 3) + (pos & 7 != 0) as usize -} - - -struct InflateState { - lmap: [u16; 32768], - dmap: [u16; 32768], - lbits: u8, - dbits: u8, - bfinal: bool, - pos: usize, - last: bool, - head: bool, -} - -impl InflateState { - #[inline(always)] - pub fn new() -> Self { - Default::default() - } -} - -impl Default for InflateState { - fn default() -> Self { - InflateState { - lmap: [0; 32768], - dmap: [0; 32768], - lbits: 0, - dbits: 0, - bfinal: false, - pos: 0, - last: false, - head: true - } - } -} - -pub enum InflateError { - UnexpectedEOF, - InvalidBlockType, - InvalidLengthOrLiteral, - InvalidDistance -} - -// #[cfg(feature = "std")] -impl From for Error { - fn from(error: InflateError) -> Self { - Error::new(match error { - InflateError::UnexpectedEOF => ErrorKind::UnexpectedEof, - _ => ErrorKind::Other - }, match error { - InflateError::UnexpectedEOF => "unexpected EOF", - InflateError::InvalidBlockType => "invalid block type", - InflateError::InvalidLengthOrLiteral => "invalid length/literal", - InflateError::InvalidDistance => "invalid distance" - }) - } -} - -fn max(dat: &[u8]) -> u8 { - let mut m = 0; - for &v in dat { - if v > m { - m = v; - } - } - m -} - -pub trait OutputBuffer { - fn write(&mut self, value: u8); - fn write_all(&mut self, slice: &[u8]) { - for &value in slice { - self.write(value); - } - } - fn pre_alloc(&mut self, extra_bytes: usize); - fn copy_back(&mut self, back: usize, len: usize); -} - -// #[cfg(feature = "std")] -impl OutputBuffer for Vec { - #[inline(always)] - fn write(&mut self, value: u8) { - self.push(value); - } - #[inline(always)] - fn write_all(&mut self, slice: &[u8]) { - self.extend(slice.iter()); - } - #[inline(always)] - fn pre_alloc(&mut self, extra_bytes: usize) { - self.reserve(extra_bytes); - } - fn copy_back(&mut self, back: usize, mut len: usize) { - let no_cp = len > back; - let l = self.len(); - let st = l - back; - if no_cp && back < 4 { - for i in 0..len { - OutputBuffer::write(self, self[st + i]); - } - } else { - let buf = &mut [0u8; 258]; - if no_cp { - while len != 0 { - let add = std::cmp::min(len, back); - buf[0..add].copy_from_slice(&self[st..st + add]); - OutputBuffer::write_all(self, &buf[0..add]); - len -= add; - } - } else { - buf[0..len].copy_from_slice(&self[st..st + len]); - OutputBuffer::write_all(self, &buf[0..len]); - } - } - } -} - -// pub struct SliceOutputBuffer<'a > { -// buf: &'a mut [u8], -// byte: usize -// } - -// impl<'a> SliceOutputBuffer<'a> { -// #[inline(always)] -// pub fn new(slice: &'a mut [u8]) -> SliceOutputBuffer<'a> { -// SliceOutputBuffer { -// buf: slice, -// byte: 0 -// } -// } -// } - -// impl<'a> OutputBuffer for SliceOutputBuffer<'a> { -// #[inline(always)] -// fn write(&mut self, value: u8) { -// if self.byte < self.buf.len() { -// self.buf[self.byte] = value; -// } -// self.byte += 1; -// } -// #[inline(always)] -// fn write_all(&mut self, slice: &[u8]) { -// let sl = slice.len(); -// let end = self.byte + sl; -// if end <= self.buf.len() { -// self.buf[self.byte..end].copy_from_slice(slice); -// } -// self.byte = end; -// } -// #[inline(always)] -// fn pre_alloc(&mut self, _eb: usize) {} -// fn copy_back(&mut self, back: usize, mut len: usize) { -// if len > back { -// while len != 0 { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..std::cmp::min(st + len as usize, self.byte)]); -// len -= back; -// } -// } else { -// let st = self.byte - back; -// OutputBuffer::write_all(self, &self.buf[st..st + len]) -// } -// } - -// } - -fn inflt(dat: &[u8], buf: &mut dyn OutputBuffer, st: &mut InflateState) -> Result<(), InflateError> { - let mut pos = st.pos; - let sl = dat.len(); - if sl == 0 || (st.head && sl < 5) { return Ok(()); } - let tbts = sl << 3; - let mut clmap = [0u16; 128]; - let mut le = [0u16; 16]; - let mut ldt = [0u8; 320]; - let mut clt = [0u8; 19]; - loop { - if st.head { - st.bfinal = bits(dat, pos, 1) != 0; - let btype = bits(dat, pos + 1, 3); - pos += 3; - match btype { - 0 => { - let s = shft(pos) + 4; - let t = s + (dat[s - 4] as u16 | ((dat[s - 3] as u16) << 8)) as usize; - if t > dat.len() { - if st.last { - return Err(InflateError::UnexpectedEOF); - } - break; - } - buf.write_all(&dat[s..t]); - continue; - } - 1 => { - st.lmap[..512].copy_from_slice(&*flrm); - st.dmap[..32].copy_from_slice(&*fdrm); - st.lbits = 9; - st.dbits = 5; - } - 2 => { - let hlit = bits(dat, pos, 31) as usize + 257; - let hclen = (bits(dat, pos + 10, 15) + 4) as usize; - let tl = hlit + (bits(dat, pos + 5, 31) + 1) as usize; - pos += 14; - for i in 0..hclen { - clt[clim[i]] = bits(dat, pos + (i * 3) as usize, 7); - } - pos += hclen * 3; - for i in hclen..19 { - clt[clim[i]] = 0; - } - let clb = max(&clt); - let clbmsk = (1 << clb) - 1; - if !st.last && pos + tl * (clb + 7) as usize > tbts { - break; - } - hrmap(&clt, clb, &mut clmap, &mut le); - let mut i = 0; - loop { - let r = clmap[bits(dat, pos, clbmsk) as usize]; - pos += (r & 15) as usize; - let s = (r >> 4) as u8; - if s < 16 { - ldt[i] = s; - i += 1; - } else { - let mut c = 0; - let mut n = 0; - if s == 16 { - n = 3 + bits(dat, pos, 3); - pos += 2; - c = ldt[i - 1]; - } - else if s == 17 { - n = 3 + bits(dat, pos, 7); - pos += 3; - } - else if s == 18 { - n = 11 + bits(dat, pos, 127); - pos += 7; - } - let mut un = n as usize; - i += un; - while un > 0 { - ldt[i - un] = c; - un -= 1; - } - } - if i >= tl { - break; - } - } - let lt = &ldt[0..hlit]; - let dt = &ldt[hlit..tl]; - st.lbits = max(lt); - st.dbits = max(dt); - hrmap(lt, st.lbits, &mut st.lmap, &mut le); - hrmap(dt, st.dbits, &mut st.dmap, &mut le); - } - _ => { - return Err(InflateError::InvalidBlockType); - } - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - } - st.head = false; - let lms = (1u16 << st.lbits) - 1; - let dms = (1u16 << st.dbits) - 1; - let top = tbts - (st.lbits + st.dbits + 18) as usize; - while st.last || pos < top { - let c = st.lmap[ - bits16(dat, pos, lms) as usize - ]; - pos += (c & 15) as usize; - if c == 0 { - return Err(InflateError::InvalidLengthOrLiteral); - } - let sym = c >> 4; - if (sym & 256) == 0 { - buf.write(sym as u8); - } else if sym == 256 { - st.head = true; - break; - } else { - let mut add = sym - 254; - if add > 10 { - let i = add as usize - 3; - let b = fleb[i]; - add = bits(dat, pos, (1 << b) - 1) as u16 + fl[i]; - pos += b; - } - let d = st.dmap[ - bits16(dat, pos, dms) as usize - ]; - if d == 0 { - return Err(InflateError::InvalidDistance); - } - pos += (d & 15) as usize; - let dsym = (d >> 4) as usize; - let mut dt = fd[dsym] as usize; - if dsym > 3 { - let b = fdeb[dsym]; - dt += bits16(dat, pos, (1 << b) - 1) as usize; - pos += b; - } - if pos > tbts { - return Err(InflateError::UnexpectedEOF); - } - buf.copy_back(dt, add as usize); - } - } - st.pos = pos; - if !st.head || st.bfinal { - break; - } - } - Ok(()) -} - -pub fn inflate(dat: &[u8], out: &mut dyn OutputBuffer) -> Result<(), InflateError> { - let mut st = InflateState::new(); - st.last = true; - inflt(dat, out, &mut st)?; - Ok(()) -} \ No newline at end of file