1pub mod test;
2
3pub mod lzw {
4 use std::collections::HashMap;
5
6 pub fn compress(data: &[u8]) -> Vec<u32> {
7 let mut dictionary: HashMap<Vec<u8>, u32> =
9 (0u32..=255).map(|i| (vec![i as u8], i)).collect();
10
11 let mut current_sequence = Vec::new();
12 let mut compressed = Vec::new();
13
14 for &byte in data {
15 current_sequence.push(byte);
17
18 if let Some(&_code) = dictionary.get(¤t_sequence) {
20 continue;
22 }
23
24 if let Some(&code) = dictionary.get(¤t_sequence[..current_sequence.len() - 1]) {
27 compressed.push(code);
28 } else {
29 panic!("Invalid dictionary state.");
30 }
31
32 dictionary.insert(current_sequence.clone(), dictionary.len() as u32);
34
35 current_sequence.clear();
37 current_sequence.push(byte);
38 }
39
40 if let Some(&code) = dictionary.get(¤t_sequence) {
42 compressed.push(code);
43 } else {
44 panic!("Invalid dictionary state.");
45 }
46
47 compressed
48 }
49
50 pub fn decompress(data: &[u32]) -> Vec<u8> {
51 let mut dictionary: HashMap<u32, Vec<u8>> =
53 (0u32..=255).map(|i| (i, vec![i as u8])).collect();
54
55 let mut result = Vec::new();
56
57 let mut entry = dictionary[&data[0]].clone();
58 result.extend_from_slice(&entry);
59
60 for &code in &data[1..] {
61 let mut new_entry = dictionary.get(&code).cloned();
62
63 if new_entry.is_none() {
64 if code == dictionary.len() as u32 {
65 new_entry = Some(entry.clone());
66 new_entry.as_mut().unwrap().push(entry[0]);
67 } else {
68 panic!("Invalid data!");
69 }
70 }
71
72 entry.extend_from_slice(new_entry.as_ref().unwrap());
73
74 dictionary.insert(dictionary.len() as u32, entry.clone());
75 result.extend_from_slice(new_entry.as_ref().unwrap());
76 }
77
78 result
79 }
80}