1 use super::pixel::*;
2 use crate::alt::Gray;
3 use crate::alt::GrayAlpha;
4 use crate::alt::BGR;
5 use crate::alt::BGRA;
6 use crate::RGB;
7 use crate::RGBA;
8 use core::convert::*;
9 use core::mem;
10 use core::slice;
11 
12 mod array;
13 mod tuple;
14 
15 /// Casts a slice of bytes into a slice of pixels, e.g. `[u8]` to `[RGB8]`.
16 ///
17 /// See also `FromSlice`
18 pub trait AsPixels<PixelType> {
19     /// Reinterpret the slice as a read-only/shared slice of pixels.
20     /// Multiple consecutive elements in the slice are intepreted as a single pixel
21     /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
22     ///
23     /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
24     ///
25     /// Use this method only when the type is known from context.
26     /// See also `FromSlice`.
as_pixels(&self) -> &[PixelType]27     fn as_pixels(&self) -> &[PixelType];
28     /// Reinterpret the slice as a mutable/exclusive slice of pixels.
29     /// Multiple consecutive elements in the slice are intepreted as a single pixel
30     /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
31     ///
32     /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
33     ///
34     /// Use this method only when the type is known from context.
35     /// See also `FromSlice`.
as_pixels_mut(&mut self) -> &mut [PixelType]36     fn as_pixels_mut(&mut self) -> &mut [PixelType];
37 }
38 
39 macro_rules! as_pixels_impl {
40     ($typ:ident, $elems:expr) => {
41         impl<T> AsPixels<$typ<T>> for [T] {
42             fn as_pixels(&self) -> &[$typ<T>] {
43                 unsafe {
44                     slice::from_raw_parts(self.as_ptr() as *const _, self.len() / $elems)
45                 }
46             }
47             fn as_pixels_mut(&mut self) -> &mut [$typ<T>] {
48                 unsafe {
49                     slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / $elems)
50                 }
51             }
52         }
53     }
54 }
55 
56 as_pixels_impl!{RGB, 3}
57 as_pixels_impl!{RGBA, 4}
58 as_pixels_impl!{BGR, 3}
59 as_pixels_impl!{BGRA, 3}
60 as_pixels_impl!{Gray, 1}
61 as_pixels_impl!{GrayAlpha, 2}
62 
63 /// Cast a slice of component values (bytes) as a slice of RGB/RGBA pixels
64 ///
65 /// If there's any incomplete pixel at the end of the slice it is ignored.
66 pub trait FromSlice<T: Copy> {
67     /// Reinterpert slice as RGB pixels
as_rgb(&self) -> &[RGB<T>]68     fn as_rgb(&self) -> &[RGB<T>];
69     /// Reinterpert slice as RGBA pixels
as_rgba(&self) -> &[RGBA<T>]70     fn as_rgba(&self) -> &[RGBA<T>];
71     /// Reinterpert mutable slice as RGB pixels
as_rgb_mut(&mut self) -> &mut [RGB<T>]72     fn as_rgb_mut(&mut self) -> &mut [RGB<T>];
73     /// Reinterpert mutable slice as RGBA pixels
as_rgba_mut(&mut self) -> &mut [RGBA<T>]74     fn as_rgba_mut(&mut self) -> &mut [RGBA<T>];
75 
76     /// Reinterpert slice as reverse-order BGR pixels
as_bgr(&self) -> &[BGR<T>]77     fn as_bgr(&self) -> &[BGR<T>];
78     /// Reinterpert slice as reverse-order BGRA pixels
as_bgra(&self) -> &[BGRA<T>]79     fn as_bgra(&self) -> &[BGRA<T>];
80     /// Reinterpert ntable slice as reverse-order BGR pixels
as_bgr_mut(&mut self) -> &mut [BGR<T>]81     fn as_bgr_mut(&mut self) -> &mut [BGR<T>];
82     /// Reinterpert mutable slice as reverse-order BGRA pixels
as_bgra_mut(&mut self) -> &mut [BGRA<T>]83     fn as_bgra_mut(&mut self) -> &mut [BGRA<T>];
84 }
85 
86 impl<T: Copy> FromSlice<T> for [T] {
as_rgb(&self) -> &[RGB<T>]87     fn as_rgb(&self) -> &[RGB<T>] {
88         debug_assert_eq!(3, mem::size_of::<RGB<T>>() / mem::size_of::<T>());
89         unsafe {
90             slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 3)
91         }
92     }
as_rgba(&self) -> &[RGBA<T>]93     fn as_rgba(&self) -> &[RGBA<T>] {
94         debug_assert_eq!(4, mem::size_of::<RGBA<T>>() / mem::size_of::<T>());
95         unsafe {
96             slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 4)
97         }
98     }
as_rgb_mut(&mut self) -> &mut [RGB<T>]99     fn as_rgb_mut(&mut self) -> &mut [RGB<T>] {
100         debug_assert_eq!(3, mem::size_of::<RGB<T>>() / mem::size_of::<T>());
101         unsafe {
102             slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 3)
103         }
104     }
as_rgba_mut(&mut self) -> &mut [RGBA<T>]105     fn as_rgba_mut(&mut self) -> &mut [RGBA<T>] {
106         debug_assert_eq!(4, mem::size_of::<RGBA<T>>() / mem::size_of::<T>());
107         unsafe {
108             slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 4)
109         }
110     }
111 
as_bgr(&self) -> &[BGR<T>]112     fn as_bgr(&self) -> &[BGR<T>] {
113         debug_assert_eq!(3, mem::size_of::<BGR<T>>() / mem::size_of::<T>());
114         unsafe {
115             slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 3)
116         }
117     }
as_bgra(&self) -> &[BGRA<T>]118     fn as_bgra(&self) -> &[BGRA<T>] {
119         debug_assert_eq!(4, mem::size_of::<BGRA<T>>() / mem::size_of::<T>());
120         unsafe {
121             slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 4)
122         }
123     }
as_bgr_mut(&mut self) -> &mut [BGR<T>]124     fn as_bgr_mut(&mut self) -> &mut [BGR<T>] {
125         debug_assert_eq!(3, mem::size_of::<BGR<T>>() / mem::size_of::<T>());
126         unsafe {
127             slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 3)
128         }
129     }
as_bgra_mut(&mut self) -> &mut [BGRA<T>]130     fn as_bgra_mut(&mut self) -> &mut [BGRA<T>] {
131         debug_assert_eq!(4, mem::size_of::<BGRA<T>>() / mem::size_of::<T>());
132         unsafe {
133             slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 4)
134         }
135     }
136 }
137 
138 macro_rules! rgb_impl_from {
139     ($typename:ident, $from:ty, $to:ty) => {
140         impl From<$typename<$from>> for $typename<$to> {
141 
142             #[inline(always)]
143             fn from(other: $typename<$from>) -> Self {
144                 other.map(core::convert::Into::into)
145             }
146         }
147     }
148 }
149 
150 rgb_impl_from!{RGB, u8,i16}
151 rgb_impl_from!{RGB, u16,i32}
152 
153 rgb_impl_from!{RGB, u8,f32}
154 rgb_impl_from!{RGB, u8,f64}
155 rgb_impl_from!{RGB, u16,f32}
156 rgb_impl_from!{RGB, u16,f64}
157 
158 rgb_impl_from!{RGB, i16,f32}
159 rgb_impl_from!{RGB, i16,f64}
160 
161 rgb_impl_from!{RGB, i32,f64}
162 rgb_impl_from!{RGB, f32,f64}
163 
164 
165 rgb_impl_from!{RGBA, u16,i32}
166 
167 rgb_impl_from!{RGBA, u8,f32}
168 rgb_impl_from!{RGBA, u8,f64}
169 rgb_impl_from!{RGBA, u16,f32}
170 rgb_impl_from!{RGBA, u16,f64}
171 
172 rgb_impl_from!{RGBA, i16,f32}
173 rgb_impl_from!{RGBA, i16,f64}
174 
175 rgb_impl_from!{RGBA, i32,f64}
176 rgb_impl_from!{RGBA, f32,f64}
177 
178 impl<T: Clone> From<Gray<T>> for RGB<T> {
from(other: Gray<T>) -> Self179     fn from(other: Gray<T>) -> Self {
180         Self {
181             r: other.0.clone(),
182             g: other.0.clone(),
183             b: other.0,
184         }
185     }
186 }
187 
188 impl<T: Clone,A> From<GrayAlpha<T,A>> for RGBA<T,A> {
from(other: GrayAlpha<T,A>) -> Self189     fn from(other: GrayAlpha<T,A>) -> Self {
190         Self {
191             r: other.0.clone(),
192             g: other.0.clone(),
193             b: other.0,
194             a: other.1,
195         }
196     }
197 }
198 
199 impl<T> From<RGB<T>> for BGR<T> {
from(other: RGB<T>) -> Self200     fn from(other: RGB<T>) -> Self {
201         Self {
202             r: other.r,
203             g: other.g,
204             b: other.b,
205         }
206     }
207 }
208 
209 impl<T> From<RGBA<T>> for BGRA<T> {
from(other: RGBA<T>) -> Self210     fn from(other: RGBA<T>) -> Self {
211         Self {
212             r: other.r,
213             g: other.g,
214             b: other.b,
215             a: other.a,
216         }
217     }
218 }
219 
220 impl<T> From<BGR<T>> for RGB<T> {
from(other: BGR<T>) -> Self221     fn from(other: BGR<T>) -> Self {
222         Self {
223             r: other.r,
224             g: other.g,
225             b: other.b,
226         }
227     }
228 }
229 
230 impl<T> From<BGRA<T>> for RGBA<T> {
from(other: BGRA<T>) -> Self231     fn from(other: BGRA<T>) -> Self {
232         Self {
233             r: other.r,
234             g: other.g,
235             b: other.b,
236             a: other.a,
237         }
238     }
239 }
240 
241 impl<T> AsRef<T> for Gray<T> {
as_ref(&self) -> &T242     fn as_ref(&self) -> &T {
243         &self.0
244     }
245 }
246 
247 impl<T> AsRef<[T]> for RGB<T> {
as_ref(&self) -> &[T]248     fn as_ref(&self) -> &[T] {
249         self.as_slice()
250     }
251 }
252 
253 impl<T> AsRef<[T]> for RGBA<T> {
as_ref(&self) -> &[T]254     fn as_ref(&self) -> &[T] {
255         self.as_slice()
256     }
257 }
258 
259 impl<T> AsRef<T> for GrayAlpha<T> {
as_ref(&self) -> &T260     fn as_ref(&self) -> &T {
261         &self.0
262     }
263 }
264 
265 
266 impl<T> AsMut<T> for Gray<T> {
as_mut(&mut self) -> &mut T267     fn as_mut(&mut self) -> &mut T {
268         &mut self.0
269     }
270 }
271 
272 impl<T> AsMut<[T]> for RGB<T> {
as_mut(&mut self) -> &mut [T]273     fn as_mut(&mut self) -> &mut [T] {
274         self.as_mut_slice()
275     }
276 }
277 
278 impl<T> AsMut<[T]> for RGBA<T> {
as_mut(&mut self) -> &mut [T]279     fn as_mut(&mut self) -> &mut [T] {
280         self.as_mut_slice()
281     }
282 }
283 
284 impl<T> AsMut<T> for GrayAlpha<T> {
as_mut(&mut self) -> &mut T285     fn as_mut(&mut self) -> &mut T {
286         &mut self.0
287     }
288 }
289 
290 
291 #[test]
converts()292 fn converts() {
293     assert_eq!(RGBA::new(1u8,2,3,255), RGB::new(1u8,2,3).into());
294     assert_eq!(RGBA::new(1u16,2,3,65535), RGB::new(1u16,2,3).into());
295     assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, BGR{r:1u8,g:2u8,b:3u8}.into());
296     assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, RGB{r:1u8,g:2u8,b:3u8}.into());
297     assert_eq!(RGBA {r:1u8,g:2,b:3,a:4u8}, BGRA{r:1u8,g:2u8,b:3u8,a:4u8}.into());
298     assert_eq!(BGR {r:1u8,g:2,b:3u8}, RGB {r:1u8,g:2,b:3u8}.into());
299     assert_eq!(RGB {r:1u16,g:0x5678,b:0xABCDu16}, BGR {r:1u16,g:0x5678,b:0xABCDu16}.into());
300     assert_eq!(BGR {r:0x1234567u32,g:2,b:3u32}, RGB {r:0x1234567u32,g:2,b:3u32}.into());
301 
302     assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_slice());
303     assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_ref());
304     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_slice());
305     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_ref());
306 
307     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut_slice());
308     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut());
309 }
310 
311