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>> {
17 let expected_len = self.runs.into_usize().checked_mul(2).or_overflow()?;
18 fail_if_invalid_stream_size(data.len(), expected_len)?;
19
20 let (run_lens, values) = data.split_at(self.runs.into_usize());
21 fail_if_invalid_stream_size(
22 self.num_rle_values.into_usize(),
23 Self::calc_size(run_lens)?.into_usize(),
24 )?;
25
26 let alloc_size = self.num_rle_values.into_usize();
27 let mut result = dec.alloc(alloc_size)?;
28 for (&run_len, &val) in run_lens.iter().zip(values.iter()) {
29 let run = run_len
30 .to_usize()
31 .ok_or_else(|| RleRunLenInvalid(run_len.to_i128().unwrap_or_default()))?;
32 result.extend(repeat_n(val, run));
33 }
34 dec.adjust_alloc(&result, alloc_size)?;
35 Ok(result)
36 }
37
38 fn calc_size<T: PrimInt + Debug>(run_lens: &[T]) -> MltResult<u32> {
39 run_lens
40 .iter()
41 .try_fold(T::zero(), |a, v| a.checked_add(v))
42 .and_then(|v| v.to_u32())
43 .ok_or_else(|| RleRunLenInvalid(run_lens.len().to_i128().unwrap_or_default()))
44 }
45}
46
47impl LogicalTechnique {
48 pub fn parse(value: u8) -> MltResult<Self> {
49 Self::try_from(value).or(Err(ParsingLogicalTechnique(value)))
50 }
51}
52
53impl LogicalValue {
54 #[must_use]
55 pub fn new(meta: StreamMeta) -> Self {
56 Self { meta }
57 }
58
59 pub fn decode_i32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<i32>> {
64 match self.meta.encoding.logical {
65 LogicalEncoding::None => decode_zigzag(data, dec),
66 LogicalEncoding::Rle(v) => decode_zigzag(&v.decode(data, dec)?, dec),
67 LogicalEncoding::ComponentwiseDelta => decode_componentwise_delta_vec2s(data, dec),
68 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
69 LogicalEncoding::DeltaRle(v) => {
70 let expanded = v.decode(data, dec)?;
71 decode_zigzag_delta::<i32, _>(&expanded, dec)
72 }
73 LogicalEncoding::Morton(v) => v.decode_codes(data, dec),
74 LogicalEncoding::MortonDelta(v) => v.decode_delta(data, dec),
75 LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
76 self.meta.encoding.logical,
77 "i32 (MortonRle)",
78 )),
79 LogicalEncoding::PseudoDecimal => Err(UnsupportedLogicalEncoding(
80 self.meta.encoding.logical,
81 "i32",
82 )),
83 }
84 }
85
86 pub fn decode_u32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<u32>> {
91 let num = self.meta.num_values.into_usize();
92 match self.meta.encoding.logical {
93 LogicalEncoding::None => {
94 dec.consume_items::<u32>(num)?;
96 Ok(data.to_vec())
97 }
98 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
99 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
100 LogicalEncoding::DeltaRle(rle) => {
101 decode_zigzag_delta::<i32, _>(&rle.decode(data, dec)?, dec)
102 }
103 _ => Err(UnsupportedLogicalEncoding(
104 self.meta.encoding.logical,
105 "u32",
106 )),
107 }
108 }
109
110 pub fn decode_i64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<i64>> {
115 match self.meta.encoding.logical {
116 LogicalEncoding::None => decode_zigzag(data, dec),
117 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
118 LogicalEncoding::DeltaRle(rle) => {
119 let expanded = rle.decode(data, dec)?;
120 decode_zigzag_delta::<i64, _>(&expanded, dec)
121 }
122 LogicalEncoding::Rle(rle) => {
123 let expanded = rle.decode(data, dec)?;
125 decode_zigzag(&expanded, dec)
126 }
127 _ => Err(UnsupportedLogicalEncoding(
128 self.meta.encoding.logical,
129 "i64",
130 )),
131 }
132 }
133
134 pub fn decode_u64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<u64>> {
139 let num = self.meta.num_values.into_usize();
140 match self.meta.encoding.logical {
141 LogicalEncoding::None => {
142 dec.consume_items::<u64>(num)?;
144 Ok(data.to_vec())
145 }
146 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
147 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
148 LogicalEncoding::DeltaRle(rle) => {
149 let expanded = rle.decode(data, dec)?;
150 decode_zigzag_delta::<i64, _>(&expanded, dec)
151 }
152 _ => Err(UnsupportedLogicalEncoding(
153 self.meta.encoding.logical,
154 "u64",
155 )),
156 }
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163 use crate::MltError::InvalidDecodingStreamSize;
164 use crate::test_helpers::dec;
165
166 #[test]
167 fn test_decode_rle_empty() {
168 let rle = RleMeta {
169 runs: 0,
170 num_rle_values: 0,
171 };
172 assert_eq!(rle.decode::<u32>(&[], &mut dec()).unwrap(), [] as [u32; 0]);
173 }
174
175 #[test]
176 fn test_decode_rle_invalid_stream_size() {
177 let rle = RleMeta {
179 runs: 2,
180 num_rle_values: 3,
181 };
182 let data = [1u32, 2, 3];
183 let err = rle.decode::<u32>(&data, &mut dec()).unwrap_err();
184 assert!(matches!(err, InvalidDecodingStreamSize(3, 4)));
185 }
186}