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
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue