use crate::utils;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Cicp {
pub color_primaries: ColorPrimaries,
pub transfer_characteristics: TransferCharacteristics,
pub matrix_coefficients: MatrixCoefficients,
pub video_full_range_flag: VideoRangeFlag,
}
impl Cicp {
pub const SRGB: Cicp = Cicp {
color_primaries: ColorPrimaries::Srgb,
transfer_characteristics: TransferCharacteristics::Gamma24,
matrix_coefficients: MatrixCoefficients::Identity,
video_full_range_flag: VideoRangeFlag::Full,
};
pub const REC2020_LINEAR: Cicp = Cicp {
color_primaries: ColorPrimaries::Rec2020,
transfer_characteristics: TransferCharacteristics::Linear,
matrix_coefficients: MatrixCoefficients::Identity,
video_full_range_flag: VideoRangeFlag::Full,
};
pub fn from_bytes(bytes: &[u8; 4]) -> Result<Self, CicpError> {
let color_primaries = ColorPrimaries::from(bytes[0]);
let transfer_characteristics = TransferCharacteristics::from(bytes[1]);
let matrix_coefficients: MatrixCoefficients = MatrixCoefficients::from(bytes[2]);
let video_full_range_flag = VideoRangeFlag::try_from(bytes[3])
.map_err(|err| CicpError::InvalidVideoFullRangeFlag(err.0))?;
Ok(Self {
color_primaries,
transfer_characteristics,
matrix_coefficients,
video_full_range_flag,
})
}
pub fn to_bytes(&self) -> [u8; 4] {
[
self.color_primaries.into(),
self.transfer_characteristics.into(),
self.matrix_coefficients.into(),
self.video_full_range_flag.into(),
]
}
}
impl From<Cicp> for Vec<u8> {
fn from(value: Cicp) -> Self {
vec![
value.color_primaries.into(),
value.transfer_characteristics.into(),
value.matrix_coefficients.into(),
value.video_full_range_flag.into(),
]
}
}
utils::convertible_enum!(
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ColorPrimaries {
Srgb = 1,
Unspecified = 2,
Rec2020 = 9,
DciP3 = 11,
DisplayP3 = 12,
}
);
utils::convertible_enum!(
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum TransferCharacteristics {
Gamma22 = 1,
Unspecified = 2,
Gamma22_ = 6,
Linear = 8,
Gamma24 = 13,
Gamma22Bit10 = 14,
Gamma22Bit12 = 15,
Pq = 16,
Dci = 17,
Hlg = 18,
}
);
utils::convertible_enum!(
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum MatrixCoefficients {
Identity = 0,
Unspecified = 2,
ICtCp = 14,
}
);
utils::maybe_convertible_enum!(
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum VideoRangeFlag {
Narrow = 0,
Full = 1,
}
);
#[derive(Debug, thiserror::Error)]
pub enum CicpError {
#[error("Invalid video full range flag '{0}'. Expected '0' or '1'.")]
InvalidVideoFullRangeFlag(u8),
}