#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum Primaries {
Reserved,
Bt709 = 1,
Unspecified = 2,
Bt470M = 4,
Bt470Bg = 5,
Bt601 = 6,
Smpte240 = 7,
GenericFilm = 8,
Bt2020 = 9,
Xyz = 10,
Smpte431 = 11,
Smpte432 = 12,
Ebu3213 = 22,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum TransferFunction {
Reserved,
Bt709 = 1,
Unspecified = 2,
Bt470M = 4,
Bt470Bg = 5,
Bt601 = 6,
Smpte240 = 7,
Linear = 8,
Log100 = 9,
Log100sqrt10 = 10,
Iec61966 = 11,
Bt1361 = 12,
Srgb = 13,
Bt202010bit = 14,
Bt202012bit = 15,
Smpte2084 = 16,
Smpte428 = 17,
Hlg = 18,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum MatrixCoefficients {
Identity = 0, Bt709 = 1, Unspecified = 2, Reserved = 3, Fcc = 4, Bt470Bg = 5, Smpte170m = 6, Smpte240m = 7, YCgCo = 8, Bt2020Ncl = 9, Bt2020Cl = 10, Smpte2085 = 11, ChromaticityDerivedNCL = 12, ChromaticityDerivedCL = 13, ICtCp = 14, IPtC2 = 15, YCgCoRe = 16, YCgCoRo = 17, }
impl MatrixCoefficients {
pub fn from_u8(v: u8) -> Self {
match v {
0 => MatrixCoefficients::Identity,
1 => MatrixCoefficients::Bt709,
2 => MatrixCoefficients::Unspecified,
3 => MatrixCoefficients::Reserved,
4 => MatrixCoefficients::Fcc,
5 => MatrixCoefficients::Bt470Bg,
6 => MatrixCoefficients::Smpte170m,
7 => MatrixCoefficients::Smpte240m,
8 => MatrixCoefficients::YCgCo,
9 => MatrixCoefficients::Bt2020Ncl,
10 => MatrixCoefficients::Bt2020Cl,
11 => MatrixCoefficients::Smpte2085,
12 => MatrixCoefficients::ChromaticityDerivedNCL,
13 => MatrixCoefficients::ChromaticityDerivedCL,
14 => MatrixCoefficients::ICtCp,
15 => MatrixCoefficients::IPtC2,
16 => MatrixCoefficients::YCgCoRe,
17 => MatrixCoefficients::YCgCoRo,
_ => MatrixCoefficients::Unspecified,
}
}
}
#[derive(Clone, Debug)]
pub enum ColorMetadata {
Cicp(Cicp),
Icc(Vec<u8>),
}
impl ColorMetadata {
pub fn color_encoding(&self) -> Cicp {
match self {
ColorMetadata::Cicp(c) => *c,
ColorMetadata::Icc(_) => Cicp::srgb(),
}
}
}
impl Default for ColorMetadata {
fn default() -> Self {
ColorMetadata::Cicp(Cicp::srgb())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Cicp {
pub primaries: Primaries,
pub transfer: TransferFunction,
pub matrix: MatrixCoefficients,
pub full_range: bool,
pub chroma_sample_position: ChromaSamplePosition,
}
impl Cicp {
pub fn identity_rgb() -> Cicp {
Cicp {
primaries: Primaries::Bt709,
transfer: TransferFunction::Srgb,
matrix: MatrixCoefficients::Identity,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
}
impl Cicp {
pub const fn srgb() -> Self {
Cicp {
primaries: Primaries::Bt709,
transfer: TransferFunction::Srgb,
matrix: MatrixCoefficients::Bt709,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
pub const fn srgb_ycbcr() -> Self {
Cicp {
primaries: Primaries::Bt709,
transfer: TransferFunction::Srgb,
matrix: MatrixCoefficients::Smpte170m,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
pub const fn unspecified() -> Self {
Cicp {
primaries: Primaries::Unspecified,
transfer: TransferFunction::Unspecified,
matrix: MatrixCoefficients::Unspecified,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
pub const fn bt709() -> Self {
Cicp {
primaries: Primaries::Bt709,
transfer: TransferFunction::Bt709,
matrix: MatrixCoefficients::Bt709,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
pub const fn bt2020_pq() -> Self {
Cicp {
primaries: Primaries::Bt2020,
transfer: TransferFunction::Smpte2084,
matrix: MatrixCoefficients::Bt2020Ncl,
full_range: true,
chroma_sample_position: ChromaSamplePosition::Unknown,
}
}
pub fn nclx_payload(&self) -> Vec<u8> {
let mut p = Vec::with_capacity(11);
p.extend_from_slice(b"nclx");
p.extend_from_slice(&(self.primaries as u16).to_be_bytes());
p.extend_from_slice(&(self.transfer as u16).to_be_bytes());
p.extend_from_slice(&(self.matrix as u16).to_be_bytes());
p.push(if self.full_range { 0x80 } else { 0x00 });
p
}
}
impl Default for Cicp {
fn default() -> Self {
Cicp::srgb()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum ChromaSamplePosition {
Unknown = 0,
Vertical = 1,
Colocated = 2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MasteringDisplay {
pub primaries: [(u16, u16); 3],
pub white_point: (u16, u16),
pub max_luminance: u32,
pub min_luminance: u32,
}
impl MasteringDisplay {
pub fn from_floats(p: [(f64, f64); 3], w: (f64, f64), max: f64, min: f64) -> Self {
let q = |v: f64| (v * 50000.0).round() as u16;
MasteringDisplay {
primaries: [
(q(p[0].0), q(p[0].1)),
(q(p[1].0), q(p[1].1)),
(q(p[2].0), q(p[2].1)),
],
white_point: (q(w.0), q(w.1)),
max_luminance: (max * 10000.0).round() as u32,
min_luminance: (min * 10000.0).round() as u32,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ItutT35 {
pub country_code: u8,
pub country_code_extension: Option<u8>,
pub payload: Vec<u8>,
}