rgb/
as_bytes.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use crate::{RGB, RGBA};
use crate::alt::{Gray, GrayAlpha, BGR, BGRA};
use crate::alt::{ARGB, ABGR};
use crate::ComponentBytes;

#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Pod for RGB<T> where T: crate::Pod {}
#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Pod for BGR<T> where T: crate::Pod {}
#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Zeroable for RGB<T> where T: crate::Zeroable {}
#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Zeroable for BGR<T> where T: crate::Zeroable {}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Zeroable for ABGR<T, A> where T: crate::Zeroable, A: crate::Zeroable {
    #[track_caller]
    #[inline(always)]
    fn zeroed() -> Self {
        unsafe {
            let _ = assert_no_padding::<T, A, Self>();
            core::mem::zeroed()
        }
    }
}

#[track_caller]
const fn assert_no_padding<T, A, S>() {
    if core::mem::size_of::<A>() + 3 * core::mem::size_of::<T>() != core::mem::size_of::<S>() {
        panic!("type has padding");
    }
}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Pod for RGBA<T, A> where T: crate::Pod, A: crate::Pod {}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Pod for BGRA<T, A> where T: crate::Pod, A: crate::Pod {}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Zeroable for RGBA<T, A> where T: crate::Zeroable, A: crate::Zeroable {
    #[track_caller]
    #[inline(always)]
    fn zeroed() -> Self {
        unsafe {
            let _ = assert_no_padding::<T, A, Self>();
            core::mem::zeroed()
        }
    }
}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Pod for ARGB<T, A> where T: crate::Pod, A: crate::Pod {}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Pod for ABGR<T, A> where T: crate::Pod, A: crate::Pod {}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Zeroable for ARGB<T, A> where T: crate::Zeroable, A: crate::Zeroable {
    #[track_caller]
    #[inline(always)]
    fn zeroed() -> Self {
        unsafe {
            let _ = assert_no_padding::<T, A, Self>();
            core::mem::zeroed()
        }
    }
}

#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Zeroable for BGRA<T, A> where T: crate::Zeroable, A: crate::Zeroable {
    #[track_caller]
    #[inline(always)]
    fn zeroed() -> Self {
        unsafe {
            let _ = assert_no_padding::<T, A, Self>();
            core::mem::zeroed()
        }
    }
}

#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Pod for Gray<T> where T: crate::Pod {}
#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Pod for GrayAlpha<T, A> where T: crate::Pod, A: crate::Pod {}
#[cfg(feature = "as-bytes")]
unsafe impl<T> crate::Zeroable for Gray<T> where T: crate::Zeroable {}
#[cfg(feature = "as-bytes")]
/// This is unsound. You can disable `as-bytes` feature, enable `bytemuck`, and use `bytemuck::cast_slice()` instead.
unsafe impl<T, A> crate::Zeroable for GrayAlpha<T, A> where T: crate::Zeroable, A: crate::Zeroable {
    #[track_caller]
    #[inline(always)]
    fn zeroed() -> Self {
        unsafe {
            if core::mem::size_of::<A>() + core::mem::size_of::<T>() != core::mem::size_of::<Self>() {
                panic!("type has padding");
            }
            core::mem::zeroed()
        }
    }
}

#[cfg(feature = "as-bytes")]
impl<T: crate::Pod> ComponentBytes<T> for [Gray<T>] {}

#[cfg(feature = "as-bytes")]
impl<T: crate::Pod> ComponentBytes<T> for [GrayAlpha<T>] {}

#[test]
#[allow(dead_code)]
fn shared_impl() {
    struct SharedPixelBuffer<Pixel> {
        data: [Pixel; 1],
    }

    impl<Pixel: Clone + crate::Pod> SharedPixelBuffer<Pixel>
    where
        [Pixel]: crate::ComponentBytes<u8>,
    {
        pub fn as_bytes(&self) -> &[u8] {
            self.data.as_slice().as_bytes()
        }
    }

    let b = SharedPixelBuffer {
        data: [crate::RGB8::new(0,0,0)],
    };
    let _ = b.as_bytes();
}