Skip to main content

mlt_core/frames/v01/stream/
decode.rs

1use std::mem;
2
3use crate::codecs::bytes::{decode_bytes_to_bools, decode_bytes_to_u32s, decode_bytes_to_u64s};
4use crate::codecs::fastpfor::decode_fastpfor;
5use crate::codecs::rle::decode_byte_rle;
6use crate::codecs::varint::parse_varint_vec;
7use crate::errors::{AsMltError as _, fail_if_invalid_stream_size};
8use crate::utils::AsUsize as _;
9use crate::v01::{LogicalEncoding, LogicalValue, PhysicalEncoding, RawStream, RawStreamData};
10use crate::{Decoder, MltError, MltResult};
11
12impl RawStream<'_> {
13    /// Decode a boolean stream: byte-RLE → packed bitmap → `Vec<bool>`, charging `dec`.
14    pub fn decode_bools(self, dec: &mut Decoder) -> Result<Vec<bool>, MltError> {
15        let num_values = self.meta.num_values.as_usize();
16        let num_bytes = num_values.div_ceil(8);
17        let raw = match &self.data {
18            RawStreamData::Encoded(v) => v,
19            RawStreamData::VarInt(_) => {
20                return Err(MltError::NotImplemented("varint bool decoding"));
21            }
22        };
23        let decoded = decode_byte_rle(raw, num_bytes, dec)?;
24        decode_bytes_to_bools(&decoded, num_values, dec)
25    }
26
27    pub fn decode_i8s(self, dec: &mut Decoder) -> Result<Vec<i8>, MltError> {
28        self.decode_i32s(dec)?
29            .into_iter()
30            .map(i8::try_from)
31            .collect::<Result<Vec<_>, _>>()
32            .map_err(Into::into)
33    }
34
35    pub fn decode_u8s(self, dec: &mut Decoder) -> Result<Vec<u8>, MltError> {
36        self.decode_u32s(dec)?
37            .into_iter()
38            .map(u8::try_from)
39            .collect::<Result<Vec<u8>, _>>()
40            .map_err(Into::into)
41    }
42
43    pub fn decode_i32s(self, dec: &mut Decoder) -> Result<Vec<i32>, MltError> {
44        let meta = self.meta;
45        // i32 always needs a logical transform (zigzag at minimum) — use scratch buffer.
46        let mut buf = mem::take(&mut dec.buffer_u32);
47        self.decode_bits_u32(&mut buf, dec)?;
48        let result = LogicalValue::new(meta).decode_i32(&buf, dec);
49        dec.buffer_u32 = buf;
50        dec.buffer_u32.clear();
51        result
52    }
53
54    pub fn decode_u32s(self, dec: &mut Decoder) -> Result<Vec<u32>, MltError> {
55        let meta = self.meta;
56        if meta.encoding.logical == LogicalEncoding::None {
57            // No logical transform: physical words are the output — decode into a fresh Vec.
58            let mut out = Vec::new();
59            self.decode_bits_u32(&mut out, dec)?;
60            Ok(out)
61        } else {
62            // Logical transform needed — use the reusable scratch buffer.
63            let mut buf = mem::take(&mut dec.buffer_u32);
64            self.decode_bits_u32(&mut buf, dec)?;
65            let result = LogicalValue::new(meta).decode_u32(&buf, dec);
66            dec.buffer_u32 = buf;
67            dec.buffer_u32.clear();
68            result
69        }
70    }
71
72    pub fn decode_u64s(self, dec: &mut Decoder) -> Result<Vec<u64>, MltError> {
73        let meta = self.meta;
74        if meta.encoding.logical == LogicalEncoding::None {
75            // No logical transform: physical words are the output — decode into a fresh Vec.
76            let mut out = Vec::new();
77            self.decode_bits_u64(&mut out, dec)?;
78            Ok(out)
79        } else {
80            // Logical transform needed — use the reusable scratch buffer.
81            let mut buf = mem::take(&mut dec.buffer_u64);
82            self.decode_bits_u64(&mut buf, dec)?;
83            let result = LogicalValue::new(meta).decode_u64(&buf, dec);
84            dec.buffer_u64 = buf;
85            dec.buffer_u64.clear();
86            result
87        }
88    }
89
90    pub fn decode_i64s(self, dec: &mut Decoder) -> Result<Vec<i64>, MltError> {
91        let meta = self.meta;
92        // i64 always needs a logical transform (zigzag at minimum) — use scratch buffer.
93        let mut buf = mem::take(&mut dec.buffer_u64);
94        self.decode_bits_u64(&mut buf, dec)?;
95        let result = LogicalValue::new(meta).decode_i64(&buf, dec);
96        dec.buffer_u64 = buf;
97        dec.buffer_u64.clear();
98        result
99    }
100
101    /// Decode a stream of f32 values from raw little-endian bytes, charging `dec`.
102    pub fn decode_f32s(self, dec: &mut Decoder) -> Result<Vec<f32>, MltError> {
103        let num = self.meta.num_values.as_usize();
104        dec.consume_items::<f32>(num)?;
105        let raw = match &self.data {
106            RawStreamData::Encoded(v) => v,
107            RawStreamData::VarInt(_) => {
108                return Err(MltError::NotImplemented("varint f32 decoding"));
109            }
110        };
111        fail_if_invalid_stream_size(raw.len(), num.checked_mul(4).or_overflow()?)?;
112
113        Ok(raw
114            .chunks_exact(4)
115            .map(|chunk| f32::from_le_bytes(chunk.try_into().expect("infallible: chunks_exact(4)")))
116            .collect())
117    }
118
119    /// Decode a stream of f64 values from raw little-endian bytes, charging `dec`.
120    pub fn decode_f64s(self, dec: &mut Decoder) -> Result<Vec<f64>, MltError> {
121        let raw = match &self.data {
122            RawStreamData::Encoded(v) => v,
123            RawStreamData::VarInt(_) => {
124                return Err(MltError::NotImplemented("varint f64 decoding"));
125            }
126        };
127
128        let num = self.meta.num_values.as_usize();
129        fail_if_invalid_stream_size(raw.len(), num.checked_mul(8).or_overflow()?)?;
130
131        dec.consume_items::<f64>(num)?;
132        Ok(raw
133            .chunks_exact(8)
134            .map(|chunk| f64::from_le_bytes(chunk.try_into().expect("infallible: chunks_exact(8)")))
135            .collect())
136    }
137
138    /// Physically decode the stream into `buf` as `u32` values.
139    ///
140    /// `buf` is cleared and filled with the decoded words. The caller owns the
141    /// buffer and is responsible for deciding whether it constitutes a final
142    /// persistent allocation (and therefore should be charged to a [`Decoder`]).
143    pub fn decode_bits_u32(self, buf: &mut Vec<u32>, dec: &mut Decoder) -> MltResult<()> {
144        buf.clear();
145        match self.meta.encoding.physical {
146            PhysicalEncoding::VarInt => match &self.data {
147                RawStreamData::VarInt(v) => {
148                    let (_, values) = parse_varint_vec::<u32, u32>(v, self.meta.num_values, dec)?;
149                    *buf = values;
150                }
151                RawStreamData::Encoded(_) => {
152                    return Err(MltError::StreamDataMismatch("VarInt", "Encoded"));
153                }
154            },
155            PhysicalEncoding::None => match &self.data {
156                RawStreamData::Encoded(v) => {
157                    let (_, values) = decode_bytes_to_u32s(v, self.meta.num_values, dec)?;
158                    *buf = values;
159                }
160                RawStreamData::VarInt(_) => {
161                    return Err(MltError::StreamDataMismatch("Encoded", "VarInt"));
162                }
163            },
164            PhysicalEncoding::FastPFOR => match &self.data {
165                RawStreamData::Encoded(v) => {
166                    *buf = decode_fastpfor(v, self.meta.num_values, dec)?;
167                }
168                RawStreamData::VarInt(_) => {
169                    return Err(MltError::StreamDataMismatch("Encoded", "VarInt"));
170                }
171            },
172            PhysicalEncoding::Alp => return Err(MltError::UnsupportedPhysicalEncoding("ALP")),
173        }
174        Ok(())
175    }
176
177    /// Physically decode the stream into `buf` as `u64` values.
178    ///
179    /// `buf` is cleared and filled with the decoded words. The caller owns the
180    /// buffer and is responsible for deciding whether it constitutes a final
181    /// persistent allocation (and therefore should be charged to a [`Decoder`]).
182    pub fn decode_bits_u64(self, buf: &mut Vec<u64>, dec: &mut Decoder) -> MltResult<()> {
183        buf.clear();
184        match self.meta.encoding.physical {
185            PhysicalEncoding::VarInt => match &self.data {
186                RawStreamData::VarInt(v) => {
187                    let (_, values) = parse_varint_vec::<u64, u64>(v, self.meta.num_values, dec)?;
188                    *buf = values;
189                }
190                RawStreamData::Encoded(_) => {
191                    return Err(MltError::StreamDataMismatch("VarInt", "Encoded"));
192                }
193            },
194            PhysicalEncoding::None => match &self.data {
195                RawStreamData::Encoded(v) => {
196                    let (_, values) = decode_bytes_to_u64s(v, self.meta.num_values, dec)?;
197                    *buf = values;
198                }
199                RawStreamData::VarInt(_) => {
200                    return Err(MltError::StreamDataMismatch("Encoded", "VarInt"));
201                }
202            },
203            PhysicalEncoding::FastPFOR => {
204                return Err(MltError::UnsupportedPhysicalEncoding(
205                    "FastPFOR decoding u64",
206                ));
207            }
208            PhysicalEncoding::Alp => return Err(MltError::UnsupportedPhysicalEncoding("ALP")),
209        }
210        Ok(())
211    }
212}