171 | 171 |
*coverage = coverage_tmp;
|
172 | 172 |
return TRUE;
|
173 | 173 |
}
|
|
174 |
|
|
175 |
/**
|
|
176 |
* cd_icc_utils_get_chroma_matrix:
|
|
177 |
* @icc: The profile to use.
|
|
178 |
* @mat: (out): The returned matrix containing the primaries from @icc.
|
|
179 |
*
|
|
180 |
* Fills a 3x3 matrix with the XYZ red, green, and blue primary values from an
|
|
181 |
* ICC profile as columns.
|
|
182 |
*/
|
|
183 |
static void
|
|
184 |
cd_icc_utils_get_chroma_matrix (CdIcc *icc, CdMat3x3 *mat)
|
|
185 |
{
|
|
186 |
const CdColorXYZ *red = cd_icc_get_red (icc);
|
|
187 |
const CdColorXYZ *green = cd_icc_get_green (icc);
|
|
188 |
const CdColorXYZ *blue = cd_icc_get_blue (icc);
|
|
189 |
CdMat3x3 matrix = {
|
|
190 |
red->X, green->X, blue->X,
|
|
191 |
red->Y, green->Y, blue->Y,
|
|
192 |
red->Z, green->Z, blue->Z };
|
|
193 |
|
|
194 |
*mat = matrix;
|
|
195 |
}
|
|
196 |
|
|
197 |
/**
|
|
198 |
* cd_bradford_transform:
|
|
199 |
* @reference: The white point to use as a reference.
|
|
200 |
* @measured: The white point measurement for the target device.
|
|
201 |
* @mat: (out): The returned Bradford color adaptation matrix.
|
|
202 |
*/
|
|
203 |
static void
|
|
204 |
cd_bradford_transform (const CdColorXYZ *reference,
|
|
205 |
const CdColorXYZ *measured,
|
|
206 |
CdMat3x3 *mat)
|
|
207 |
{
|
|
208 |
/* see https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781119021780.app3 */
|
|
209 |
const CdMat3x3 bradford_response_matrix = {
|
|
210 |
0.8951, 0.2664, -0.1614,
|
|
211 |
-0.7502, 1.7135, 0.0367,
|
|
212 |
0.0389, -0.0685, 1.0296 };
|
|
213 |
CdMat3x3 bradford_inv;
|
|
214 |
CdMat3x3 ratio;
|
|
215 |
CdMat3x3 tmp;
|
|
216 |
CdVec3 ref_xyz = { reference->X / reference->Y,
|
|
217 |
1.0,
|
|
218 |
reference->Z / reference->Y };
|
|
219 |
CdVec3 meas_xyz = { measured->X / measured->Y,
|
|
220 |
1.0,
|
|
221 |
measured->Z / measured->Y };
|
|
222 |
CdVec3 ref_rgb;
|
|
223 |
CdVec3 meas_rgb;
|
|
224 |
|
|
225 |
/* convert XYZ white point values to RGB */
|
|
226 |
cd_mat33_vector_multiply (&bradford_response_matrix,
|
|
227 |
&ref_xyz,
|
|
228 |
&ref_rgb);
|
|
229 |
cd_mat33_vector_multiply (&bradford_response_matrix,
|
|
230 |
&meas_xyz,
|
|
231 |
&meas_rgb);
|
|
232 |
|
|
233 |
/* construct a diagonal matrix D of the ratios between the RGB values */
|
|
234 |
cd_mat33_clear (&ratio);
|
|
235 |
ratio.m00 = meas_rgb.v0 / ref_rgb.v0;
|
|
236 |
ratio.m11 = meas_rgb.v1 / ref_rgb.v1;
|
|
237 |
ratio.m22 = meas_rgb.v2 / ref_rgb.v2;
|
|
238 |
|
|
239 |
/* transform is inv(B) * D * B */
|
|
240 |
cd_mat33_reciprocal (&bradford_response_matrix, &bradford_inv);
|
|
241 |
cd_mat33_matrix_multiply (&bradford_inv, &ratio, &tmp);
|
|
242 |
cd_mat33_matrix_multiply (&tmp, &bradford_response_matrix, mat);
|
|
243 |
}
|
|
244 |
|
|
245 |
/**
|
|
246 |
* cd_icc_utils_get_adaptation_matrix:
|
|
247 |
* @icc: The measured ICC profile for the target device.
|
|
248 |
* @icc_reference: The ICC profile to use as a reference (typically sRGB).
|
|
249 |
* @mat: (out): The returned adaptation matrix.
|
|
250 |
* @error: (out): A #GError, or %NULL
|
|
251 |
*
|
|
252 |
* Computes a correction matrix suitable for adjusting colors in a reference
|
|
253 |
* color space @icc_reference (typically sRGB) to the color space of a target
|
|
254 |
* device described by @icc.
|
|
255 |
*
|
|
256 |
* This function is designed to be used by desktop window systems to program the
|
|
257 |
* color transform matrix (CTM) property of the display hardware.
|
|
258 |
*
|
|
259 |
* Return value: %TRUE for success
|
|
260 |
*
|
|
261 |
* Since: 1.4.5
|
|
262 |
*/
|
|
263 |
gboolean
|
|
264 |
cd_icc_utils_get_adaptation_matrix (CdIcc *icc,
|
|
265 |
CdIcc *icc_reference,
|
|
266 |
CdMat3x3 *mat,
|
|
267 |
GError **error)
|
|
268 |
{
|
|
269 |
CdMat3x3 reference;
|
|
270 |
CdMat3x3 measured_chroma;
|
|
271 |
CdMat3x3 measured;
|
|
272 |
CdMat3x3 measured_inv;
|
|
273 |
CdMat3x3 bradford;
|
|
274 |
|
|
275 |
cd_icc_utils_get_chroma_matrix (icc_reference, &reference);
|
|
276 |
cd_icc_utils_get_chroma_matrix (icc, &measured_chroma);
|
|
277 |
|
|
278 |
/* compute a Bradford color adaptation transform from the measured white
|
|
279 |
* point to the reference white point */
|
|
280 |
cd_bradford_transform (cd_icc_get_white (icc_reference),
|
|
281 |
cd_icc_get_white (icc),
|
|
282 |
&bradford);
|
|
283 |
|
|
284 |
/* use the Bradford transform to adjust the measured chroma values to
|
|
285 |
* match the reference luminance */
|
|
286 |
cd_mat33_matrix_multiply (&bradford, &measured_chroma, &measured);
|
|
287 |
|
|
288 |
/* invert the adjusted measured chroma matrix and multiply by the
|
|
289 |
* reference colors to compute the resulting CSC matrix */
|
|
290 |
cd_mat33_reciprocal (&measured, &measured_inv);
|
|
291 |
cd_mat33_matrix_multiply (&measured_inv,
|
|
292 |
&reference,
|
|
293 |
mat);
|
|
294 |
|
|
295 |
return cd_mat33_is_finite (mat, error);
|
|
296 |
}
|