1 use super::pixel::*;
2 use crate::alt::*;
3 use crate::RGB;
4 use crate::RGBA;
5 use core::convert::*;
6 use core::mem;
7 use core::slice;
8 
9 mod array;
10 mod tuple;
11 
12 /// Casts a slice of bytes into a slice of pixels, e.g. `[u8]` to `[RGB8]`.
13 ///
14 /// See also `FromSlice`
15 pub trait AsPixels<PixelType> {
16     /// Reinterpret the slice as a read-only/shared slice of pixels.
17     /// Multiple consecutive elements in the slice are intepreted as a single pixel
18     /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
19     ///
20     /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
21     ///
22     /// Use this method only when the type is known from context.
23     /// See also `FromSlice`.
as_pixels(&self) -> &[PixelType]24     fn as_pixels(&self) -> &[PixelType];
25     /// Reinterpret the slice as a mutable/exclusive slice of pixels.
26     /// Multiple consecutive elements in the slice are intepreted as a single pixel
27     /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
28     ///
29     /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
30     ///
31     /// Use this method only when the type is known from context.
32     /// See also `FromSlice`.
as_pixels_mut(&mut self) -> &mut [PixelType]33     fn as_pixels_mut(&mut self) -> &mut [PixelType];
34 }
35 
36 macro_rules! as_pixels_impl {
37     ($typ:ident, $elems:expr) => {
38         impl<T> AsPixels<$typ<T>> for [T] {
39             fn as_pixels(&self) -> &[$typ<T>] {
40                 unsafe {
41                     slice::from_raw_parts(self.as_ptr() as *const _, self.len() / $elems)
42                 }
43             }
44             fn as_pixels_mut(&mut self) -> &mut [$typ<T>] {
45                 unsafe {
46                     slice::from_raw_parts_mut(self.as_mut_ptr() as *mut _, self.len() / $elems)
47                 }
48             }
49         }
50     }
51 }
52 
53 as_pixels_impl!{RGB, 3}
54 as_pixels_impl!{RGBA, 4}
55 as_pixels_impl!{BGR, 3}
56 as_pixels_impl!{BGRA, 4}
57 as_pixels_impl!{Gray, 1}
58 as_pixels_impl!{GrayAlpha, 2}
59 #[cfg(feature = "argb")]
60 as_pixels_impl!{ARGB, 2}
61 #[cfg(feature = "argb")]
62 as_pixels_impl!{ABGR, 2}
63 
64 /// Cast a slice of component values (bytes) as a slice of RGB/RGBA pixels
65 ///
66 /// If there's any incomplete pixel at the end of the slice it is ignored.
67 pub trait FromSlice<T: Copy> {
68     /// Reinterpert slice as RGB pixels
as_rgb(&self) -> &[RGB<T>]69     fn as_rgb(&self) -> &[RGB<T>];
70     /// Reinterpert slice as RGBA pixels
as_rgba(&self) -> &[RGBA<T>]71     fn as_rgba(&self) -> &[RGBA<T>];
72     /// Reinterpert slice as alpha-first ARGB pixels
73     #[cfg(feature = "argb")]
as_argb(&self) -> &[ARGB<T>]74     fn as_argb(&self) -> &[ARGB<T>];
75     /// Reinterpert mutable slice as RGB pixels
as_rgb_mut(&mut self) -> &mut [RGB<T>]76     fn as_rgb_mut(&mut self) -> &mut [RGB<T>];
77     /// Reinterpert mutable slice as RGBA pixels
as_rgba_mut(&mut self) -> &mut [RGBA<T>]78     fn as_rgba_mut(&mut self) -> &mut [RGBA<T>];
79     /// Reinterpert mutable slice as alpha-first ARGB pixels
80     #[cfg(feature = "argb")]
as_argb_mut(&mut self) -> &mut [ARGB<T>]81     fn as_argb_mut(&mut self) -> &mut [ARGB<T>];
82 
83     /// Reinterpert mutable slice as grayscale pixels
as_gray(&self) -> &[Gray<T>]84     fn as_gray(&self) -> &[Gray<T>];
85     /// Reinterpert mutable slice as grayscale pixels with alpha
as_gray_alpha(&self) -> &[GrayAlpha<T>]86     fn as_gray_alpha(&self) -> &[GrayAlpha<T>];
87     /// Reinterpert mutable slice as grayscale pixels
as_gray_mut(&mut self) -> &mut [Gray<T>]88     fn as_gray_mut(&mut self) -> &mut [Gray<T>];
89     /// Reinterpert mutable slice as grayscale pixels with alpha
as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>]90     fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>];
91 
92     /// Reinterpert slice as reverse-order BGR pixels
as_bgr(&self) -> &[BGR<T>]93     fn as_bgr(&self) -> &[BGR<T>];
94     /// Reinterpert slice as reverse-order BGRA pixels
as_bgra(&self) -> &[BGRA<T>]95     fn as_bgra(&self) -> &[BGRA<T>];
96     /// Reinterpert slice as reverse-order ABGR pixels
97     #[cfg(feature = "argb")]
as_abgr(&self) -> &[ABGR<T>]98     fn as_abgr(&self) -> &[ABGR<T>];
99     /// Reinterpert ntable slice as reverse-order BGR pixels
as_bgr_mut(&mut self) -> &mut [BGR<T>]100     fn as_bgr_mut(&mut self) -> &mut [BGR<T>];
101     /// Reinterpert mutable slice as reverse-order alpha-last BGRA pixels
as_bgra_mut(&mut self) -> &mut [BGRA<T>]102     fn as_bgra_mut(&mut self) -> &mut [BGRA<T>];
103     /// Reinterpert mutable slice as reverse-order alpha-first ABGR pixels
104     #[cfg(feature = "argb")]
as_abgr_mut(&mut self) -> &mut [ABGR<T>]105     fn as_abgr_mut(&mut self) -> &mut [ABGR<T>];
106 }
107 
108 impl<T: Copy> FromSlice<T> for [T] {
109     #[inline]
as_rgb(&self) -> &[RGB<T>]110     fn as_rgb(&self) -> &[RGB<T>] {
111         unsafe { from_items_to_struct(self) }
112     }
113 
114     #[inline]
as_rgba(&self) -> &[RGBA<T>]115     fn as_rgba(&self) -> &[RGBA<T>] {
116         unsafe { from_items_to_struct(self) }
117     }
118 
119     #[inline]
120     #[cfg(feature = "argb")]
as_argb(&self) -> &[ARGB<T>]121     fn as_argb(&self) -> &[ARGB<T>] {
122         unsafe { from_items_to_struct(self) }
123     }
124 
125     #[inline]
as_rgb_mut(&mut self) -> &mut [RGB<T>]126     fn as_rgb_mut(&mut self) -> &mut [RGB<T>] {
127         unsafe { from_items_to_struct_mut(self) }
128     }
129 
130     #[inline]
as_rgba_mut(&mut self) -> &mut [RGBA<T>]131     fn as_rgba_mut(&mut self) -> &mut [RGBA<T>] {
132         unsafe { from_items_to_struct_mut(self) }
133     }
134 
135     #[inline]
136     #[cfg(feature = "argb")]
as_argb_mut(&mut self) -> &mut [ARGB<T>]137     fn as_argb_mut(&mut self) -> &mut [ARGB<T>] {
138         unsafe { from_items_to_struct_mut(self) }
139     }
140 
141     #[inline]
as_gray(&self) -> &[Gray<T>]142     fn as_gray(&self) -> &[Gray<T>] {
143         unsafe { from_items_to_struct(self) }
144     }
145 
146     #[inline]
as_gray_alpha(&self) -> &[GrayAlpha<T>]147     fn as_gray_alpha(&self) -> &[GrayAlpha<T>] {
148         unsafe { from_items_to_struct(self) }
149     }
150 
151     #[inline]
as_gray_mut(&mut self) -> &mut [Gray<T>]152     fn as_gray_mut(&mut self) -> &mut [Gray<T>] {
153         unsafe { from_items_to_struct_mut(self) }
154     }
155 
156     #[inline]
as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>]157     fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>] {
158         unsafe { from_items_to_struct_mut(self) }
159     }
160 
161 
162     #[inline]
as_bgr(&self) -> &[BGR<T>]163     fn as_bgr(&self) -> &[BGR<T>] {
164         unsafe { from_items_to_struct(self) }
165     }
166 
167     #[inline]
168     #[cfg(feature = "argb")]
as_abgr(&self) -> &[ABGR<T>]169     fn as_abgr(&self) -> &[ABGR<T>] {
170         unsafe { from_items_to_struct(self) }
171     }
172 
173     #[inline]
as_bgra(&self) -> &[BGRA<T>]174     fn as_bgra(&self) -> &[BGRA<T>] {
175         unsafe { from_items_to_struct(self) }
176     }
177 
178     #[inline]
as_bgr_mut(&mut self) -> &mut [BGR<T>]179     fn as_bgr_mut(&mut self) -> &mut [BGR<T>] {
180         unsafe { from_items_to_struct_mut(self) }
181     }
182 
183     #[inline]
as_bgra_mut(&mut self) -> &mut [BGRA<T>]184     fn as_bgra_mut(&mut self) -> &mut [BGRA<T>] {
185         unsafe { from_items_to_struct_mut(self) }
186     }
187 
188     #[inline]
189     #[cfg(feature = "argb")]
as_abgr_mut(&mut self) -> &mut [ABGR<T>]190     fn as_abgr_mut(&mut self) -> &mut [ABGR<T>] {
191         unsafe { from_items_to_struct_mut(self) }
192     }
193 }
194 
195 #[inline(always)]
from_items_to_struct<F, T>(from: &[F]) -> &[T]196 unsafe fn from_items_to_struct<F, T>(from: &[F]) -> &[T] {
197     debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
198     let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
199     slice::from_raw_parts(from.as_ptr() as *const T, len)
200 }
201 
202 #[inline(always)]
from_items_to_struct_mut<F, T>(from: &mut [F]) -> &mut [T]203 unsafe fn from_items_to_struct_mut<F, T>(from: &mut [F]) -> &mut [T] {
204     debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
205     let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
206     slice::from_raw_parts_mut(from.as_ptr() as *mut T, len)
207 }
208 
209 macro_rules! rgb_impl_from {
210     ($typename:ident, $from:ty, $to:ty) => {
211         impl From<$typename<$from>> for $typename<$to> {
212 
213             #[inline(always)]
214             fn from(other: $typename<$from>) -> Self {
215                 other.map(core::convert::Into::into)
216             }
217         }
218     }
219 }
220 
221 rgb_impl_from!{RGB, u8,i16}
222 rgb_impl_from!{RGB, u16,i32}
223 
224 rgb_impl_from!{RGB, u8,f32}
225 rgb_impl_from!{RGB, u8,f64}
226 rgb_impl_from!{RGB, u16,f32}
227 rgb_impl_from!{RGB, u16,f64}
228 
229 rgb_impl_from!{RGB, i16,f32}
230 rgb_impl_from!{RGB, i16,f64}
231 
232 rgb_impl_from!{RGB, i32,f64}
233 rgb_impl_from!{RGB, f32,f64}
234 
235 
236 rgb_impl_from!{RGBA, u16,i32}
237 
238 rgb_impl_from!{RGBA, u8,f32}
239 rgb_impl_from!{RGBA, u8,f64}
240 rgb_impl_from!{RGBA, u16,f32}
241 rgb_impl_from!{RGBA, u16,f64}
242 
243 rgb_impl_from!{RGBA, i16,f32}
244 rgb_impl_from!{RGBA, i16,f64}
245 
246 rgb_impl_from!{RGBA, i32,f64}
247 rgb_impl_from!{RGBA, f32,f64}
248 
249 impl<T: Clone> From<Gray<T>> for RGB<T> {
250     #[inline(always)]
from(other: Gray<T>) -> Self251     fn from(other: Gray<T>) -> Self {
252         Self {
253             r: other.0.clone(),
254             g: other.0.clone(),
255             b: other.0,
256         }
257     }
258 }
259 
260 impl<T: Clone,A> From<GrayAlpha<T,A>> for RGBA<T,A> {
261     #[inline(always)]
from(other: GrayAlpha<T,A>) -> Self262     fn from(other: GrayAlpha<T,A>) -> Self {
263         Self {
264             r: other.0.clone(),
265             g: other.0.clone(),
266             b: other.0,
267             a: other.1,
268         }
269     }
270 }
271 
272 impl<T> From<RGB<T>> for BGR<T> {
273     #[inline(always)]
from(other: RGB<T>) -> Self274     fn from(other: RGB<T>) -> Self {
275         Self {
276             r: other.r,
277             g: other.g,
278             b: other.b,
279         }
280     }
281 }
282 
283 impl<T> From<RGBA<T>> for BGRA<T> {
284     #[inline(always)]
from(other: RGBA<T>) -> Self285     fn from(other: RGBA<T>) -> Self {
286         Self {
287             r: other.r,
288             g: other.g,
289             b: other.b,
290             a: other.a,
291         }
292     }
293 }
294 
295 impl<T> From<BGR<T>> for RGB<T> {
296     #[inline(always)]
from(other: BGR<T>) -> Self297     fn from(other: BGR<T>) -> Self {
298         Self {
299             r: other.r,
300             g: other.g,
301             b: other.b,
302         }
303     }
304 }
305 
306 impl<T> From<BGRA<T>> for RGBA<T> {
307     #[inline(always)]
from(other: BGRA<T>) -> Self308     fn from(other: BGRA<T>) -> Self {
309         Self {
310             r: other.r,
311             g: other.g,
312             b: other.b,
313             a: other.a,
314         }
315     }
316 }
317 
318 impl<T> AsRef<T> for Gray<T> {
319     #[inline(always)]
as_ref(&self) -> &T320     fn as_ref(&self) -> &T {
321         &self.0
322     }
323 }
324 
325 impl<T> AsRef<[T]> for RGB<T> {
326     #[inline(always)]
as_ref(&self) -> &[T]327     fn as_ref(&self) -> &[T] {
328         self.as_slice()
329     }
330 }
331 
332 impl<T> AsRef<[T]> for RGBA<T> {
333     #[inline(always)]
as_ref(&self) -> &[T]334     fn as_ref(&self) -> &[T] {
335         self.as_slice()
336     }
337 }
338 
339 impl<T> AsRef<T> for GrayAlpha<T> {
340     #[inline(always)]
as_ref(&self) -> &T341     fn as_ref(&self) -> &T {
342         &self.0
343     }
344 }
345 
346 
347 impl<T> AsMut<T> for Gray<T> {
348     #[inline(always)]
as_mut(&mut self) -> &mut T349     fn as_mut(&mut self) -> &mut T {
350         &mut self.0
351     }
352 }
353 
354 impl<T> AsMut<[T]> for RGB<T> {
355     #[inline(always)]
as_mut(&mut self) -> &mut [T]356     fn as_mut(&mut self) -> &mut [T] {
357         self.as_mut_slice()
358     }
359 }
360 
361 impl<T> AsMut<[T]> for RGBA<T> {
362     #[inline(always)]
as_mut(&mut self) -> &mut [T]363     fn as_mut(&mut self) -> &mut [T] {
364         self.as_mut_slice()
365     }
366 }
367 
368 impl<T> AsMut<T> for GrayAlpha<T> {
369     #[inline(always)]
as_mut(&mut self) -> &mut T370     fn as_mut(&mut self) -> &mut T {
371         &mut self.0
372     }
373 }
374 
375 
376 #[test]
converts()377 fn converts() {
378     assert_eq!([1,2].as_gray(), [Gray::new(1), Gray::new(2)]);
379     assert_eq!([3].as_gray_mut(), [Gray::new(3)]);
380     assert_eq!([1,2].as_gray_alpha(), [GrayAlpha::new(1, 2)]);
381     // excess bytes are ignored
382     assert_eq!([1,2,3].as_gray_alpha_mut(), [GrayAlpha::new(1, 2)]);
383     assert_eq!([1,2,3,4].as_gray_alpha_mut(), [GrayAlpha::new(1, 2), GrayAlpha::new(3, 4)]);
384 
385     assert_eq!(RGBA::new(1u8,2,3,255), RGB::new(1u8,2,3).into());
386     assert_eq!(RGBA::new(1u16,2,3,65535), RGB::new(1u16,2,3).into());
387     assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, BGR{r:1u8,g:2u8,b:3u8}.into());
388     assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, RGB{r:1u8,g:2u8,b:3u8}.into());
389     assert_eq!(RGBA {r:1u8,g:2,b:3,a:4u8}, BGRA{r:1u8,g:2u8,b:3u8,a:4u8}.into());
390     assert_eq!(BGR {r:1u8,g:2,b:3u8}, RGB {r:1u8,g:2,b:3u8}.into());
391     assert_eq!(RGB {r:1u16,g:0x5678,b:0xABCDu16}, BGR {r:1u16,g:0x5678,b:0xABCDu16}.into());
392     assert_eq!(BGR {r:0x1234567u32,g:2,b:3u32}, RGB {r:0x1234567u32,g:2,b:3u32}.into());
393 
394     assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_slice());
395     assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_ref());
396     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_slice());
397     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_ref());
398 
399     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut_slice());
400     assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut());
401 }
402 
403