use crate::boxes::{bx, push_u32};
use crate::fourcc::{CONFIG_BOX, CONFIG_VERSION};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Subsampling {
Yuv420,
Yuv422,
Yuv444,
Mono,
}
impl Subsampling {
fn to_byte(self) -> u8 {
match self {
Subsampling::Yuv420 => 0,
Subsampling::Yuv422 => 1,
Subsampling::Yuv444 => 2,
Subsampling::Mono => 3,
}
}
fn from_byte(b: u8) -> Option<Subsampling> {
Some(match b {
0 => Subsampling::Yuv420,
1 => Subsampling::Yuv422,
2 => Subsampling::Yuv444,
3 => Subsampling::Mono,
_ => return None,
})
}
pub fn channels(self) -> u8 {
match self {
Subsampling::Mono => 1,
_ => 3,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Config {
pub bit_depth: u8,
pub subsampling: Subsampling,
pub full_still_picture_header: bool,
}
impl Default for Config {
fn default() -> Self {
Config {
bit_depth: 8,
subsampling: Subsampling::Yuv420,
full_still_picture_header: true,
}
}
}
impl Config {
pub fn to_box(self) -> Vec<u8> {
let mut b = Vec::with_capacity(8);
b.push(CONFIG_VERSION);
b.push(self.bit_depth);
b.push(self.subsampling.to_byte());
b.push(self.full_still_picture_header as u8);
push_u32(&mut b, 0); bx(CONFIG_BOX, &b)
}
pub fn from_body(body: &[u8]) -> Option<Config> {
if body.len() < 8 || *body.first()? != CONFIG_VERSION {
return None;
}
Some(Config {
bit_depth: *body.get(1)?,
subsampling: Subsampling::from_byte(*body.get(2)?)?,
full_still_picture_header: *body.get(3)? != 0,
})
}
}