gcode_nom/binary/
inflate.rs1use std::sync::LazyLock;
2
3use heatshrink::decode;
4use heatshrink::Config;
5use meatpack::MeatPackResult;
6use meatpack::Unpacker;
7use nom::bytes::streaming::take;
8use nom::Err::Error;
9use nom::IResult;
10
11use super::block_header::BlockHeader;
12use super::default_params::Encoding;
13use super::BlockError;
14use super::CompressionType;
15
16use inflate::inflate_bytes_zlib;
17
18static CONFIG_W12_L4: LazyLock<Config> =
19 LazyLock::new(|| Config::new(12, 4).expect("Failed to configure HeatshrinkW11L4 decoder"));
20
21#[derive(Debug)]
23pub enum DecompressError {
24 None,
26 Deflate,
28 HeatShrink11,
30 HeatShrink12,
32 MeatPackAlgorithm,
34}
35
36pub fn decompress_data_block<'a>(
47 data: &'a [u8],
48 encoding: &Encoding,
49 header: &BlockHeader,
50) -> IResult<&'a [u8], Vec<u8>, DecompressError> {
51 let (after_data, data) = match header.compression_type {
53 CompressionType::None => {
54 let (remain, data_raw) = take(header.uncompressed_size)(data)
55 .map_err(|e| e.map(|_e: nom::error::Error<_>| DecompressError::None))?;
56 (remain, data_raw.to_vec())
57 }
58 CompressionType::Deflate => {
59 let (remain, encoded) = take(header.compressed_size.unwrap())(data)
60 .map_err(|e| e.map(|_e: nom::error::Error<_>| DecompressError::Deflate))?;
61
62 match inflate_bytes_zlib(encoded) {
63 Ok(decoded) => (remain, decoded),
64 Err(msg) => {
65 log::error!("Failed to decode decompression failed {msg}");
66 return Err(Error(DecompressError::Deflate))?;
67 }
68 }
69 }
70 CompressionType::HeatShrink11 => {
71 let (_remain, _data_compressed) = take(header.uncompressed_size)(data)
72 .map_err(|e| e.map(|_e: nom::error::Error<_>| DecompressError::HeatShrink11))?;
73 log::info!("TODO: Must implement decompression");
75 todo!()
76 }
77 CompressionType::HeatShrink12 => {
78 let (remain, encoded) = take::<_, _, BlockError>(header.compressed_size.unwrap())(data)
79 .map_err(|e| e.map(|_e| DecompressError::HeatShrink12))?;
80
81 let mut scratch = vec![0u8; 1 + header.uncompressed_size as usize];
83
84 let data = match decode(encoded, &mut scratch, &CONFIG_W12_L4) {
85 Ok(decoded_hs) => match encoding {
86 Encoding::None => scratch,
87 Encoding::MeatPackAlgorithm => {
88 log::error!("Must decode with standard meat packing algorithm");
89 unimplemented!("Decoding with the meatpacking algorithm is not yet support please create an issue.");
90 }
91 Encoding::MeatPackModifiedAlgorithm => {
92 let mut data = vec![];
93 let mut unpacker = Unpacker::<64>::default();
94 for b in decoded_hs {
95 match unpacker.unpack(b) {
96 Ok(MeatPackResult::WaitingForNextByte) => {
97 }
99 Ok(MeatPackResult::Line(line)) => {
100 data.extend_from_slice(line);
101 }
102 Err(_e) => {
103 return Err(nom::Err::Error(
106 DecompressError::MeatPackAlgorithm,
107 ));
108 }
109 }
110 }
111 data
112 }
113 },
114 Err(_e) => {
115 return Err(nom::Err::Error(DecompressError::MeatPackAlgorithm));
118 }
119 };
120
121 (remain, data)
122 }
123 };
124
125 Ok((after_data, data))
126}