1use core::{marker::PhantomData, slice};
28
29use byteorder::{ByteOrder, BE, LE};
30
31use crate::pixelcolor::raw::{
32 BigEndian, LittleEndian, RawData, RawU1, RawU16, RawU2, RawU24, RawU32, RawU4, RawU8,
33};
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
44pub struct RawDataSlice<'a, R, BO> {
45 data: &'a [u8],
46 raw_type: PhantomData<R>,
47 byte_order: PhantomData<BO>,
48}
49
50impl<'a, R, BO> RawDataSlice<'a, R, BO> {
51 pub const fn new(data: &'a [u8]) -> Self {
53 Self {
54 data,
55 raw_type: PhantomData,
56 byte_order: PhantomData,
57 }
58 }
59}
60
61macro_rules! impl_bits_iterator {
62 ($type:ident, $bit_index_bits:expr) => {
63 impl<'a, BO> IntoIterator for RawDataSlice<'a, $type, BO> {
64 type Item = $type;
65 type IntoIter = BitsIterator<'a, $type>;
66
67 fn into_iter(self) -> Self::IntoIter {
68 BitsIterator::new(self.data)
69 }
70 }
71
72 impl<'a> Iterator for BitsIterator<'a, $type> {
73 type Item = $type;
74
75 #[inline]
76 fn next(&mut self) -> Option<Self::Item> {
77 self.data.get(self.index >> $bit_index_bits).map(|byte| {
78 let first_pixel_shift = 8 - $type::BITS_PER_PIXEL;
80
81 let sub_index = self.index & (1 << $bit_index_bits) - 1;
83
84 let shift = first_pixel_shift - (sub_index << 3 - $bit_index_bits);
86
87 self.index += 1;
88
89 $type::new(*byte >> shift)
90 })
91 }
92
93 #[inline]
94 fn nth(&mut self, n: usize) -> Option<Self::Item> {
95 self.index = self.index.saturating_add(n);
96 self.next()
97 }
98
99 fn size_hint(&self) -> (usize, Option<usize>) {
100 let size =
101 (self.data.len() * (8 / $type::BITS_PER_PIXEL)).saturating_sub(self.index);
102
103 (size, Some(size))
104 }
105 }
106 };
107}
108
109impl_bits_iterator!(RawU1, 3);
110impl_bits_iterator!(RawU2, 2);
111impl_bits_iterator!(RawU4, 1);
112
113impl<'a, BO> IntoIterator for RawDataSlice<'a, RawU8, BO> {
114 type Item = RawU8;
115 type IntoIter = ByteIterator<'a>;
116
117 fn into_iter(self) -> Self::IntoIter {
118 ByteIterator::new(self.data)
119 }
120}
121
122#[derive(Debug)]
128#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
129pub struct BitsIterator<'a, R> {
130 data: &'a [u8],
131 index: usize,
132 raw_type: PhantomData<R>,
133}
134
135impl<'a, R: RawData> BitsIterator<'a, R> {
136 const fn new(data: &'a [u8]) -> Self {
137 Self {
138 data,
139 index: 0,
140 raw_type: PhantomData,
141 }
142 }
143}
144
145#[derive(Debug)]
151#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
152pub struct ByteIterator<'a> {
153 data: slice::Iter<'a, u8>,
154}
155
156impl<'a> ByteIterator<'a> {
157 fn new(data: &'a [u8]) -> Self {
158 Self { data: data.iter() }
159 }
160}
161
162impl<'a> Iterator for ByteIterator<'a> {
163 type Item = RawU8;
164
165 #[inline]
166 fn next(&mut self) -> Option<Self::Item> {
167 self.data.next().copied().map(RawU8::new)
168 }
169
170 #[inline]
171 fn nth(&mut self, n: usize) -> Option<Self::Item> {
172 self.data.nth(n).copied().map(RawU8::new)
173 }
174
175 fn size_hint(&self) -> (usize, Option<usize>) {
176 self.data.size_hint()
177 }
178}
179
180#[derive(Debug)]
186#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
187pub struct BytesIterator<'a, R, BO> {
188 data: slice::ChunksExact<'a, u8>,
190 raw_type: PhantomData<R>,
191 byte_order: PhantomData<BO>,
192}
193
194impl<'a, R: RawData, BO> BytesIterator<'a, R, BO> {
195 fn new(data: &'a [u8]) -> Self {
196 Self {
197 data: data.chunks_exact(R::BITS_PER_PIXEL / 8),
198 raw_type: PhantomData,
199 byte_order: PhantomData,
200 }
201 }
202}
203
204macro_rules! impl_bytes_iterator {
205 ($type:ident, $byte_order:ident, $read_function:path) => {
206 impl<'a> Iterator for BytesIterator<'a, $type, $byte_order> {
207 type Item = $type;
208
209 #[inline]
210 fn next(&mut self) -> Option<Self::Item> {
211 self.data.next().map(|raw| $read_function(raw).into())
212 }
213
214 #[inline]
215 fn nth(&mut self, n: usize) -> Option<Self::Item> {
216 self.data.nth(n).map(|raw| $read_function(raw).into())
217 }
218
219 fn size_hint(&self) -> (usize, Option<usize>) {
220 self.data.size_hint()
221 }
222 }
223
224 impl<'a> IntoIterator for RawDataSlice<'a, $type, $byte_order> {
225 type Item = $type;
226 type IntoIter = BytesIterator<'a, $type, $byte_order>;
227
228 fn into_iter(self) -> Self::IntoIter {
229 BytesIterator::new(self.data)
230 }
231 }
232 };
233
234 ($type:ident, $read_function:ident) => {
235 impl_bytes_iterator!($type, LittleEndian, LE::$read_function);
236 impl_bytes_iterator!($type, BigEndian, BE::$read_function);
237 };
238}
239
240impl_bytes_iterator!(RawU16, read_u16);
241impl_bytes_iterator!(RawU24, read_u24);
242impl_bytes_iterator!(RawU32, read_u32);
243
244#[cfg(test)]
245mod tests {
246 use super::*;
247
248 const BITS_DATA: &[u8] = &[0x12, 0x48, 0x5A, 0x0F];
249 const BYTES_DATA_1: &[u8] = &[0x10, 0x20, 0x30, 0x40, 0x50, 0x60];
250 const BYTES_DATA_2: &[u8] = &[0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80];
251
252 #[test]
253 fn raw_u1() {
254 #[rustfmt::skip]
255 let expected = [
256 0, 0, 0, 1,
257 0, 0, 1, 0,
258 0, 1, 0, 0,
259 1, 0, 0, 0,
260 0, 1, 0, 1,
261 1, 0, 1, 0,
262 0, 0, 0, 0,
263 1, 1, 1, 1,
264 ]
265 .iter()
266 .copied()
267 .map(RawU1::new);
268
269 let iter = RawDataSlice::<RawU1, LittleEndian>::new(BITS_DATA).into_iter();
270 assert!(iter.eq(expected));
271 }
272
273 #[test]
274 fn raw_u2() {
275 let expected = [0, 1, 0, 2, 1, 0, 2, 0, 1, 1, 2, 2, 0, 0, 3, 3]
276 .iter()
277 .copied()
278 .map(RawU2::new);
279
280 let iter = RawDataSlice::<RawU2, LittleEndian>::new(BITS_DATA).into_iter();
281 assert!(iter.eq(expected));
282 }
283
284 #[test]
285 fn raw_u4() {
286 let expected = [0x1, 0x2, 0x4, 0x8, 0x5, 0xA, 0x0, 0xF]
287 .iter()
288 .copied()
289 .map(RawU4::new);
290
291 let iter = RawDataSlice::<RawU4, LittleEndian>::new(BITS_DATA).into_iter();
292 assert!(iter.eq(expected));
293 }
294
295 #[test]
296 fn raw_u8() {
297 let expected = BYTES_DATA_1.iter().map(|&v| RawU8::new(v));
298
299 let iter = RawDataSlice::<RawU8, LittleEndian>::new(BYTES_DATA_1).into_iter();
300 assert!(iter.eq(expected));
301 }
302
303 #[test]
304 fn raw_u16_le() {
305 let expected = [0x2010, 0x4030, 0x6050].iter().copied().map(RawU16::new);
306
307 let iter = RawDataSlice::<RawU16, LittleEndian>::new(BYTES_DATA_1).into_iter();
308 assert!(iter.eq(expected));
309 }
310
311 #[test]
312 fn raw_u16_be() {
313 let expected = [0x1020, 0x3040, 0x5060].iter().copied().map(RawU16::new);
314
315 let iter = RawDataSlice::<RawU16, BigEndian>::new(BYTES_DATA_1).into_iter();
316 assert!(iter.eq(expected));
317 }
318
319 #[test]
320 fn raw_u16_excess_bytes_are_ignored() {
321 let iter = RawDataSlice::<RawU16, LittleEndian>::new(&[0; 3]).into_iter();
322 assert_eq!(iter.count(), 1);
323 }
324
325 #[test]
326 fn raw_u24_le() {
327 let expected = [0x302010, 0x605040].iter().copied().map(RawU24::new);
328
329 let iter = RawDataSlice::<RawU24, LittleEndian>::new(BYTES_DATA_1).into_iter();
330 assert!(iter.into_iter().eq(expected));
331 }
332
333 #[test]
334 fn raw_u24_be() {
335 let expected = [0x102030, 0x405060].iter().copied().map(RawU24::new);
336
337 let iter = RawDataSlice::<RawU24, BigEndian>::new(BYTES_DATA_1).into_iter();
338 assert!(iter.into_iter().eq(expected));
339 }
340
341 #[test]
342 fn raw_u24_excess_bytes_are_ignored() {
343 let iter = RawDataSlice::<RawU24, LittleEndian>::new(&[0; 7]).into_iter();
344 assert_eq!(iter.count(), 2);
345 }
346
347 #[test]
348 fn raw_u32_le() {
349 let expected = [0x40302010, 0x80706050].iter().copied().map(RawU32::new);
350
351 let iter = RawDataSlice::<RawU32, LittleEndian>::new(BYTES_DATA_2).into_iter();
352 assert!(iter.into_iter().eq(expected));
353 }
354
355 #[test]
356 fn raw_u32_be() {
357 let expected = [0x10203040, 0x50607080].iter().copied().map(RawU32::new);
358
359 let iter = RawDataSlice::<RawU32, BigEndian>::new(BYTES_DATA_2).into_iter();
360 assert!(iter.into_iter().eq(expected));
361 }
362
363 #[test]
364 fn raw_u32_excess_bytes_are_ignored() {
365 let iter = RawDataSlice::<RawU32, LittleEndian>::new(&[0; 13]).into_iter();
366 assert_eq!(iter.count(), 3);
367 }
368}