|
@@ -9,17 +9,11 @@
|
|
|
|
|
|
extern crate alloc;
|
|
extern crate alloc;
|
|
|
|
|
|
-use alloc::boxed::Box;
|
|
|
|
-use alloc::vec::Vec;
|
|
|
|
|
|
+use alloc::vec::{Vec, from_elem};
|
|
use lazy_static::lazy_static;
|
|
use lazy_static::lazy_static;
|
|
|
|
+use core::result::Result;
|
|
|
|
|
|
-macro_rules! BM {
|
|
|
|
- ($num:expr) => {
|
|
|
|
- (1 << $num) - 1
|
|
|
|
- };
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const fleb: [u8; 32] = [
|
|
|
|
|
|
+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,
|
|
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,
|
|
];
|
|
];
|
|
|
|
|
|
@@ -41,7 +35,7 @@ const flt: [u8; 288] = [
|
|
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,
|
|
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: [u8; 32] = [
|
|
|
|
|
|
+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,
|
|
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,
|
|
13, 0, 0,
|
|
];
|
|
];
|
|
@@ -53,18 +47,10 @@ const fd: [u16; 32] = [
|
|
|
|
|
|
const fdt: [u8; 31] = [5u8; 31];
|
|
const fdt: [u8; 31] = [5u8; 31];
|
|
|
|
|
|
-const clim: [u8; 19] = [
|
|
|
|
|
|
+const clim: [usize; 19] = [
|
|
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
|
|
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
|
|
];
|
|
];
|
|
|
|
|
|
-fn uvec<T>(sz: usize) -> Vec<T> {
|
|
|
|
- let mut v = Vec::with_capacity(sz);
|
|
|
|
- unsafe {
|
|
|
|
- v.set_len(sz);
|
|
|
|
- }
|
|
|
|
- v
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
fn freb(b: &[u16], r: &mut [u32]) {
|
|
fn freb(b: &[u16], r: &mut [u32]) {
|
|
for i in 1..30 {
|
|
for i in 1..30 {
|
|
let base = b[i];
|
|
let base = b[i];
|
|
@@ -82,39 +68,40 @@ fn hmb(cd: &[u8], mb: u8) -> [u16; 16] {
|
|
}
|
|
}
|
|
let mut le = [0u16; 16];
|
|
let mut le = [0u16; 16];
|
|
let mut v = 0;
|
|
let mut v = 0;
|
|
- for i in 1..mb {
|
|
|
|
- v += l[i as usize];
|
|
|
|
- le[i as usize] = v;
|
|
|
|
|
|
+ let t = (mb + 1) as usize;
|
|
|
|
+ for i in 1..t {
|
|
|
|
+ le[i] = v;
|
|
|
|
+ v = (v + l[i]) << 1;
|
|
}
|
|
}
|
|
le
|
|
le
|
|
}
|
|
}
|
|
|
|
|
|
-fn hmap(cd: &[u8], mb: u8) -> Box<[u16]> {
|
|
|
|
|
|
+fn hmap(cd: &[u8], mb: u8) -> Vec<u16> {
|
|
let mut le = hmb(cd, mb);
|
|
let mut le = hmb(cd, mb);
|
|
cd.iter()
|
|
cd.iter()
|
|
.map(|&cl| {
|
|
.map(|&cl| {
|
|
let v = rev[le[cl as usize] as usize] >> (15 - cl);
|
|
let v = rev[le[cl as usize] as usize] >> (15 - cl);
|
|
le[cl as usize] += 1;
|
|
le[cl as usize] += 1;
|
|
- v
|
|
|
|
|
|
+ v as u16
|
|
})
|
|
})
|
|
.collect::<Vec<_>>()
|
|
.collect::<Vec<_>>()
|
|
- .into_boxed_slice()
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-fn hrmap(cd: &[u8], mb: u8) -> Box<[u16]> {
|
|
|
|
|
|
+fn hrmap(cd: &[u8], mb: u8) -> Vec<u16> {
|
|
let mut le = hmb(cd, mb);
|
|
let mut le = hmb(cd, mb);
|
|
- let mut co = uvec(1 << mb).into_boxed_slice();
|
|
|
|
|
|
+ let mut co = from_elem(0, 1 << mb);
|
|
let rvb = 15 - mb;
|
|
let rvb = 15 - mb;
|
|
|
|
+ let mbu = mb as usize;
|
|
for i in 0..cd.len() {
|
|
for i in 0..cd.len() {
|
|
- let cl = cd[i];
|
|
|
|
|
|
+ let cl = cd[i] as usize;
|
|
if cl != 0 {
|
|
if cl != 0 {
|
|
let sv = ((i as u16) << 4) | cl as u16;
|
|
let sv = ((i as u16) << 4) | cl as u16;
|
|
- let r = mb - cl;
|
|
|
|
- let v = le[cl as usize] << r;
|
|
|
|
- le[cl as usize] += 1;
|
|
|
|
|
|
+ let r = mbu - cl;
|
|
|
|
+ let v = (le[cl] << r) as usize;
|
|
|
|
+ le[cl] += 1;
|
|
let m = v + (1 << r);
|
|
let m = v + (1 << r);
|
|
for j in v..m {
|
|
for j in v..m {
|
|
- co[rev[j as usize] as usize >> rvb] = sv;
|
|
|
|
|
|
+ co[rev[j] >> rvb] = sv;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -122,41 +109,46 @@ fn hrmap(cd: &[u8], mb: u8) -> Box<[u16]> {
|
|
}
|
|
}
|
|
|
|
|
|
lazy_static! {
|
|
lazy_static! {
|
|
- static ref revfl: Box<[u32]> = {
|
|
|
|
- let mut v = Vec::with_capacity(261).into_boxed_slice();
|
|
|
|
|
|
+ static ref revfl: Vec<u32> = {
|
|
|
|
+ let mut v = Vec::with_capacity(261);
|
|
freb(&fl, &mut v);
|
|
freb(&fl, &mut v);
|
|
|
|
+ v[258] = 28;
|
|
v
|
|
v
|
|
};
|
|
};
|
|
- static ref revfd: Box<[u32]> = {
|
|
|
|
- let mut v = Vec::with_capacity(32769).into_boxed_slice();
|
|
|
|
|
|
+ static ref revfd: Vec<u32> = {
|
|
|
|
+ let mut v = Vec::with_capacity(32769);
|
|
freb(&fd, &mut v);
|
|
freb(&fd, &mut v);
|
|
v
|
|
v
|
|
};
|
|
};
|
|
- static ref rev: Box<[u16]> = (0..32768)
|
|
|
|
|
|
+ static ref rev: Vec<usize> = (0..32768)
|
|
.map(|mut v| {
|
|
.map(|mut v| {
|
|
v = ((v & 0xAAAA) >> 1) | ((v & 0x5555) << 1);
|
|
v = ((v & 0xAAAA) >> 1) | ((v & 0x5555) << 1);
|
|
v = ((v & 0xCCCC) >> 2) | ((v & 0x3333) << 2);
|
|
v = ((v & 0xCCCC) >> 2) | ((v & 0x3333) << 2);
|
|
v = ((v & 0xF0F0) >> 4) | ((v & 0x0F0F) << 4);
|
|
v = ((v & 0xF0F0) >> 4) | ((v & 0x0F0F) << 4);
|
|
(((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8)) >> 1
|
|
(((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8)) >> 1
|
|
})
|
|
})
|
|
- .collect::<Vec<_>>()
|
|
|
|
- .into_boxed_slice();
|
|
|
|
- static ref flm: Box<[u16]> = hmap(&flt, 9);
|
|
|
|
- static ref flrm: Box<[u16]> = hrmap(&flt, 9);
|
|
|
|
- static ref fdm: Box<[u16]> = hmap(&fdt, 5);
|
|
|
|
- static ref fdrm: Box<[u16]> = hrmap(&flt, 5);
|
|
|
|
|
|
+ .collect::<Vec<_>>();
|
|
|
|
+ static ref flm: Vec<u16> = hmap(&flt, 9);
|
|
|
|
+ static ref flrm: Vec<u16> = hrmap(&flt, 9);
|
|
|
|
+ static ref fdm: Vec<u16> = hmap(&fdt, 5);
|
|
|
|
+ static ref fdrm: Vec<u16> = hrmap(&flt, 5);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[inline(always)]
|
|
|
|
+fn byte(dat: &[u8], bpos: usize) -> u8 {
|
|
|
|
+ dat[bpos]
|
|
}
|
|
}
|
|
|
|
|
|
#[inline]
|
|
#[inline]
|
|
fn bits(dat: &[u8], pos: usize, mask: u8) -> u8 {
|
|
fn bits(dat: &[u8], pos: usize, mask: u8) -> u8 {
|
|
let b = pos >> 3;
|
|
let b = pos >> 3;
|
|
- return ((dat[b] as u16 | ((dat[b + 1] as u16) << 8)) >> (pos & 7)) as u8 & mask;
|
|
|
|
|
|
+ return ((byte(dat, b) as u16 | ((byte(dat, b + 1) as u16) << 8)) >> (pos & 7)) as u8 & mask;
|
|
}
|
|
}
|
|
|
|
|
|
#[inline]
|
|
#[inline]
|
|
fn bits16(dat: &[u8], pos: usize, mask: u16) -> u16 {
|
|
fn bits16(dat: &[u8], pos: usize, mask: u16) -> u16 {
|
|
let b = pos >> 3;
|
|
let b = pos >> 3;
|
|
- return ((dat[b] as u32 | ((dat[b + 1] as u32) << 8) | ((dat[b + 2] as u32) << 16)) >> (pos & 7))
|
|
|
|
|
|
+ return ((byte(dat, b) as u32 | ((byte(dat, b + 1) as u32) << 8) | ((byte(dat, b + 2) as u32) << 16)) >> (pos & 7))
|
|
as u16
|
|
as u16
|
|
& mask;
|
|
& mask;
|
|
}
|
|
}
|
|
@@ -166,3 +158,196 @@ fn shft(pos: usize) -> usize {
|
|
pos >> 3 + (pos & 7 != 0) as usize
|
|
pos >> 3 + (pos & 7 != 0) as usize
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct InflateState {
|
|
|
|
+ lmap: Option<Vec<u16>>,
|
|
|
|
+ dmap: Option<Vec<u16>>,
|
|
|
|
+ lbits: u8,
|
|
|
|
+ dbits: u8,
|
|
|
|
+ bfinal: bool,
|
|
|
|
+ pos: usize,
|
|
|
|
+ last: bool,
|
|
|
|
+ head: bool
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+pub enum InflateError {
|
|
|
|
+ UnexpectedEOF,
|
|
|
|
+ InvalidBlockType,
|
|
|
|
+ InvalidLengthOrLiteral,
|
|
|
|
+ InvalidDistance
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+fn inflt(dat: &[u8], buf: &mut Vec<u8>, st: &mut InflateState) -> Result<(), InflateError> {
|
|
|
|
+ let mut pos = st.pos;
|
|
|
|
+ let sl = dat.len();
|
|
|
|
+ if st.bfinal && st.head { return Ok(()) };
|
|
|
|
+ let tbts = sl << 3;
|
|
|
|
+ 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 l = dat[s - 4] as u16 | ((dat[s - 3] as u16) << 8);
|
|
|
|
+ let t = s + l as usize;
|
|
|
|
+ if t > dat.len() {
|
|
|
|
+ if st.last {
|
|
|
|
+ return Err(InflateError::UnexpectedEOF);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ buf.extend(dat[s..t].iter());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ 1 => {
|
|
|
|
+ st.lmap = None;
|
|
|
|
+ st.dmap = None;
|
|
|
|
+ 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 = *clt.iter().max().unwrap();
|
|
|
|
+ let clbmsk = (1 << clb) - 1;
|
|
|
|
+ if !st.last && pos + tl * (clb + 7) as usize > tbts {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ let clm = hrmap(&clt, clb);
|
|
|
|
+ let mut i = 0;
|
|
|
|
+ loop {
|
|
|
|
+ let r = clm[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 = *lt.iter().max().unwrap();
|
|
|
|
+ st.dbits = *dt.iter().max().unwrap();
|
|
|
|
+ st.lmap = Some(hrmap(lt, st.lbits));
|
|
|
|
+ st.dmap = Some(hrmap(dt, st.dbits));
|
|
|
|
+ }
|
|
|
|
+ _ => {
|
|
|
|
+ return Err(InflateError::InvalidBlockType);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if pos > tbts {
|
|
|
|
+ return Err(InflateError::UnexpectedEOF);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ st.head = false;
|
|
|
|
+ let lm = st.lmap.as_ref().unwrap_or(&flm);
|
|
|
|
+ let dm = st.dmap.as_ref().unwrap_or(&fdm);
|
|
|
|
+ let lms = (1 << st.lbits) - 1;
|
|
|
|
+ let dms = (1 << st.dbits) - 1;
|
|
|
|
+ let mxa = (st.lbits + st.dbits + 18) as usize;
|
|
|
|
+ while st.last || pos + mxa < tbts {
|
|
|
|
+ let c = lm[bits16(dat, pos, lms) as usize];
|
|
|
|
+ pos += (c & 15) as usize;
|
|
|
|
+ if pos > tbts {
|
|
|
|
+ return Err(InflateError::UnexpectedEOF);
|
|
|
|
+ }
|
|
|
|
+ if c == 0 {
|
|
|
|
+ return Err(InflateError::InvalidLengthOrLiteral);
|
|
|
|
+ }
|
|
|
|
+ let sym = c >> 4;
|
|
|
|
+ if (sym >> 8) == 0 {
|
|
|
|
+ buf.push(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 as usize];
|
|
|
|
+ pos += b;
|
|
|
|
+ }
|
|
|
|
+ let d = dm[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.push(buf[buf.len() - dt]);
|
|
|
|
+ add -= 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ st.pos = pos;
|
|
|
|
+ if !st.head || st.bfinal {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Ok(())
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+pub fn inflate(dat: &[u8]) -> Result<Vec<u8>, InflateError> {
|
|
|
|
+ let mut v = Vec::with_capacity(dat.len() * 3);
|
|
|
|
+ let mut st = InflateState {
|
|
|
|
+ lmap: None,
|
|
|
|
+ dmap: None,
|
|
|
|
+ lbits: 0,
|
|
|
|
+ dbits: 0,
|
|
|
|
+ bfinal: false,
|
|
|
|
+ pos: 0,
|
|
|
|
+ last: true,
|
|
|
|
+ head: true
|
|
|
|
+ };
|
|
|
|
+ if let Err(e) = inflt(dat, &mut v, &mut st) {
|
|
|
|
+ return Err(e);
|
|
|
|
+ };
|
|
|
|
+ Ok(v)
|
|
|
|
+}
|