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 }
140 }
141
142 pub fn decode_u32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<u32>> {
147 let num = self.meta.num_values.into_usize();
148 match self.meta.encoding.logical {
149 LogicalEncoding::None => {
150 dec.consume_items::<u32>(num)?;
152 Ok(data.to_vec())
153 }
154 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
155 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
156 LogicalEncoding::DeltaRle(rle) => {
157 decode_zigzag_delta::<i32, _>(&rle.decode(data, dec)?, dec)
158 }
159 LogicalEncoding::ComponentwiseDelta
160 | LogicalEncoding::Morton(_)
161 | LogicalEncoding::MortonDelta(_)
162 | LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
163 self.meta.encoding.logical,
164 "u32",
165 )),
166 }
167 }
168
169 pub fn decode_i64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<i64>> {
174 match self.meta.encoding.logical {
175 LogicalEncoding::None => decode_zigzag(data, dec),
176 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
177 LogicalEncoding::DeltaRle(rle) => {
178 let expanded = rle.decode(data, dec)?;
179 decode_zigzag_delta::<i64, _>(&expanded, dec)
180 }
181 LogicalEncoding::Rle(rle) => {
182 let expanded = rle.decode(data, dec)?;
184 decode_zigzag(&expanded, dec)
185 }
186 LogicalEncoding::ComponentwiseDelta
187 | LogicalEncoding::Morton(_)
188 | LogicalEncoding::MortonDelta(_)
189 | LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
190 self.meta.encoding.logical,
191 "i64",
192 )),
193 }
194 }
195
196 pub fn decode_u64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<u64>> {
201 let num = self.meta.num_values.into_usize();
202 match self.meta.encoding.logical {
203 LogicalEncoding::None => {
204 dec.consume_items::<u64>(num)?;
206 Ok(data.to_vec())
207 }
208 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
209 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
210 LogicalEncoding::DeltaRle(rle) => {
211 let expanded = rle.decode(data, dec)?;
212 decode_zigzag_delta::<i64, _>(&expanded, dec)
213 }
214 LogicalEncoding::ComponentwiseDelta
215 | LogicalEncoding::Morton(_)
216 | LogicalEncoding::MortonDelta(_)
217 | LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
218 self.meta.encoding.logical,
219 "u64",
220 )),
221 }
222 }
223}
224
225#[cfg(test)]
226mod tests {
227 use super::*;
228 use crate::MltError::InvalidDecodingStreamSize;
229 use crate::test_helpers::dec;
230
231 #[test]
232 fn test_decode_rle_empty() {
233 let rle = RleMeta::Split {
234 runs: 0,
235 num_rle_values: 0,
236 };
237 assert_eq!(rle.decode::<u32>(&[], &mut dec()).unwrap(), [] as [u32; 0]);
238 }
239
240 #[test]
241 fn test_decode_rle_invalid_stream_size() {
242 let rle = RleMeta::Split {
244 runs: 2,
245 num_rle_values: 3,
246 };
247 let data = [1u32, 2, 3];
248 let err = rle.decode::<u32>(&data, &mut dec()).unwrap_err();
249 assert!(matches!(err, InvalidDecodingStreamSize(3, 4)));
250 }
251
252 #[cfg(feature = "unstable-v2")]
253 #[test]
254 fn test_decode_rle_interleaved() {
255 let rle = RleMeta::Interleaved { num_rle_values: 6 };
256 let data = [3u32, 7, 1, 9, 2, 7];
258 let decoded = rle.decode(&data, &mut dec()).unwrap();
259 assert_eq!(decoded, vec![7, 7, 7, 9, 7, 7]);
260 }
261
262 #[cfg(feature = "unstable-v2")]
263 #[test]
264 fn test_decode_rle_interleaved_empty() {
265 let rle = RleMeta::Interleaved { num_rle_values: 0 };
266 assert!(rle.decode::<u32>(&[], &mut dec()).unwrap().is_empty());
267 }
268
269 #[cfg(feature = "unstable-v2")]
270 #[test]
271 fn test_decode_rle_interleaved_count_mismatch() {
272 let rle = RleMeta::Interleaved { num_rle_values: 5 };
274 let data = [3u32, 7, 1, 9];
275 assert!(rle.decode(&data, &mut dec()).is_err());
276 }
277
278 #[cfg(feature = "unstable-v2")]
279 #[test]
280 fn test_decode_rle_interleaved_odd_length() {
281 let rle = RleMeta::Interleaved { num_rle_values: 3 };
282 let data = [3u32, 7, 1];
283 assert!(rle.decode(&data, &mut dec()).is_err());
284 }
285
286 #[cfg(feature = "unstable-v2")]
287 #[test]
288 fn test_decode_rle_interleaved_overflowing_run() {
289 let rle = RleMeta::Interleaved { num_rle_values: 2 };
291 let data = [u32::MAX, 7];
292 assert!(rle.decode(&data, &mut dec()).is_err());
293 }
294}