Skip to main content

grim_rs/
pixel_format.rs

1/// Pixel format variants for 32-bit RGBA-like layouts.
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3#[repr(u32)]
4pub enum PixelFormat {
5    /// A, R, G, B — alpha in byte 0 (most significant).
6    Argb8888 = 0,
7    /// X, R, G, B — alpha unused, byte 0 ignored.
8    Xrgb8888 = 1,
9    /// A, B, G, R — alpha in byte 0.
10    Abgr8888 = 2,
11    /// X, B, G, R — alpha unused.
12    Xbgr8888 = 3,
13}
14
15/// Map a DRM fourcc code to a [`PixelFormat`].
16pub fn fourcc_to_format(fourcc: u32) -> Option<PixelFormat> {
17    match fourcc {
18        0x34325241 => Some(PixelFormat::Argb8888), // DRM_FORMAT_ARGB8888
19        0x34325258 => Some(PixelFormat::Xrgb8888), // DRM_FORMAT_XRGB8888
20        0x34324241 => Some(PixelFormat::Abgr8888), // DRM_FORMAT_ABGR8888
21        0x34324258 => Some(PixelFormat::Xbgr8888), // DRM_FORMAT_XBGR8888
22        _ => None,
23    }
24}
25
26/// Convert 32-bit pixel data from the given [`PixelFormat`] to RGBA byte order.
27///
28/// Conversion is done in-place on the slice. Unrecognized formats are left
29/// unchanged.
30pub fn convert_to_rgba(data: &mut [u8], format: PixelFormat) {
31    match format {
32        PixelFormat::Xrgb8888 => {
33            for chunk in data.chunks_exact_mut(4) {
34                chunk.swap(0, 2);
35                chunk[3] = 255;
36            }
37        }
38        PixelFormat::Argb8888 => {
39            for chunk in data.chunks_exact_mut(4) {
40                chunk.swap(0, 2);
41            }
42        }
43        PixelFormat::Xbgr8888 => {
44            for chunk in data.chunks_exact_mut(4) {
45                chunk[3] = 255;
46            }
47        }
48        PixelFormat::Abgr8888 => {}
49    }
50}