lzw_compress/
lib.rs

1pub mod test;
2
3pub mod lzw {
4    use std::collections::HashMap;
5
6    pub fn compress(data: &[u8]) -> Vec<u32> {
7        // Build the initial dictionary with single-byte sequences.
8        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            // Try to extend the current sequence.
16            current_sequence.push(byte);
17
18            // Check if the extended sequence is in the dictionary.
19            if let Some(&_code) = dictionary.get(&current_sequence) {
20                // The sequence is in the dictionary, continue to extend it.
21                continue;
22            }
23
24            // The sequence is not in the dictionary, so add it.
25            // Write the code for the current sequence to the output.
26            if let Some(&code) = dictionary.get(&current_sequence[..current_sequence.len() - 1]) {
27                compressed.push(code);
28            } else {
29                panic!("Invalid dictionary state.");
30            }
31
32            // Add the new sequence to the dictionary.
33            dictionary.insert(current_sequence.clone(), dictionary.len() as u32);
34
35            // Reset the current sequence to the last byte.
36            current_sequence.clear();
37            current_sequence.push(byte);
38        }
39
40        // Write the code for the last sequence to the output.
41        if let Some(&code) = dictionary.get(&current_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        // Build the initial dictionary with single-byte sequences.
52        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}