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}