1use std::fmt::Debug;
2use std::iter::repeat_n;
3
4use num_traits::{PrimInt, ToPrimitive as _};
5use usize_cast::IntoUsize as _;
6
7use crate::MltError::{ParsingLogicalTechnique, RleRunLenInvalid, UnsupportedLogicalEncoding};
8use crate::codecs::zigzag::{decode_componentwise_delta_vec2s, decode_zigzag, decode_zigzag_delta};
9use crate::decoder::{LogicalEncoding, LogicalTechnique, LogicalValue, RleMeta, StreamMeta};
10use crate::errors::{AsMltError as _, fail_if_invalid_stream_size};
11use crate::{Decoder, MltResult};
12
13impl RleMeta {
14 pub fn decode<T: PrimInt + Debug>(self, data: &[T], dec: &mut Decoder) -> MltResult<Vec<T>> {
32 match self {
33 Self::Split {
34 runs,
35 num_rle_values,
36 } => Self::decode_split(runs, num_rle_values, data, dec),
37 #[cfg(feature = "unstable-v2")]
38 Self::Interleaved { num_rle_values } => {
39 Self::decode_interleaved(num_rle_values, data, dec)
40 }
41 }
42 }
43
44 fn decode_split<T: PrimInt + Debug>(
46 runs: u32,
47 num_rle_values: u32,
48 data: &[T],
49 dec: &mut Decoder,
50 ) -> MltResult<Vec<T>> {
51 let expected_len = runs.into_usize().checked_mul(2).or_overflow()?;
52 fail_if_invalid_stream_size(data.len(), expected_len)?;
53
54 let (run_lens, values) = data.split_at(runs.into_usize());
55 fail_if_invalid_stream_size(
56 num_rle_values.into_usize(),
57 Self::calc_size(run_lens)?.into_usize(),
58 )?;
59
60 let alloc_size = num_rle_values.into_usize();
61 let mut result = dec.alloc(alloc_size)?;
62 for (&run_len, &val) in run_lens.iter().zip(values.iter()) {
63 let run = run_len
64 .to_usize()
65 .ok_or_else(|| RleRunLenInvalid(run_len.to_i128().unwrap_or_default()))?;
66 result.extend(repeat_n(val, run));
67 }
68 dec.adjust_alloc(&result, alloc_size)?;
69 Ok(result)
70 }
71
72 #[cfg(feature = "unstable-v2")]
75 fn decode_interleaved<T: PrimInt + Debug>(
76 num_rle_values: u32,
77 data: &[T],
78 dec: &mut Decoder,
79 ) -> MltResult<Vec<T>> {
80 if !data.len().is_multiple_of(2) {
81 return Err(RleRunLenInvalid(data.len().to_i128().unwrap_or_default()));
82 }
83 let alloc_size = num_rle_values.into_usize();
84 let mut result = dec.alloc(alloc_size)?;
85 for [cnt, val] in data.as_chunks::<2>().0 {
86 let run = cnt
87 .to_usize()
88 .filter(|&run| run <= alloc_size - result.len())
89 .ok_or_else(|| RleRunLenInvalid(cnt.to_i128().unwrap_or_default()))?;
90 result.extend(repeat_n(val, run));
91 }
92 fail_if_invalid_stream_size(result.len(), alloc_size)?;
94 dec.adjust_alloc(&result, alloc_size)?;
95 Ok(result)
96 }
97
98 fn calc_size<T: PrimInt + Debug>(run_lens: &[T]) -> MltResult<u32> {
99 run_lens
100 .iter()
101 .try_fold(T::zero(), |a, v| a.checked_add(v))
102 .and_then(|v| v.to_u32())
103 .ok_or_else(|| RleRunLenInvalid(run_lens.len().to_i128().unwrap_or_default()))
104 }
105}
106
107impl LogicalTechnique {
108 pub fn parse(value: u8) -> MltResult<Self> {
109 Self::try_from(value).or(Err(ParsingLogicalTechnique(value)))
110 }
111}
112
113impl LogicalValue {
114 #[must_use]
115 pub fn new(meta: StreamMeta) -> Self {
116 Self { meta }
117 }
118
119 pub fn decode_i32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<i32>> {
124 match self.meta.encoding.logical {
125 LogicalEncoding::None => decode_zigzag(data, dec),
126 LogicalEncoding::Rle(v) => decode_zigzag(&v.decode(data, dec)?, dec),
127 LogicalEncoding::ComponentwiseDelta => decode_componentwise_delta_vec2s(data, dec),
128 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
129 LogicalEncoding::DeltaRle(v) => {
130 let expanded = v.decode(data, dec)?;
131 decode_zigzag_delta::<i32, _>(&expanded, dec)
132 }
133 LogicalEncoding::Morton(v) => v.decode_codes(data, dec),
134 LogicalEncoding::MortonDelta(v) => v.decode_delta(data, dec),
135 LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
136 self.meta.encoding.logical,
137 "i32 (MortonRle)",
138 )),
139 LogicalEncoding::PseudoDecimal => Err(UnsupportedLogicalEncoding(
140 self.meta.encoding.logical,
141 "i32",
142 )),
143 }
144 }
145
146 pub fn decode_u32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<u32>> {
151 let num = self.meta.num_values.into_usize();
152 match self.meta.encoding.logical {
153 LogicalEncoding::None => {
154 dec.consume_items::<u32>(num)?;
156 Ok(data.to_vec())
157 }
158 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
159 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
160 LogicalEncoding::DeltaRle(rle) => {
161 decode_zigzag_delta::<i32, _>(&rle.decode(data, dec)?, dec)
162 }
163 _ => Err(UnsupportedLogicalEncoding(
164 self.meta.encoding.logical,
165 "u32",
166 )),
167 }
168 }
169
170 pub fn decode_i64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<i64>> {
175 match self.meta.encoding.logical {
176 LogicalEncoding::None => decode_zigzag(data, dec),
177 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
178 LogicalEncoding::DeltaRle(rle) => {
179 let expanded = rle.decode(data, dec)?;
180 decode_zigzag_delta::<i64, _>(&expanded, dec)
181 }
182 LogicalEncoding::Rle(rle) => {
183 let expanded = rle.decode(data, dec)?;
185 decode_zigzag(&expanded, dec)
186 }
187 _ => Err(UnsupportedLogicalEncoding(
188 self.meta.encoding.logical,
189 "i64",
190 )),
191 }
192 }
193
194 pub fn decode_u64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<u64>> {
199 let num = self.meta.num_values.into_usize();
200 match self.meta.encoding.logical {
201 LogicalEncoding::None => {
202 dec.consume_items::<u64>(num)?;
204 Ok(data.to_vec())
205 }
206 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
207 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
208 LogicalEncoding::DeltaRle(rle) => {
209 let expanded = rle.decode(data, dec)?;
210 decode_zigzag_delta::<i64, _>(&expanded, dec)
211 }
212 _ => Err(UnsupportedLogicalEncoding(
213 self.meta.encoding.logical,
214 "u64",
215 )),
216 }
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223 use crate::MltError::InvalidDecodingStreamSize;
224 use crate::test_helpers::dec;
225
226 #[test]
227 fn test_decode_rle_empty() {
228 let rle = RleMeta::Split {
229 runs: 0,
230 num_rle_values: 0,
231 };
232 assert_eq!(rle.decode::<u32>(&[], &mut dec()).unwrap(), [] as [u32; 0]);
233 }
234
235 #[test]
236 fn test_decode_rle_invalid_stream_size() {
237 let rle = RleMeta::Split {
239 runs: 2,
240 num_rle_values: 3,
241 };
242 let data = [1u32, 2, 3];
243 let err = rle.decode::<u32>(&data, &mut dec()).unwrap_err();
244 assert!(matches!(err, InvalidDecodingStreamSize(3, 4)));
245 }
246
247 #[cfg(feature = "unstable-v2")]
248 #[test]
249 fn test_decode_rle_interleaved() {
250 let rle = RleMeta::Interleaved { num_rle_values: 6 };
251 let data = [3u32, 7, 1, 9, 2, 7];
253 let decoded = rle.decode(&data, &mut dec()).unwrap();
254 assert_eq!(decoded, vec![7, 7, 7, 9, 7, 7]);
255 }
256
257 #[cfg(feature = "unstable-v2")]
258 #[test]
259 fn test_decode_rle_interleaved_empty() {
260 let rle = RleMeta::Interleaved { num_rle_values: 0 };
261 assert!(rle.decode::<u32>(&[], &mut dec()).unwrap().is_empty());
262 }
263
264 #[cfg(feature = "unstable-v2")]
265 #[test]
266 fn test_decode_rle_interleaved_count_mismatch() {
267 let rle = RleMeta::Interleaved { num_rle_values: 5 };
269 let data = [3u32, 7, 1, 9];
270 assert!(rle.decode(&data, &mut dec()).is_err());
271 }
272
273 #[cfg(feature = "unstable-v2")]
274 #[test]
275 fn test_decode_rle_interleaved_odd_length() {
276 let rle = RleMeta::Interleaved { num_rle_values: 3 };
277 let data = [3u32, 7, 1];
278 assert!(rle.decode(&data, &mut dec()).is_err());
279 }
280
281 #[cfg(feature = "unstable-v2")]
282 #[test]
283 fn test_decode_rle_interleaved_overflowing_run() {
284 let rle = RleMeta::Interleaved { num_rle_values: 2 };
286 let data = [u32::MAX, 7];
287 assert!(rle.decode(&data, &mut dec()).is_err());
288 }
289}