Skip to content

Commit 37f7d61

Browse files
committed
Improve PQ OETF accuracy
JzAzBz and ICtCp succeed nan checks on f64 now
1 parent 4f75dd7 commit 37f7d61

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod tests;
1616

1717
use core::cmp::PartialOrd;
1818
use core::ffi::{c_char, CStr};
19+
use core::fmt::Display;
1920
use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
2021

2122
// DType {{{
@@ -72,6 +73,7 @@ pub trait DType:
7273
+ Rem<Output = Self>
7374
+ Sub<Output = Self>
7475
+ PartialOrd
76+
+ Display
7577
+ FromF32
7678
{
7779
fn powi(self, rhs: i32) -> Self;
@@ -395,7 +397,7 @@ fn pq_oetf_common<T: DType>(f: T, m2: T) -> T {
395397
let numerator: T = T::ff32(PQEOTF_C2).fma(y_pow_m1, PQEOTF_C1.to_dt());
396398
let denominator: T = T::ff32(PQEOTF_C3).fma(y_pow_m1, 1.0.to_dt());
397399

398-
(numerator / denominator).powf(m2)
400+
(numerator / denominator).spowf(m2)
399401
}
400402

401403
/// Dolby Perceptual Quantizer Electro-Optical Transfer Function primarily used for ICtCP
@@ -544,7 +546,7 @@ impl TryFrom<&str> for Space {
544546
}
545547
}
546548

547-
impl core::fmt::Display for Space {
549+
impl Display for Space {
548550
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
549551
core::fmt::write(
550552
f,

src/tests.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ fn individual() {
240240
("CIELAB->XYZ", CIELAB, XYZ, cielab_to_xyz),
241241
("XYZ->OKLAB", XYZ, OKLAB, xyz_to_oklab),
242242
("OKLAB->XYZ", OKLAB, XYZ, oklab_to_xyz),
243-
//("XYZ->JZAZBZ", XYZ, JZAZBZ, xyz_to_jzazbz)
243+
//("XYZ->JZAZBZ", XYZ, JZAZBZ, xyz_to_jzazbz),
244244
("JZAZBZ->XYZ", JZAZBZ, XYZ, jzazbz_to_xyz),
245245
("CIELAB->CIELCH", CIELAB, CIELCH, lab_to_lch),
246246
("CIELCH->CIELAB", CIELCH, CIELAB, lch_to_lab),
@@ -426,26 +426,30 @@ fn nan_checks() {
426426
let it = [1e+3, -1e+3, 1e-3, -1e-3];
427427
// do these at f32 to faster approach bounds
428428
let fns: &[(&'static str, fn(&mut [f32; 3]))] = &[
429-
("hsv_forwards", srgb_to_hsv),
430-
("hsv_backwards", hsv_to_srgb),
431-
("lrgb_forwards", srgb_to_lrgb),
432-
("lrgb_backwards", lrgb_to_srgb),
433-
("xyz_forwards", lrgb_to_xyz),
434-
("xyz_backwards", xyz_to_lrgb),
435-
("lab_forwards", xyz_to_cielab),
436-
("lab_backwards", cielab_to_xyz),
437-
("lch_forwards", lab_to_lch),
438-
("lch_backwards", lch_to_lab),
439-
("oklab_forwards", xyz_to_oklab),
440-
("oklab_backwards", oklab_to_xyz),
441-
//("jzazbz_forwards", xyz_to_jzazbz), // ugh
442-
("jzazbz_backwards", jzazbz_to_xyz),
429+
("srgb_to_hsv", srgb_to_hsv),
430+
("hsv_to_srgb", hsv_to_srgb),
431+
("srgb_to_lrgb", srgb_to_lrgb),
432+
("lrgb_to_srgb", lrgb_to_srgb),
433+
("lrgb_to_xyz", lrgb_to_xyz),
434+
("xyz_to_lrgb", xyz_to_lrgb),
435+
("xyz_to_cielab", xyz_to_cielab),
436+
("cielab_to_xyz", cielab_to_xyz),
437+
("lab_to_lch", lab_to_lch),
438+
("lch_to_lab", lch_to_lab),
439+
("xyz_to_oklab", xyz_to_oklab),
440+
("oklab_to_xyz", oklab_to_xyz),
441+
// fails hard in the PQ function with (N/D)^P
442+
// Succeeds in F64 but graphics is almost always run in F32
443+
//("xyz_to_jzazbz", xyz_to_jzazbz),
444+
("jzazbz_to_xyz", jzazbz_to_xyz),
445+
("_lrgb_to_ictcp", _lrgb_to_ictcp),
446+
("_ictcp_to_lrgb", _ictcp_to_lrgb),
443447
];
444448
for (label, func) in fns {
445449
for a in it.iter() {
446450
for b in it.iter() {
447451
for c in it.iter() {
448-
let from: [f32; 3] = [*a, *b, *c];
452+
let from = [*a, *b, *c];
449453
let mut to = from;
450454
func(&mut to);
451455
if to.iter().any(|c| !c.is_finite()) {

0 commit comments

Comments
 (0)