use derive_more::{Display, IsVariant};
pub const DOMAIN_EXT_BASE: u32 = 0x8000_0000;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, IsVariant)]
#[display("{}", self.as_str())]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::matrix")
)]
pub enum Matrix {
Unknown(u32),
Rgb,
Bt601,
Bt709,
Unspecified,
Fcc,
Bt470Bg,
Smpte170M,
Smpte240m,
YCgCo,
Bt2020Ncl,
Bt2020Cl,
Smpte2085,
ChromaDerivedNcl,
ChromaDerivedCl,
Ictcp,
IptC2,
YCgCoRe,
YCgCoRo,
}
impl Default for Matrix {
#[inline]
fn default() -> Self {
Self::Unspecified
}
}
impl Matrix {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Unknown(_) => "unknown",
Self::Rgb => "rgb",
Self::Bt601 => "bt601",
Self::Bt709 => "bt709",
Self::Unspecified => "unspecified",
Self::Fcc => "fcc",
Self::Bt470Bg => "bt470bg",
Self::Smpte170M => "smpte170m",
Self::Smpte240m => "smpte240m",
Self::YCgCo => "ycgco",
Self::Bt2020Ncl => "bt2020nc",
Self::Bt2020Cl => "bt2020c",
Self::Smpte2085 => "smpte2085",
Self::ChromaDerivedNcl => "chroma-derived-nc",
Self::ChromaDerivedCl => "chroma-derived-c",
Self::Ictcp => "ictcp",
Self::IptC2 => "ipt-c2",
Self::YCgCoRe => "ycgco-re",
Self::YCgCoRo => "ycgco-ro",
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::Rgb => 0,
Self::Bt601 => DOMAIN_EXT_BASE,
Self::Bt709 => 1,
Self::Unspecified => 2,
Self::Fcc => 4,
Self::Bt470Bg => 5,
Self::Smpte170M => 6,
Self::Smpte240m => 7,
Self::YCgCo => 8,
Self::Bt2020Ncl => 9,
Self::Bt2020Cl => 10,
Self::Smpte2085 => 11,
Self::ChromaDerivedNcl => 12,
Self::ChromaDerivedCl => 13,
Self::Ictcp => 14,
Self::IptC2 => 15,
Self::YCgCoRe => 16,
Self::YCgCoRo => 17,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
0 => Self::Rgb,
1 => Self::Bt709,
2 => Self::Unspecified,
4 => Self::Fcc,
5 => Self::Bt470Bg,
6 => Self::Smpte170M,
7 => Self::Smpte240m,
8 => Self::YCgCo,
9 => Self::Bt2020Ncl,
10 => Self::Bt2020Cl,
11 => Self::Smpte2085,
12 => Self::ChromaDerivedNcl,
13 => Self::ChromaDerivedCl,
14 => Self::Ictcp,
15 => Self::IptC2,
16 => Self::YCgCoRe,
17 => Self::YCgCoRo,
DOMAIN_EXT_BASE => Self::Bt601,
_ => Self::Unknown(v),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, IsVariant)]
#[display("{}", self.as_str())]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::primaries")
)]
pub enum Primaries {
Unknown(u32),
Bt709,
Unspecified,
Bt470M,
Bt470Bg,
Smpte170M,
Smpte240M,
Film,
Bt2020,
SmpteSt428,
SmpteRp431,
SmpteEg432,
Ebu3213E,
}
impl Default for Primaries {
#[inline]
fn default() -> Self {
Self::Unspecified
}
}
impl Primaries {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Unknown(_) => "unknown",
Self::Bt709 => "bt709",
Self::Unspecified => "unspecified",
Self::Bt470M => "bt470m",
Self::Bt470Bg => "bt470bg",
Self::Smpte170M => "smpte170m",
Self::Smpte240M => "smpte240m",
Self::Film => "film",
Self::Bt2020 => "bt2020",
Self::SmpteSt428 => "smpte428",
Self::SmpteRp431 => "smpte431",
Self::SmpteEg432 => "smpte432",
Self::Ebu3213E => "ebu3213",
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::Bt709 => 1,
Self::Unspecified => 2,
Self::Bt470M => 4,
Self::Bt470Bg => 5,
Self::Smpte170M => 6,
Self::Smpte240M => 7,
Self::Film => 8,
Self::Bt2020 => 9,
Self::SmpteSt428 => 10,
Self::SmpteRp431 => 11,
Self::SmpteEg432 => 12,
Self::Ebu3213E => 22,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
1 => Self::Bt709,
2 => Self::Unspecified,
4 => Self::Bt470M,
5 => Self::Bt470Bg,
6 => Self::Smpte170M,
7 => Self::Smpte240M,
8 => Self::Film,
9 => Self::Bt2020,
10 => Self::SmpteSt428,
11 => Self::SmpteRp431,
12 => Self::SmpteEg432,
22 => Self::Ebu3213E,
_ => Self::Unknown(v),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, IsVariant)]
#[display("{}", self.as_str())]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::transfer")
)]
pub enum Transfer {
Unknown(u32),
Bt709,
Unspecified,
Gamma22,
Gamma28,
Smpte170M,
Smpte240M,
Linear,
Log100,
Log316,
Iec6196624,
Bt1361Ecg,
Iec6196621,
Bt2020_10Bit,
Bt2020_12Bit,
SmpteSt2084Pq,
SmpteSt428,
AribStdB67Hlg,
}
impl Default for Transfer {
#[inline]
fn default() -> Self {
Self::Unspecified
}
}
impl Transfer {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Unknown(_) => "unknown",
Self::Bt709 => "bt709",
Self::Unspecified => "unspecified",
Self::Gamma22 => "gamma22",
Self::Gamma28 => "gamma28",
Self::Smpte170M => "smpte170m",
Self::Smpte240M => "smpte240m",
Self::Linear => "linear",
Self::Log100 => "log100",
Self::Log316 => "log316",
Self::Iec6196624 => "iec61966-2-4",
Self::Bt1361Ecg => "bt1361e",
Self::Iec6196621 => "iec61966-2-1",
Self::Bt2020_10Bit => "bt2020-10",
Self::Bt2020_12Bit => "bt2020-12",
Self::SmpteSt2084Pq => "smpte2084",
Self::SmpteSt428 => "smpte428",
Self::AribStdB67Hlg => "arib-std-b67",
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::Bt709 => 1,
Self::Unspecified => 2,
Self::Gamma22 => 4,
Self::Gamma28 => 5,
Self::Smpte170M => 6,
Self::Smpte240M => 7,
Self::Linear => 8,
Self::Log100 => 9,
Self::Log316 => 10,
Self::Iec6196624 => 11,
Self::Bt1361Ecg => 12,
Self::Iec6196621 => 13,
Self::Bt2020_10Bit => 14,
Self::Bt2020_12Bit => 15,
Self::SmpteSt2084Pq => 16,
Self::SmpteSt428 => 17,
Self::AribStdB67Hlg => 18,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
1 => Self::Bt709,
2 => Self::Unspecified,
4 => Self::Gamma22,
5 => Self::Gamma28,
6 => Self::Smpte170M,
7 => Self::Smpte240M,
8 => Self::Linear,
9 => Self::Log100,
10 => Self::Log316,
11 => Self::Iec6196624,
12 => Self::Bt1361Ecg,
13 => Self::Iec6196621,
14 => Self::Bt2020_10Bit,
15 => Self::Bt2020_12Bit,
16 => Self::SmpteSt2084Pq,
17 => Self::SmpteSt428,
18 => Self::AribStdB67Hlg,
_ => Self::Unknown(v),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, IsVariant)]
#[display("{}", self.as_str())]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::dynamic_range")
)]
pub enum DynamicRange {
Unknown(u32),
Unspecified,
Limited,
Full,
}
impl Default for DynamicRange {
#[inline]
fn default() -> Self {
Self::Unspecified
}
}
impl DynamicRange {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Unknown(_) => "unknown",
Self::Unspecified => "unspecified",
Self::Limited => "tv",
Self::Full => "pc",
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::Unspecified => 0,
Self::Limited => 1,
Self::Full => 2,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
0 => Self::Unspecified,
1 => Self::Limited,
2 => Self::Full,
_ => Self::Unknown(v),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, IsVariant)]
#[display("{}", self.as_str())]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::chroma_location")
)]
pub enum ChromaLocation {
Unknown(u32),
Unspecified,
Left,
Center,
TopLeft,
Top,
BottomLeft,
Bottom,
}
impl Default for ChromaLocation {
#[inline]
fn default() -> Self {
Self::Unspecified
}
}
impl ChromaLocation {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Unknown(_) => "unknown",
Self::Unspecified => "unspecified",
Self::Left => "left",
Self::Center => "center",
Self::TopLeft => "topleft",
Self::Top => "top",
Self::BottomLeft => "bottomleft",
Self::Bottom => "bottom",
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::Unspecified => 0,
Self::Left => 1,
Self::Center => 2,
Self::TopLeft => 3,
Self::Top => 4,
Self::BottomLeft => 5,
Self::Bottom => 6,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
0 => Self::Unspecified,
1 => Self::Left,
2 => Self::Center,
3 => Self::TopLeft,
4 => Self::Top,
5 => Self::BottomLeft,
6 => Self::Bottom,
_ => Self::Unknown(v),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::info")
)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Info {
primaries: Primaries,
transfer: Transfer,
matrix: Matrix,
range: DynamicRange,
chroma_location: ChromaLocation,
}
impl Default for Info {
#[cfg_attr(not(tarpaulin), inline(always))]
fn default() -> Self {
Self::UNSPECIFIED
}
}
impl Info {
pub const UNSPECIFIED: Self = Self {
primaries: Primaries::Unspecified,
transfer: Transfer::Unspecified,
matrix: Matrix::Unspecified,
range: DynamicRange::Unspecified,
chroma_location: ChromaLocation::Unspecified,
};
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(
primaries: Primaries,
transfer: Transfer,
matrix: Matrix,
range: DynamicRange,
chroma_location: ChromaLocation,
) -> Self {
Self {
primaries,
transfer,
matrix,
range,
chroma_location,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn primaries(&self) -> Primaries {
self.primaries
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn transfer(&self) -> Transfer {
self.transfer
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn matrix(&self) -> Matrix {
self.matrix
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn range(&self) -> DynamicRange {
self.range
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn chroma_location(&self) -> ChromaLocation {
self.chroma_location
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_primaries(mut self, v: Primaries) -> Self {
self.primaries = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_transfer(mut self, v: Transfer) -> Self {
self.transfer = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_matrix(mut self, v: Matrix) -> Self {
self.matrix = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_range(mut self, v: DynamicRange) -> Self {
self.range = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_chroma_location(mut self, v: ChromaLocation) -> Self {
self.chroma_location = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_primaries(&mut self, v: Primaries) -> &mut Self {
self.primaries = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_transfer(&mut self, v: Transfer) -> &mut Self {
self.transfer = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_matrix(&mut self, v: Matrix) -> &mut Self {
self.matrix = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_range(&mut self, v: DynamicRange) -> &mut Self {
self.range = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_chroma_location(&mut self, v: ChromaLocation) -> &mut Self {
self.chroma_location = v;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant)]
#[non_exhaustive]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::dcp_target_gamut")
)]
pub enum DcpTargetGamut {
Unknown(u32),
DciP3,
Rec709,
Rec2020,
}
impl Default for DcpTargetGamut {
#[inline]
fn default() -> Self {
Self::DciP3
}
}
impl DcpTargetGamut {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn default_dcp() -> Self {
Self::DciP3
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> u32 {
match self {
Self::Unknown(v) => *v,
Self::DciP3 => 0,
Self::Rec709 => 1,
Self::Rec2020 => 2,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Self {
match v {
0 => Self::DciP3,
1 => Self::Rec709,
2 => Self::Rec2020,
_ => Self::Unknown(v),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::content_light_level")
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ContentLightLevel {
max_cll: u32,
max_fall: u32,
}
impl ContentLightLevel {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(max_cll: u32, max_fall: u32) -> Self {
Self { max_cll, max_fall }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_cll(&self) -> u32 {
self.max_cll
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_fall(&self) -> u32 {
self.max_fall
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_max_cll(mut self, v: u32) -> Self {
self.max_cll = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_max_fall(mut self, v: u32) -> Self {
self.max_fall = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_cll(&mut self, v: u32) -> &mut Self {
self.max_cll = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_fall(&mut self, v: u32) -> &mut Self {
self.max_fall = v;
self
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::chroma_coord")
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ChromaCoord {
x: u32,
y: u32,
}
impl ChromaCoord {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(x: u32, y: u32) -> Self {
Self { x, y }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn x(&self) -> u32 {
self.x
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn y(&self) -> u32 {
self.y
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_x(mut self, x: u32) -> Self {
self.x = x;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_y(mut self, y: u32) -> Self {
self.y = y;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_x(&mut self, x: u32) -> &mut Self {
self.x = x;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_y(&mut self, y: u32) -> &mut Self {
self.y = y;
self
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::mastering_display")
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MasteringDisplay {
display_primaries: [ChromaCoord; 3],
white_point: ChromaCoord,
max_luminance: u32,
min_luminance: u32,
}
impl MasteringDisplay {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(
display_primaries: [ChromaCoord; 3],
white_point: ChromaCoord,
max_luminance: u32,
min_luminance: u32,
) -> Self {
Self {
display_primaries,
white_point,
max_luminance,
min_luminance,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn display_primaries(&self) -> [ChromaCoord; 3] {
self.display_primaries
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn white_point(&self) -> ChromaCoord {
self.white_point
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn max_luminance(&self) -> u32 {
self.max_luminance
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn min_luminance(&self) -> u32 {
self.min_luminance
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_display_primaries(mut self, v: [ChromaCoord; 3]) -> Self {
self.display_primaries = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_white_point(mut self, v: ChromaCoord) -> Self {
self.white_point = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_max_luminance(mut self, v: u32) -> Self {
self.max_luminance = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_min_luminance(mut self, v: u32) -> Self {
self.min_luminance = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_display_primaries(&mut self, v: [ChromaCoord; 3]) -> &mut Self {
self.display_primaries = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_white_point(&mut self, v: ChromaCoord) -> &mut Self {
self.white_point = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_max_luminance(&mut self, v: u32) -> &mut Self {
self.max_luminance = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_min_luminance(&mut self, v: u32) -> &mut Self {
self.min_luminance = v;
self
}
}
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(default)
)]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::hdr_static_metadata")
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HdrStaticMetadata {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
mastering: Option<MasteringDisplay>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
content_light: Option<ContentLightLevel>,
}
impl HdrStaticMetadata {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(
mastering: Option<MasteringDisplay>,
content_light: Option<ContentLightLevel>,
) -> Self {
Self {
mastering,
content_light,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn mastering(&self) -> Option<MasteringDisplay> {
self.mastering
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn content_light(&self) -> Option<ContentLightLevel> {
self.content_light
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_mastering(mut self, v: Option<MasteringDisplay>) -> Self {
self.mastering = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_content_light(mut self, v: Option<ContentLightLevel>) -> Self {
self.content_light = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_mastering(&mut self, v: Option<MasteringDisplay>) -> &mut Self {
self.mastering = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_content_light(&mut self, v: Option<ContentLightLevel>) -> &mut Self {
self.content_light = v;
self
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::coded::dolby_vision_config")
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DolbyVisionConfig {
profile: u8,
level: u8,
rpu_present: bool,
el_present: bool,
bl_signal_compat_id: u8,
}
impl DolbyVisionConfig {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(
profile: u8,
level: u8,
rpu_present: bool,
el_present: bool,
bl_signal_compat_id: u8,
) -> Self {
Self {
profile,
level,
rpu_present,
el_present,
bl_signal_compat_id,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn profile(&self) -> u8 {
self.profile
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn level(&self) -> u8 {
self.level
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rpu_present(&self) -> bool {
self.rpu_present
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn el_present(&self) -> bool {
self.el_present
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bl_signal_compat_id(&self) -> u8 {
self.bl_signal_compat_id
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_profile(mut self, v: u8) -> Self {
self.profile = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_level(mut self, v: u8) -> Self {
self.level = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_rpu_present(mut self) -> Self {
self.rpu_present = true;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn maybe_rpu_present(mut self, v: bool) -> Self {
self.rpu_present = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_el_present(mut self) -> Self {
self.el_present = true;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn maybe_el_present(mut self, v: bool) -> Self {
self.el_present = v;
self
}
#[must_use]
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_bl_signal_compat_id(mut self, v: u8) -> Self {
self.bl_signal_compat_id = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_profile(&mut self, v: u8) -> &mut Self {
self.profile = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_level(&mut self, v: u8) -> &mut Self {
self.level = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_rpu_present(&mut self) -> &mut Self {
self.rpu_present = true;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn update_rpu_present(&mut self, v: bool) -> &mut Self {
self.rpu_present = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn clear_rpu_present(&mut self) -> &mut Self {
self.rpu_present = false;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_el_present(&mut self) -> &mut Self {
self.el_present = true;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn update_el_present(&mut self, v: bool) -> &mut Self {
self.el_present = v;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn clear_el_present(&mut self) -> &mut Self {
self.el_present = false;
self
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn set_bl_signal_compat_id(&mut self, v: u8) -> &mut Self {
self.bl_signal_compat_id = v;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_match_spec() {
assert!(matches!(Matrix::default(), Matrix::Unspecified));
assert!(matches!(Primaries::default(), Primaries::Unspecified));
assert!(matches!(Transfer::default(), Transfer::Unspecified));
assert!(matches!(DynamicRange::default(), DynamicRange::Unspecified));
assert!(matches!(
ChromaLocation::default(),
ChromaLocation::Unspecified
));
assert!(matches!(DcpTargetGamut::default(), DcpTargetGamut::DciP3));
}
#[test]
fn is_variant_helpers_compile_for_each_enum() {
assert!(Matrix::Bt709.is_bt_709());
assert!(Matrix::Rgb.is_rgb());
assert!(Primaries::Bt2020.is_bt_2020());
assert!(Transfer::SmpteSt2084Pq.is_smpte_st_2084_pq());
assert!(DynamicRange::Full.is_full());
assert!(ChromaLocation::Center.is_center());
}
#[test]
fn copy_and_eq() {
let m1 = Matrix::Bt709;
let m2 = m1; assert_eq!(m1, m2);
}
#[test]
fn color_info_default_is_all_unspecified() {
let ci = Info::default();
assert_eq!(ci, Info::UNSPECIFIED);
assert!(ci.primaries().is_unspecified());
assert!(ci.matrix().is_unspecified());
assert!(ci.transfer().is_unspecified());
assert!(ci.range().is_unspecified());
assert!(ci.chroma_location().is_unspecified());
}
#[test]
fn color_info_builders_chain() {
let ci = Info::UNSPECIFIED
.with_primaries(Primaries::Bt2020)
.with_transfer(Transfer::SmpteSt2084Pq)
.with_matrix(Matrix::Bt2020Ncl)
.with_range(DynamicRange::Limited)
.with_chroma_location(ChromaLocation::Left);
assert!(ci.primaries().is_bt_2020());
assert!(ci.transfer().is_smpte_st_2084_pq());
assert!(ci.matrix().is_bt_2020_ncl());
assert!(ci.range().is_limited());
assert!(ci.chroma_location().is_left());
}
#[test]
fn color_info_setters_chain() {
let mut ci = Info::UNSPECIFIED;
ci.set_primaries(Primaries::Bt709)
.set_transfer(Transfer::Bt709)
.set_matrix(Matrix::Bt709)
.set_range(DynamicRange::Limited)
.set_chroma_location(ChromaLocation::Left);
assert!(ci.primaries().is_bt_709());
assert!(ci.range().is_limited());
}
#[test]
fn color_info_const_construction() {
const CI: Info = Info::new(
Primaries::Bt709,
Transfer::Bt709,
Matrix::Bt709,
DynamicRange::Limited,
ChromaLocation::Left,
);
assert!(CI.matrix().is_bt_709());
}
#[cfg(feature = "std")]
#[test]
fn as_str_matches_display() {
use std::format;
for (s, d) in [
(Matrix::Bt709.as_str(), format!("{}", Matrix::Bt709)),
(Matrix::Bt2020Ncl.as_str(), format!("{}", Matrix::Bt2020Ncl)),
(Matrix::YCgCo.as_str(), format!("{}", Matrix::YCgCo)),
] {
assert_eq!(s, d, "Matrix as_str/Display mismatch");
}
assert_eq!(Matrix::Bt2020Ncl.as_str(), "bt2020nc");
assert_eq!(Matrix::Smpte240m.as_str(), "smpte240m");
assert_eq!(Matrix::YCgCo.as_str(), "ycgco");
assert_eq!(Primaries::SmpteSt428.as_str(), "smpte428");
assert_eq!(Transfer::SmpteSt2084Pq.as_str(), "smpte2084");
assert_eq!(Transfer::Bt2020_10Bit.as_str(), "bt2020-10");
assert_eq!(Transfer::Gamma22.as_str(), "gamma22");
assert_eq!(Transfer::Gamma28.as_str(), "gamma28");
assert_eq!(DynamicRange::Limited.as_str(), "tv");
assert_eq!(DynamicRange::Full.as_str(), "pc");
assert_eq!(ChromaLocation::TopLeft.as_str(), "topleft");
}
#[test]
fn enum_u32_uses_ffmpeg_codes_and_round_trips() {
assert_eq!(Primaries::Unspecified.to_u32(), 2);
assert_eq!(Primaries::Bt709.to_u32(), 1);
assert_eq!(Primaries::Ebu3213E.to_u32(), 22);
assert_eq!(Transfer::Unspecified.to_u32(), 2);
assert_eq!(Transfer::SmpteSt2084Pq.to_u32(), 16);
assert_eq!(Transfer::AribStdB67Hlg.to_u32(), 18);
assert_eq!(Matrix::Rgb.to_u32(), 0);
assert_eq!(Matrix::Unspecified.to_u32(), 2);
assert_eq!(Matrix::Ictcp.to_u32(), 14);
assert_eq!(DynamicRange::Unspecified.to_u32(), 0);
assert_eq!(DynamicRange::Limited.to_u32(), 1);
assert_eq!(DynamicRange::Full.to_u32(), 2);
assert_eq!(ChromaLocation::Unspecified.to_u32(), 0);
assert_eq!(Matrix::default(), Matrix::Unspecified);
assert_eq!(Primaries::default(), Primaries::Unspecified);
assert_eq!(Transfer::default(), Transfer::Unspecified);
assert_eq!(DynamicRange::default(), DynamicRange::Unspecified);
assert_eq!(ChromaLocation::default(), ChromaLocation::Unspecified);
assert_eq!(DcpTargetGamut::default(), DcpTargetGamut::DciP3);
for m in [
Matrix::Rgb,
Matrix::Bt601,
Matrix::Bt709,
Matrix::Unspecified,
Matrix::Fcc,
Matrix::Bt470Bg,
Matrix::Smpte170M,
Matrix::Smpte240m,
Matrix::YCgCo,
Matrix::Bt2020Ncl,
Matrix::Bt2020Cl,
Matrix::Smpte2085,
Matrix::ChromaDerivedNcl,
Matrix::ChromaDerivedCl,
Matrix::Ictcp,
Matrix::IptC2,
Matrix::YCgCoRe,
Matrix::YCgCoRo,
] {
assert_eq!(Matrix::from_u32(m.to_u32()), m);
}
for p in [
Primaries::Bt709,
Primaries::Unspecified,
Primaries::Bt470M,
Primaries::Bt470Bg,
Primaries::Smpte170M,
Primaries::Smpte240M,
Primaries::Film,
Primaries::Bt2020,
Primaries::SmpteSt428,
Primaries::SmpteRp431,
Primaries::SmpteEg432,
Primaries::Ebu3213E,
] {
assert_eq!(Primaries::from_u32(p.to_u32()), p);
}
for t in [
Transfer::Bt709,
Transfer::Unspecified,
Transfer::Gamma22,
Transfer::Gamma28,
Transfer::Smpte170M,
Transfer::Smpte240M,
Transfer::Linear,
Transfer::Log100,
Transfer::Log316,
Transfer::Iec6196624,
Transfer::Bt1361Ecg,
Transfer::Iec6196621,
Transfer::Bt2020_10Bit,
Transfer::Bt2020_12Bit,
Transfer::SmpteSt2084Pq,
Transfer::SmpteSt428,
Transfer::AribStdB67Hlg,
] {
assert_eq!(Transfer::from_u32(t.to_u32()), t);
}
for r in [
DynamicRange::Unspecified,
DynamicRange::Limited,
DynamicRange::Full,
] {
assert_eq!(DynamicRange::from_u32(r.to_u32()), r);
}
for c in [
ChromaLocation::Unspecified,
ChromaLocation::Left,
ChromaLocation::Center,
ChromaLocation::TopLeft,
ChromaLocation::Top,
ChromaLocation::BottomLeft,
ChromaLocation::Bottom,
] {
assert_eq!(ChromaLocation::from_u32(c.to_u32()), c);
}
for g in [
DcpTargetGamut::DciP3,
DcpTargetGamut::Rec709,
DcpTargetGamut::Rec2020,
] {
assert_eq!(DcpTargetGamut::from_u32(g.to_u32()), g);
}
assert_eq!(Matrix::from_u32(9_999), Matrix::Unknown(9_999));
assert_eq!(Matrix::Unknown(9_999).to_u32(), 9_999);
assert_eq!(Primaries::from_u32(3), Primaries::Unknown(3));
assert_eq!(Primaries::from_u32(0), Primaries::Unknown(0));
assert_eq!(Transfer::from_u32(3), Transfer::Unknown(3));
assert_eq!(DynamicRange::from_u32(7), DynamicRange::Unknown(7));
assert_eq!(DynamicRange::Unknown(7).to_u32(), 7);
assert_eq!(ChromaLocation::from_u32(42), ChromaLocation::Unknown(42));
assert_eq!(
DcpTargetGamut::from_u32(9_999),
DcpTargetGamut::Unknown(9_999)
);
assert_eq!(DcpTargetGamut::Unknown(9_999).to_u32(), 9_999);
}
#[test]
fn color_matrix_bt601_is_domain_variant() {
assert_eq!(Matrix::Bt601.as_str(), "bt601");
#[cfg(feature = "std")]
{
use std::format;
assert_eq!(format!("{}", Matrix::Bt601), "bt601");
}
assert_eq!(Matrix::Bt601.to_u32(), DOMAIN_EXT_BASE);
assert_eq!(Matrix::Bt601.to_u32(), 0x8000_0000);
assert_eq!(Matrix::from_u32(0x8000_0000), Matrix::Bt601);
assert_eq!(Matrix::from_u32(Matrix::Bt601.to_u32()), Matrix::Bt601);
assert_eq!(Matrix::from_u32(5), Matrix::Bt470Bg);
assert_eq!(Matrix::from_u32(6), Matrix::Smpte170M);
assert_ne!(Matrix::from_u32(5), Matrix::Bt601);
assert_ne!(Matrix::from_u32(6), Matrix::Bt601);
assert_eq!(Matrix::default(), Matrix::Unspecified);
assert_ne!(Matrix::default(), Matrix::Bt601);
assert_eq!(Matrix::from_u32(0x8000_00FF), Matrix::Unknown(0x8000_00FF));
assert_eq!(Matrix::Unknown(0x8000_00FF).to_u32(), 0x8000_00FF);
assert!(Matrix::Bt601.is_bt_601());
}
#[test]
fn content_light_level_construct_and_builders() {
let c = ContentLightLevel::new(1000, 400);
assert_eq!(c.max_cll(), 1000);
assert_eq!(c.max_fall(), 400);
assert_eq!(ContentLightLevel::default(), ContentLightLevel::new(0, 0));
let c2 = ContentLightLevel::default()
.with_max_cll(4000)
.with_max_fall(1000);
assert_eq!((c2.max_cll(), c2.max_fall()), (4000, 1000));
let mut c3 = ContentLightLevel::default();
c3.set_max_cll(600).set_max_fall(200);
assert_eq!((c3.max_cll(), c3.max_fall()), (600, 200));
}
#[test]
fn chroma_coord_and_mastering_display() {
let red = ChromaCoord::new(34000, 16000);
let green = ChromaCoord::new(13250, 34500);
let blue = ChromaCoord::new(7500, 3000);
let wp = ChromaCoord::default().with_x(15635).with_y(16450);
assert_eq!((red.x(), red.y()), (34000, 16000));
assert_eq!((wp.x(), wp.y()), (15635, 16450));
const MD: MasteringDisplay = MasteringDisplay::new(
[
ChromaCoord::new(34000, 16000),
ChromaCoord::new(13250, 34500),
ChromaCoord::new(7500, 3000),
],
ChromaCoord::new(15635, 16450),
10_000_000,
50,
);
assert_eq!(MD.display_primaries()[1], green);
assert_eq!(MD.white_point(), ChromaCoord::new(15635, 16450));
assert_eq!(MD.max_luminance(), 10_000_000);
assert_eq!(MD.min_luminance(), 50);
let mut md = MasteringDisplay::default();
md.set_display_primaries([red, green, blue])
.set_white_point(wp)
.set_max_luminance(40_000_000)
.set_min_luminance(5);
assert_eq!(md.display_primaries()[2], blue);
assert_eq!(md.min_luminance(), 5);
}
#[test]
fn hdr_static_metadata_optionals() {
let empty = HdrStaticMetadata::default();
assert!(empty.mastering().is_none());
assert!(empty.content_light().is_none());
let cll = ContentLightLevel::new(1000, 400);
let md = MasteringDisplay::new(
[
ChromaCoord::new(1, 2),
ChromaCoord::new(3, 4),
ChromaCoord::new(5, 6),
],
ChromaCoord::new(7, 8),
9,
10,
);
let h = HdrStaticMetadata::new(Some(md), Some(cll));
assert_eq!(h.mastering(), Some(md));
assert_eq!(h.content_light(), Some(cll));
let h2 = HdrStaticMetadata::default()
.with_content_light(Some(cll))
.with_mastering(None);
assert_eq!(h2.content_light(), Some(cll));
assert!(h2.mastering().is_none());
}
#[test]
fn dolby_vision_config_default_and_accessors() {
let d = DolbyVisionConfig::default();
assert_eq!(d.profile(), 0);
assert_eq!(d.level(), 0);
assert!(!d.rpu_present());
assert!(!d.el_present());
assert_eq!(d.bl_signal_compat_id(), 0);
let c = DolbyVisionConfig::new(8, 9, true, false, 1);
assert_eq!(c.profile(), 8);
assert_eq!(c.level(), 9);
assert!(c.rpu_present());
assert!(!c.el_present());
assert_eq!(c.bl_signal_compat_id(), 1);
let c2 = DolbyVisionConfig::default()
.with_profile(5)
.with_level(6)
.with_rpu_present()
.with_el_present()
.with_bl_signal_compat_id(2);
assert_eq!(
(
c2.profile(),
c2.level(),
c2.rpu_present(),
c2.el_present(),
c2.bl_signal_compat_id()
),
(5, 6, true, true, 2)
);
let c2b = DolbyVisionConfig::default()
.maybe_rpu_present(true)
.maybe_el_present(false);
assert!(c2b.rpu_present());
assert!(!c2b.el_present());
let mut c3 = DolbyVisionConfig::default();
c3.set_profile(7)
.set_level(4)
.set_rpu_present()
.set_el_present()
.set_bl_signal_compat_id(4);
assert_eq!(c3, DolbyVisionConfig::new(7, 4, true, true, 4));
c3.update_el_present(false);
assert!(!c3.el_present());
c3.clear_rpu_present();
assert!(!c3.rpu_present());
c3.update_rpu_present(true);
assert!(c3.rpu_present());
}
}