use crate::Size;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Color {
Bt601Limited,
Bt601Full,
Bt709Limited,
Bt709Full,
}
impl Color {
pub fn infer(size: Size) -> Self {
match size.height <= 576 {
true => Color::Bt601Limited,
false => Color::Bt709Limited,
}
}
#[cfg(target_os = "macos")]
pub(crate) fn with_range(self, limited: bool) -> Self {
match (self, limited) {
(Color::Bt601Limited | Color::Bt601Full, true) => Color::Bt601Limited,
(Color::Bt601Limited | Color::Bt601Full, false) => Color::Bt601Full,
(_, true) => Color::Bt709Limited,
(_, false) => Color::Bt709Full,
}
}
pub(crate) fn limited(self) -> bool {
matches!(self, Color::Bt601Limited | Color::Bt709Limited)
}
pub(crate) fn yuv(self) -> (yuv::YuvRange, yuv::YuvStandardMatrix) {
let range = match self.limited() {
true => yuv::YuvRange::Limited,
false => yuv::YuvRange::Full,
};
let matrix = match self {
Color::Bt601Limited | Color::Bt601Full => yuv::YuvStandardMatrix::Bt601,
Color::Bt709Limited | Color::Bt709Full => yuv::YuvStandardMatrix::Bt709,
};
(range, matrix)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn inference_splits_at_standard_definition() {
assert_eq!(Color::infer(Size::new(720, 480)), Color::Bt601Limited);
assert_eq!(Color::infer(Size::new(720, 576)), Color::Bt601Limited);
assert_eq!(Color::infer(Size::new(1280, 720)), Color::Bt709Limited);
}
#[cfg(target_os = "macos")]
#[test]
fn with_range_keeps_the_matrix() {
assert_eq!(Color::Bt709Limited.with_range(false), Color::Bt709Full);
assert_eq!(Color::Bt709Full.with_range(true), Color::Bt709Limited);
assert_eq!(Color::Bt601Limited.with_range(false), Color::Bt601Full);
}
}