moxcms/conversions/
bpc.rs

1/*
2 * // Copyright (c) Radzivon Bartoshyk 3/2025. All rights reserved.
3 * //
4 * // Redistribution and use in source and binary forms, with or without modification,
5 * // are permitted provided that the following conditions are met:
6 * //
7 * // 1.  Redistributions of source code must retain the above copyright notice, this
8 * // list of conditions and the following disclaimer.
9 * //
10 * // 2.  Redistributions in binary form must reproduce the above copyright notice,
11 * // this list of conditions and the following disclaimer in the documentation
12 * // and/or other materials provided with the distribution.
13 * //
14 * // 3.  Neither the name of the copyright holder nor the names of its
15 * // contributors may be used to endorse or promote products derived from
16 * // this software without specific prior written permission.
17 * //
18 * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 * // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29//
30// use crate::conversions::interpolator::{MultidimensionalInterpolation, Tetrahedral};
31// use crate::conversions::transform_lut4_to_4::{NonFiniteVector3fLerp, Vector3fCmykLerp};
32// use crate::mlaf::mlaf;
33// use crate::{Chromaticity, ColorProfile, DataColorSpace, Lab, Xyz};
34//
35// impl ColorProfile {
36//     #[inline]
37//     pub(crate) fn detect_black_point<const GRID_SIZE: usize>(&self, lut: &[f32]) -> Option<Xyz> {
38//         if self.color_space == DataColorSpace::Cmyk {
39//             // if let Some(mut bp) = self.black_point {
40//             //     if let Some(wp) = self.media_white_point.map(|x| x.normalize()) {
41//             //         if wp != Chromaticity::D50.to_xyz() {
42//             //             let ad = adaption_matrix(wp, Chromaticity::D50.to_xyz());
43//             //             let v = ad.mul_vector(bp.to_vector());
44//             //             bp = Xyz {
45//             //                 x: v.v[0],
46//             //                 y: v.v[1],
47//             //                 z: v.v[2],
48//             //             };
49//             //         }
50//             //     }
51//             //     let mut lab = Lab::from_xyz(bp);
52//             //     lab.a = 0.;
53//             //     lab.b = 0.;
54//             //     if lab.l > 50. {
55//             //         lab.l = 50.;
56//             //     }
57//             //     bp = lab.to_xyz();
58//             //     return Some(bp);
59//             // }
60//             let c = 65535;
61//             let m = 65535;
62//             let y = 65535;
63//             let k = 65535;
64//
65//             let linear_k: f32 = k as f32 * (1. / 65535.);
66//             let w: i32 = k * (GRID_SIZE as i32 - 1) / 65535;
67//             let w_n: i32 = (w + 1).min(GRID_SIZE as i32 - 1);
68//             let t: f32 = linear_k * (GRID_SIZE as i32 - 1) as f32 - w as f32;
69//
70//             let grid_size = GRID_SIZE as i32;
71//             let grid_size3 = grid_size * grid_size * grid_size;
72//
73//             let table1 = &lut[(w * grid_size3 * 3) as usize..];
74//             let table2 = &lut[(w_n * grid_size3 * 3) as usize..];
75//
76//             let tetrahedral1 = Tetrahedral::<GRID_SIZE>::new(table1);
77//             let tetrahedral2 = Tetrahedral::<GRID_SIZE>::new(table2);
78//             let r1 = tetrahedral1.inter3(c, m, y);
79//             let r2 = tetrahedral2.inter3(c, m, y);
80//             let r = NonFiniteVector3fLerp::interpolate(r1, r2, t, 1.0);
81//
82//             let mut lab = Lab::from_xyz(Xyz {
83//                 x: r.v[0],
84//                 y: r.v[1],
85//                 z: r.v[2],
86//             });
87//             lab.a = 0.;
88//             lab.b = 0.;
89//             if lab.l > 50. {
90//                 lab.l = 50.;
91//             }
92//             let bp = lab.to_xyz();
93//
94//             return Some(bp);
95//         }
96//         if self.color_space == DataColorSpace::Rgb {
97//             return Some(Xyz::new(0.0, 0.0, 0.0));
98//         }
99//         None
100//     }
101// }
102//
103// pub(crate) fn compensate_bpc_in_lut(lut_xyz: &mut [f32], src_bp: Xyz, dst_bp: Xyz) {
104//     const WP_50: Xyz = Chromaticity::D50.to_xyz();
105//     let tx = src_bp.x - WP_50.x;
106//     let ty = src_bp.y - WP_50.y;
107//     let tz = src_bp.z - WP_50.z;
108//     let ax = (dst_bp.x - WP_50.x) / tx;
109//     let ay = (dst_bp.y - WP_50.y) / ty;
110//     let az = (dst_bp.z - WP_50.z) / tz;
111//
112//     let bx = -WP_50.x * (dst_bp.x - src_bp.x) / tx;
113//     let by = -WP_50.y * (dst_bp.y - src_bp.y) / ty;
114//     let bz = -WP_50.z * (dst_bp.z - src_bp.z) / tz;
115//
116//     for dst in lut_xyz.chunks_exact_mut(3) {
117//         dst[0] = mlaf(bx, dst[0], ax);
118//         dst[1] = mlaf(by, dst[1], ay);
119//         dst[2] = mlaf(bz, dst[2], az);
120//     }
121// }