// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//! XYB color space constants (matching libjxl)
//!
//! Allow excessive precision as these constants are copied verbatim from libjxl for compatibility
#! [allow(clippy::excessive_precision)]
pub const OPSIN_ABSORBANCE_BIAS: f32 = 0 .0037930732552754493 ;
#[ allow(dead_code)]
pub const NEG_OPSIN_ABSORBANCE_BIAS_RGB: [f32; 3 ] = [
-OPSIN_ABSORBANCE_BIAS,
-OPSIN_ABSORBANCE_BIAS,
-OPSIN_ABSORBANCE_BIAS,
];
const SCALED_XYB_OFFSET: [f32; 3 ] = [0 .015386134 , 0 .0 , 0 .27770459 ];
const SCALED_XYB_SCALE: [f32; 3 ] = [22 .995788804 , 1 .183000077 , 1 .502141333 ];
const fn reciprocal_sum(r1: f32, r2: f32) -> f32 {
(r1 * r2) / (r1 + r2)
}
pub const XYB_OFFSET: [f32; 3 ] = [
SCALED_XYB_OFFSET[0 ] + SCALED_XYB_OFFSET[1 ],
SCALED_XYB_OFFSET[1 ] - SCALED_XYB_OFFSET[0 ] + (1 .0 / SCALED_XYB_SCALE[0 ]),
SCALED_XYB_OFFSET[1 ] + SCALED_XYB_OFFSET[2 ],
];
pub const fn xyb_scale() -> [f32; 3 ] {
[
reciprocal_sum(SCALED_XYB_SCALE[0 ], SCALED_XYB_SCALE[1 ]),
reciprocal_sum(SCALED_XYB_SCALE[0 ], SCALED_XYB_SCALE[1 ]),
reciprocal_sum(SCALED_XYB_SCALE[1 ], SCALED_XYB_SCALE[2 ]),
]
}
const fn xyb_corner(x: usize, y: usize, b: usize, idx: usize) -> f32 {
let val = match idx {
0 => x,
1 => y,
_ => b,
};
(val as f32 / SCALED_XYB_SCALE[idx]) - SCALED_XYB_OFFSET[idx]
}
const fn scaled_a2b_corner(x: usize, y: usize, b: usize, idx: usize) -> f32 {
match idx {
0 => xyb_corner(x, y, b, 1 ) + xyb_corner(x, y, b, 0 ),
1 => xyb_corner(x, y, b, 1 ) - xyb_corner(x, y, b, 0 ),
_ => xyb_corner(x, y, b, 2 ) + xyb_corner(x, y, b, 1 ),
}
}
const fn unscaled_a2b_corner(x: usize, y: usize, b: usize) -> [f32; 3 ] {
let scale = xyb_scale();
[
(scaled_a2b_corner(x, y, b, 0 ) + XYB_OFFSET[0 ]) * scale[0 ],
(scaled_a2b_corner(x, y, b, 1 ) + XYB_OFFSET[1 ]) * scale[1 ],
(scaled_a2b_corner(x, y, b, 2 ) + XYB_OFFSET[2 ]) * scale[2 ],
]
}
/// Compute the 2x2x2 CLUT cube for XYB to linear RGB conversion.
pub const fn unscaled_a2b_cube_full() -> [[[[f32; 3 ]; 2 ]; 2 ]; 2 ] {
[
[
[unscaled_a2b_corner(0 , 0 , 0 ), unscaled_a2b_corner(0 , 0 , 1 )],
[unscaled_a2b_corner(0 , 1 , 0 ), unscaled_a2b_corner(0 , 1 , 1 )],
],
[
[unscaled_a2b_corner(1 , 0 , 0 ), unscaled_a2b_corner(1 , 0 , 1 )],
[unscaled_a2b_corner(1 , 1 , 0 ), unscaled_a2b_corner(1 , 1 , 1 )],
],
]
}
/// Matrix for XYB ICC profile (from libjxl).
pub const XYB_ICC_MATRIX: [f64; 9 ] = [
1 .5170095 , -1 .1065225 , 0 .071623 , -0 .050022 , 0 .5683655 , -0 .018344 , -1 .387676 , 1 .1145555 ,
0 .6857255 ,
];
Messung V0.5 in Prozent C=95 H=100 G=97
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland