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