1 | use crate::{encoder::compression::*, tags::CompressionMethod}; |
2 | use std::io::Write; |
3 | use weezl::encode::Encoder as LZWEncoder; |
4 | |
5 | /// The LZW algorithm used to compress image data in TIFF files. |
6 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Default)] |
7 | pub struct Lzw; |
8 | |
9 | impl Compression for Lzw { |
10 | const COMPRESSION_METHOD: CompressionMethod = CompressionMethod::LZW; |
11 | |
12 | fn get_algorithm(&self) -> Compressor { |
13 | Compressor::Lzw(*self) |
14 | } |
15 | } |
16 | |
17 | impl CompressionAlgorithm for Lzw { |
18 | fn write_to<W: Write>(&mut self, writer: &mut W, bytes: &[u8]) -> Result<u64, io::Error> { |
19 | let mut encoder: Encoder = LZWEncoder::with_tiff_size_switch(order:weezl::BitOrder::Msb, size:8); |
20 | let result: StreamResult = encoder.into_stream(writer).encode_all(read:bytes); |
21 | let byte_count: u64 = result.bytes_written as u64; |
22 | result.status.map(|_| byte_count) |
23 | } |
24 | } |
25 | |
26 | #[cfg (test)] |
27 | mod tests { |
28 | use super::*; |
29 | use crate::encoder::compression::tests::TEST_DATA; |
30 | use std::io::Cursor; |
31 | |
32 | #[test ] |
33 | fn test_lzw() { |
34 | const EXPECTED_COMPRESSED_DATA: [u8; 63] = [ |
35 | 0x80, 0x15, 0x0D, 0x06, 0x93, 0x98, 0x82, 0x08, 0x20, 0x30, 0x88, 0x0E, 0x67, 0x43, |
36 | 0x91, 0xA4, 0xDC, 0x67, 0x10, 0x19, 0x8D, 0xE7, 0x21, 0x01, 0x8C, 0xD0, 0x65, 0x31, |
37 | 0x9A, 0xE1, 0xD1, 0x03, 0xB1, 0x86, 0x1A, 0x6F, 0x3A, 0xC1, 0x4C, 0x66, 0xF3, 0x69, |
38 | 0xC0, 0xE4, 0x65, 0x39, 0x9C, 0xCD, 0x26, 0xF3, 0x74, 0x20, 0xD8, 0x67, 0x89, 0x9A, |
39 | 0x4E, 0x86, 0x83, 0x69, 0xCC, 0x5D, 0x01, |
40 | ]; |
41 | |
42 | let mut compressed_data = Vec::<u8>::new(); |
43 | let mut writer = Cursor::new(&mut compressed_data); |
44 | Lzw.write_to(&mut writer, TEST_DATA).unwrap(); |
45 | assert_eq!(EXPECTED_COMPRESSED_DATA, compressed_data.as_slice()); |
46 | } |
47 | } |
48 | |