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