1use super::Img;
2use alloc::vec::Vec;
3use core::ops;
4
5#[cfg(test)]
6use alloc::vec;
7
8macro_rules! impl_imgref_index {
9 ($container:ty, $index:ty) => {
10 impl<'a, Pixel: Copy> ops::Index<($index, $index)> for Img<$container> {
11 type Output = Pixel;
12 #[inline(always)]
13 /// Read a pixel at `(x,y)` location (e.g. px = `img[(x,y)]`)
14 ///
15 /// Coordinates may be outside `width`/`height` if the buffer has enough padding.
16 /// The x coordinate can't exceed `stride`.
17 fn index(&self, index: ($index, $index)) -> &Self::Output {
18 let stride = self.stride();
19 debug_assert_eq!(stride, stride as $index as usize);
20 debug_assert!(index.0 < stride as $index);
21 &self.buf()[(index.1 * (stride as $index) + index.0) as usize]
22 }
23 }
24 };
25}
26
27macro_rules! impl_imgref_index_mut {
28 ($container:ty, $index:ty) => {
29 impl<'a, Pixel: Copy> ops::IndexMut<($index, $index)> for Img<$container> {
30 #[inline(always)]
31 /// Write a pixel at `(x,y)` location (e.g. `img[(x,y)] = px`)
32 ///
33 /// Coordinates may be outside `width`/`height` if the buffer has enough padding.
34 /// The x coordinate can't exceed `stride`.
35 fn index_mut(&mut self, index: ($index, $index)) -> &mut Self::Output {
36 let stride = self.stride();
37 debug_assert_eq!(stride, stride as $index as usize);
38 debug_assert!(index.0 < stride as $index);
39 &mut self.buf_mut()[(index.1 * (stride as $index) + index.0) as usize]
40 }
41 }
42 };
43}
44
45impl_imgref_index! {&'a [Pixel], usize}
46impl_imgref_index! {&'a [Pixel], u32}
47impl_imgref_index! {&'a mut [Pixel], usize}
48impl_imgref_index! {&'a mut [Pixel], u32}
49impl_imgref_index_mut! {&'a mut [Pixel], usize}
50impl_imgref_index_mut! {&'a mut [Pixel], u32}
51impl_imgref_index! {Vec<Pixel>, usize}
52impl_imgref_index! {Vec<Pixel>, u32}
53impl_imgref_index_mut! {Vec<Pixel>, usize}
54impl_imgref_index_mut! {Vec<Pixel>, u32}
55
56#[test]
57fn index() {
58 let mut img: Img<&mut [i32]> = Img::new_stride(buf:vec![1,2,3,4,5,6,7,8], width:2, height:2, stride:3);
59 assert_eq!(1, img[(0u32,0u32)]);
60 assert_eq!(2, img.as_ref()[(1usize,0usize)]);
61 assert_eq!(3, img.as_ref()[(2u32,0u32)]);
62 assert_eq!(4, img[(0usize,1usize)]);
63 assert_eq!(8, img[(1usize,2usize)]);
64 assert_eq!(5, img.sub_image_mut(1,1,1,1)[(0usize,0usize)]);
65}
66
67
68macro_rules! impl_imgref_row_index {
69 ($container:ty) => {
70 impl<'a, Pixel: Copy> ops::Index<usize> for Img<$container> {
71 type Output = [Pixel];
72 #[inline(always)]
73 /// Take n-th row as a slice. Same as .rows().nth(n).unwrap()
74 ///
75 /// Slice length is guaranteed to equal image width.
76 /// Row must be within image height.
77 fn index(&self, row: usize) -> &Self::Output {
78 let stride = self.stride();
79 let width = self.width();
80 let start = row * stride;
81 &self.buf()[start .. start + width]
82 }
83 }
84 };
85}
86
87macro_rules! impl_imgref_row_index_mut {
88 ($container:ty) => {
89 impl<'a, Pixel: Copy> ops::IndexMut<usize> for Img<$container> {
90 #[inline(always)]
91 /// Take n-th row as a mutable slice. Same as .rows().nth(n).unwrap()
92 ///
93 /// Slice length is guaranteed to equal image width.
94 /// Row must be within image height.
95 fn index_mut(&mut self, row: usize) -> &mut Self::Output {
96 let stride = self.stride();
97 let width = self.width();
98 let start = row * stride;
99 &mut self.buf_mut()[start .. start + width]
100 }
101 }
102 };
103}
104
105impl_imgref_row_index! {&'a [Pixel]}
106impl_imgref_row_index! {&'a mut [Pixel]}
107impl_imgref_row_index_mut! {&'a mut [Pixel]}
108impl_imgref_row_index! {Vec<Pixel>}
109impl_imgref_row_index_mut! {Vec<Pixel>}
110
111#[test]
112fn index_by_row() {
113 let mut img: Img<&mut [i32]> = Img::new_stride(buf:vec![1,2,3,4,5,6,7,8], width:2, height:2, stride:3);
114 assert_eq!(&[1,2], &img[0]);
115 assert_eq!(&[4,5], &img[1]);
116 assert_eq!(&[1,2], &img.as_ref()[0]);
117 assert_eq!(&[4,5], &img.as_ref()[1]);
118 assert_eq!(&[1,2], &img.as_mut()[0]);
119 assert_eq!(&[4,5], &img.as_mut()[1]);
120}
121