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