1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use bitstream_io::{BigEndian, BitRead, BitReader};
use std::io;

pub fn decode_val(r: &mut BitReader<&[u8], BigEndian>, from: u32, to: u32) -> io::Result<u16> {
    let mut res = 0;
    let mut add = 0;
    let mut exp = 1 << from;
    let mut bit = from;
    while bit < to {
        res = r.read::<u16>(1)?;
        if res == 0 {
            break;
        }
        add += exp;
        exp <<= 1;
        bit += 1;
    }
    if bit != 0 {
        res = r.read::<u16>(bit)?;
    }
    res += add;
    Ok(res)
}

const THRESHOLD: usize = 3;

pub fn decode_fastest(data: &[u8], original_size: usize) -> io::Result<Vec<u8>> {
    let mut res = Vec::with_capacity(original_size);
    let mut r = BitReader::endian(data, BigEndian);
    while res.len() < original_size {
        let len = decode_val(&mut r, 0, 7)?;
        if len == 0 {
            let next_char = r.read::<u8>(8)?;
            res.push(next_char);
        } else {
            let rep_count = len as usize + THRESHOLD - 1;
            let back_ptr = decode_val(&mut r, 9, 13)? as usize;
            if back_ptr > res.len() - 1 {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    "Invalid back_ptr",
                ));
            }
            let mut i = res.len() - 1 - back_ptr;
            for _ in 0..rep_count {
                res.push(res[i]);
                i += 1;
            }
        }
    }
    Ok(res)
}