1 /* 2 * Copyright (c) 2019-2020 Kevin Townsend (KTOWN) 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @defgroup COLORIMETRY Colorimetry 9 * 10 * @brief Various conversion and mathematic functions to work with different color 11 * systems and values. 12 */ 13 14 /** 15 * @file 16 * @brief API header file for colorimetry in zscilib. 17 * 18 * This file contains the entry points to the colorimetry APIs. 19 */ 20 21 #ifndef ZEPHYR_INCLUDE_ZSL_COLORIMETRY_H_ 22 #define ZEPHYR_INCLUDE_ZSL_COLORIMETRY_H_ 23 24 #include <stddef.h> 25 #include <stdint.h> 26 #include <zsl/zsl.h> 27 #include <zsl/matrices.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /** 34 * @addtogroup COLOR_STRUCTS Structs and Enums 35 * 36 * @brief Common colorimetry-related structs and enums. 37 * 38 * @ingroup COLORIMETRY 39 * @{ */ 40 41 /** 42 * @brief List of supported CIE standard observer models. All models cover 43 * the 360 nm to 830 nm range in 5 nm steps. 44 * 45 * CIE standard observers define a model that enables the correlation of 46 * spectral data to human visual assessments of color. The older 2 degree 47 * model is widely used in scientific measurements and instruments, but the 48 * 10 degree model is considered a more accurate approximation of how normal 49 * human vision perceives color. 50 */ 51 enum zsl_clr_obs { 52 /** 53 * CIE 1931 2 degree standard observer color matching functions from 54 * 360nm to 830nm in 5 nm steps. 55 */ 56 ZSL_CLR_OBS_2_DEG = 0, 57 58 /** 59 * CIE 1964 10 degree standard observer color matching functions from 60 * 360nm to 830nm in 5 nm steps. 61 */ 62 ZSL_CLR_OBS_10_DEG 63 }; 64 65 /** 66 * @brief List of supported CIE standard illuminants. 67 */ 68 enum zsl_clr_illum { 69 /** 70 * XYZ tristimulus for the standard 'A' white point or 'illuminant', 71 * used with transmissive light measurements. This illuminant 72 * simulates tungsten-filament light with a CCT of 2856K. 73 */ 74 ZSL_CLR_ILLUM_A = 0, 75 76 /** 77 * XYZ tristimulus for the standard 'B' white point or 'illuminant', 78 * used with transmissive light measurements. This illuminant 79 * simulates noon sunlight with a CCT of 4874K. 80 */ 81 ZSL_CLR_ILLUM_B, 82 83 /** 84 * XYZ tristimulus for the standard 'C' white point or 'illuminant', 85 * used with transmissive light measurements. This illuminant simulates 86 * typical north sky daylight with a CCT of 6774K. 87 */ 88 ZSL_CLR_ILLUM_C, 89 90 /** 91 * XYZ tristimulus for the standard D50 white point or 'illuminant', 92 * used with transmissive light measurements. 93 */ 94 ZSL_CLR_ILLUM_D50, 95 96 /** 97 * XYZ tristimulus for the standard D55 white point or 'illuminant', 98 * used with transmissive light measurements. 99 */ 100 ZSL_CLR_ILLUM_D55, 101 102 /** 103 * XYZ tristimulus for the standard D65 white point or 'illuminant', 104 * used with transmissive light measurements. 105 */ 106 ZSL_CLR_ILLUM_D65, 107 108 /** 109 * XYZ tristimulus for the standard 'E' white point or 'illuminant', 110 * used with transmissive light measurements. This illuminant is an 111 * 'equal-energy radiator' and a theoretical reference value. 112 */ 113 ZSL_CLR_ILLUM_E, 114 115 /** 116 * XYZ tristimulus for the profile connection space (PCS) illuminant 117 * used in ICC profiles. 118 */ 119 ZSL_CLR_ILLUM_ICC 120 }; 121 122 /** 123 * @brief List of supported CIE luminous efficiency functions. All functions 124 * cover the 380 nm to 780 nm range in 5 nm steps. 125 * 126 * Luminous efficiency functions enable conversion from radiometric units, 127 * representing radiant or electromagnetic energy, into photometric units, 128 * representing luminous energy as perceived by the human eye. 129 * 130 * For example: 131 * 132 * Irradiance is a radiometric unit usually represented in W/m^2, and has a 133 * direct relationship to energy (watts). It is a measure of the 134 * electromagnetic energy within a specified area, visible or not. 135 * 136 * Luminance is a photometric unit, and indicates luminous intensity per unit 137 * area, as perceived by normal human vision, and is usually represented in 138 * cd/m^2. 139 * 140 * Irradiance can be converted to luminance by means of an appropriate 141 * luminous efficiency function, shaping the radiometric measurement into 142 * an approximation of how a human with normal vision would perceive the 143 * visible aspects of the radiometric phenomenon. 144 * 145 * Two major luminous efficiency functions are widely used, depending on if 146 * human vision is being modelled in normal daylight conditions, where color 147 * can be perceived, or in night-time conditions where sensitivity to 148 * brightness is dominant. 149 */ 150 enum zsl_clr_lef { 151 /** 152 * CIE 1988 Photopic Luminous Efficiency Function, which models typical 153 * human vision in well-lit conditions, and is based on the response of 154 * color-sensitive cones in the human eye. 155 */ 156 ZSL_CLR_LEF_CIE88_PHOTOPIC = 0, 157 158 /** 159 * CIE 1951 Scotopic Luminous Efficiency Function, which models typical 160 * human vision in dark conditions, and is based on the response of 161 * rods in the human eye. 162 */ 163 ZSL_CLR_LEF_CIE51_SCOTOPIC = 1, 164 }; 165 166 /** 167 * @brief List of included 3x3 XYZ to RGB color space correlation matrices. 168 */ 169 enum zsl_clr_rgb_ccm { 170 /** XYZ to linear sRGB (D65 white point). */ 171 ZSL_CLR_RGB_CCM_SRGB_D65 = 0, 172 173 /** XYZ to linear sRGB (D50 white point). */ 174 ZSL_CLR_RGB_CCM_SRGB_D50, 175 176 /** AdobeRGB98. */ 177 ZSL_CLR_RGB_CCM_ADOBERGB98, 178 179 /** Sony S-Gamut3.cine D65. */ 180 ZSL_CLR_RGB_CCM_SONY_SGAMUT3_CINE, 181 182 /** NTSC. */ 183 ZSL_CLR_RGB_CCM_NTSC, 184 185 /** PAL/SECAM. */ 186 ZSL_CLR_RGB_CCM_PAL_SECAM, 187 188 /** ITU-R BT.709. */ 189 ZSL_CLR_RGB_CCM_BT_709, 190 191 /** ITU-R BT.2020. */ 192 ZSL_CLR_RGB_CCM_BT_2020, 193 194 /** ACES Primaries #0 (AP0). */ 195 ZSL_CLR_RGB_CCM_ACES_P0, 196 197 /** ACES Primaries #1 (AP1). */ 198 ZSL_CLR_RGB_CCM_ACES_P1, 199 200 /** DCI-P3. */ 201 ZSL_CLR_RGB_CCM_DCI_P3, 202 203 /** DCI-P3+. */ 204 ZSL_CLR_RGB_CCM_DCI_P3_PLUS, 205 206 /** CIE linear RGB. */ 207 ZSL_CLR_RGB_CCM_CIE_RGB, 208 }; 209 210 /** 211 * @brief The algorithm to use when converting a CIE 1960 UV value to 212 * CCT, Duv. 213 */ 214 enum zsl_clr_uv_cct_method { 215 /** 216 * @brief McCamy's approximation. 217 * 218 * McCamy's approximation provides an approximate CCT using a CIE 1931 219 * xyY chromaticity: 220 * 221 * CCT(x, y) = 449 * n^3 + 3525 * n^2 + 6823.3 * n + 5520.33 222 * 223 * Where: 224 * 225 * n = (x − 0.3320) / (0.1858 - y) 226 * 227 * This is accurate for color temperatures between ~2800K-6500K. 228 */ 229 ZSL_CLR_UV_CCT_METHOD_MCCAMY, 230 231 /** 232 * @brief Yoshi Ohno 2011 CORM. 233 * 234 * Yoshi Ohno, "Calculation of CCT and Duv and Practical Conversion 235 * Formulae", CORM 2011. 236 * 237 * Highly accurate between 2,000 and 20,000 K, making it the ideal 238 * choice for artifical lighting. 239 */ 240 ZSL_CLR_UV_CCT_METHOD_OHNO2011, 241 242 /** 243 * @brief Yoshi Ohno 2014. 244 * 245 * Source: Yoshi Ohno (2014) 246 * Practical Use and Calculation of CCT and Duv 247 * LEUKOS, 10:1, 47-55, DOI: 10.1080/15502724.2014.839020 248 * 249 * Highly accurate between 2,600 and 20,000 K, making it the ideal 250 * choice for artifical lighting. 251 */ 252 ZSL_CLR_UV_CCT_METHOD_OHNO2014 253 }; 254 255 /** 256 * @brief CIE 1931 XYZ tristimulus values. 257 */ 258 struct zsl_clr_xyz { 259 /** The X component of the XYZ tristimulus. */ 260 zsl_real_t xyz_x; 261 /** The Y component of the XYZ tristimulus. */ 262 zsl_real_t xyz_y; 263 /** The Z component of the XYZ tristimulus. */ 264 zsl_real_t xyz_z; 265 /** The standard observer model this data is based upon. */ 266 enum zsl_clr_obs observer; 267 /** The reference illuminant for this data (default = ZSL_CLR_ILLUM_A). */ 268 enum zsl_clr_illum illuminant; 269 /** If non-zero, indicates that the #xyz_x value is invalid. */ 270 uint8_t x_invalid : 1; 271 /** If non-zero, indicates that the #xyz_y value is invalid. */ 272 uint8_t y_invalid : 1; 273 /** If non-zero, indicates that the #xyz_z value is invalid. */ 274 uint8_t z_invalid : 1; 275 }; 276 277 /** 278 * @brief CIE 1931 xyY chromaticity coordinates. 279 */ 280 struct zsl_clr_xyy { 281 /** The x component of the xyY chromaticity coordinates. */ 282 zsl_real_t xyy_x; 283 /** The y component of the xyY chromaticity coordinates. */ 284 zsl_real_t xyy_y; 285 /** The Y component of the xyY chromaticity coordinates. */ 286 zsl_real_t xyy_Y; 287 /** The standard observer model this data is based upon. */ 288 enum zsl_clr_obs observer; 289 /** The reference illuminant for this data (default = ZSL_CLR_ILLUM_A). */ 290 enum zsl_clr_illum illuminant; 291 /** If non-zero, indicates that the #xyy_x value is invalid. */ 292 uint8_t x_invalid : 1; 293 /** If non-zero, indicates that the #xyy_y value is invalid. */ 294 uint8_t y_invalid : 1; 295 /** If non-zero, indicates that the #xyy_Y value is invalid. */ 296 uint8_t Y_invalid : 1; 297 }; 298 299 /** 300 * @brief CIE 1960 UCS chromaticity coordinates. 301 */ 302 struct zsl_clr_uv60 { 303 /** The u component of the CIE 1960 (u, v) chromaticity coordinates. */ 304 zsl_real_t uv60_u; 305 /** The v component of the CIE 1960 (u, v) chromaticity coordinates. */ 306 zsl_real_t uv60_v; 307 /** The standard observer model this data is based upon. */ 308 enum zsl_clr_obs observer; 309 /** The reference illuminant for this data (default = ZSL_CLR_ILLUM_A). */ 310 enum zsl_clr_illum illuminant; 311 /** If non-zero, indicates that the #uv60_u value is invalid. */ 312 uint8_t u_invalid : 1; 313 /** If non-zero, indicates that the #uv60_v value is invalid. */ 314 uint8_t v_invalid : 1; 315 }; 316 317 /** 318 * @brief CIE 1976 UCS chromaticity coordinates. 319 */ 320 struct zsl_clr_uv76 { 321 /** The u component of the CIE 1976 (u, v) chromaticity coordinates. */ 322 zsl_real_t uv76_u; 323 /** The v component of the CIE 1976 (u, v) chromaticity coordinates. */ 324 zsl_real_t uv76_v; 325 /** The standard observer model this data is based upon. */ 326 enum zsl_clr_obs observer; 327 /** The reference illuminant for this data (default = ZSL_CLR_ILLUM_A). */ 328 enum zsl_clr_illum illuminant; 329 /** If non-zero, indicates that the #uv76_u value is invalid. */ 330 uint8_t u_invalid : 1; 331 /** If non-zero, indicates that the #uv76_v value is invalid. */ 332 uint8_t v_invalid : 1; 333 }; 334 335 /** 336 * @brief RGBA color using floating-space notation from 0.0 .. 1.0. 337 */ 338 struct zsl_clr_rgbf { 339 /** The relative red components of an RGBA color (0.0 .. 1.0). */ 340 zsl_real_t r; 341 /** The relative green components of an RGBA color (0.0 .. 1.0). */ 342 zsl_real_t g; 343 /** The relative blue components of an RGBA color (0.0 .. 1.0). */ 344 zsl_real_t b; 345 /** The relative alpha channel component (0.0 .. 1.0). */ 346 zsl_real_t a; 347 /** If non-zero, indicates that the #r value is invalid. */ 348 uint8_t r_invalid : 1; 349 /** If non-zero, indicates that the #g value is invalid. */ 350 uint8_t g_invalid : 1; 351 /** If non-zero, indicates that the #b value is invalid. */ 352 uint8_t b_invalid : 1; 353 /** If non-zero, indicates that the #a value is invalid. */ 354 uint8_t a_invalid : 1; 355 }; 356 357 /** 358 * @brief RGBA color using 8-bit values. 359 */ 360 struct zsl_clr_rgb8 { 361 /** The 8-bit red components of an RGBA color. */ 362 uint8_t r; 363 /** The 8-bit green components of an RGBA color. */ 364 uint8_t g; 365 /** The 8-bit blue components of an RGBA color. */ 366 uint8_t b; 367 /** The 8-bit alpha channel component. */ 368 uint8_t a; 369 /** If non-zero, indicates that the #r value is invalid. */ 370 uint8_t r_invalid : 1; 371 /** If non-zero, indicates that the #g value is invalid. */ 372 uint8_t g_invalid : 1; 373 /** If non-zero, indicates that the #b value is invalid. */ 374 uint8_t b_invalid : 1; 375 /** If non-zero, indicates that the #a value is invalid. */ 376 uint8_t a_invalid : 1; 377 }; 378 379 /** 380 * @brief RGBA color using 16-bit values. 381 */ 382 struct zsl_clr_rgb16 { 383 /** The 16-bit red components of an RGBA color. */ 384 uint16_t r; 385 /** The 16-bit green components of an RGBA color. */ 386 uint16_t g; 387 /** The 16-bit blue components of an RGBA color. */ 388 uint16_t b; 389 /** The 16-bit alpha channel component. */ 390 uint16_t a; 391 /** If non-zero, indicates that the #r value is invalid. */ 392 uint8_t r_invalid : 1; 393 /** If non-zero, indicates that the #g value is invalid. */ 394 uint8_t g_invalid : 1; 395 /** If non-zero, indicates that the #b value is invalid. */ 396 uint8_t b_invalid : 1; 397 /** If non-zero, indicates that the #a value is invalid. */ 398 uint8_t a_invalid : 1; 399 /** The bit-depth of color samples (typically 10, 12, or 16). */ 400 uint8_t bit_depth; 401 }; 402 403 /** 404 * @brief Data representing a single CIE 1960 CCT, Duv value pair. 405 */ 406 struct zsl_clr_cct { 407 /** @brief Correlated color temperature. 408 * 409 * Indicates the color temperature that yields the minimum Euclidean 410 * distance between u1,v1 and the Planckian chromaticity 'up, vp' of 411 * the color temperature. 412 */ 413 zsl_real_t cct; 414 /** @brief Distance of the measured chromaticity from the Planckian 415 * locus (AKA black body curve). 416 * 417 * A negative Duv indicates that the measured chromaticity is below 418 * the Planckian locus (in the magenta and pink color range). A 419 * positive Duv indicates a point above the locus (in the green or 420 * yellow color range). */ 421 zsl_real_t duv; 422 /** If non-zero, indicates that #cct is invalid. */ 423 uint8_t cct_invalid : 1; 424 /** If non-zero, indicates that #duv is invalid. */ 425 uint8_t duv_invalid : 1; 426 }; 427 428 /** 429 * @brief CIE 1931 XYZ tristimulus values for a standard illuminant. 430 */ 431 struct zsl_clr_illum_data { 432 /** The CIE standard illuminant reference identifier. */ 433 enum zsl_clr_illum illuminant; 434 /** The CIE standard observer model used. */ 435 enum zsl_clr_obs observer; 436 /** Display name string for the illuminant. */ 437 char *name; 438 /** The illuminant's XYZ tristimulus values. */ 439 struct { 440 /** The CIE XYZ tristimulus X value. */ 441 zsl_real_t xyz_x; 442 /** The CIE XYZ tristimulus Y value. */ 443 zsl_real_t xyz_y; 444 /** The CIE XYZ tristimulus Z value. */ 445 zsl_real_t xyz_z; 446 } data; 447 }; 448 449 /** 450 * @brief CIE 1931 XYZ tristimulus values for a standard observer model in 451 * 5 nm steps from 360-830 nm (95 steps). 452 */ 453 struct zsl_clr_obs_data { 454 /** The CIE standard observer model identifier. */ 455 enum zsl_clr_obs observer; 456 /** Display name string for the standard observer model. */ 457 char *name; 458 /** 459 * The observer model's XYZ tristimulus values in 5 nm increments 460 * from 360..830 nm (95 values). 461 */ 462 struct { 463 /** The CIE XYZ tristimulus X value. */ 464 zsl_real_t xyz_x; 465 /** The CIE XYZ tristimulus Y value. */ 466 zsl_real_t xyz_y; 467 /** The CIE XYZ tristimulus Z value. */ 468 zsl_real_t xyz_z; 469 } data[95]; 470 }; 471 472 /** 473 * @brief Spectral power distribution for a specific illumination. 474 * 475 * This struct contains the illuminant power at given wavelength intervals. 476 * 477 * @b Example 478 * 479 * The following code defines a zsl_clr_spd instance for an illumnation 480 * that was captured on a spectrograph in 20 nm intervals between 380 and 481 * 780 nm, for a total of 21 data samples. 482 * 483 * CCT was calculated as 5983.00 K and 0.0033 Duv, with an output CIE 1931 XYZ 484 * tristimulus of X: 0.9516409, Y: 1.0000000, Z: 1.0059365. 485 * 486 * @code 487 * const struct zsl_clr_spd zsl_clr_test_spd_5983k = { 488 * .size = 21, 489 * .comps = { 490 * { .nm = 380, .value = 0.290 }, 491 * { .nm = 400, .value = 0.471 }, 492 * { .nm = 420, .value = 0.719 }, 493 * { .nm = 440, .value = 0.826 }, 494 * { .nm = 460, .value = 1.006 }, 495 * { .nm = 480, .value = 0.989 }, 496 * { .nm = 500, .value = 0.955 }, 497 * { .nm = 520, .value = 0.910 }, 498 * { .nm = 540, .value = 0.950 }, 499 * { .nm = 560, .value = 0.912 }, 500 * { .nm = 580, .value = 0.848 }, 501 * { .nm = 600, .value = 0.814 }, 502 * { .nm = 620, .value = 0.827 }, 503 * { .nm = 640, .value = 0.771 }, 504 * { .nm = 660, .value = 0.749 }, 505 * { .nm = 680, .value = 0.766 }, 506 * { .nm = 700, .value = 0.705 }, 507 * { .nm = 720, .value = 0.599 }, 508 * { .nm = 740, .value = 0.850 }, 509 * { .nm = 760, .value = 0.699 }, 510 * { .nm = 780, .value = 0.898 } 511 * } 512 * }; 513 * @endcode 514 */ 515 struct zsl_clr_spd { 516 /** The number of elements in the component array. */ 517 size_t size; 518 struct { 519 /** The wavelength in nm for this specific sample. */ 520 unsigned int nm; 521 /** The relative value of this specific sample. */ 522 zsl_real_t value; 523 } comps[]; /**< The spectral component data that makes up the spd. */ 524 }; 525 526 /** @} */ /* End of STRUCT group */ 527 528 /** 529 * @addtogroup CONV Conversion Functions 530 * 531 * Helper functions to convert between color systems and coordinates. 532 * 533 * @ingroup COLORIMETRY 534 * @{ */ 535 536 /** 537 * @brief Converts the supplied spectral power distribution data into it's 538 * equivalent XYZ tristimulus using the specified standard observer model. 539 * 540 * @param spd Pointer to the spectral power distribution data to use. 541 * @param obs The CIE standard observer model to use for the conversion. 542 * @param xyz Pointer to the placeholder for the output XYZ tristimulus. 543 * 544 * @returns 0 on normal execution, otherwise an appropriate error code. 545 */ 546 int zsl_clr_conv_spd_xyz(const struct zsl_clr_spd *spd, enum zsl_clr_obs obs, 547 struct zsl_clr_xyz *xyz); 548 549 /** 550 * @brief Converts a CIE 1931 xyY chromaticity to its XYZ tristimulus 551 * equivalent. 552 * 553 * @param xyy Pointer to the input xyY triplet. 554 * @param xyz Pointer to the output XYZ triplet. 555 * 556 * @return 0 on success, error code on failure. 557 */ 558 int zsl_clr_conv_xyy_xyz(struct zsl_clr_xyy *xyy, struct zsl_clr_xyz *xyz); 559 560 /** 561 * @brief Converts CIE 1931 XYZ tristimulus values to the xyY chromaticity 562 * equivalent. 563 * 564 * @param xyz Pointer to the input XYZ triplet. 565 * @param xyy Pointer to the output xyY triplet. 566 * 567 * @return 0 on success, error code on failure. 568 */ 569 int zsl_clr_conv_xyz_xyy(struct zsl_clr_xyz *xyz, struct zsl_clr_xyy *xyy); 570 571 /** 572 * @brief Converts a CIE 1931 xyY chromaticity to its CIE 1960 uv equivalent. 573 * 574 * @param xyy Pointer to the input xyY triplet. 575 * @param uv Pointer to the output CIE 1960 u,v pair. 576 * 577 * @return 0 on success, error code on failure. 578 */ 579 int zsl_clr_conv_xyy_uv60(struct zsl_clr_xyy *xyy, struct zsl_clr_uv60 *uv); 580 581 /** 582 * @brief Converts CIE 1931 XYZ tristimulus values to its CIE 1960 uv 583 * equivalent. 584 * 585 * @param xyz Pointer to the input zsl_clr_xyz triplet. 586 * @param uv Pointer to the output CIE 1960 u,v pair. 587 * 588 * @return 0 on success, error code on failure. 589 */ 590 int zsl_clr_conv_xyz_uv60(struct zsl_clr_xyz *xyz, struct zsl_clr_uv60 *uv); 591 592 /** 593 * @brief Converts a CIE 1960 uv value to its CIE 1931 XYZ tristimulus 594 * equivalent. 595 * 596 * @param uv Pointer to the input CIE 1960 u,v pair. 597 * @param xyz Pointer to the output XYZ tristimulus. 598 * 599 * @return 0 on success, error code on failure. 600 */ 601 int zsl_clr_conv_uv60_xyz(struct zsl_clr_uv60 *uv, struct zsl_clr_xyz *xyz); 602 603 /** 604 * @brief Converts a CIE 1960 uv value to its CIE 1931 xyY chromaticity 605 * equivalent. 606 * 607 * @param uv Pointer to the input CIE 1960 u,v pair. 608 * @param xyy Pointer to the output xyY triplet. 609 * 610 * @return 0 on success, error code on failure. 611 */ 612 int zsl_clr_conv_uv60_xyy(struct zsl_clr_uv60 *uv, struct zsl_clr_xyy *xyy); 613 614 /** 615 * @brief Converts a CIE 1960 uv value to its CIE 1976 u'v' equivalent. 616 * 617 * @param uv60 Pointer to the input CIE 1960 u,v pair. 618 * @param uv76 Pointer to the input CIE 1976 u',v' pair. 619 * 620 * @return 0 on success, error code on failure. 621 */ 622 int zsl_clr_conv_uv60_uv76(struct zsl_clr_uv60 *uv60, 623 struct zsl_clr_uv76 *uv76); 624 625 /** 626 * @brief Converts a CIE 1976 u'v' value to its CIE 1960 uv equivalent. 627 * 628 * @param uv76 Pointer to the input CIE 1976 u',v' pair. 629 * @param uv60 Pointer to the input CIE 1960 u,v pair. 630 * 631 * @return 0 on success, error code on failure. 632 */ 633 int zsl_clr_conv_uv76_uv60(struct zsl_clr_uv76 *uv76, 634 struct zsl_clr_uv60 *uv60); 635 636 /** 637 * Convert the specified color temperature to a (u,v) chromaticity. 638 * 639 * @param ct The color temperature to use. 640 * @param obs The CIE standard observer model to use for the conversion. 641 * @param uv Pointer to the output (u,v) chromaticity. 642 * 643 * @return 0 on success, error code on failure. 644 */ 645 int zsl_clr_conv_ct_uv60(zsl_real_t ct, enum zsl_clr_obs obs, 646 struct zsl_clr_uv60 *uv); 647 648 /** 649 * @brief Converts an exact CIE 1960 CCT (Duv = 0.0) to a CIE 1931 XYZ 650 * tristimulus. 651 * 652 * @param ct The color temperature to use. 653 * @param obs The CIE standard observer model to use for the conversion. 654 * @param xyz Pointer to the output CIE 1931 XYZ tristimulus. 655 * 656 * @return 0 on success, error code on failure. 657 */ 658 int zsl_clr_conv_ct_xyz(zsl_real_t ct, enum zsl_clr_obs obs, 659 struct zsl_clr_xyz *xyz); 660 661 /** 662 * @brief Converts an exact CIE 1960 CCT (Duv = 0.0) to an 8-bit RGBA value 663 * using the supplied XYZ to RGB color space correlation matrix. 664 * 665 * @param ct The color temperature to use. 666 * @param obs The CIE standard observer model to use for the conversion. 667 * @param mtx Pointer to the 3x3 XYZ to RGB color space correlation matrix. 668 * @param rgb Pointer to the output zsl_clr_rgb8 value. 669 * 670 * @return 0 on success, error code on failure. 671 */ 672 int zsl_clr_conv_ct_rgb8(zsl_real_t ct, enum zsl_clr_obs obs, 673 struct zsl_mtx *mtx, struct zsl_clr_rgb8 *rgb); 674 675 /** 676 * @brief Converts an exact CIE 1960 CCT (Duv = 0.0) to an floating point RGBA 677 * value using the supplied XYZ to RGB color space correlation matrix. 678 * 679 * @param ct The color temperature to use. 680 * @param obs The CIE standard observer model to use for the conversion. 681 * @param mtx Pointer to the 3x3 XYZ to RGB color space correlation matrix. 682 * @param rgb Pointer to the output zsl_clr_rgbf value. 683 * 684 * @return 0 on success, error code on failure. 685 */ 686 int zsl_clr_conv_ct_rgbf(zsl_real_t ct, enum zsl_clr_obs obs, 687 struct zsl_mtx *mtx, struct zsl_clr_rgbf *rgb); 688 689 /** 690 * @brief Converts a CIE 1960 CCT and Duv pair to a CIE 1931 xyY chromaticity. 691 * 692 * @param cct Pointer to CIE 1960 correlated color temperature and Duv. 693 * @param obs The CIE standard observer model to use for the conversion. 694 * @param xyy Pointer to the output CIE 1931 xyY chromaticity. 695 * 696 * @return 0 on success, error code on failure. 697 */ 698 int zsl_clr_conv_cct_xyy(struct zsl_clr_cct *cct, enum zsl_clr_obs obs, 699 struct zsl_clr_xyy *xyy); 700 701 /** 702 * @brief Converts a CIE 1960 CCT and Duv pair to a CIE 1931 XYZ tristimulus. 703 * 704 * @param cct Pointer to CIE 1960 correlated color temperature and Duv. 705 * @param obs The CIE standard observer model to use for the conversion. 706 * @param xyz Pointer to the output CIE 1931 XYZ tristimulus. 707 * 708 * @return 0 on success, error code on failure. 709 */ 710 int zsl_clr_conv_cct_xyz(struct zsl_clr_cct *cct, enum zsl_clr_obs obs, 711 struct zsl_clr_xyz *xyz); 712 713 /** 714 * @brief Converts a CIE 1960 (u, v) pair to a CIE 1960 CCT and Duv 715 * pair using the specified conversion algorithm. 716 * 717 * @param method The algoorithm to use for the conversion. 718 * @param uv Pointer to input CIE 1960 (u, v) pair. 719 * @param cct Pointer to output zsl_clr_cct. 720 * 721 * @return 0 on success, error code on failure. 722 */ 723 int zsl_clr_conv_uv60_cct(enum zsl_clr_uv_cct_method method, 724 struct zsl_clr_uv60 *uv, struct zsl_clr_cct *cct); 725 726 /** 727 * @brief Converts a CIE 1931 XYZ tristimulus to an 8-bit RGBA value 728 * using the supplied XYZ to RGB color space correlation matrix. 729 * 730 * @param xyz The input CIE 1931 XYZ tristimulus value to convert to RGB. 731 * @param mtx Pointer to the 3x3 XYZ to RGB color space correlation matrix. 732 * @param rgb Pointer to the output zsl_clr_rgb8 value. 733 * 734 * @return 0 on success, error code on failure. 735 */ 736 int zsl_clr_conv_xyz_rgb8(struct zsl_clr_xyz *xyz, struct zsl_mtx *mtx, 737 struct zsl_clr_rgb8 *rgb); 738 739 /** 740 * @brief Converts a CIE 1931 XYZ tristimulus to an floating point RGBA value 741 * using the supplied XYZ to RGB color space correlation matrix. 742 * 743 * Depending on the value of CONFIG_ZSL_CLR_RGBF_BOUND_CAP, the output values 744 * may be outside of the 0.0..1.0 range if the resulting value is out of 745 * gamut for the specified RGB color space. 746 * 747 * @param xyz The input CIE 1931 XYZ tristimulus value to convert to RGB. 748 * @param mtx Pointer to the 3x3 XYZ to RGB color space correlation matrix. 749 * @param rgb Pointer to the output zsl_clr_rgbf value. 750 * 751 * @return 0 on success, error code on failure. 752 */ 753 int zsl_clr_conv_xyz_rgbf(struct zsl_clr_xyz *xyz, struct zsl_mtx *mtx, 754 struct zsl_clr_rgbf *rgb); 755 756 /** @} */ /* End of CONV group */ 757 758 /** 759 * @addtogroup NORM Normalisation Functions 760 * 761 * Helper functions to normalise data sets. 762 * 763 * @ingroup COLORIMETRY 764 * @{ */ 765 766 /** 767 * @brief Normalises the supplied spectral power distribution data to a 768 * 1.0 range. This function call is destructive to the input zsl_clr_spd data. 769 * 770 * @param spd Pointer to the spectral power distribution data to normalise. 771 * 772 * @returns 0 on normal execution, otherwise an appropriate error code. 773 */ 774 int zsl_clr_norm_spd(struct zsl_clr_spd *spd); 775 776 /** @} */ /* End of NORM group */ 777 778 /** 779 * @addtogroup COLOR_DATA Data Access Functions 780 * 781 * Function to access various colorimetry datasets. 782 * 783 * @ingroup COLORIMETRY 784 * @{ */ 785 786 /** 787 * @brief Retrieves a pointer to the zsl_clr_illum_data for the specified 788 * illuminant. 789 * 790 * @param obs The standard observer associated with this #illum. 791 * @param illum The illuminant whose data should be retrieved. 792 * @param data Pointer to the pointer where the const zsl_clr_illum_data 793 * should be made accessible. 794 * 795 * @returns 0 on normal execution, otherwise an appropriate error code. 796 * 797 * @b Example 798 * 799 * The following example shows how to use the pointer to a pointer 800 * mechnaism to access illuminant A data in an resource efficient manner. 801 * 802 * @code 803 * void 804 * get_illum(void) 805 * { 806 * int rc; 807 * const struct zsl_clr_illum_data *illum; 808 * 809 * rc = zsl_clr_illum_get(ZSL_CLR_OBS_2_DEG, ZSL_CLR_ILLUM_A, &illum); 810 * if (rc) { 811 * // No matching illuminant found! 812 * return; 813 * } 814 * 815 * printf("Illum %s - x = %f\n", illum->name, illum->data.xyz_z); 816 * } 817 * 818 * @endcode 819 */ 820 int zsl_clr_illum_get(enum zsl_clr_obs obs, enum zsl_clr_illum illum, 821 const struct zsl_clr_illum_data **data); 822 823 /** 824 * @brief Retrieves a pointer to the zsl_clr_obs_data for the specified 825 * CIE standard observer model. 826 * 827 * @param obs The standard observer whose data should be retrieved. 828 * @param data Pointer to the pointer where the const zsl_clr_obs_data should 829 * be made accessible. 830 * 831 * @returns 0 on normal execution, otherwise an appropriate error code. 832 * 833 * @b Example 834 * 835 * The following example shows how to use the pointer to a pointer 836 * mechnaism to access standard 2 degree observer data in an resource 837 * efficient manner. 838 * 839 * @code 840 * void 841 * get_stdobs(void) 842 * { 843 * const struct zsl_clr_obs_data *obs; 844 * 845 * zsl_clr_obs_get(ZSL_CLR_OBS_2DEG, &obs); 846 * printf("obs: %s\n", obs->name); 847 * } 848 * @endcode 849 */ 850 void zsl_clr_obs_get(enum zsl_clr_obs obs, 851 const struct zsl_clr_obs_data **data); 852 853 /** 854 * @brief Retrieves a pointer to the zsl_clr_spd data for the specified 855 * CIE luminous efficiency function. 856 * 857 * @param lef The luminous efficiency func. whose data should be retrieved. 858 * @param data Pointer to the pointer where the const zsl_clr_spd data should 859 * be made accessible. 860 */ 861 void zsl_clr_lef_get(enum zsl_clr_lef lef, const struct zsl_clr_spd **data); 862 863 /** 864 * @brief Interpolates a single value from the specified CIE luminous 865 * efficiency function using linear interpolation. 866 * 867 * @param lef The luminous efficiency function to use. 868 * @param nm The wavelength to interpolate. 869 * @param val Pointer to the interpolated value's placeholder. 870 * 871 * @returns 0 on normal execution, otherwise an appropriate error code. 872 */ 873 int zsl_clr_lef_lerp(enum zsl_clr_lef lef, unsigned int nm, zsl_real_t *val); 874 875 /** 876 * @brief Retrieves a pointer to a standard 3x3 XYZ to RGB color space 877 * correlation matrix. 878 * 879 * @param ccm The XYZ to RGB color space correlation matrix to retrieve. 880 * @param mtx Pointer to the pointer where the const zsl_mtx data should 881 * be made accessible. 882 * 883 * @returns 0 on normal execution, otherwise an appropriate error code. 884 */ 885 void zsl_clr_rgbccm_get(enum zsl_clr_rgb_ccm ccm, struct zsl_mtx **mtx); 886 887 /** @} */ /* End of COLOR_DATA group */ 888 889 #ifdef __cplusplus 890 } 891 #endif 892 893 #endif /* ZEPHYR_INCLUDE_ZSL_COLORIMETRY_H_ */ 894 895 /** @} */ /* End of colorimetry group */ 896