1 | use super::Img; |
2 | use alloc::vec::Vec; |
3 | use core::ops; |
4 | |
5 | #[cfg (test)] |
6 | use alloc::vec; |
7 | |
8 | macro_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 | |
27 | macro_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 | |
45 | impl_imgref_index! {&'a [Pixel], usize} |
46 | impl_imgref_index! {&'a [Pixel], u32} |
47 | impl_imgref_index! {&'a mut [Pixel], usize} |
48 | impl_imgref_index! {&'a mut [Pixel], u32} |
49 | impl_imgref_index_mut! {&'a mut [Pixel], usize} |
50 | impl_imgref_index_mut! {&'a mut [Pixel], u32} |
51 | impl_imgref_index! {Vec<Pixel>, usize} |
52 | impl_imgref_index! {Vec<Pixel>, u32} |
53 | impl_imgref_index_mut! {Vec<Pixel>, usize} |
54 | impl_imgref_index_mut! {Vec<Pixel>, u32} |
55 | |
56 | #[test ] |
57 | fn 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 | |
68 | macro_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 | |
87 | macro_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 | |
105 | impl_imgref_row_index! {&'a [Pixel]} |
106 | impl_imgref_row_index! {&'a mut [Pixel]} |
107 | impl_imgref_row_index_mut! {&'a mut [Pixel]} |
108 | impl_imgref_row_index! {Vec<Pixel>} |
109 | impl_imgref_row_index_mut! {Vec<Pixel>} |
110 | |
111 | #[test ] |
112 | fn 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 | |