unarj_rs/
decode_fastest.rs1use bitstream_io::{BigEndian, BitRead, BitReader};
2use std::io;
3
4pub fn decode_val(r: &mut BitReader<&[u8], BigEndian>, from: u32, to: u32) -> io::Result<u16> {
5 let mut res = 0;
6 let mut add = 0;
7 let mut exp = 1 << from;
8 let mut bit = from;
9 while bit < to {
10 res = r.read::<u16>(1)?;
11 if res == 0 {
12 break;
13 }
14 add += exp;
15 exp <<= 1;
16 bit += 1;
17 }
18 if bit != 0 {
19 res = r.read::<u16>(bit)?;
20 }
21 res += add;
22 Ok(res)
23}
24
25const THRESHOLD: usize = 3;
26
27pub fn decode_fastest(data: &[u8], original_size: usize) -> io::Result<Vec<u8>> {
28 let mut res = Vec::with_capacity(original_size);
29 let mut r = BitReader::endian(data, BigEndian);
30 while res.len() < original_size {
31 let len = decode_val(&mut r, 0, 7)?;
32 if len == 0 {
33 let next_char = r.read::<u8>(8)?;
34 res.push(next_char);
35 } else {
36 let rep_count = len as usize + THRESHOLD - 1;
37 let back_ptr = decode_val(&mut r, 9, 13)? as usize;
38 if back_ptr > res.len() - 1 {
39 return Err(io::Error::new(
40 io::ErrorKind::InvalidData,
41 "Invalid back_ptr",
42 ));
43 }
44 let mut i = res.len() - 1 - back_ptr;
45 for _ in 0..rep_count {
46 res.push(res[i]);
47 i += 1;
48 }
49 }
50 }
51 Ok(res)
52}