Decompress interleaved rANS data.
(data: &[u8])
| 125 | |
| 126 | /// Decompress interleaved rANS data. |
| 127 | pub fn decode(data: &[u8]) -> Result<Vec<u8>, CodecError> { |
| 128 | if data.len() < HEADER_SIZE { |
| 129 | return Err(CodecError::Truncated { |
| 130 | expected: HEADER_SIZE, |
| 131 | actual: data.len(), |
| 132 | }); |
| 133 | } |
| 134 | |
| 135 | let uncompressed_size = u32::from_le_bytes([data[0], data[1], data[2], data[3]]) as usize; |
| 136 | if uncompressed_size == 0 { |
| 137 | return Ok(Vec::new()); |
| 138 | } |
| 139 | |
| 140 | // Read frequency table. |
| 141 | let mut norm_freqs = [0u32; 256]; |
| 142 | for (i, freq) in norm_freqs.iter_mut().enumerate() { |
| 143 | let pos = 4 + i * 4; |
| 144 | *freq = u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]); |
| 145 | } |
| 146 | |
| 147 | let (cum_freqs, sym_freqs) = build_cum_table(&norm_freqs); |
| 148 | |
| 149 | // Build reverse lookup table for decoding. |
| 150 | let lookup = build_decode_table(&cum_freqs, &sym_freqs); |
| 151 | |
| 152 | let _comp_size = u32::from_le_bytes([ |
| 153 | data[HEADER_SIZE - 4], |
| 154 | data[HEADER_SIZE - 3], |
| 155 | data[HEADER_SIZE - 2], |
| 156 | data[HEADER_SIZE - 1], |
| 157 | ]) as usize; |
| 158 | |
| 159 | // Read per-stream sizes. |
| 160 | let mut pos = HEADER_SIZE; |
| 161 | if pos + NUM_STREAMS * 4 > data.len() { |
| 162 | return Err(CodecError::Truncated { |
| 163 | expected: pos + NUM_STREAMS * 4, |
| 164 | actual: data.len(), |
| 165 | }); |
| 166 | } |
| 167 | |
| 168 | let mut stream_sizes = [0usize; NUM_STREAMS]; |
| 169 | for size in stream_sizes.iter_mut() { |
| 170 | *size = |
| 171 | u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize; |
| 172 | pos += 4; |
| 173 | } |
| 174 | |
| 175 | // Read streams. |
| 176 | let mut stream_data: [Vec<u8>; NUM_STREAMS] = std::array::from_fn(|_| Vec::new()); |
| 177 | for i in 0..NUM_STREAMS { |
| 178 | let end = pos + stream_sizes[i]; |
| 179 | if end > data.len() { |
| 180 | return Err(CodecError::Truncated { |
| 181 | expected: end, |
| 182 | actual: data.len(), |
| 183 | }); |
| 184 | } |