compression/deflate/
mod.rs1#![cfg(feature = "deflate")]
8
9pub(crate) mod decoder;
10pub(crate) mod encoder;
11
12use crate::bitio::small_bit_vec::SmallBitVec;
13use crate::core::u16;
14#[cfg(not(feature = "std"))]
15#[allow(unused_imports)]
16use alloc::vec;
17#[cfg(not(feature = "std"))]
18use alloc::vec::Vec;
19
20fn fix_symbol_table() -> Vec<u8> {
21 let mut r = vec![8; 144];
22 r.append(&mut vec![9; 112]);
23 r.append(&mut vec![7; 24]);
24 r.append(&mut vec![8; 8]);
25 r
26}
27
28fn fix_offset_table() -> &'static [u8; 32] {
29 &[5; 32]
30}
31
32#[derive(Debug)]
33struct CodeTable {
34 codes: Vec<u8>,
35 offsets: Vec<u16>,
36 ext_bits: Vec<u8>,
37}
38
39impl CodeTable {
40 fn convert(&self, value: u16) -> (u8, SmallBitVec<u16>) {
41 let pos = self.codes[value as usize];
42 (
43 pos,
44 SmallBitVec::new(
45 value - self.offsets[pos as usize],
46 self.ext_bits(pos as usize),
47 ),
48 )
49 }
50
51 fn ext_bits(&self, pos: usize) -> usize {
52 self.ext_bits[pos] as usize
53 }
54
55 fn convert_back(&self, pos: usize, ext: u16) -> u16 {
56 self.offsets[pos] + ext
57 }
58}
59
60fn gen_codes(len: usize, offsets: &[u16]) -> Vec<u8> {
61 let mut codes = Vec::with_capacity(len);
62 let mut j = 0;
63 for i in 0..(len as u16) {
64 while offsets[j as usize + 1] <= i {
65 j += 1;
66 }
67 codes.push(j);
68 }
69 codes
70}
71
72fn gen_len_tab() -> CodeTable {
73 let mut offsets = Vec::with_capacity(30);
74 let mut ext_bits = Vec::with_capacity(29);
75 for i in 0..8 {
76 offsets.push(i);
77 ext_bits.push(0);
78 }
79
80 for i in 8..28 {
81 let n = (i >> 2) - 1;
82 offsets.push(u16::from(i & 3 | 4) << n);
83 ext_bits.push(n);
84 }
85
86 offsets.push(255);
88 ext_bits.push(0);
89
90 offsets.push(u16::MAX);
92
93 let codes = gen_codes(256, &offsets);
94
95 CodeTable {
96 codes,
97 offsets,
98 ext_bits,
99 }
100}
101
102fn gen_off_tab() -> CodeTable {
103 let mut offsets = Vec::with_capacity(31);
104 let mut ext_bits = Vec::with_capacity(30);
105 for i in 0..4 {
106 offsets.push(i);
107 ext_bits.push(0);
108 }
109
110 for i in 4..30 {
111 let n = (i >> 1) - 1;
112 offsets.push(u16::from(i & 1 | 2) << n);
113 ext_bits.push(n);
114 }
115
116 offsets.push(u16::MAX);
118
119 let codes = gen_codes(0x8000, &offsets);
120
121 CodeTable {
122 codes,
123 offsets,
124 ext_bits,
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use crate::action::Action;
131 use crate::deflate::decoder::Deflater;
132 use crate::deflate::encoder::Inflater;
133 use crate::traits::decoder::DecodeExt;
134 use crate::traits::encoder::EncodeExt;
135 #[cfg(not(feature = "std"))]
136 use alloc::vec::Vec;
137 use rand::distributions::Standard;
138 use rand::{thread_rng, Rng};
139
140 fn check(testarray: &[u8]) {
141 let encoded = testarray
142 .to_vec()
143 .encode(&mut Inflater::new(), Action::Finish)
144 .collect::<Result<Vec<_>, _>>();
145 let decoded = encoded
146 .unwrap()
147 .decode(&mut Deflater::new())
148 .collect::<Result<Vec<_>, _>>()
149 .unwrap();
150
151 assert_eq!(testarray.to_vec(), decoded);
152 }
153
154 #[test]
155 fn test_empty() {
156 check(&[]);
157 }
158
159 #[test]
160 fn test_unit() {
161 check(b"a");
162 }
163
164 #[test]
165 fn test_arr() {
166 check(b"aaaaaaaaaaa");
167 }
168
169 #[test]
170 fn test_std() {
171 check(b"aabbaabbaaabbbaaabbbaabbaabb");
172 }
173
174 #[test]
175 fn test_long() {
176 check(&(b"a".iter().cycle().take(260).cloned().collect::<Vec<u8>>()));
177 }
178
179 #[test]
180 fn test_long2() {
181 check(
182 &((144..256)
183 .cycle()
184 .take(224)
185 .map(|x| x as u8)
186 .collect::<Vec<u8>>()),
187 )
188 }
189
190 #[test]
191 fn test_multiblocks() {
192 let rng = thread_rng();
193
194 check(&(rng.sample_iter(&Standard).take(323_742).collect::<Vec<_>>()));
195 }
196
197 #[test]
198 fn test_multiblocks2() {
199 let rng = thread_rng();
200
201 check(&(rng.sample_iter(&Standard).take(323_742).collect::<Vec<_>>()));
202 }
203
204 #[test]
205 fn test_multiblocks3() {
206 let rng = thread_rng();
207
208 check(
209 &(rng
210 .sample_iter(&Standard)
211 .take(0xF_FFFF)
212 .collect::<Vec<_>>()),
213 );
214 }
215
216 fn test_rand_with_len(len: usize) {
217 let rng = thread_rng();
218
219 check(&(rng.sample_iter(&Standard).take(len).collect::<Vec<_>>()));
220 }
221
222 #[test]
223 fn test_multiblocks6() {
224 test_rand_with_len(6);
225 }
226
227 #[test]
228 fn test_multiblocks4() {
229 test_rand_with_len(0x10_000);
230 }
231
232 #[test]
233 fn test_multiblocks5() {
234 test_rand_with_len(0x10_0001);
235 }
236}