1 /* 2 * Copyright (c) 2019-2020 Kevin Townsend (KTOWN) 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zsl/colorimetry.h> 8 9 /** 10 * CIE 1931 2 Degree Standard Observer Color Matching Functions from 380 nm 11 * to 830 nm in 5nm steps. 12 * 13 * @section Using the Color Matching Functions 14 * 15 * The calculation of CIE chromaticity coordinates for a given colored object 16 * requires the multiplication of its spectral power at each wavelength times 17 * the weighting factor from each of the three (X, Y, Z) color matching 18 * functions. Summing these contributions gives three values called the 19 * tristimulus values, from which the chromaticity coordinates are derived. 20 * 21 * For a visual representation of the color matching function see: 22 * https://en.wikipedia.org/wiki/File:CIE_1931_XYZ_Color_Matching_Functions.svg 23 */ 24 static const struct zsl_clr_obs_data zsl_clr_obs_2_deg_data = { 25 .observer = ZSL_CLR_OBS_2_DEG, 26 .name = "CIE 1931 2 degree standard observer", 27 .data = { 28 { 1.2990000E-04, 3.9200000E-06, 6.0610000E-04, }, /* 360 nm */ 29 { 2.3210000E-04, 6.9700000E-06, 1.0860000E-03, }, /* 365 nm */ 30 { 4.1490000E-04, 1.2390000E-05, 1.9460000E-03, }, /* 370 nm */ 31 { 7.4160000E-04, 2.2020000E-05, 3.4860000E-03, }, /* 375 nm */ 32 { 1.3680000E-03, 4.0000000E-05, 6.4500000E-04, }, /* 380 nm */ 33 { 2.2360000E-03, 6.0000000E-05, 1.0550000E-02, }, /* 385 nm */ 34 { 4.2430000E-03, 1.2000000E-04, 2.0050000E-02, }, /* 390 nm */ 35 { 7.6500000E-03, 2.1700000E-04, 3.6210000E-02, }, /* 395 nm */ 36 { 1.4310000E-02, 4.0000000E-04, 6.7850000E-02, }, /* 400 nm */ 37 { 2.3190000E-02, 6.4000000E-04, 1.1020000E-01, }, /* 405 nm */ 38 { 4.3510000E-02, 1.2100000E-03, 2.0740000E-01, }, /* 410 nm */ 39 { 7.7630000E-02, 2.1800000E-03, 3.7130000E-01, }, /* 415 nm */ 40 { 1.3438000E-01, 4.0000000E-03, 6.4560000E-01, }, /* 420 nm */ 41 { 2.1477000E-01, 7.3000000E-03, 1.0390500E+00, }, /* 425 nm */ 42 { 2.8390000E-01, 1.1600000E-02, 1.3856000E+00, }, /* 430 nm */ 43 { 3.2850000E-01, 1.6840000E-02, 1.6229600E+00, }, /* 435 nm */ 44 { 3.4828000E-01, 2.3000000E-02, 1.7470600E+00, }, /* 440 nm */ 45 { 3.4806000E-01, 2.9800000E-02, 1.7826000E+00, }, /* 445 nm */ 46 { 3.3620000E-01, 3.8000000E-02, 1.7721100E+00, }, /* 450 nm */ 47 { 3.1870000E-01, 4.8000000E-02, 1.7441000E+00, }, /* 455 nm */ 48 { 2.9080000E-01, 6.0000000E-02, 1.6692000E+00, }, /* 460 nm */ 49 { 2.5110000E-01, 7.3900000E-02, 1.5281000E+00, }, /* 465 nm */ 50 { 1.9536000E-01, 9.0980000E-02, 1.2876400E+00, }, /* 470 nm */ 51 { 1.4210000E-01, 1.1260000E-01, 1.0419000E+00, }, /* 475 nm */ 52 { 9.5640000E-02, 1.3902000E-01, 8.1295000E-01, }, /* 480 nm */ 53 { 5.7950000E-02, 1.6930000E-01, 6.1620000E-01, }, /* 485 nm */ 54 { 3.2010000E-02, 2.0802000E-01, 4.6518000E-01, }, /* 490 nm */ 55 { 1.4700000E-02, 2.5860000E-01, 3.5330000E-01, }, /* 495 nm */ 56 { 4.9000000E-03, 3.2300000E-01, 2.7200000E-01, }, /* 500 nm */ 57 { 2.4000000E-03, 4.0730000E-01, 2.1230000E-01, }, /* 505 nm */ 58 { 9.3000000E-03, 5.0300000E-01, 1.5820000E-01, }, /* 510 nm */ 59 { 2.9100000E-02, 6.0820000E-01, 1.1170000E-01, }, /* 515 nm */ 60 { 6.3270000E-02, 7.1000000E-01, 7.8250000E-02, }, /* 520 nm */ 61 { 1.0960000E-01, 7.9320000E-01, 5.7250000E-02, }, /* 525 nm */ 62 { 1.6550000E-01, 8.6200000E-01, 4.2160000E-02, }, /* 530 nm */ 63 { 2.2575000E-01, 9.1485000E-01, 2.9840000E-02, }, /* 535 nm */ 64 { 2.9040000E-01, 9.5400000E-01, 2.0300000E-02, }, /* 540 nm */ 65 { 3.5970000E-01, 9.8030000E-01, 1.3400000E-02, }, /* 545 nm */ 66 { 4.3345000E-01, 9.9495000E-01, 8.7500000E-03, }, /* 550 nm */ 67 { 5.1205000E-01, 1.0000000E+00, 5.7500000E-03, }, /* 555 nm */ 68 { 5.9450000E-01, 9.9500000E-01, 3.9000000E-03, }, /* 560 nm */ 69 { 6.7840000E-01, 9.7860000E-01, 2.7500000E-03, }, /* 565 nm */ 70 { 7.6210000E-01, 9.5200000E-01, 2.1000000E-03, }, /* 570 nm */ 71 { 8.4250000E-01, 9.1540000E-01, 1.8000000E-03, }, /* 575 nm */ 72 { 9.1630000E-01, 8.7000000E-01, 1.6500000E-03, }, /* 580 nm */ 73 { 9.7860000E-01, 8.1630000E-01, 1.4000000E-03, }, /* 585 nm */ 74 { 1.0263000E+00, 7.5700000E-01, 1.1000000E-03, }, /* 590 nm */ 75 { 1.0567000E+00, 6.9490000E-01, 1.0000000E-03, }, /* 595 nm */ 76 { 1.0622000E+00, 6.3100000E-01, 8.0000000E-04, }, /* 600 nm */ 77 { 1.0456000E+00, 5.6680000E-01, 6.0000000E-04, }, /* 605 nm */ 78 { 1.0026000E+00, 5.0300000E-01, 3.4000000E-04, }, /* 610 nm */ 79 { 9.3840000E-01, 4.4120000E-01, 2.4000000E-04, }, /* 615 nm */ 80 { 8.5450000E-01, 3.8100000E-01, 1.9000000E-04, }, /* 620 nm */ 81 { 7.5140000E-01, 3.2100000E-01, 1.0000000E-04, }, /* 625 nm */ 82 { 6.4240000E-01, 2.6500000E-01, 5.0000000E-04, }, /* 630 nm */ 83 { 5.4190000E-01, 2.1700000E-01, 3.0000000E-04, }, /* 635 nm */ 84 { 4.4790000E-01, 1.7500000E-01, 2.0000000E-04, }, /* 640 nm */ 85 { 3.6080000E-01, 1.3800000E-01, 1.0000000E-04, }, /* 645 nm */ 86 { 2.8350000E-01, 1.0700000E-01, 0.0000000E+00, }, /* 650 nm */ 87 { 2.1870000E-01, 8.1600000E-02, 0.0000000E+00, }, /* 655 nm */ 88 { 1.6490000E-01, 6.1000000E-02, 0.0000000E+00, }, /* 660 nm */ 89 { 1.2120000E-01, 4.4580000E-02, 0.0000000E+00, }, /* 665 nm */ 90 { 8.7400000E-02, 3.2000000E-02, 0.0000000E+00, }, /* 670 nm */ 91 { 6.3600000E-02, 2.3200000E-02, 0.0000000E+00, }, /* 675 nm */ 92 { 4.6770000E-02, 1.7000000E-02, 0.0000000E+00, }, /* 680 nm */ 93 { 3.2900000E-02, 1.1920000E-02, 0.0000000E+00, }, /* 685 nm */ 94 { 2.2700000E-02, 8.2100000E-03, 0.0000000E+00, }, /* 690 nm */ 95 { 1.5840000E-02, 5.7230000E-03, 0.0000000E+00, }, /* 695 nm */ 96 { 1.1359000E-02, 4.1020000E-03, 0.0000000E+00, }, /* 700 nm */ 97 { 8.1110000E-03, 2.9290000E-03, 0.0000000E+00, }, /* 705 nm */ 98 { 5.7900000E-03, 2.0910000E-03, 0.0000000E+00, }, /* 710 nm */ 99 { 4.1090000E-03, 1.4840000E-03, 0.0000000E+00, }, /* 715 nm */ 100 { 2.8990000E-03, 1.0470000E-03, 0.0000000E+00, }, /* 720 nm */ 101 { 2.0490000E-03, 7.4000000E-04, 0.0000000E+00, }, /* 725 nm */ 102 { 1.4400000E-03, 5.2000000E-04, 0.0000000E+00, }, /* 730 nm */ 103 { 1.0000000E-03, 3.6100000E-04, 0.0000000E+00, }, /* 735 nm */ 104 { 6.9000000E-04, 2.4900000E-04, 0.0000000E+00, }, /* 740 nm */ 105 { 4.7600000E-04, 1.7190000E-04, 0.0000000E+00, }, /* 745 nm */ 106 { 3.3200000E-04, 1.2000000E-04, 0.0000000E+00, }, /* 750 nm */ 107 { 2.3500000E-04, 8.4800000E-05, 0.0000000E+00, }, /* 755 nm */ 108 { 1.6600000E-04, 6.0000000E-05, 0.0000000E+00, }, /* 760 nm */ 109 { 1.7700000E-04, 4.2400000E-05, 0.0000000E+00, }, /* 765 nm */ 110 { 8.3000000E-05, 3.0000000E-05, 0.0000000E+00, }, /* 770 nm */ 111 { 5.9000000E-05, 2.1000000E-05, 0.0000000E+00, }, /* 775 nm */ 112 { 4.2000000E-05, 1.5000000E-05, 0.0000000E+00, }, /* 780 nm */ 113 { 2.9350000E-05, 1.0600000E-05, 0.0000000E+00, }, /* 785 nm */ 114 { 2.0670000E-05, 7.4700000E-06, 0.0000000E+00, }, /* 790 nm */ 115 { 1.4560000E-05, 5.2600000E-06, 0.0000000E+00, }, /* 795 nm */ 116 { 1.0250000E-05, 3.7000000E-06, 0.0000000E+00, }, /* 800 nm */ 117 { 7.2200000E-06, 2.6100000E-06, 0.0000000E+00, }, /* 805 nm */ 118 { 5.0900000E-06, 1.8400000E-06, 0.0000000E+00, }, /* 810 nm */ 119 { 3.5800000E-06, 1.2900000E-06, 0.0000000E+00, }, /* 815 nm */ 120 { 2.5200000E-06, 9.1000000E-07, 0.0000000E+00, }, /* 820 nm */ 121 { 1.7800000E-06, 6.4000000E-07, 0.0000000E+00, }, /* 825 nm */ 122 { 1.2500000E-06, 4.5000000E-07, 0.0000000E+00, } /* 830 nm */ 123 } 124 }; 125 126 /** 127 * CIE 1964 10 degree supplementary standard observer color matching functions 128 * from 380 nm to 830 nm in 5nm steps. 129 */ 130 static const struct zsl_clr_obs_data zsl_clr_obs_10_deg_data = { 131 .observer = ZSL_CLR_OBS_10_DEG, 132 .name = "CIE 1964 10 degree standard observer", 133 .data = { 134 { 0.000000122200, 0.000000013398, 0.000000535027 }, /* 360 nm */ 135 { 0.000000919270, 0.000000100650, 0.000004028300 }, /* 365 nm */ 136 { 0.000005958600, 0.000000651100, 0.000026143700 }, /* 370 nm */ 137 { 0.000033266000, 0.000003625000, 0.000146220000 }, /* 375 nm */ 138 { 0.000159952000, 0.000017364000, 0.000704776000 }, /* 380 nm */ 139 { 0.000662440000, 0.000071560000, 0.002927800000 }, /* 385 nm */ 140 { 0.002361600000, 0.000253400000, 0.010482200000 }, /* 390 nm */ 141 { 0.007242300000, 0.000768500000, 0.032344000000 }, /* 395 nm */ 142 { 0.019109700000, 0.002004400000, 0.086010900000 }, /* 400 nm */ 143 { 0.043400000000, 0.004509000000, 0.197120000000 }, /* 405 nm */ 144 { 0.084736000000, 0.008756000000, 0.389366000000 }, /* 410 nm */ 145 { 0.140638000000, 0.014456000000, 0.656760000000 }, /* 415 nm */ 146 { 0.204492000000, 0.021391000000, 0.972542000000 }, /* 420 nm */ 147 { 0.264737000000, 0.029497000000, 1.282500000000 }, /* 425 nm */ 148 { 0.314679000000, 0.038676000000, 1.553480000000 }, /* 430 nm */ 149 { 0.357719000000, 0.049602000000, 1.798500000000 }, /* 435 nm */ 150 { 0.383734000000, 0.062077000000, 1.967280000000 }, /* 440 nm */ 151 { 0.386726000000, 0.074704000000, 2.027300000000 }, /* 445 nm */ 152 { 0.370702000000, 0.089456000000, 1.994800000000 }, /* 450 nm */ 153 { 0.342957000000, 0.106256000000, 1.900700000000 }, /* 455 nm */ 154 { 0.302273000000, 0.128201000000, 1.745370000000 }, /* 460 nm */ 155 { 0.254085000000, 0.152761000000, 1.554900000000 }, /* 465 nm */ 156 { 0.195618000000, 0.185190000000, 1.317560000000 }, /* 470 nm */ 157 { 0.132349000000, 0.219940000000, 1.030200000000 }, /* 475 nm */ 158 { 0.080507000000, 0.253589000000, 0.772125000000 }, /* 480 nm */ 159 { 0.041072000000, 0.297665000000, 0.570060000000 }, /* 485 nm */ 160 { 0.016172000000, 0.339133000000, 0.415254000000 }, /* 490 nm */ 161 { 0.005132000000, 0.395379000000, 0.302356000000 }, /* 495 nm */ 162 { 0.003816000000, 0.460777000000, 0.218502000000 }, /* 500 nm */ 163 { 0.015444000000, 0.531360000000, 0.159249000000 }, /* 505 nm */ 164 { 0.037465000000, 0.606741000000, 0.112044000000 }, /* 510 nm */ 165 { 0.071358000000, 0.685660000000, 0.082248000000 }, /* 515 nm */ 166 { 0.117749000000, 0.761757000000, 0.060709000000 }, /* 520 nm */ 167 { 0.172953000000, 0.823330000000, 0.043050000000 }, /* 525 nm */ 168 { 0.236491000000, 0.875211000000, 0.030451000000 }, /* 530 nm */ 169 { 0.304213000000, 0.923810000000, 0.020584000000 }, /* 535 nm */ 170 { 0.376772000000, 0.961988000000, 0.013676000000 }, /* 540 nm */ 171 { 0.451584000000, 0.982200000000, 0.007918000000 }, /* 545 nm */ 172 { 0.529826000000, 0.991761000000, 0.003988000000 }, /* 550 nm */ 173 { 0.616053000000, 0.999110000000, 0.001091000000 }, /* 555 nm */ 174 { 0.705224000000, 0.997340000000, 0.000000000000 }, /* 560 nm */ 175 { 0.793832000000, 0.982380000000, 0.000000000000 }, /* 565 nm */ 176 { 0.878655000000, 0.955552000000, 0.000000000000 }, /* 570 nm */ 177 { 0.951162000000, 0.915175000000, 0.000000000000 }, /* 575 nm */ 178 { 1.014160000000, 0.868934000000, 0.000000000000 }, /* 580 nm */ 179 { 1.074300000000, 0.825623000000, 0.000000000000 }, /* 585 nm */ 180 { 1.118520000000, 0.777405000000, 0.000000000000 }, /* 590 nm */ 181 { 1.134300000000, 0.720353000000, 0.000000000000 }, /* 595 nm */ 182 { 1.123990000000, 0.658341000000, 0.000000000000 }, /* 600 nm */ 183 { 1.089100000000, 0.593878000000, 0.000000000000 }, /* 605 nm */ 184 { 1.030480000000, 0.527963000000, 0.000000000000 }, /* 610 nm */ 185 { 0.950740000000, 0.461834000000, 0.000000000000 }, /* 615 nm */ 186 { 0.856297000000, 0.398057000000, 0.000000000000 }, /* 620 nm */ 187 { 0.754930000000, 0.339554000000, 0.000000000000 }, /* 625 nm */ 188 { 0.647467000000, 0.283493000000, 0.000000000000 }, /* 630 nm */ 189 { 0.535110000000, 0.228254000000, 0.000000000000 }, /* 635 nm */ 190 { 0.431567000000, 0.179828000000, 0.000000000000 }, /* 640 nm */ 191 { 0.343690000000, 0.140211000000, 0.000000000000 }, /* 645 nm */ 192 { 0.268329000000, 0.107633000000, 0.000000000000 }, /* 650 nm */ 193 { 0.204300000000, 0.081187000000, 0.000000000000 }, /* 655 nm */ 194 { 0.152568000000, 0.060281000000, 0.000000000000 }, /* 660 nm */ 195 { 0.112210000000, 0.044096000000, 0.000000000000 }, /* 665 nm */ 196 { 0.081260600000, 0.031800400000, 0.000000000000 }, /* 670 nm */ 197 { 0.057930000000, 0.022601700000, 0.000000000000 }, /* 675 nm */ 198 { 0.040850800000, 0.015905100000, 0.000000000000 }, /* 680 nm */ 199 { 0.028623000000, 0.011130300000, 0.000000000000 }, /* 685 nm */ 200 { 0.019941300000, 0.007748800000, 0.000000000000 }, /* 690 nm */ 201 { 0.013842000000, 0.005375100000, 0.000000000000 }, /* 695 nm */ 202 { 0.009576880000, 0.003717740000, 0.000000000000 }, /* 700 nm */ 203 { 0.006605200000, 0.002564560000, 0.000000000000 }, /* 705 nm */ 204 { 0.004552630000, 0.001768470000, 0.000000000000 }, /* 710 nm */ 205 { 0.003144700000, 0.001222390000, 0.000000000000 }, /* 715 nm */ 206 { 0.002174960000, 0.000846190000, 0.000000000000 }, /* 720 nm */ 207 { 0.001505700000, 0.000586440000, 0.000000000000 }, /* 725 nm */ 208 { 0.001044760000, 0.000407410000, 0.000000000000 }, /* 730 nm */ 209 { 0.000727450000, 0.000284041000, 0.000000000000 }, /* 735 nm */ 210 { 0.000508258000, 0.000198730000, 0.000000000000 }, /* 740 nm */ 211 { 0.000356380000, 0.000139550000, 0.000000000000 }, /* 745 nm */ 212 { 0.000250969000, 0.000098428000, 0.000000000000 }, /* 750 nm */ 213 { 0.000177730000, 0.000069819000, 0.000000000000 }, /* 755 nm */ 214 { 0.000126390000, 0.000049737000, 0.000000000000 }, /* 760 nm */ 215 { 0.000090151000, 0.000035540500, 0.000000000000 }, /* 765 nm */ 216 { 0.000064525800, 0.000025486000, 0.000000000000 }, /* 770 nm */ 217 { 0.000046339000, 0.000018338400, 0.000000000000 }, /* 775 nm */ 218 { 0.000033411700, 0.000013249000, 0.000000000000 }, /* 780 nm */ 219 { 0.000024209000, 0.000009619600, 0.000000000000 }, /* 785 nm */ 220 { 0.000017611500, 0.000007012800, 0.000000000000 }, /* 790 nm */ 221 { 0.000012855000, 0.000005129800, 0.000000000000 }, /* 795 nm */ 222 { 0.000009413630, 0.000003764730, 0.000000000000 }, /* 800 nm */ 223 { 0.000006913000, 0.000002770810, 0.000000000000 }, /* 805 nm */ 224 { 0.000005093470, 0.000002046130, 0.000000000000 }, /* 810 nm */ 225 { 0.000003767100, 0.000001516770, 0.000000000000 }, /* 815 nm */ 226 { 0.000002795310, 0.000001128090, 0.000000000000 }, /* 820 nm */ 227 { 0.000002082000, 0.000000842160, 0.000000000000 }, /* 825 nm */ 228 { 0.000001553140, 0.000000629700, 0.000000000000 } /* 830 nm */ 229 } 230 }; 231 232 void zsl_clr_obs_get(enum zsl_clr_obs obs,const struct zsl_clr_obs_data ** data)233 zsl_clr_obs_get(enum zsl_clr_obs obs, const struct zsl_clr_obs_data **data) 234 { 235 switch (obs) { 236 case ZSL_CLR_OBS_10_DEG: 237 *data = &zsl_clr_obs_10_deg_data; 238 break; 239 case ZSL_CLR_OBS_2_DEG: 240 *data = &zsl_clr_obs_2_deg_data; 241 break; 242 } 243 } 244