| 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 | |
| 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 | |
| 29 | macro_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 | |
| 48 | impl_imgref_index! {&'a [Pixel], usize} |
| 49 | impl_imgref_index! {&'a [Pixel], u32} |
| 50 | impl_imgref_index! {&'a mut [Pixel], usize} |
| 51 | impl_imgref_index! {&'a mut [Pixel], u32} |
| 52 | impl_imgref_index_mut! {&'a mut [Pixel], usize} |
| 53 | impl_imgref_index_mut! {&'a mut [Pixel], u32} |
| 54 | impl_imgref_index! {Vec<Pixel>, usize} |
| 55 | impl_imgref_index! {Vec<Pixel>, u32} |
| 56 | impl_imgref_index_mut! {Vec<Pixel>, usize} |
| 57 | impl_imgref_index_mut! {Vec<Pixel>, u32} |
| 58 | |
| 59 | #[test ] |
| 60 | fn 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 | |
| 70 | macro_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 | |
| 90 | macro_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 | |
| 108 | impl_imgref_row_index! {&'a [Pixel]} |
| 109 | impl_imgref_row_index! {&'a mut [Pixel]} |
| 110 | impl_imgref_row_index_mut! {&'a mut [Pixel]} |
| 111 | impl_imgref_row_index! {Vec<Pixel>} |
| 112 | impl_imgref_row_index_mut! {Vec<Pixel>} |
| 113 | |
| 114 | #[test ] |
| 115 | fn 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 | } |
| 124 | |