use std::str::FromStr;
use v4l::FourCC;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PixelFormat {
#[default]
YUYV,
UYVY,
MJPG,
Custom([u8; 4]),
}
impl PixelFormat {
pub fn to_fourcc(&self) -> FourCC {
match self {
Self::YUYV => FourCC::new(b"YUYV"),
Self::UYVY => FourCC::new(b"UYVY"),
Self::MJPG => FourCC::new(b"MJPG"),
Self::Custom(bytes) => FourCC::new(bytes),
}
}
pub fn from_fourcc(fourcc: FourCC) -> Self {
match fourcc.str() {
Ok("YUYV") => Self::YUYV,
Ok("UYVY") => Self::UYVY,
Ok("MJPG") => Self::MJPG,
_ => {
let bytes = [
fourcc.repr[0],
fourcc.repr[1],
fourcc.repr[2],
fourcc.repr[3],
];
Self::Custom(bytes)
}
}
}
pub fn bytes_per_pixel(&self) -> Option<usize> {
match self {
Self::YUYV => Some(2), Self::UYVY => Some(2), Self::MJPG => None, Self::Custom(_) => None, }
}
pub fn as_str(&self) -> &str {
match self {
Self::YUYV => "YUYV",
Self::UYVY => "UYVY",
Self::MJPG => "MJPG",
Self::Custom(_) => "custom",
}
}
}
impl std::fmt::Display for PixelFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::YUYV => write!(f, "YUYV"),
Self::UYVY => write!(f, "UYVY"),
Self::MJPG => write!(f, "MJPG"),
Self::Custom(bytes) => {
let fourcc_str = std::str::from_utf8(bytes).unwrap_or("????");
write!(f, "{fourcc_str}")
}
}
}
}
impl FromStr for PixelFormat {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"YUYV" => Ok(Self::YUYV),
"UYVY" => Ok(Self::UYVY),
"MJPG" => Ok(Self::MJPG),
_ => Err(format!("Invalid pixel format: {s}")),
}
}
}