ezk_image/
image_traits.rs

1use crate::{BoundsCheckError, ColorInfo, CropError, Cropped, PixelFormat, Window};
2
3/// # Safety
4///
5/// Values returned must always be the same every call
6pub unsafe trait ImageRef {
7    fn format(&self) -> PixelFormat;
8    fn width(&self) -> usize;
9    fn height(&self) -> usize;
10    /// Returns an iterator yielding every plane with their associated stride
11    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_>;
12    fn color(&self) -> ColorInfo;
13}
14
15/// # Safety
16///
17/// Values returned must always be the same every call
18pub unsafe trait ImageMut: ImageRef {
19    /// Returns an iterator yielding every plane with their associated stride
20    fn planes_mut(&mut self) -> Box<dyn Iterator<Item = (&mut [u8], usize)> + '_>;
21}
22
23/// [`ImageRef`] extension methods
24pub trait ImageRefExt: ImageRef {
25    /// Perform a bounds check, return an error when it fails
26    fn bounds_check(&self) -> Result<(), BoundsCheckError> {
27        self.format()
28            .bounds_check(self.planes(), self.width(), self.height())
29    }
30
31    /// Crop the image with the given window
32    fn crop(self, window: Window) -> Result<Cropped<Self>, CropError>
33    where
34        Self: Sized,
35    {
36        Cropped::new(self, window)
37    }
38
39    /// Crop the image to the next lowest even resolution
40    fn crop_even(self) -> Result<Cropped<Self>, CropError>
41    where
42        Self: Sized,
43    {
44        let width = self.width().saturating_sub(1).next_multiple_of(2);
45        let height = self.height().saturating_sub(1).next_multiple_of(2);
46
47        Cropped::new(
48            self,
49            Window {
50                x: 0,
51                y: 0,
52                width,
53                height,
54            },
55        )
56    }
57}
58
59impl<T: ImageRef + ?Sized> ImageRefExt for T {}
60
61unsafe impl<T: ImageRef> ImageRef for &T {
62    fn format(&self) -> PixelFormat {
63        <T as ImageRef>::format(self)
64    }
65
66    fn width(&self) -> usize {
67        <T as ImageRef>::width(self)
68    }
69
70    fn height(&self) -> usize {
71        <T as ImageRef>::height(self)
72    }
73
74    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_> {
75        <T as ImageRef>::planes(self)
76    }
77
78    fn color(&self) -> ColorInfo {
79        <T as ImageRef>::color(self)
80    }
81}
82
83unsafe impl<T: ImageRef> ImageRef for &mut T {
84    fn format(&self) -> PixelFormat {
85        <T as ImageRef>::format(self)
86    }
87
88    fn width(&self) -> usize {
89        <T as ImageRef>::width(self)
90    }
91
92    fn height(&self) -> usize {
93        <T as ImageRef>::height(self)
94    }
95
96    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_> {
97        <T as ImageRef>::planes(self)
98    }
99
100    fn color(&self) -> ColorInfo {
101        <T as ImageRef>::color(self)
102    }
103}
104
105unsafe impl<T: ImageMut> ImageMut for &mut T {
106    fn planes_mut(&mut self) -> Box<dyn Iterator<Item = (&mut [u8], usize)> + '_> {
107        <T as ImageMut>::planes_mut(self)
108    }
109}
110
111unsafe impl ImageRef for &dyn ImageRef {
112    fn format(&self) -> PixelFormat {
113        (**self).format()
114    }
115
116    fn width(&self) -> usize {
117        (**self).width()
118    }
119
120    fn height(&self) -> usize {
121        (**self).height()
122    }
123
124    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_> {
125        (**self).planes()
126    }
127
128    fn color(&self) -> ColorInfo {
129        (**self).color()
130    }
131}
132
133unsafe impl ImageRef for &mut dyn ImageRef {
134    fn format(&self) -> PixelFormat {
135        (**self).format()
136    }
137
138    fn width(&self) -> usize {
139        (**self).width()
140    }
141
142    fn height(&self) -> usize {
143        (**self).height()
144    }
145
146    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_> {
147        (**self).planes()
148    }
149
150    fn color(&self) -> ColorInfo {
151        (**self).color()
152    }
153}
154
155unsafe impl ImageRef for &mut dyn ImageMut {
156    fn format(&self) -> PixelFormat {
157        (**self).format()
158    }
159
160    fn width(&self) -> usize {
161        (**self).width()
162    }
163
164    fn height(&self) -> usize {
165        (**self).height()
166    }
167
168    fn planes(&self) -> Box<dyn Iterator<Item = (&[u8], usize)> + '_> {
169        (**self).planes()
170    }
171
172    fn color(&self) -> ColorInfo {
173        (**self).color()
174    }
175}
176
177unsafe impl ImageMut for &mut dyn ImageMut {
178    fn planes_mut(&mut self) -> Box<dyn Iterator<Item = (&mut [u8], usize)> + '_> {
179        (**self).planes_mut()
180    }
181}