linuxvideo/
pixel_format.rs

1use std::fmt;
2
3/// Four character code (fourcc) defining the encoding of pixel data in an image buffer.
4///
5/// fourcc codes are documented on <https://www.fourcc.org/>.
6#[derive(Clone, Copy, PartialEq, Eq)]
7#[repr(transparent)]
8pub struct PixelFormat(u32);
9
10impl PixelFormat {
11    /// Creates a [`PixelFormat`] from a *fourcc* code.
12    pub const fn from_fourcc(fourcc: [u8; 4]) -> Self {
13        Self(u32::from_le_bytes(fourcc))
14    }
15
16    /// Returns the *fourcc* code represented by `self`.
17    pub const fn as_fourcc(self) -> [u8; 4] {
18        self.0.to_le_bytes()
19    }
20}
21
22// Just a shorthand for `PixelFormat::from_fourcc`.
23const fn f(fourcc: &[u8; 4]) -> PixelFormat {
24    PixelFormat::from_fourcc(*fourcc)
25}
26
27/// Pixel format constants.
28impl PixelFormat {
29    /// **`BGR3`** `bbbbbbbb gggggggg rrrrrrrr`
30    ///
31    /// Same as **`24BG`**.
32    pub const BGR3: Self = f(b"BGR3");
33
34    /// **`RGB3`** `rrrrrrrr gggggggg bbbbbbbb`
35    ///
36    /// Same as **`raw `**.
37    pub const RGB3: Self = f(b"RGB3");
38
39    /// **`AR24`**: `bbbbbbbb gggggggg rrrrrrrr aaaaaaaa`
40    pub const ABGR32: Self = f(b"AR24");
41
42    /// **`XR24`**: `bbbbbbbb gggggggg rrrrrrrr xxxxxxxx`
43    ///
44    /// The `xxxxxxxx` channel data is ignored.
45    pub const XBGR32: Self = f(b"XR24");
46
47    /// **`RA24`**: `aaaaaaaa bbbbbbbb gggggggg rrrrrrrr`
48    pub const BGRA32: Self = f(b"RA24");
49
50    /// **`RX24`**: `xxxxxxxx bbbbbbbb gggggggg rrrrrrrr`
51    pub const BGRX32: Self = f(b"RX24");
52
53    /// **`AB24`**: `rrrrrrrr gggggggg bbbbbbbb aaaaaaaa`
54    pub const RGBA32: Self = f(b"AB24");
55
56    /// **`XB24`**: `rrrrrrrr gggggggg bbbbbbbb xxxxxxxx`
57    ///
58    /// The `xxxxxxxx` channel data is ignored.
59    pub const RGBX32: Self = f(b"XB24");
60
61    /// **`BA24`**: `aaaaaaaa rrrrrrrr gggggggg bbbbbbbb`
62    pub const ARGB32: Self = f(b"BA24");
63
64    /// **`BX24`**: `xxxxxxxx rrrrrrrr gggggggg bbbbbbbb`
65    ///
66    /// The `xxxxxxxx` channel data is ignored.
67    pub const XRGB32: Self = f(b"BX24");
68
69    /// **`BGR4`**: `bbbbbbbb gggggggg rrrrrrrr ????????` **DEPRECATED**
70    ///
71    /// This format is deprecated because the meaning of the last channel is ill-defined and its
72    /// interpretation depends on driver and application. It will either be ignored (`xxxxxxxx` /
73    /// [`Self::XBGR32`]) or treated as an alpha channel (`aaaaaaaa` / [`Self::ABGR32`]), so one of
74    /// those formats should be used instead if possible.
75    pub const BGR32: Self = f(b"BGR4");
76
77    /// **`RGB4`**: `???????? rrrrrrrr gggggggg bbbbbbbb` **DEPRECATED**
78    ///
79    /// This format is deprecated because the meaning of the first channel is ill-defined and its
80    /// interpretation depends on driver and application. It will either be ignored (`xxxxxxxx` /
81    /// [`Self::XRGB32`]) or treated as an alpha channel (`aaaaaaaa` / [`Self::ARGB32`]), so one of
82    /// those formats should be used instead if possible.
83    pub const RGB32: Self = f(b"RGB4");
84
85    /// **`YUYV`**: `yyyyyyyy uuuuuuuu YYYYYYYY vvvvvvvv`
86    ///
87    /// Packed YUV/YCbCr data with 4:2:2 chroma subsampling.
88    ///
89    /// `uuuuuuuu` and `vvvvvvvv` are shared by 2 neighboring pixels, while `yyyyyyyy` is the left
90    /// pixel's Y value, and `YYYYYYYY` is the right pixel's Y value.
91    pub const YUYV: Self = f(b"YUYV");
92
93    /// **`MJPG`**: Motion JPEG, a sequence of JPEG images with omitted huffman tables.
94    ///
95    /// The transmitted JPEG images lack the "DHT" frame (Define Huffman Table), and instead use a
96    /// predefined one. Most common JPEG decoders will handle this fine and don't need any extra
97    /// preprocessing.
98    pub const MJPG: Self = f(b"MJPG");
99
100    /// **`JPEG`**: Data is a sequence of regular JFIF JPEG still images.
101    ///
102    /// Images can be decoded with any off-the-shelf JPEG decoder, no preprocessing is needed.
103    pub const JPEG: Self = f(b"JPEG");
104
105    /// **`UVCH`**: UVC payload header metadata.
106    ///
107    /// Data is a stream of [`UvcMetadata`][crate::uvc::UvcMetadata] structures.
108    pub const UVC: Self = f(b"UVCH");
109}
110
111impl fmt::Display for PixelFormat {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        let bytes = self.0.to_le_bytes();
114        let [a, b, c, d] = bytes.map(|b| (b as char).escape_default());
115        write!(f, "{}{}{}{}", a, b, c, d)
116    }
117}
118
119impl fmt::Debug for PixelFormat {
120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121        <Self as fmt::Display>::fmt(self, f)
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn simple() {
131        assert_eq!(PixelFormat::RGBA32.to_string(), "AB24");
132    }
133}