1use crate::ParsedPng;
2use crate::types::PixelType;
3use core::marker::PhantomData;
4use embedded_graphics_core::pixelcolor::{BinaryColor, Gray2, Gray4, Gray8, Rgb888};
5use embedded_graphics_core::prelude::PixelColor;
6
7pub trait AlphaHandler<C>: Clone {}
20pub trait ReturnC {}
21
22#[derive(Clone)]
23pub struct IgnoreAlpha;
24impl<C> AlphaHandler<C> for IgnoreAlpha {}
25impl ReturnC for IgnoreAlpha {}
26
27#[derive(Clone)]
29pub struct AlphaColor;
30impl<C> AlphaHandler<C> for AlphaColor {}
31impl ReturnC for AlphaColor {}
32
33#[derive(Clone)]
34pub struct WithBackground<C>(C);
35impl<C: PixelColor> AlphaHandler<C> for WithBackground<C> {}
36impl<C> ReturnC for WithBackground<C> {}
37
38#[derive(Clone)]
39pub struct DontDraw;
40impl<C> AlphaHandler<C> for DontDraw {}
41
42pub struct PixelsIterator<'a, Color, Handler> {
43 pixel_type: PixelType<'a>,
44 palette: Option<&'a [u8]>,
45 scanline: &'a [u8],
46 pos: usize,
47 max_pos: usize, handler: Handler,
49 _phantom: PhantomData<Color>,
50}
51
52#[inline]
53fn tnt(reference: u8, value: u8) -> u8 {
55 if reference == value { 0 } else { 255 }
56}
57
58#[inline]
59fn tpal(palette: &[u8], value: u8) -> u8 {
61 match palette.get(value as usize) {
62 None => 255,
63 Some(v) => *v,
64 }
65}
66
67#[inline]
68fn tntr(reference: &[u8], value: &[u8]) -> u8 {
70 if reference == value { 0 } else { 255 }
71}
72
73impl<'a, Color, Handler: AlphaHandler<Color>> PixelsIterator<'a, Color, Handler> {
74 pub fn new(png: &ParsedPng<'a, Handler>, scanline: &'a [u8]) -> Self {
75 PixelsIterator {
76 pixel_type: png.pixel_type,
77 palette: png.palette,
78 scanline,
79 pos: 0,
80 max_pos: scanline.len(),
81 handler: png.alpha_handler.clone(),
82 _phantom: PhantomData,
83 }
84 }
85
86 #[inline]
87 fn bits<const N: usize>(&mut self) -> u8 {
88 let s = 8 / N;
89 let byte = self.scanline[self.pos / s];
90 let rshift = self.pos % s;
91 let bits = (byte >> ((s - 1 - rshift) * N)) & (0xFF >> (s - 1) * N);
92 self.pos += 1;
93 bits
94 }
95
96 #[inline]
97 fn bytes<const N: usize>(&mut self) -> [u8; N] {
98 let mut res = [0_u8; N];
99 for (i, item) in res.iter_mut().enumerate().take(N) {
100 *item = self.scanline[self.pos + i];
101 }
102 self.pos += N;
103 res
104 }
105
106 #[inline]
107 fn words<const N: usize>(&mut self) -> [u8; N] {
108 let mut res = [0_u8; N];
111 for (i, item) in res.iter_mut().enumerate().take(N) {
112 *item = self.scanline[self.pos + 2 * i]; }
114 self.pos += 2 * N;
115 res
116 }
117
118 fn next_opaque(&mut self) -> Color
119 where
120 BinaryColor: Into<Color>,
121 Gray2: Into<Color>,
122 Gray4: Into<Color>,
123 Gray8: Into<Color>,
124 Rgb888: Into<Color>,
125 {
126 match self.pixel_type {
127 PixelType::Grayscale1 => {
128 let bit = self.bits::<1>();
129 if bit != 0 {
130 BinaryColor::On
131 } else {
132 BinaryColor::Off
133 }
134 .into() }
136 PixelType::Grayscale2 => {
137 let bits = self.bits::<2>();
138 Gray2::new(bits >> 6).into()
139 }
140 PixelType::Grayscale4 => {
141 let bits = self.bits::<2>();
142 Gray4::new(bits >> 4).into()
143 }
144 PixelType::Grayscale8 => {
145 let byte = self.bytes::<1>();
146 Gray8::new(byte[0]).into()
147 }
148 PixelType::Grayscale16 => {
149 let byte = self.words::<1>();
150 Gray8::new(byte[0]).into()
151 }
152 PixelType::Palette1(palette) => {
153 let bit = self.bits::<1>();
154 get_rgb_from_palette(palette, bit >> 7).into()
155 }
156 PixelType::Palette2(palette) => {
157 let bits = self.bits::<2>();
158 get_rgb_from_palette(palette, bits >> 6).into()
159 }
160 PixelType::Palette4(palette) => {
161 let bits = self.bits::<4>();
162 get_rgb_from_palette(palette, bits >> 4).into()
163 }
164 PixelType::Palette8(palette) => {
165 let byte = self.bytes::<1>();
166 get_rgb_from_palette(palette, byte[0]).into()
167 }
168 PixelType::Rgb8 => {
169 let bytes = self.bytes::<3>();
170 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
171 }
172 PixelType::Rgb16 => {
173 let bytes = self.words::<3>();
174 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
175 }
176 _ => unreachable!(),
177 }
178 }
179
180 fn next_skip_alpha(&mut self) -> Color
182 where
183 BinaryColor: Into<Color>,
184 Gray2: Into<Color>,
185 Gray4: Into<Color>,
186 Gray8: Into<Color>,
187 Rgb888: Into<Color>,
188 {
189 match self.pixel_type {
190 PixelType::Grayscale1Transparent(_) => {
191 let bit = self.bits::<1>();
192 if bit != 0 {
193 BinaryColor::On
194 } else {
195 BinaryColor::Off
196 }
197 .into()
198 }
199 PixelType::Grayscale2Transparent(_) => {
200 let bits = self.bits::<2>();
201 Gray2::new(bits >> 6).into()
202 }
203 PixelType::Grayscale4Transparent(_) => {
204 let bits = self.bits::<2>();
205 Gray4::new(bits >> 4).into()
206 }
207 PixelType::Grayscale8Transparent(_) => {
208 let byte = self.bytes::<1>();
209 Gray8::new(byte[0]).into()
210 }
211 PixelType::Grayscale16Transparent(_) => {
212 let byte = self.words::<1>();
213 Gray8::new(byte[0]).into()
214 }
215 PixelType::Palette1Transparent(palette, _) => {
216 let bit = self.bits::<1>();
217 get_rgb_from_palette(palette, bit >> 7).into()
218 }
219 PixelType::Palette2Transparent(palette, _) => {
220 let bits = self.bits::<2>();
221 get_rgb_from_palette(palette, bits >> 6).into()
222 }
223 PixelType::Palette4Transparent(palette, _) => {
224 let bits = self.bits::<4>();
225 get_rgb_from_palette(palette, bits >> 4).into()
226 }
227 PixelType::Palette8Transparent(palette, _) => {
228 let byte = self.bytes::<1>();
229 get_rgb_from_palette(palette, byte[0]).into()
230 }
231 PixelType::Rgb8Transparent(_) => {
232 let bytes = self.bytes::<3>();
233 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
234 }
235 PixelType::Rgb16Transparent(_) => {
236 let bytes = self.words::<3>();
237 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
238 }
239 PixelType::GrayscaleAlpha8 => {
240 let bytes = self.bytes::<2>();
241 Gray8::new(bytes[0]).into()
242 }
243 PixelType::GrayscaleAlpha16 => {
244 let byte = self.words::<2>();
245 Gray8::new(byte[0]).into()
246 }
247 PixelType::RgbAlpha8 => {
248 let bytes = self.bytes::<4>();
249 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
250 }
251 PixelType::RgbAlpha16 => {
252 let bytes = self.words::<4>();
253 Rgb888::new(bytes[0], bytes[1], bytes[2]).into()
254 }
255 _ => self.next_opaque(),
256 }
257 }
258
259 fn next_keep_alpha(&mut self) -> (u8, Color)
260 where
261 BinaryColor: Into<Color>,
262 Gray2: Into<Color>,
263 Gray4: Into<Color>,
264 Gray8: Into<Color>,
265 Rgb888: Into<Color>,
266 {
267 match self.pixel_type {
268 PixelType::Grayscale1Transparent(t) => {
269 let bit = self.bits::<1>();
270 (
271 tnt(t, bit),
272 if bit != 0 {
273 BinaryColor::On
274 } else {
275 BinaryColor::Off
276 }
277 .into(),
278 )
279 }
280 PixelType::Grayscale2Transparent(t) => {
281 let bits = self.bits::<2>();
282 (tnt(t, bits), Gray2::new(bits >> 6).into())
283 }
284 PixelType::Grayscale4Transparent(t) => {
285 let bits = self.bits::<2>();
286 (tnt(t, bits), Gray4::new(bits >> 4).into())
287 }
288 PixelType::Grayscale8Transparent(t) => {
289 let byte = self.bytes::<1>();
290 (tnt(t, byte[0]), Gray8::new(byte[0]).into())
291 }
292 PixelType::Grayscale16Transparent(t) => {
293 let byte = self.words::<1>();
294 (tnt((t >> 8) as u8, byte[0]), Gray8::new(byte[0]).into())
295 }
296 PixelType::Palette1Transparent(palette, p) => {
297 let bit = self.bits::<1>();
298 (tpal(p, bit), get_rgb_from_palette(palette, bit >> 7).into())
299 }
300 PixelType::Palette2Transparent(palette, p) => {
301 let bits = self.bits::<2>();
302 (
303 tpal(p, bits),
304 get_rgb_from_palette(palette, bits >> 6).into(),
305 )
306 }
307 PixelType::Palette4Transparent(palette, p) => {
308 let bits = self.bits::<4>();
309 (
310 tpal(p, bits),
311 get_rgb_from_palette(palette, bits >> 4).into(),
312 )
313 }
314 PixelType::Palette8Transparent(palette, p) => {
315 let byte = self.bytes::<1>();
316 (
317 tpal(p, byte[0]),
318 get_rgb_from_palette(palette, byte[0]).into(),
319 )
320 }
321 PixelType::Rgb8Transparent(t) => {
322 let bytes = self.bytes::<3>();
323 (
324 tntr(&t, &bytes),
325 Rgb888::new(bytes[0], bytes[1], bytes[2]).into(),
326 )
327 }
328 PixelType::Rgb16Transparent(t) => {
329 let bytes = self.words::<3>();
330 (
331 tntr(&t, &bytes),
332 Rgb888::new(bytes[0], bytes[1], bytes[2]).into(),
333 )
334 }
335 PixelType::GrayscaleAlpha8 => {
336 let bytes = self.bytes::<2>();
337 (bytes[1], Gray8::new(bytes[0]).into())
338 }
339 PixelType::GrayscaleAlpha16 => {
340 let bytes = self.words::<2>();
341 (bytes[1], Gray8::new(bytes[0]).into())
342 }
343 PixelType::RgbAlpha8 => {
344 let bytes = self.bytes::<4>();
345 (bytes[3], Rgb888::new(bytes[0], bytes[1], bytes[2]).into())
346 }
347 PixelType::RgbAlpha16 => {
348 let bytes = self.words::<4>();
349 (bytes[3], Rgb888::new(bytes[0], bytes[1], bytes[2]).into())
350 }
351 _ => (0xFF, self.next_opaque()),
352 }
353 }
354
355 fn next_alpha_color(&mut self) -> Color
356 where
357 BinaryColor: Into<Color>,
358 Gray2: Into<Color>,
359 Gray4: Into<Color>,
360 Gray8: Into<Color>,
361 Rgb888: Into<Color>,
362 {
364 match self.pixel_type {
365 PixelType::Grayscale1Transparent(t) => {
366 let bit = self.bits::<1>();
367 todo!()
368 }
369 PixelType::Grayscale2Transparent(t) => {
370 let bits = self.bits::<2>();
371 todo!()
372 }
373 PixelType::Grayscale4Transparent(t) => {
374 let bits = self.bits::<2>();
375 todo!()
376 }
377 PixelType::Grayscale8Transparent(t) => {
378 let byte = self.bytes::<1>();
379 todo!()
380 }
381 PixelType::Grayscale16Transparent(t) => {
382 let byte = self.words::<1>();
383 todo!()
384 }
385 PixelType::Palette1Transparent(palette, p) => {
386 let bit = self.bits::<1>();
387 todo!()
388 }
389 PixelType::Palette2Transparent(palette, p) => {
390 let bits = self.bits::<2>();
391 todo!()
392 }
393 PixelType::Palette4Transparent(palette, p) => {
394 let bits = self.bits::<4>();
395 todo!()
396 }
397 PixelType::Palette8Transparent(palette, p) => {
398 let byte = self.bytes::<1>();
399 todo!()
400 }
401 PixelType::Rgb8Transparent(t) => {
402 let bytes = self.bytes::<3>();
403 todo!()
405 }
406 PixelType::Rgb16Transparent(t) => {
407 let bytes = self.words::<3>();
408 todo!()
410 }
411 PixelType::GrayscaleAlpha8 => {
412 let bytes = self.bytes::<2>();
413 todo!()
414 }
415 PixelType::GrayscaleAlpha16 => {
416 let bytes = self.words::<2>();
417 todo!()
418 }
419 PixelType::RgbAlpha8 => {
420 let bytes = self.bytes::<4>();
421 todo!()
423 }
424 PixelType::RgbAlpha16 => {
425 let bytes = self.words::<4>();
426 todo!()
428 }
429 _ => self.next_opaque(),
430 }
431 }
432}
433
434fn get_rgb_from_palette(palette: &[u8], idx: u8) -> Rgb888 {
435 let idx = (idx as usize) * 3;
436 if idx + 2 >= palette.len() {
437 Rgb888::new(0, 0, 0)
439 } else {
440 let r = palette[idx];
441 let g = palette[idx + 1];
442 let b = palette[idx + 2];
443 Rgb888::new(r, g, b)
444 }
445}
446
447impl<'a, C> Iterator for PixelsIterator<'a, C, IgnoreAlpha>
448where
449 BinaryColor: Into<C>,
450 Gray2: Into<C>,
451 Gray4: Into<C>,
452 Gray8: Into<C>,
453 Rgb888: Into<C>,
454{
455 type Item = C;
456
457 fn next(&mut self) -> Option<Self::Item> {
458 if self.pos >= self.max_pos {
459 return None;
460 }
461 Some(self.next_skip_alpha())
462 }
463}
464
465impl<'a, C> Iterator for PixelsIterator<'a, C, AlphaColor>
466where
467 BinaryColor: Into<C>,
468 Gray2: Into<C>,
469 Gray4: Into<C>,
470 Gray8: Into<C>,
471 Rgb888: Into<C>,
472 {
474 type Item = C;
475
476 fn next(&mut self) -> Option<Self::Item> {
477 if self.pos >= self.max_pos {
478 return None;
479 }
480 Some(self.next_alpha_color())
481 }
482}
483
484impl<'a, C> Iterator for PixelsIterator<'a, C, WithBackground<C>>
485where
486 BinaryColor: Into<C>,
487 Gray2: Into<C>,
488 Gray4: Into<C>,
489 Gray8: Into<C>,
490 Rgb888: Into<C>,
491 C: PixelColor,
492{
493 type Item = C;
494
495 fn next(&mut self) -> Option<Self::Item> {
496 if self.pos >= self.max_pos {
497 return None;
498 }
499 let (alpha, color) = self.next_keep_alpha();
500 todo!()
501 }
502}
503
504impl<'a, C> Iterator for PixelsIterator<'a, C, DontDraw>
505where
506 BinaryColor: Into<C>,
507 Gray2: Into<C>,
508 Gray4: Into<C>,
509 Gray8: Into<C>,
510 Rgb888: Into<C>,
511{
512 type Item = (u8, C);
513
514 fn next(&mut self) -> Option<Self::Item> {
515 if self.pos >= self.max_pos {
516 return None;
517 }
518 Some(self.next_keep_alpha())
519 }
520}
521
522#[cfg(test)]
523mod tests {
524 use super::*;
525
526 #[test]
527 fn bits1() {
528 let scanline = [0b1010_1100, 0b1010_1100];
529 let mut it = PixelsIterator {
530 pixel_type: PixelType::Grayscale1,
531 palette: None,
532 scanline: &scanline,
533 pos: 0,
534 max_pos: 0,
535 handler: IgnoreAlpha,
536 _phantom: PhantomData::<Rgb888>,
537 };
538 assert_eq!(it.bits::<1>(), 1);
539 assert_eq!(it.bits::<1>(), 0);
540 assert_eq!(it.bits::<1>(), 1);
541 assert_eq!(it.bits::<1>(), 0);
542 assert_eq!(it.bits::<1>(), 1);
543 assert_eq!(it.bits::<1>(), 1);
544 assert_eq!(it.bits::<1>(), 0);
545 assert_eq!(it.bits::<1>(), 0);
546 assert_eq!(it.bits::<1>(), 1);
547 assert_eq!(it.bits::<1>(), 0);
548 }
549 #[test]
550 fn bits2() {
551 let scanline = [0b1010_1100, 0b1010_1100];
552 let mut it = PixelsIterator {
553 pixel_type: PixelType::Grayscale1,
554 palette: None,
555 scanline: &scanline,
556 pos: 0,
557 max_pos: 0,
558 handler: IgnoreAlpha,
559 _phantom: PhantomData::<Rgb888>,
560 };
561 assert_eq!(it.bits::<2>(), 0b10);
562 assert_eq!(it.bits::<2>(), 0b10);
563 assert_eq!(it.bits::<2>(), 0b11);
564 assert_eq!(it.bits::<2>(), 0b00);
565 assert_eq!(it.bits::<2>(), 0b10);
566 assert_eq!(it.bits::<2>(), 0b10);
567 assert_eq!(it.bits::<2>(), 0b11);
568 assert_eq!(it.bits::<2>(), 0b00);
569 }
570 #[test]
571 fn bits4() {
572 let scanline = [0b1010_1100, 0b1010_1100];
573 let mut it = PixelsIterator {
574 pixel_type: PixelType::Grayscale1,
575 palette: None,
576 scanline: &scanline,
577 pos: 0,
578 max_pos: 0,
579 handler: IgnoreAlpha,
580 _phantom: PhantomData::<Rgb888>,
581 };
582 assert_eq!(it.bits::<4>(), 0b1010);
583 assert_eq!(it.bits::<4>(), 0b1100);
584 assert_eq!(it.bits::<4>(), 0b1010);
585 assert_eq!(it.bits::<4>(), 0b1100);
586 }
587 #[test]
588 fn bytes1() {
589 let scanline = [0xAA, 0xBB, 0xCC, 0xDD];
590 let mut it = PixelsIterator {
591 pixel_type: PixelType::Grayscale1,
592 palette: None,
593 scanline: &scanline,
594 pos: 0,
595 max_pos: 0,
596 handler: IgnoreAlpha,
597 _phantom: PhantomData::<Rgb888>,
598 };
599 assert_eq!(it.bytes::<1>(), [0xAA]);
600 assert_eq!(it.bytes::<1>(), [0xBB]);
601 assert_eq!(it.bytes::<1>(), [0xCC]);
602 assert_eq!(it.bytes::<1>(), [0xDD]);
603 }
604 #[test]
605 fn bytes2() {
606 let scanline = [0xAA, 0xBB, 0xCC, 0xDD];
607 let mut it = PixelsIterator {
608 pixel_type: PixelType::Grayscale1,
609 palette: None,
610 scanline: &scanline,
611 pos: 0,
612 max_pos: 0,
613 handler: IgnoreAlpha,
614 _phantom: PhantomData::<Rgb888>,
615 };
616 assert_eq!(it.bytes::<2>(), [0xAA, 0xBB]);
617 assert_eq!(it.bytes::<2>(), [0xCC, 0xDD]);
618 }
619}