Skip to main content

icc_profile/cms/
mod.rs

1//! Color space Management System
2
3
4use crate::iccprofile::ICCNumber;
5use crate::S15Fixed16Number;
6
7pub mod transration;
8
9pub enum ColorEntries {
10    Rgb24(Vec<u8>),
11    Rgba32(Vec<u8>),
12    Lab24(Vec<u8>),
13    Lab(Vec<f64>),
14    Lab48(Vec<u16>),
15    Ymck(Vec<u8>),
16    Xyz(Vec<f64>),
17    Xyz24(Vec<u8>),
18}
19
20impl ColorEntries {
21    pub fn to_rgb(&self) -> Option<Vec<u8>> {
22        None
23    }
24
25    pub fn to_lab(&self) -> Option<Vec<f64>> {
26        None
27    }
28
29    pub fn to_lab24(&self) -> Option<Vec<u8>> {
30        None
31    }
32
33    pub fn to_lab48(&self) -> Option<Vec<u16>> {
34        None
35    }
36
37
38    pub fn to_xyz(&self) -> Option<Vec<f64>> {
39        None
40    }
41
42    pub fn to_xyz24(&self) -> Option<Vec<u8>> {
43        None
44    }
45
46    pub fn to_ymck(&self) -> Option<Vec<f64>> {
47        None
48    }
49
50}
51
52#[derive(Clone)]
53pub struct ColorMatrix3D {
54    pub e: [f64;9]
55}
56
57#[derive(Clone)]
58pub struct ColorMatrix3DWithShift {
59    pub e: [f64;12]
60}
61
62
63impl ColorMatrix3D {
64    pub fn cie_rgb_to_xyz() -> Self {
65        Self {
66            e : [0.4898, 0.3101, 0.2001, 0.1769, 0.8124, 0.0107, 0.0000, 0.0100, 0.9903]
67        }
68    }
69
70    pub fn d65_rgb_to_xyz() -> Self {
71        Self {
72            e : [0.412391,  0.357584,  0.180481,
73                 0.212639,  0.715169,  0.072192,
74                 0.019331,  0.119195,  0.950532]
75        }
76    }
77    pub fn c_rgb_to_xyz() -> Self {
78        Self {
79            e : [0.6069, 0.1735, 0.2003, 0.2989, 0.5866, 0.1144, 0.0000, 0.0661, 1.1157]
80        }
81    }
82
83    pub fn adobe_rgb_to_xyz() -> Self {
84        Self {
85            e : [0.5778, 0.1825, 0.1902, 0.3070, 0.6170, 0.0761, 0.0181, 0.0695, 1.0015]
86        }
87    }
88    pub fn ntsc_rgb_to_xyz() -> Self {
89        Self {
90            e : [0.6070, 0.1734, 0.2006, 0.2990, 0.5864, 0.1146, 0.0000, 0.0661, 1.1175]
91        }
92    }
93
94    pub fn cie_xyz_to_rgb() -> Self {
95        Self {
96            e : [2.3655, - 0.8971, - 0.4683, -0.5151, 1.4264, 0.0887, 0.0052, -0.0144, 1.0089]
97        }
98    }
99
100    pub fn d65_xyz_to_rgb() -> Self {
101        Self {
102            e : [3.240970, -1.537383, -0.498611,
103                -0.969244 , 1.875968,  0.041555,
104                 0.055630, -0.203977,  1.056972]
105        }
106    }
107
108    pub fn c_xyz_to_rgb() -> Self {
109        Self {
110            e : [1.9099, - 0.5324, - 0.2882, -0.9846, 1.9991, -0.0283, 0.0583, -0.1184, 0.8979]
111        }
112    }
113
114    pub fn adobe_xyz_to_rgb() -> Self {
115        Self {
116            e : [2.0416, -0.5650, -0.3447, -1.0199, 1.9171, 0.0481, 0.0340, - 0.1229, 1.0014]
117        }
118    }
119
120    pub fn ntsc_xyz_to_rgb() -> Self {
121        Self {
122            e : [1.9097, - 0.5324, - 0.2882, -0.9850, 1.9998, - 0.0283, 0.0582, - 0.1182, 0.8966]
123        }
124    }
125
126    pub fn from(e:&[f64]) -> Option<Self> {
127        if e.len() != 9 {None}
128        else {
129            Some(Self {
130                e: [e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]
131            })
132        }
133    }
134
135    pub fn from_s15_fixed16_number(e:&[S15Fixed16Number])-> Option<Self> {
136        if e.len() != 9 {None}
137        else {
138            Some(Self {
139                e: [e[0].as_f64(),e[1].as_f64(),e[2].as_f64(),
140                    e[3].as_f64(),e[4].as_f64(),e[5].as_f64(),
141                    e[6].as_f64(),e[7].as_f64(),e[8].as_f64()]
142            })
143        }
144    }
145
146    pub fn invese(matrix:&Self) -> Option<Self> {
147        let a11 = matrix.e[0];
148        let a12 = matrix.e[1];
149        let a13 = matrix.e[2];
150        let a21 = matrix.e[3];
151        let a22 = matrix.e[4];
152        let a23 = matrix.e[5];
153        let a31 = matrix.e[6];
154        let a32 = matrix.e[7];
155        let a33 = matrix.e[8];
156        
157        let delta =  a11 * a22 * a33 + a12 *a23 * a31 + a13 * a21 * a32
158            - a13 * a22 * a31 - a11 * a23 * a32 - a12 * a21 *a33;
159        if delta == 0.0 {
160            None
161        } else {
162            Some(Self{
163                e:[
164                (a22 * a33 - a23 * a32) /delta,
165                (a13 * a32 - a12 * a33) /delta,
166                (a12 * a23 - a13 * a22) /delta,
167
168                (a23 * a31 - a21 * a33) /delta,
169                (a11 * a33 - a13 * a31) /delta,
170                (a13 * a21 - a11 * a23) /delta,
171                
172                (a21 * a32 - a22 * a31) /delta,
173                (a12 * a31 - a11 * a32) /delta,
174                (a11 * a22 - a12 * a21) /delta
175                ]
176            })
177        }
178    }
179
180    pub fn convert_3d(&self,x:f64,y:f64,z:f64) -> (f64,f64,f64) {
181        let e = self.e;
182        let (x,y,z) = (x,y,z);
183        
184        let a = x * e[0] + y * e[1] + z * e[2];    
185        let b = x * e[3] + y * e[4] + z * e[5];    
186        let c = x * e[6] + y * e[7] + z * e[8];    
187        
188        (a,b,c)
189    }
190
191    pub fn convert_3d_u8(&self,x:u8,y:u8,z:u8) -> (u8,u8,u8) {
192        let e = self.e;
193        let (x,y,z) = (x as f64,y as f64,z as f64);
194        
195        let a = x * e[0] + y * e[1] + z * e[2];    
196        let b = x * e[3] + y * e[4] + z * e[5];    
197        let c = x * e[6] + y * e[7] + z * e[8];    
198        
199        let a = (a as i16).clamp(0,255) as u8;
200        let b = (b as i16).clamp(0,255) as u8;
201        let c = (c as i16).clamp(0,255) as u8;
202        (a,b,c)
203    }
204
205    pub fn convert_3d_f64_u8(&self,x:f64,y:f64,z:f64) -> (u8,u8,u8) {
206        let e = self.e;
207        let (x,y,z) = (x as f64,y as f64,z as f64);
208        
209        let a = x * e[0] + y * e[1] + z * e[2];    
210        let b = x * e[3] + y * e[4] + z * e[5];    
211        let c = x * e[6] + y * e[7] + z * e[8];    
212        
213        let a = ((a * 255.0 + 0.5) as i16).clamp(0,255) as u8;
214        let b = ((b * 255.0 + 0.5) as i16).clamp(0,255) as u8;
215        let c = ((c * 255.0 + 0.5) as i16).clamp(0,255) as u8;
216        (a,b,c)
217    }
218
219    pub fn convert_3d_u8_f64(&self,x:u8,y:u8,z:u8) -> (f64,f64,f64) {
220        let e = self.e;
221        let (x,y,z) = (x as f64/255.0,y as f64/255.0,z as f64/255.0);
222        
223        let a = x * e[0] + y * e[1] + z * e[2];    
224        let b = x * e[3] + y * e[4] + z * e[5];    
225        let c = x * e[6] + y * e[7] + z * e[8];    
226        
227        (a,b,c)
228    }
229
230}
231