picto/iter/pixel/
immutable.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use std::marker::PhantomData;
16
17use crate::{iter::Coordinates, pixel, region::Region};
18
19/// Immutable iterator over pixels.
20pub struct Iter<'a, P, C>
21where
22	P: pixel::Read<C>,
23	C: pixel::Channel,
24{
25	inner: Coordinates,
26	owner: Region,
27
28	data: &'a [C],
29	stride: usize,
30
31	pixel: PhantomData<P>,
32	channel: PhantomData<C>,
33}
34
35impl<'a, P, C> Iter<'a, P, C>
36where
37	P: pixel::Read<C>,
38	C: pixel::Channel,
39{
40	#[doc(hidden)]
41	#[inline]
42	pub fn new(data: &[C], stride: usize, owner: Region, region: Region) -> Iter<P, C> {
43		Iter {
44			inner: Coordinates::new(region),
45			owner,
46
47			data,
48			stride,
49
50			pixel: PhantomData,
51			channel: PhantomData,
52		}
53	}
54}
55
56/// A readable pixel from the iterator.
57#[derive(Eq, PartialEq, Debug)]
58pub struct Item<'a, P, C>
59where
60	P: pixel::Read<C>,
61	C: pixel::Channel,
62{
63	pixel: PhantomData<P>,
64	channel: PhantomData<C>,
65	data: &'a [C],
66}
67
68impl<'a, P, C> Item<'a, P, C>
69where
70	P: pixel::Read<C>,
71	C: pixel::Channel,
72{
73	#[doc(hidden)]
74	#[inline]
75	pub fn new(data: &[C]) -> Item<P, C> {
76		Item {
77			pixel: PhantomData,
78			channel: PhantomData,
79			data,
80		}
81	}
82
83	/// Get the pixel value.
84	#[inline]
85	pub fn get(&self) -> P {
86		P::read(self.data)
87	}
88}
89
90impl<'a, P, C> Iterator for Iter<'a, P, C>
91where
92	P: pixel::Read<C>,
93	C: pixel::Channel,
94{
95	type Item = (u32, u32, Item<'a, P, C>);
96
97	fn next(&mut self) -> Option<Self::Item> {
98		let (x, y) = if let Some((x, y)) = self.inner.next() {
99			(x, y)
100		}
101		else {
102			return None;
103		};
104
105		let channels = P::channels();
106		let index = (y as usize * self.stride) + (x as usize * channels);
107
108		Some((
109			x - self.inner.region().x,
110			y - self.inner.region().y,
111			Item::new(&self.data[index..index + channels]),
112		))
113	}
114
115	#[inline]
116	fn size_hint(&self) -> (usize, Option<usize>) {
117		self.inner.size_hint()
118	}
119}
120
121impl<'a, P, C> ExactSizeIterator for Iter<'a, P, C>
122where
123	P: pixel::Read<C>,
124	C: pixel::Channel,
125{
126	#[inline]
127	fn len(&self) -> usize {
128		self.inner.len()
129	}
130}