1use super::pixel::*;
2use crate::alt::*;
3use crate::{RGB, RGBA};
4use core::{mem, slice};
5
6mod array;
7mod tuple;
8
9pub trait AsPixels<PixelType> {
15 fn as_pixels(&self) -> &[PixelType];
26 fn as_pixels_mut(&mut self) -> &mut [PixelType];
37}
38
39macro_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
48 fn as_pixels_mut(&mut self) -> &mut [$typ<T>] {
49 unsafe {
50 slice::from_raw_parts_mut(self.as_mut_ptr() as *mut _, self.len() / $elems)
51 }
52 }
53 }
54 };
55}
56
57as_pixels_impl! {RGB, 3}
58as_pixels_impl! {RGBA, 4}
59as_pixels_impl! {BGR, 3}
60as_pixels_impl! {BGRA, 4}
61as_pixels_impl! {GRB, 3}
62as_pixels_impl! {Gray, 1}
63as_pixels_impl! {GrayAlpha, 2}
64as_pixels_impl! {ARGB, 4}
65as_pixels_impl! {ABGR, 4}
66
67pub trait FromSlice<T: Copy> {
73 fn as_rgb(&self) -> &[RGB<T>];
75 fn as_rgba(&self) -> &[RGBA<T>];
77 fn as_argb(&self) -> &[ARGB<T>];
79 fn as_rgb_mut(&mut self) -> &mut [RGB<T>];
81 fn as_rgba_mut(&mut self) -> &mut [RGBA<T>];
83 fn as_argb_mut(&mut self) -> &mut [ARGB<T>];
85
86 fn as_gray(&self) -> &[Gray<T>];
88 fn as_gray_alpha(&self) -> &[GrayAlpha<T>];
90 fn as_gray_mut(&mut self) -> &mut [Gray<T>];
92 fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>];
94
95 fn as_bgr(&self) -> &[BGR<T>];
97 fn as_bgra(&self) -> &[BGRA<T>];
99 fn as_abgr(&self) -> &[ABGR<T>];
101 fn as_bgr_mut(&mut self) -> &mut [BGR<T>];
103 fn as_bgra_mut(&mut self) -> &mut [BGRA<T>];
105 fn as_abgr_mut(&mut self) -> &mut [ABGR<T>];
107}
108
109impl<T: Copy> FromSlice<T> for [T] {
110 #[inline]
111 fn as_rgb(&self) -> &[RGB<T>] {
112 unsafe { from_items_to_struct(self) }
113 }
114
115 #[inline]
116 fn as_rgba(&self) -> &[RGBA<T>] {
117 unsafe { from_items_to_struct(self) }
118 }
119
120 #[inline]
121 fn as_argb(&self) -> &[ARGB<T>] {
122 unsafe { from_items_to_struct(self) }
123 }
124
125 #[inline]
126 fn as_rgb_mut(&mut self) -> &mut [RGB<T>] {
127 unsafe { from_items_to_struct_mut(self) }
128 }
129
130 #[inline]
131 fn as_rgba_mut(&mut self) -> &mut [RGBA<T>] {
132 unsafe { from_items_to_struct_mut(self) }
133 }
134
135 #[inline]
136 fn as_argb_mut(&mut self) -> &mut [ARGB<T>] {
137 unsafe { from_items_to_struct_mut(self) }
138 }
139
140 #[inline]
141 fn as_gray(&self) -> &[Gray<T>] {
142 unsafe { from_items_to_struct(self) }
143 }
144
145 #[inline]
146 fn as_gray_alpha(&self) -> &[GrayAlpha<T>] {
147 unsafe { from_items_to_struct(self) }
148 }
149
150 #[inline]
151 fn as_gray_mut(&mut self) -> &mut [Gray<T>] {
152 unsafe { from_items_to_struct_mut(self) }
153 }
154
155 #[inline]
156 fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>] {
157 unsafe { from_items_to_struct_mut(self) }
158 }
159
160 #[inline]
161 fn as_bgr(&self) -> &[BGR<T>] {
162 unsafe { from_items_to_struct(self) }
163 }
164
165 #[inline]
166 fn as_abgr(&self) -> &[ABGR<T>] {
167 unsafe { from_items_to_struct(self) }
168 }
169
170 #[inline]
171 fn as_bgra(&self) -> &[BGRA<T>] {
172 unsafe { from_items_to_struct(self) }
173 }
174
175 #[inline]
176 fn as_bgr_mut(&mut self) -> &mut [BGR<T>] {
177 unsafe { from_items_to_struct_mut(self) }
178 }
179
180 #[inline]
181 fn as_bgra_mut(&mut self) -> &mut [BGRA<T>] {
182 unsafe { from_items_to_struct_mut(self) }
183 }
184
185 #[inline]
186 fn as_abgr_mut(&mut self) -> &mut [ABGR<T>] {
187 unsafe { from_items_to_struct_mut(self) }
188 }
189}
190
191#[inline(always)]
192unsafe fn from_items_to_struct<F, T>(from: &[F]) -> &[T] {
193 debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
194 let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
195 slice::from_raw_parts(from.as_ptr().cast::<T>(), len)
196}
197
198#[inline(always)]
199unsafe fn from_items_to_struct_mut<F, T>(from: &mut [F]) -> &mut [T] {
200 debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
201 let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
202 slice::from_raw_parts_mut(from.as_mut_ptr().cast::<T>(), len)
203}
204
205macro_rules! rgb_impl_from {
206 ($typename:ident, $from:ty, $to:ty) => {
207 impl From<$typename<$from>> for $typename<$to> {
208 #[inline(always)]
209 fn from(other: $typename<$from>) -> Self {
210 other.map(core::convert::Into::into)
211 }
212 }
213 };
214}
215
216rgb_impl_from! {RGB, u8,i16}
217rgb_impl_from! {RGB, u8,i32}
218rgb_impl_from! {RGB, u8,u16}
219rgb_impl_from! {RGB, u8,u32}
220rgb_impl_from! {RGB, u16,i32}
221rgb_impl_from! {RGB, u16,u32}
222rgb_impl_from! {RGB, u16,u64}
223
224rgb_impl_from! {RGB, u8,f32}
225rgb_impl_from! {RGB, u8,f64}
226rgb_impl_from! {RGB, u16,f32}
227rgb_impl_from! {RGB, u16,f64}
228
229rgb_impl_from! {RGB, i16,f32}
230rgb_impl_from! {RGB, i16,f64}
231
232rgb_impl_from! {RGB, i32,f64}
233rgb_impl_from! {RGB, f32,f64}
234
235rgb_impl_from! {RGBA, u16,i32}
236rgb_impl_from! {RGBA, u16,u32}
237rgb_impl_from! {RGBA, u16,u64}
238
239rgb_impl_from! {RGBA, u8,i16}
240rgb_impl_from! {RGBA, u8,u16}
241rgb_impl_from! {RGBA, u8,u32}
242rgb_impl_from! {RGBA, u8,f32}
243rgb_impl_from! {RGBA, u8,f64}
244rgb_impl_from! {RGBA, u16,f32}
245rgb_impl_from! {RGBA, u16,f64}
246
247rgb_impl_from! {RGBA, i16,f32}
248rgb_impl_from! {RGBA, i16,f64}
249
250rgb_impl_from! {RGBA, i32,f64}
251rgb_impl_from! {RGBA, f32,f64}
252
253macro_rules! reorder_impl_from {
254 (@rgb $t1:ident, $t2:ident) => {
255 reorder_impl_from!(@once $t1, $t2, r, g, b);
256 reorder_impl_from!(@once $t2, $t1, r, g, b);
257 };
258 (@rgba $t1:ident, $t2:ident) => {
259 reorder_impl_from!(@once $t1, $t2, r, g, b, a);
260 reorder_impl_from!(@once $t2, $t1, r, g, b, a);
261 };
262 (@once $t1:ident, $t2:ident, $($component:ident),+) => {
263 impl<T> From<$t1<T>> for $t2<T> where T: ::core::clone::Clone {
264 fn from(other: $t1<T>) -> Self {
265 let $t1 { $($component),+ } = other;
266 Self {
267 $($component),+
268 }
269 }
270 }
271 }
272}
273
274reorder_impl_from!(@rgba RGBA, ARGB);
275reorder_impl_from!(@rgba ABGR, ARGB);
276reorder_impl_from!(@rgba BGRA, ARGB);
277reorder_impl_from!(@rgba BGRA, ABGR);
278
279reorder_impl_from!(@rgb RGB, BGR);
280reorder_impl_from!(@rgba BGRA, RGBA);
281reorder_impl_from!(@rgba ABGR, RGBA);
282reorder_impl_from!(@rgb RGB, GRB);
283
284impl<T: Clone> From<Gray<T>> for RGB<T> {
285 #[inline(always)]
286 fn from(other: Gray<T>) -> Self {
287 Self {
288 r: other.0.clone(),
289 g: other.0.clone(),
290 b: other.0,
291 }
292 }
293}
294
295impl<T: Clone> From<Gray<T>> for RGBA<T, u8> {
296 #[inline(always)]
297 fn from(other: Gray<T>) -> Self {
298 Self {
299 r: other.0.clone(),
300 g: other.0.clone(),
301 b: other.0,
302 a: 255,
303 }
304 }
305}
306
307impl<T: Clone, A> From<GrayAlpha<T, A>> for RGBA<T, A> {
308 #[inline(always)]
309 fn from(other: GrayAlpha<T, A>) -> Self {
310 Self {
311 r: other.0.clone(),
312 g: other.0.clone(),
313 b: other.0,
314 a: other.1,
315 }
316 }
317}
318
319#[cfg(not(feature = "unstable-experimental"))]
320impl<T> AsRef<T> for Gray<T> {
321 #[inline(always)]
322 fn as_ref(&self) -> &T {
323 &self.0
324 }
325}
326
327#[cfg(not(feature = "unstable-experimental"))]
328impl<T> AsRef<[T]> for RGB<T> {
329 #[inline(always)]
330 fn as_ref(&self) -> &[T] {
331 self.as_slice()
332 }
333}
334
335#[cfg(feature = "unstable-experimental")]
336impl<T> AsRef<[T; 3]> for RGB<T> {
337 fn as_ref(&self) -> &[T; 3] {
338 unsafe { &*(self as *const Self).cast() }
339 }
340}
341
342#[cfg(not(feature = "unstable-experimental"))]
343impl<T> AsRef<[T]> for RGBA<T> {
344 #[inline(always)]
345 fn as_ref(&self) -> &[T] {
346 self.as_slice()
347 }
348}
349
350#[cfg(feature = "unstable-experimental")]
351impl<T> AsRef<[T; 4]> for RGBA<T> {
352 fn as_ref(&self) -> &[T; 4] {
353 unsafe { &*(self as *const Self).cast() }
354 }
355}
356
357impl<T> AsRef<[T; 4]> for ARGB<T> {
358 fn as_ref(&self) -> &[T; 4] {
359 unsafe { &*(self as *const Self).cast() }
360 }
361}
362
363impl<T> AsRef<[T; 4]> for BGRA<T> {
364 fn as_ref(&self) -> &[T; 4] {
365 unsafe { &*(self as *const Self).cast() }
366 }
367}
368
369impl<T> AsRef<[T; 4]> for ABGR<T> {
370 fn as_ref(&self) -> &[T; 4] {
371 unsafe { &*(self as *const Self).cast() }
372 }
373}
374
375#[cfg(not(feature = "unstable-experimental"))]
376impl<T> AsRef<T> for GrayAlpha<T> {
377 #[inline(always)]
378 fn as_ref(&self) -> &T {
379 &self.0
380 }
381}
382
383#[cfg(feature = "unstable-experimental")]
384impl<T> AsRef<[T; 2]> for GrayAlpha<T> {
385 fn as_ref(&self) -> &[T; 2] {
386 unsafe { &*(self as *const Self).cast() }
387 }
388}
389
390#[cfg(not(feature = "unstable-experimental"))]
391impl<T> AsMut<T> for Gray<T> {
392 #[inline(always)]
393 fn as_mut(&mut self) -> &mut T {
394 &mut self.0
395 }
396}
397
398#[cfg(not(feature = "unstable-experimental"))]
399impl<T> AsMut<[T]> for RGB<T> {
400 #[inline(always)]
401 fn as_mut(&mut self) -> &mut [T] {
402 self.as_mut_slice()
403 }
404}
405
406#[cfg(feature = "unstable-experimental")]
407impl<T> AsMut<[T; 3]> for RGB<T> {
408 fn as_mut(&mut self) -> &mut [T; 3] {
409 unsafe { &mut *(self as *mut Self).cast() }
410 }
411}
412
413#[cfg(not(feature = "unstable-experimental"))]
414impl<T> AsMut<[T]> for RGBA<T> {
415 #[inline(always)]
416 fn as_mut(&mut self) -> &mut [T] {
417 self.as_mut_slice()
418 }
419}
420
421#[cfg(feature = "unstable-experimental")]
422impl<T> AsMut<[T; 4]> for RGBA<T> {
423 fn as_mut(&mut self) -> &mut [T; 4] {
424 unsafe { &mut *(self as *mut Self).cast() }
425 }
426}
427
428#[cfg(not(feature = "unstable-experimental"))]
429impl<T> AsMut<T> for GrayAlpha<T> {
430 #[inline(always)]
431 fn as_mut(&mut self) -> &mut T {
432 &mut self.0
433 }
434}
435
436#[cfg(feature = "unstable-experimental")]
437impl<T> AsMut<[T; 2]> for GrayAlpha<T> {
438 fn as_mut(&mut self) -> &mut [T; 2] {
439 unsafe { &mut *(self as *mut Self).cast() }
440 }
441}
442
443#[test]
444fn argb_converts() {
445 let argb = ARGB { a: 0xffu8, r: 0xfa, g: 0xfb, b: 0xfc };
446 let rgba = RGBA { a: 0xffu8, r: 0xfa, g: 0xfb, b: 0xfc };
447
448 assert_eq!(RGBA::from(argb), rgba);
449 assert_eq!(ARGB::from(rgba), argb);
450 assert_eq!(rgba.rgb(), argb.rgb());
451
452 let bgra = BGRA { a: 0xffu8, r: 0x1f, g: 0x2f, b: 0x3f };
453 let abgr = ABGR { a: 0xffu8, r: 0x1f, g: 0x2f, b: 0x3f };
454
455 assert_eq!(BGRA::from(abgr), bgra);
456 assert_eq!(ABGR::from(bgra), abgr);
457}
458
459#[test]
460fn converts() {
461 assert_eq!([1,2].as_gray(), [Gray::new(1), Gray::new(2)]);
462 assert_eq!([3].as_gray_mut(), [Gray::new(3)]);
463 assert_eq!([1,2].as_gray_alpha(), [GrayAlpha::new(1, 2)]);
464 assert_eq!([1,2,3].as_gray_alpha_mut(), [GrayAlpha::new(1, 2)]);
466 assert_eq!([1,2,3,4].as_gray_alpha_mut(), [GrayAlpha::new(1, 2), GrayAlpha::new(3, 4)]);
467
468 assert_eq!(RGBA::new(1u8,2,3,255), RGB::new(1u8,2,3).into());
469 assert_eq!(RGBA::new(1u16,2,3,65535), RGB::new(1u16,2,3).into());
470 assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, BGR{r:1u8,g:2u8,b:3u8}.into());
471 assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, RGB{r:1u8,g:2u8,b:3u8}.into());
472 assert_eq!(RGBA {r:1u8,g:2,b:3,a:4u8}, BGRA{r:1u8,g:2u8,b:3u8,a:4u8}.into());
473 assert_eq!(BGR {r:1u8,g:2,b:3u8}, RGB {r:1u8,g:2,b:3u8}.into());
474 assert_eq!(RGB {r:1u16,g:0x5678,b:0xABCDu16}, BGR {r:1u16,g:0x5678,b:0xABCDu16}.into());
475 assert_eq!(BGR {r:0x1234567u32,g:2,b:3u32}, RGB {r:0x1234567u32,g:2,b:3u32}.into());
476
477 assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_slice());
478 assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_ref());
479 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_slice());
480 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_ref());
481
482 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut_slice());
483 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut());
484}
485
486
487#[test]
488#[cfg(feature = "unstable-experimental")]
489fn as_refs() {
490 let mut r = RGBA::new(1u8,2,3,4u8);
491 assert_eq!(&[1,2,3,4], AsRef::<[u8; 4]>::as_ref(&r));
492 assert_eq!([1,2,3,4], *AsMut::<[u8; 4]>::as_mut(&mut r));
493
494 let mut r = GrayAlpha::new(1u8,4u8);
495 assert_eq!(&[1,4], AsRef::<[u8; 2]>::as_ref(&r));
496 assert_eq!([1,4], *AsMut::<[u8; 2]>::as_mut(&mut r));
497}