1use std::fmt::{self, Display};
2
3#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
5#[repr(transparent)]
6pub struct FourCC(pub u32);
7
8impl FourCC {
9 pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Self {
11 Self((a as u32) | ((b as u32) << 8) | ((c as u32) << 16) | ((d as u32) << 24))
12 }
13
14 }
20
21impl Display for FourCC {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 let bytes = self.0.to_le_bytes();
24
25 write!(f, "{}", String::from_utf8_lossy(&bytes))
26 }
27}
28
29impl fmt::Debug for FourCC {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "FourCC({})", self)
32 }
33}
34
35impl FourCC {
37 pub const YUYV: Self = Self::new(b'Y', b'U', b'Y', b'V');
40 pub const UYVY: Self = Self::new(b'U', b'Y', b'V', b'Y');
42 pub const NV12: Self = Self::new(b'N', b'V', b'1', b'2');
44 pub const YV12: Self = Self::new(b'Y', b'V', b'1', b'2');
46
47 pub const BGR3: Self = Self::new(b'B', b'G', b'R', b'3');
50 pub const RGB3: Self = Self::new(b'R', b'G', b'B', b'3');
52 pub const RGBA: Self = Self::new(b'R', b'G', b'B', b'A');
54
55 pub const MJPEG: Self = Self::new(b'M', b'J', b'P', b'G');
58 pub const H264: Self = Self::new(b'H', b'2', b'6', b'4');
60
61 pub const BA81: Self = Self::new(b'B', b'A', b'8', b'1');
67 pub const GBRG: Self = Self::new(b'G', b'B', b'R', b'G');
69 pub const GRBG: Self = Self::new(b'G', b'R', b'B', b'G');
71 pub const RGGB: Self = Self::new(b'R', b'G', b'G', b'B');
73
74 pub const Z16: Self = Self::new(b'Z', b'1', b'6', b' ');
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum PixelFormat {
82 Known(FourCC),
84 Unknown(u32),
86}
87
88impl PixelFormat {
89 pub fn is_compressed(&self) -> bool {
91 match self {
92 Self::Known(cc) => matches!(*cc, FourCC::MJPEG | FourCC::H264),
93 _ => false,
94 }
95 }
96
97 pub fn is_bayer(&self) -> bool {
99 match self {
100 Self::Known(cc) => matches!(
101 *cc,
102 FourCC::BA81 | FourCC::GBRG | FourCC::GRBG | FourCC::RGGB
103 ),
104 _ => false,
105 }
106 }
107
108 pub fn bpp_estimate(&self) -> u32 {
110 match self {
111 Self::Known(cc) => match *cc {
112 FourCC::YUYV | FourCC::UYVY => 16,
113 FourCC::BGR3 | FourCC::RGB3 => 24,
114 FourCC::RGBA => 32,
115 FourCC::NV12 | FourCC::YV12 => 12, FourCC::Z16 => 16,
117 FourCC::BA81 | FourCC::GBRG | FourCC::GRBG | FourCC::RGGB => 8,
119 FourCC::MJPEG | FourCC::H264 => 4,
121 _ => 0,
122 },
123 _ => 0,
124 }
125 }
126}
127
128impl From<u32> for PixelFormat {
129 fn from(val: u32) -> Self {
130 Self::Known(FourCC(val))
134 }
135}
136
137impl From<FourCC> for PixelFormat {
138 fn from(cc: FourCC) -> Self {
139 Self::Known(cc)
140 }
141}
142
143impl PartialEq<PixelFormat> for FourCC {
144 fn eq(&self, other: &PixelFormat) -> bool {
145 match other {
146 PixelFormat::Known(cc) => self == cc,
147 PixelFormat::Unknown(val) => self.0 == *val,
148 }
149 }
150}
151
152impl PartialEq<FourCC> for PixelFormat {
154 fn eq(&self, other: &FourCC) -> bool {
155 match self {
156 PixelFormat::Known(cc) => cc == other,
157 PixelFormat::Unknown(val) => *val == other.0,
158 }
159 }
160}