rgb/
as_bytes.rs

1use crate::{RGB, RGBA};
2use crate::alt::{Gray, GrayAlpha, BGR, BGRA};
3use crate::alt::{ARGB, ABGR};
4use crate::ComponentBytes;
5
6#[cfg(feature = "as-bytes")]
7unsafe impl<T> crate::Pod for RGB<T> where T: crate::Pod {}
8#[cfg(feature = "as-bytes")]
9unsafe impl<T> crate::Pod for BGR<T> where T: crate::Pod {}
10#[cfg(feature = "as-bytes")]
11unsafe impl<T> crate::Zeroable for RGB<T> where T: crate::Zeroable {}
12#[cfg(feature = "as-bytes")]
13unsafe impl<T> crate::Zeroable for BGR<T> where T: crate::Zeroable {}
14
15#[cfg(feature = "as-bytes")]
16/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
17unsafe impl<T, A> crate::Zeroable for ABGR<T, A> where T: crate::Zeroable, A: crate::Zeroable {
18    #[track_caller]
19    #[inline(always)]
20    fn zeroed() -> Self {
21        unsafe {
22            let _ = assert_no_padding::<T, A, Self>();
23            core::mem::zeroed()
24        }
25    }
26}
27
28#[track_caller]
29const fn assert_no_padding<T, A, S>() {
30    if core::mem::size_of::<A>() + 3 * core::mem::size_of::<T>() != core::mem::size_of::<S>() {
31        panic!("type has padding");
32    }
33}
34
35#[cfg(feature = "as-bytes")]
36/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
37unsafe impl<T, A> crate::Pod for RGBA<T, A> where T: crate::Pod, A: crate::Pod {}
38
39#[cfg(feature = "as-bytes")]
40/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
41unsafe impl<T, A> crate::Pod for BGRA<T, A> where T: crate::Pod, A: crate::Pod {}
42
43#[cfg(feature = "as-bytes")]
44/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
45unsafe impl<T, A> crate::Zeroable for RGBA<T, A> where T: crate::Zeroable, A: crate::Zeroable {
46    #[track_caller]
47    #[inline(always)]
48    fn zeroed() -> Self {
49        unsafe {
50            let _ = assert_no_padding::<T, A, Self>();
51            core::mem::zeroed()
52        }
53    }
54}
55
56#[cfg(feature = "as-bytes")]
57/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
58unsafe impl<T, A> crate::Pod for ARGB<T, A> where T: crate::Pod, A: crate::Pod {}
59
60#[cfg(feature = "as-bytes")]
61/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
62unsafe impl<T, A> crate::Pod for ABGR<T, A> where T: crate::Pod, A: crate::Pod {}
63
64#[cfg(feature = "as-bytes")]
65/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
66unsafe impl<T, A> crate::Zeroable for ARGB<T, A> where T: crate::Zeroable, A: crate::Zeroable {
67    #[track_caller]
68    #[inline(always)]
69    fn zeroed() -> Self {
70        unsafe {
71            let _ = assert_no_padding::<T, A, Self>();
72            core::mem::zeroed()
73        }
74    }
75}
76
77#[cfg(feature = "as-bytes")]
78/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
79unsafe impl<T, A> crate::Zeroable for BGRA<T, A> where T: crate::Zeroable, A: crate::Zeroable {
80    #[track_caller]
81    #[inline(always)]
82    fn zeroed() -> Self {
83        unsafe {
84            let _ = assert_no_padding::<T, A, Self>();
85            core::mem::zeroed()
86        }
87    }
88}
89
90#[cfg(feature = "as-bytes")]
91unsafe impl<T> crate::Pod for Gray<T> where T: crate::Pod {}
92#[cfg(feature = "as-bytes")]
93/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
94unsafe impl<T, A> crate::Pod for GrayAlpha<T, A> where T: crate::Pod, A: crate::Pod {}
95#[cfg(feature = "as-bytes")]
96unsafe impl<T> crate::Zeroable for Gray<T> where T: crate::Zeroable {}
97#[cfg(feature = "as-bytes")]
98/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
99unsafe impl<T, A> crate::Zeroable for GrayAlpha<T, A> where T: crate::Zeroable, A: crate::Zeroable {
100    #[track_caller]
101    #[inline(always)]
102    fn zeroed() -> Self {
103        unsafe {
104            if core::mem::size_of::<A>() + core::mem::size_of::<T>() != core::mem::size_of::<Self>() {
105                panic!("type has padding");
106            }
107            core::mem::zeroed()
108        }
109    }
110}
111
112#[cfg(feature = "as-bytes")]
113impl<T: crate::Pod> ComponentBytes<T> for [Gray<T>] {}
114
115#[cfg(feature = "as-bytes")]
116impl<T: crate::Pod> ComponentBytes<T> for [GrayAlpha<T>] {}
117
118#[test]
119#[allow(dead_code)]
120fn shared_impl() {
121    struct SharedPixelBuffer<Pixel> {
122        data: [Pixel; 1],
123    }
124
125    impl<Pixel: Clone + crate::Pod> SharedPixelBuffer<Pixel>
126    where
127        [Pixel]: crate::ComponentBytes<u8>,
128    {
129        pub fn as_bytes(&self) -> &[u8] {
130            self.data.as_slice().as_bytes()
131        }
132    }
133
134    let b = SharedPixelBuffer {
135        data: [crate::RGB8::new(0,0,0)],
136    };
137    let _ = b.as_bytes();
138}