imgref/
ops.rs

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