color-management-v1: implement target color volume
This commit is contained in:
parent
5ad5c5cbcf
commit
04f280aabe
10 changed files with 249 additions and 64 deletions
|
|
@ -560,8 +560,8 @@ impl MetalConnector {
|
|||
}
|
||||
return None;
|
||||
};
|
||||
if ct.cd.id != self.state.color_manager.srgb_srgb().id {
|
||||
// Direct scanout requires identical color descriptions.
|
||||
if !ct.cd.embeds_into(self.state.color_manager.srgb_srgb()) {
|
||||
// Direct scanout requires embeddable color descriptions.
|
||||
return None;
|
||||
}
|
||||
if ct.alpha.is_some() {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use {
|
||||
crate::{
|
||||
cmm::{
|
||||
cmm_luminance::{Luminance, white_balance},
|
||||
cmm_luminance::{Luminance, TargetLuminance, white_balance},
|
||||
cmm_manager::Shared,
|
||||
cmm_primaries::{NamedPrimaries, Primaries},
|
||||
cmm_transfer_function::TransferFunction,
|
||||
cmm_transform::{ColorMatrix, Local, Xyz, bradford_adjustment},
|
||||
},
|
||||
utils::free_list::FreeList,
|
||||
utils::{free_list::FreeList, ordered_float::F64},
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
|
@ -38,6 +38,10 @@ pub struct LinearColorDescription {
|
|||
pub xyz_from_local: ColorMatrix<Xyz, Local>,
|
||||
pub local_from_xyz: ColorMatrix<Local, Xyz>,
|
||||
pub luminance: Luminance,
|
||||
pub target_primaries: Primaries,
|
||||
pub target_luminance: TargetLuminance,
|
||||
pub max_cll: Option<F64>,
|
||||
pub max_fall: Option<F64>,
|
||||
pub(super) shared: Rc<Shared>,
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +49,6 @@ pub struct LinearColorDescription {
|
|||
pub struct ColorDescription {
|
||||
pub id: ColorDescriptionId,
|
||||
pub linear: Rc<LinearColorDescription>,
|
||||
#[expect(dead_code)]
|
||||
pub named_primaries: Option<NamedPrimaries>,
|
||||
pub transfer_function: TransferFunction,
|
||||
pub(super) shared: Rc<Shared>,
|
||||
|
|
@ -62,6 +65,26 @@ impl LinearColorDescription {
|
|||
}
|
||||
mat * self.xyz_from_local
|
||||
}
|
||||
|
||||
pub fn embeds_into(&self, target: &Self) -> bool {
|
||||
if self.id == target.id {
|
||||
return true;
|
||||
}
|
||||
if self.primaries != target.primaries {
|
||||
return false;
|
||||
}
|
||||
if self.luminance != target.luminance {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorDescription {
|
||||
pub fn embeds_into(&self, target: &Self) -> bool {
|
||||
self.transfer_function == target.transfer_function
|
||||
&& self.linear.embeds_into(&target.linear)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LinearColorDescription {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ pub struct Luminance {
|
|||
pub white: F64,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct TargetLuminance {
|
||||
pub min: F64,
|
||||
pub max: F64,
|
||||
}
|
||||
|
||||
impl Luminance {
|
||||
pub const SRGB: Self = Self {
|
||||
min: F64(0.2),
|
||||
|
|
@ -46,6 +52,15 @@ impl Luminance {
|
|||
};
|
||||
}
|
||||
|
||||
impl Luminance {
|
||||
pub fn to_target(&self) -> TargetLuminance {
|
||||
TargetLuminance {
|
||||
min: self.min,
|
||||
max: self.max,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Luminance {
|
||||
fn default() -> Self {
|
||||
Self::SRGB
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ use {
|
|||
ColorDescription, ColorDescriptionIds, LinearColorDescription,
|
||||
LinearColorDescriptionId, LinearColorDescriptionIds,
|
||||
},
|
||||
cmm_luminance::Luminance,
|
||||
cmm_luminance::{Luminance, TargetLuminance},
|
||||
cmm_primaries::{NamedPrimaries, Primaries},
|
||||
cmm_transfer_function::TransferFunction,
|
||||
},
|
||||
utils::{copyhashmap::CopyHashMap, numcell::NumCell},
|
||||
utils::{copyhashmap::CopyHashMap, numcell::NumCell, ordered_float::F64},
|
||||
},
|
||||
std::rc::{Rc, Weak},
|
||||
};
|
||||
|
|
@ -35,6 +35,10 @@ pub(super) struct Shared {
|
|||
struct LinearDescriptionKey {
|
||||
primaries: Primaries,
|
||||
luminance: Luminance,
|
||||
target_primaries: Primaries,
|
||||
target_luminance: TargetLuminance,
|
||||
max_cll: Option<F64>,
|
||||
max_fall: Option<F64>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
|
|
@ -60,6 +64,10 @@ impl ColorManager {
|
|||
Primaries::SRGB,
|
||||
Luminance::SRGB,
|
||||
TransferFunction::Srgb,
|
||||
Primaries::SRGB,
|
||||
Luminance::SRGB.to_target(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let srgb_linear = get_description(
|
||||
&shared,
|
||||
|
|
@ -70,6 +78,10 @@ impl ColorManager {
|
|||
Primaries::SRGB,
|
||||
Luminance::SRGB,
|
||||
TransferFunction::Linear,
|
||||
Primaries::SRGB,
|
||||
Luminance::SRGB.to_target(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let windows_scrgb = get_description(
|
||||
&shared,
|
||||
|
|
@ -80,6 +92,10 @@ impl ColorManager {
|
|||
Primaries::SRGB,
|
||||
Luminance::WINDOWS_SCRGB,
|
||||
TransferFunction::Linear,
|
||||
Primaries::BT2020,
|
||||
Luminance::ST2084_PQ.to_target(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
Rc::new(Self {
|
||||
linear_ids,
|
||||
|
|
@ -110,6 +126,10 @@ impl ColorManager {
|
|||
primaries: Primaries,
|
||||
luminance: Luminance,
|
||||
transfer_function: TransferFunction,
|
||||
target_primaries: Primaries,
|
||||
target_luminance: TargetLuminance,
|
||||
max_cll: Option<F64>,
|
||||
max_fall: Option<F64>,
|
||||
) -> Rc<ColorDescription> {
|
||||
get_description(
|
||||
&self.shared,
|
||||
|
|
@ -120,6 +140,10 @@ impl ColorManager {
|
|||
primaries,
|
||||
luminance,
|
||||
transfer_function,
|
||||
target_primaries,
|
||||
target_luminance,
|
||||
max_cll,
|
||||
max_fall,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -133,6 +157,10 @@ fn get_description(
|
|||
primaries: Primaries,
|
||||
luminance: Luminance,
|
||||
transfer_function: TransferFunction,
|
||||
target_primaries: Primaries,
|
||||
target_luminance: TargetLuminance,
|
||||
max_cll: Option<F64>,
|
||||
max_fall: Option<F64>,
|
||||
) -> Rc<ColorDescription> {
|
||||
macro_rules! gc {
|
||||
($d:ident, $i:expr) => {
|
||||
|
|
@ -147,6 +175,10 @@ fn get_description(
|
|||
let key = LinearDescriptionKey {
|
||||
primaries,
|
||||
luminance,
|
||||
target_primaries,
|
||||
target_luminance,
|
||||
max_cll,
|
||||
max_fall,
|
||||
};
|
||||
if let Some(d) = linear_descriptions.get(&key) {
|
||||
if let Some(d) = d.upgrade() {
|
||||
|
|
@ -180,6 +212,10 @@ fn get_description(
|
|||
xyz_from_local,
|
||||
local_from_xyz,
|
||||
luminance,
|
||||
target_primaries,
|
||||
target_luminance,
|
||||
max_cll,
|
||||
max_fall,
|
||||
shared: shared.clone(),
|
||||
});
|
||||
linear_descriptions.set(key, Rc::downgrade(&d));
|
||||
|
|
|
|||
|
|
@ -141,7 +141,18 @@ mod transforms {
|
|||
|
||||
fn check(p1: Primaries, p2: Primaries, expected: [[f64; 4]; 3]) {
|
||||
let manager = ColorManager::new();
|
||||
let d = |p| manager.get_description(None, p, Luminance::SRGB, TransferFunction::Linear);
|
||||
let d = |p| {
|
||||
manager.get_description(
|
||||
None,
|
||||
p,
|
||||
Luminance::SRGB,
|
||||
TransferFunction::Linear,
|
||||
p,
|
||||
Luminance::SRGB.to_target(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
};
|
||||
let d1 = d(p1);
|
||||
let d2 = d(p2);
|
||||
let m = d1.linear.color_transform(&d2.linear);
|
||||
|
|
|
|||
|
|
@ -2138,7 +2138,7 @@ impl ColorTransforms {
|
|||
src: &LinearColorDescription,
|
||||
dst: &ColorDescription,
|
||||
) -> Option<&mut ColorTransform> {
|
||||
if src.id == dst.linear.id {
|
||||
if src.embeds_into(&dst.linear) {
|
||||
return None;
|
||||
}
|
||||
let ct = match self.map.entry([src.id, dst.linear.id]) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use {
|
|||
globals::{Global, GlobalName},
|
||||
ifs::{
|
||||
color_management::{
|
||||
FEATURE_EXTENDED_TARGET_VOLUME, FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
|
||||
consts::{
|
||||
FEATURE_PARAMETRIC, FEATURE_SET_LUMINANCES, FEATURE_SET_PRIMARIES,
|
||||
FEATURE_WINDOWS_SCRGB, PRIMARIES_ADOBE_RGB, PRIMARIES_BT2020,
|
||||
|
|
@ -77,6 +78,8 @@ impl WpColorManagerV1 {
|
|||
self.send_supported_feature(FEATURE_PARAMETRIC);
|
||||
self.send_supported_feature(FEATURE_SET_PRIMARIES);
|
||||
self.send_supported_feature(FEATURE_SET_LUMINANCES);
|
||||
self.send_supported_feature(FEATURE_SET_MASTERING_DISPLAY_PRIMARIES);
|
||||
self.send_supported_feature(FEATURE_EXTENDED_TARGET_VOLUME);
|
||||
self.send_supported_feature(FEATURE_WINDOWS_SCRGB);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_BT1886);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_GAMMA22);
|
||||
|
|
@ -209,6 +212,10 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
|
|||
tf: Default::default(),
|
||||
primaries: Default::default(),
|
||||
luminance: Default::default(),
|
||||
mastering_primaries: Default::default(),
|
||||
mastering_luminance: Default::default(),
|
||||
max_cll: Default::default(),
|
||||
max_fall: Default::default(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use {
|
|||
crate::{
|
||||
client::{Client, ClientError},
|
||||
cmm::{
|
||||
cmm_luminance::Luminance,
|
||||
cmm_luminance::{Luminance, TargetLuminance},
|
||||
cmm_primaries::{NamedPrimaries, Primaries},
|
||||
cmm_transfer_function::TransferFunction,
|
||||
},
|
||||
|
|
@ -43,6 +43,10 @@ pub struct WpImageDescriptionCreatorParamsV1 {
|
|||
pub tf: Cell<Option<TransferFunction>>,
|
||||
pub primaries: Cell<Option<(Option<NamedPrimaries>, Primaries)>>,
|
||||
pub luminance: Cell<Option<Luminance>>,
|
||||
pub mastering_primaries: Cell<Option<Primaries>>,
|
||||
pub mastering_luminance: Cell<Option<TargetLuminance>>,
|
||||
pub max_cll: Cell<Option<F64>>,
|
||||
pub max_fall: Cell<Option<F64>>,
|
||||
}
|
||||
|
||||
impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreatorParamsV1 {
|
||||
|
|
@ -67,11 +71,20 @@ impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreat
|
|||
if luminance.max.0 <= luminance.min.0 || luminance.white.0 <= luminance.min.0 {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MinLuminanceTooLow);
|
||||
}
|
||||
let target_primaries = self.mastering_primaries.get().unwrap_or(primaries);
|
||||
let target_luminance = self
|
||||
.mastering_luminance
|
||||
.get()
|
||||
.unwrap_or(luminance.to_target());
|
||||
let description = self.client.state.color_manager.get_description(
|
||||
named_primaries,
|
||||
primaries,
|
||||
luminance,
|
||||
transfer_function,
|
||||
target_primaries,
|
||||
target_luminance,
|
||||
self.max_cll.get(),
|
||||
self.max_fall.get(),
|
||||
);
|
||||
let obj = Rc::new(WpImageDescriptionV1 {
|
||||
id: req.image_description,
|
||||
|
|
@ -174,25 +187,59 @@ impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreat
|
|||
|
||||
fn set_mastering_display_primaries(
|
||||
&self,
|
||||
_req: SetMasteringDisplayPrimaries,
|
||||
req: SetMasteringDisplayPrimaries,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
Err(WpImageDescriptionCreatorParamsV1Error::SetMasteringDisplayPrimariesNotSupported)
|
||||
let map = |n: i32| F64(n as f64 * PRIMARIES_MUL_INV);
|
||||
let primaries = Primaries {
|
||||
r: (map(req.r_x), map(req.r_y)),
|
||||
g: (map(req.g_x), map(req.g_y)),
|
||||
b: (map(req.b_x), map(req.b_y)),
|
||||
wp: (map(req.w_x), map(req.w_y)),
|
||||
};
|
||||
if self.mastering_primaries.replace(Some(primaries)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MasteringPrimariesAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_mastering_luminance(
|
||||
&self,
|
||||
_req: SetMasteringLuminance,
|
||||
req: SetMasteringLuminance,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
Err(WpImageDescriptionCreatorParamsV1Error::SetMasteringLuminanceNotSupported)
|
||||
}
|
||||
|
||||
fn set_max_cll(&self, _req: SetMaxCll, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let luminance = TargetLuminance {
|
||||
min: F64(req.min_lum as f64 * MIN_LUM_MUL_INV),
|
||||
max: F64(req.max_lum as f64),
|
||||
};
|
||||
if luminance.max.0 <= luminance.min.0 {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MinMasteringLuminanceTooLow);
|
||||
}
|
||||
if self.mastering_luminance.replace(Some(luminance)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MasteringLuminancesAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_max_fall(&self, _req: SetMaxFall, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
fn set_max_cll(&self, req: SetMaxCll, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
if self
|
||||
.max_cll
|
||||
.replace(Some(F64(req.max_cll as f64)))
|
||||
.is_some()
|
||||
{
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MaxCllAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_max_fall(&self, req: SetMaxFall, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
if self
|
||||
.max_fall
|
||||
.replace(Some(F64(req.max_fall as f64)))
|
||||
.is_some()
|
||||
{
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MaxFallAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -210,10 +257,6 @@ simple_add_obj!(WpImageDescriptionCreatorParamsV1);
|
|||
pub enum WpImageDescriptionCreatorParamsV1Error {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("set_mastering_luminance is not supported")]
|
||||
SetMasteringLuminanceNotSupported,
|
||||
#[error("set_mastering_display_primaries is not supported")]
|
||||
SetMasteringDisplayPrimariesNotSupported,
|
||||
#[error("{} is not a supported named primary", .0)]
|
||||
UnsupportedPrimaries(u32),
|
||||
#[error("set_tf_power is not supported")]
|
||||
|
|
@ -232,5 +275,15 @@ pub enum WpImageDescriptionCreatorParamsV1Error {
|
|||
TfNotSet,
|
||||
#[error("The primaries were not set")]
|
||||
PrimariesNotSet,
|
||||
#[error("The mastering display primaries have already been set")]
|
||||
MasteringPrimariesAlreadySet,
|
||||
#[error("The mastering display luminances have already been set")]
|
||||
MasteringLuminancesAlreadySet,
|
||||
#[error("The minimum mastering luminance is too low")]
|
||||
MinMasteringLuminanceTooLow,
|
||||
#[error("The max CLL has already been set")]
|
||||
MaxCllAlreadySet,
|
||||
#[error("The max FALL has already been set")]
|
||||
MaxFallAlreadySet,
|
||||
}
|
||||
efrom!(WpImageDescriptionCreatorParamsV1Error, ClientError);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,22 @@
|
|||
use {
|
||||
crate::{
|
||||
client::Client,
|
||||
ifs::color_management::consts::{PRIMARIES_SRGB, TRANSFER_FUNCTION_SRGB},
|
||||
cmm::{
|
||||
cmm_description::ColorDescription, cmm_primaries::NamedPrimaries,
|
||||
cmm_transfer_function::TransferFunction,
|
||||
},
|
||||
ifs::color_management::{
|
||||
MIN_LUM_MUL, PRIMARIES_ADOBE_RGB, PRIMARIES_BT2020, PRIMARIES_CIE1931_XYZ,
|
||||
PRIMARIES_DCI_P3, PRIMARIES_DISPLAY_P3, PRIMARIES_GENERIC_FILM, PRIMARIES_MUL,
|
||||
PRIMARIES_NTSC, PRIMARIES_PAL, PRIMARIES_PAL_M, TRANSFER_FUNCTION_BT1886,
|
||||
TRANSFER_FUNCTION_EXT_LINEAR, TRANSFER_FUNCTION_EXT_SRGB, TRANSFER_FUNCTION_GAMMA22,
|
||||
TRANSFER_FUNCTION_GAMMA28, TRANSFER_FUNCTION_LOG_100, TRANSFER_FUNCTION_LOG_316,
|
||||
TRANSFER_FUNCTION_ST240, TRANSFER_FUNCTION_ST428, TRANSFER_FUNCTION_ST2084_PQ,
|
||||
consts::{PRIMARIES_SRGB, TRANSFER_FUNCTION_SRGB},
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
utils::ordered_float::F64,
|
||||
wire::{WpImageDescriptionInfoV1Id, wp_image_description_info_v1::*},
|
||||
},
|
||||
std::{convert::Infallible, rc::Rc},
|
||||
|
|
@ -18,17 +31,46 @@ pub struct WpImageDescriptionInfoV1 {
|
|||
}
|
||||
|
||||
impl WpImageDescriptionInfoV1 {
|
||||
pub fn send_srgb(&self) {
|
||||
let red = [0.64, 0.33];
|
||||
let green = [0.3, 0.6];
|
||||
let blue = [0.15, 0.06];
|
||||
let white = [0.3127, 0.3290];
|
||||
self.send_primaries(red, green, blue, white);
|
||||
self.send_primaries_named(PRIMARIES_SRGB);
|
||||
self.send_tf_named(TRANSFER_FUNCTION_SRGB);
|
||||
self.send_luminances(0.2, 80.0, 80.0);
|
||||
self.send_target_primaries(red, green, blue, white);
|
||||
self.send_target_luminances(0.2, 80.0);
|
||||
pub fn send_description(&self, d: &ColorDescription) {
|
||||
let tf = match d.transfer_function {
|
||||
TransferFunction::Srgb => TRANSFER_FUNCTION_SRGB,
|
||||
TransferFunction::Linear => TRANSFER_FUNCTION_EXT_LINEAR,
|
||||
TransferFunction::St2084Pq => TRANSFER_FUNCTION_ST2084_PQ,
|
||||
TransferFunction::Bt1886 => TRANSFER_FUNCTION_BT1886,
|
||||
TransferFunction::Gamma22 => TRANSFER_FUNCTION_GAMMA22,
|
||||
TransferFunction::Gamma28 => TRANSFER_FUNCTION_GAMMA28,
|
||||
TransferFunction::St240 => TRANSFER_FUNCTION_ST240,
|
||||
TransferFunction::ExtSrgb => TRANSFER_FUNCTION_EXT_SRGB,
|
||||
TransferFunction::Log100 => TRANSFER_FUNCTION_LOG_100,
|
||||
TransferFunction::Log316 => TRANSFER_FUNCTION_LOG_316,
|
||||
TransferFunction::St428 => TRANSFER_FUNCTION_ST428,
|
||||
};
|
||||
self.send_primaries(&d.linear.primaries);
|
||||
if let Some(n) = d.named_primaries {
|
||||
let n = match n {
|
||||
NamedPrimaries::Srgb => PRIMARIES_SRGB,
|
||||
NamedPrimaries::PalM => PRIMARIES_PAL_M,
|
||||
NamedPrimaries::Pal => PRIMARIES_PAL,
|
||||
NamedPrimaries::Ntsc => PRIMARIES_NTSC,
|
||||
NamedPrimaries::GenericFilm => PRIMARIES_GENERIC_FILM,
|
||||
NamedPrimaries::Bt2020 => PRIMARIES_BT2020,
|
||||
NamedPrimaries::Cie1931Xyz => PRIMARIES_CIE1931_XYZ,
|
||||
NamedPrimaries::DciP3 => PRIMARIES_DCI_P3,
|
||||
NamedPrimaries::DisplayP3 => PRIMARIES_DISPLAY_P3,
|
||||
NamedPrimaries::AdobeRgb => PRIMARIES_ADOBE_RGB,
|
||||
};
|
||||
self.send_primaries_named(n);
|
||||
}
|
||||
self.send_tf_named(tf);
|
||||
self.send_luminances(&d.linear.luminance);
|
||||
self.send_target_primaries(&d.linear.target_primaries);
|
||||
self.send_target_luminances(&d.linear.target_luminance);
|
||||
if let Some(max_cll) = d.linear.max_cll {
|
||||
self.send_target_max_cll(max_cll.0);
|
||||
}
|
||||
if let Some(max_fall) = d.linear.max_fall {
|
||||
self.send_target_max_fall(max_fall.0);
|
||||
}
|
||||
self.send_done();
|
||||
}
|
||||
|
||||
|
|
@ -45,18 +87,18 @@ impl WpImageDescriptionInfoV1 {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn send_primaries(&self, r: [f64; 2], g: [f64; 2], b: [f64; 2], w: [f64; 2]) {
|
||||
let map = |c: f64| (c * 1_000_000.0) as i32;
|
||||
pub fn send_primaries(&self, p: &crate::cmm::cmm_primaries::Primaries) {
|
||||
let map = |c: F64| (c.0 * PRIMARIES_MUL) as i32;
|
||||
self.client.event(Primaries {
|
||||
self_id: self.id,
|
||||
r_x: map(r[0]),
|
||||
r_y: map(r[1]),
|
||||
g_x: map(g[0]),
|
||||
g_y: map(g[1]),
|
||||
b_x: map(b[0]),
|
||||
b_y: map(b[1]),
|
||||
w_x: map(w[0]),
|
||||
w_y: map(w[1]),
|
||||
r_x: map(p.r.0),
|
||||
r_y: map(p.r.1),
|
||||
g_x: map(p.g.0),
|
||||
g_y: map(p.g.1),
|
||||
b_x: map(p.b.0),
|
||||
b_y: map(p.b.1),
|
||||
w_x: map(p.wp.0),
|
||||
w_y: map(p.wp.1),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -82,39 +124,38 @@ impl WpImageDescriptionInfoV1 {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn send_luminances(&self, min_lum: f64, max_lum: f64, reference_lum: f64) {
|
||||
pub fn send_luminances(&self, l: &crate::cmm::cmm_luminance::Luminance) {
|
||||
self.client.event(Luminances {
|
||||
self_id: self.id,
|
||||
min_lum: (min_lum * 10_000.0) as u32,
|
||||
max_lum: max_lum as _,
|
||||
reference_lum: reference_lum as _,
|
||||
min_lum: (l.min.0 * MIN_LUM_MUL) as u32,
|
||||
max_lum: l.max.0 as _,
|
||||
reference_lum: l.white.0 as _,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_target_primaries(&self, r: [f64; 2], g: [f64; 2], b: [f64; 2], w: [f64; 2]) {
|
||||
let map = |c: f64| (c * 1_000_000.0) as i32;
|
||||
pub fn send_target_primaries(&self, p: &crate::cmm::cmm_primaries::Primaries) {
|
||||
let map = |c: F64| (c.0 * PRIMARIES_MUL) as i32;
|
||||
self.client.event(TargetPrimaries {
|
||||
self_id: self.id,
|
||||
r_x: map(r[0]),
|
||||
r_y: map(r[1]),
|
||||
g_x: map(g[0]),
|
||||
g_y: map(g[1]),
|
||||
b_x: map(b[0]),
|
||||
b_y: map(b[1]),
|
||||
w_x: map(w[0]),
|
||||
w_y: map(w[1]),
|
||||
r_x: map(p.r.0),
|
||||
r_y: map(p.r.1),
|
||||
g_x: map(p.g.0),
|
||||
g_y: map(p.g.1),
|
||||
b_x: map(p.b.0),
|
||||
b_y: map(p.b.1),
|
||||
w_x: map(p.wp.0),
|
||||
w_y: map(p.wp.1),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn send_target_luminances(&self, min_lum: f64, max_lum: f64) {
|
||||
pub fn send_target_luminances(&self, l: &crate::cmm::cmm_luminance::TargetLuminance) {
|
||||
self.client.event(TargetLuminance {
|
||||
self_id: self.id,
|
||||
min_lum: (min_lum * 10_000.0) as u32,
|
||||
max_lum: max_lum as _,
|
||||
min_lum: (l.min.0 * MIN_LUM_MUL) as u32,
|
||||
max_lum: l.max.0 as _,
|
||||
});
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn send_target_max_cll(&self, max_cll: f64) {
|
||||
self.client.event(TargetMaxCll {
|
||||
self_id: self.id,
|
||||
|
|
@ -122,7 +163,6 @@ impl WpImageDescriptionInfoV1 {
|
|||
});
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn send_target_max_fall(&self, max_fall: f64) {
|
||||
self.client.event(TargetMaxFall {
|
||||
self_id: self.id,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ impl WpImageDescriptionV1RequestHandler for WpImageDescriptionV1 {
|
|||
});
|
||||
self.client.add_client_obj(&obj)?;
|
||||
track!(self.client, obj);
|
||||
obj.send_srgb();
|
||||
obj.send_description(self.client.state.color_manager.srgb_srgb());
|
||||
self.client.remove_obj(&*obj)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue