pub fn decode(src_buf: &[u8]) -> Result<Vec<u8>, String> {
if src_buf.len() <= 6 {
return Err("huf buf insuf".to_owned());
}
let extra_size = src_buf.get(4).cloned().ok_or("failed reading byte")?;
let mag_idx = 6 + 2 * extra_size as usize;
if src_buf.len() <= mag_idx {
return Err("not huffman mode 28".to_owned());
}
let out_length =
src_buf[1] as usize | (src_buf[2] as usize) << 8usize | (src_buf[3] as usize) << 16usize;
let mut out_buf = vec![0u8; out_length];
let tree = &src_buf[4..mag_idx];
let mut entry = tree[1];
let mut pos = 0;
let mut dp = 0;
for sp in (mag_idx..src_buf.len()).step_by(4) {
for sq in (sp..=sp + 3).rev() {
let mut k = 128;
while k > 0 {
pos += (entry & 0x3F) + 1;
if pos > tree[0] {
return Err("pos out of tree".to_owned());
}
let isleaf = if src_buf[sq] & k != 0 {
let old_entry = entry;
entry = tree[2 * pos as usize + 1];
old_entry & 0x40
}
else {
let old_entry = entry;
entry = tree[2 * pos as usize];
old_entry & 0x80
};
if isleaf != 0 {
out_buf[dp] = entry;
dp += 1;
if dp >= out_length {
if src_buf.len() - sp != 4 {
return Err(format!("file had {} trailing bytes", src_buf.len() - sp)
.to_owned());
}
return Ok(out_buf);
}
entry = tree[1];
pos = 0;
}
k >>= 1;
}
}
}
return Err(format!("file ended with {} bytes missing", out_length - dp).to_owned());
}