1use std::result;
2
3#[derive(Debug)]
4#[derive(PartialEq)]
5#[derive(Copy)]
6#[derive(Clone)]
7pub enum Symbol {
9 Literal(u8),
11 Pair {distance: u32, length: u32},
13 End
15}
16
17impl Eq for Symbol {}
18
19pub trait ToBits {
21 fn to_bits(&self) -> u32;
23 fn size_bits(&self) -> u32;
25}
26
27macro_rules! bitmask {
28 ($bits:expr) => ((1<<$bits)-1)
29}
30
31#[derive(Debug)]
32pub struct BitDecodeOutput<T> {
34 pub decoded: T,
36 pub used_bits: u32
38}
39
40#[derive(Debug)]
41pub enum BitDecodeError {
43 NotEnoughBits(u32)
46}
47
48pub type Result<T> = result::Result<T, BitDecodeError>;
50
51pub struct LenInit {
53 pub len_bits: [u8; 16],
54 pub len_code: [u8; 16]
55}
56
57pub struct DistInit {
59 pub dist_bits: [u8; 64],
60 pub dist_code: [u8; 64]
61}
62
63pub struct ShannonInit {
65 pub shan_bits: [u8; 256],
67 pub shan_code: [u16; 256]
70}
71
72pub struct CodeTable {
74 pub extra_len_bits: [u8; 16],
75 pub len_base: [u16; 16],
76 pub len_add: [u16; 16],
77 pub len_bits: [u8; 16],
78 pub len_codes: [u8; 256],
79
80 pub dist_bits: [u8; 64],
81 pub dist_codes: [u8; 256],
82
83 pub shan_lut: [u8; 256],
84 pub shan_4_lut: [u8; 256],
85 pub shan_6_lut: [u8; 128],
86 pub shan_8_lut: [u8; 256],
87}
88
89pub struct EncodeTable {
91 pub lit_bits: [u8; 256],
92 pub lit_code: [u16; 256],
93 pub len_bits: [u8; 518],
94 pub len_code: [u16; 518],
95 pub dist_bits: [u8; 64],
96 pub dist_code: [u8; 64],
97 pub dict_bits: u32
98}
99
100pub static DEFAULT_CODE_TABLE: CodeTable = CodeTable {
103 extra_len_bits: [0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8],
104 len_base: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 14, 22, 38, 70, 134, 262],
105 len_add: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 11, 26, 57, 120, 247],
106 len_bits: [3, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7],
107 len_codes: [15, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 12, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
108 13, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 11, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
109 14, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 12, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
110 13, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 11, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
111 15, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 12, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
112 13, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 11, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
113 14, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 12, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1,
114 13, 2, 5, 1, 8, 0, 3, 1, 10, 2, 4, 1, 6, 0, 3, 1, 11, 2, 5, 1, 7, 0, 3, 1, 9, 2, 4, 1, 6, 0, 3, 1],
115
116 dist_bits: [2, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
117 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
118 dist_codes: [63, 6, 23, 0, 39, 2, 14, 0, 47, 4, 18, 0, 31, 1, 10, 0, 55, 5, 20, 0, 35, 2, 12, 0, 43, 3, 16, 0, 27, 1, 8, 0,
119 59, 6, 21, 0, 37, 2, 13, 0, 45, 4, 17, 0, 29, 1, 9, 0, 51, 5, 19, 0, 33, 2, 11, 0, 41, 3, 15, 0, 25, 1, 7, 0,
120 61, 6, 22, 0, 38, 2, 14, 0, 46, 4, 18, 0, 30, 1, 10, 0, 53, 5, 20, 0, 34, 2, 12, 0, 42, 3, 16, 0, 26, 1, 8, 0,
121 57, 6, 21, 0, 36, 2, 13, 0, 44, 4, 17, 0, 28, 1, 9, 0, 49, 5, 19, 0, 32, 2, 11, 0, 40, 3, 15, 0, 24, 1, 7, 0,
122 62, 6, 23, 0, 39, 2, 14, 0, 47, 4, 18, 0, 31, 1, 10, 0, 54, 5, 20, 0, 35, 2, 12, 0, 43, 3, 16, 0, 27, 1, 8, 0,
123 58, 6, 21, 0, 37, 2, 13, 0, 45, 4, 17, 0, 29, 1, 9, 0, 50, 5, 19, 0, 33, 2, 11, 0, 41, 3, 15, 0, 25, 1, 7, 0,
124 60, 6, 22, 0, 38, 2, 14, 0, 46, 4, 18, 0, 30, 1, 10, 0, 52, 5, 20, 0, 34, 2, 12, 0, 42, 3, 16, 0, 26, 1, 8, 0,
125 56, 6, 21, 0, 36, 2, 13, 0, 44, 4, 17, 0, 28, 1, 9, 0, 48, 5, 19, 0, 32, 2, 11, 0, 40, 3, 15, 0, 24, 1, 7, 0],
126
127 shan_lut: [0; 256], shan_4_lut: [0; 256],shan_6_lut: [0; 128],shan_8_lut: [0; 256],};
132
133pub const END: u32 = 517;
135
136pub fn decode_bits(bits: u64, nbits: u32, table: &CodeTable, dict_bits: u32) -> Result<BitDecodeOutput<Symbol>> {
181 let is_pair: u64 = bits&1;
182 let next_byte: u64 = (bits>>1)&0xFF;
183 let mut used_bits;
184
185 let sym = if is_pair==1 {
186 let code: u32 = table.len_codes[next_byte as usize] as u32;
187 let code_bits: u32 = table.len_bits[code as usize] as u32;
188 let extra_bits: u32 = table.extra_len_bits[code as usize] as u32;
189
190 used_bits = code_bits + extra_bits + 1;
191
192 let extra: u64 = (bits>>(1+code_bits)) & bitmask!(extra_bits);
194
195 let length = if extra_bits>0 {table.len_add[code as usize] as u32} else {0} + code + (extra as u32);
196
197 if length == END {
198 if nbits<used_bits {
199 return Err(BitDecodeError::NotEnoughBits(used_bits-nbits))
200 }
201
202 return Ok(BitDecodeOutput::<Symbol>{decoded: Symbol::End, used_bits: used_bits})
203 }
204
205 let dist_code: u8 = table.dist_codes[((bits>>used_bits)&0xFF) as usize];
209
210 let add_bits: u32 = if length==0 {2} else {dict_bits};
211 used_bits = used_bits+(table.dist_bits[dist_code as usize] as u32);
212
213 let distance: u32 = ((dist_code as u32) << add_bits) | (((bits>>used_bits) & bitmask!(add_bits)) as u32);
214
215 used_bits = used_bits + add_bits;
216 Symbol::Pair{distance: distance + 1, length: length + 2}
217 } else {
218 used_bits = 9;
219 Symbol::Literal(next_byte as u8)
220 };
221
222 if nbits<used_bits {
223 return Err(BitDecodeError::NotEnoughBits(used_bits-nbits))
224 }
225
226 Ok(BitDecodeOutput::<Symbol>{decoded: sym, used_bits: used_bits})
227}