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