00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_COLORSPACE
00025 #define __VCGLIB_COLORSPACE
00026
00027 #include <vcg/space/color4.h>
00028
00101 namespace vcg
00102 {
00103
00111 template <typename T>
00112 class ColorSpace
00113 {
00114
00115
00116 public:
00117
00118 enum ConeResponse { BRADFORD = 0, VON_KRIES = 1, XYZ_SCALING = 2};
00119
00120 enum Illuminant
00121 {
00122 ILLUMINANT_A = 0,
00123 ILLUMINANT_B = 1,
00124 ILLUMINANT_C = 2,
00125 ILLUMINANT_D50 = 3,
00126 ILLUMINANT_D55 = 4,
00127 ILLUMINANT_D65 = 5,
00128 ILLUMINANT_D75 = 6,
00129 ILLUMINANT_E = 7,
00130 ILLUMINANT_INVALID = 8
00131 };
00132
00133 enum RGBSpaces
00134 {
00135 ADOBE_RGB = 0,
00136 APPLE_RGB = 1,
00137 BEST_RGB = 2,
00138 BETA_RGB = 3,
00139 BRUCE_RGB = 4,
00140 CIE_RGB = 5,
00141 COLOR_MATCH = 6,
00142 DON_RGB4 = 7,
00143 ECI_RGB = 8,
00144 EKTA_SPACE = 9,
00145 NTSC_RGB = 10,
00146 PAL_RGB = 11,
00147 PROPHOTO = 12,
00148 SMPTE_C = 13,
00149 SRGB = 14,
00150 WIDE_GAMUT = 15
00151 };
00152
00153
00154 private:
00155
00156 static double CIE_EPSILON()
00157 {
00158 return 0.008856;
00159 }
00160
00161 static double CIE_KI()
00162 {
00163 return 903.3;
00164 }
00165
00166 static double RGB2XYZ(int index)
00167 {
00168
00169
00170
00171
00172 static double RGB_TO_XYZ[]=
00173 {
00174
00175 0.576700, 0.297361, 0.0270328,
00176 0.185556, 0.627355, 0.0706879,
00177 0.188212, 0.0752847, 0.991248,
00178
00179
00180 0.449695, 0.244634, 0.0251829,
00181 0.316251, 0.672034, 0.141184,
00182 0.18452, 0.0833318, 0.922602,
00183
00184
00185 0.632670, 0.228457, 0.000000,
00186 0.204556, 0.737352, 0.00951424,
00187 0.126995, 0.0341908, 0.815696,
00188
00189
00190 0.671254, 0.303273, 0.000000,
00191 0.174583, 0.663786, 0.040701,
00192 0.118383, 0.0329413, 0.784509,
00193
00194
00195 0.467384, 0.240995, 0.0219086,
00196 0.294454, 0.683554, 0.0736135,
00197 0.188629, 0.0754517, 0.993447,
00198
00199
00200 0.488718, 0.176204, 0.000000,
00201 0.310680, 0.812985, 0.0102048,
00202 0.200602, 0.0108109, 0.989795,
00203
00204
00205 0.509344, 0.274884, 0.0242545,
00206 0.320907, 0.658132, 0.108782,
00207 0.133969, 0.0669845, 0.692174,
00208
00209
00210 0.645771, 0.278350, 0.00371134,
00211 0.193351, 0.687970, 0.0179862,
00212 0.125098, 0.0336802, 0.803513,
00213
00214
00215 0.650204, 0.320250, 0.000000,
00216 0.178077, 0.602071, 0.0678390,
00217 0.135938, 0.0776791, 0.757371,
00218
00219
00220 0.593891, 0.260629, 0.000000,
00221 0.272980, 0.734946, 0.0419970,
00222 0.0973486, 0.00442493, 0.783213,
00223
00224
00225 0.606734, 0.298839, 0.000000,
00226 0.173564, 0.586811, 0.0661196,
00227 0.200112, 0.114350, 1.11491,
00228
00229
00230 0.430587, 0.222021, 0.0201837,
00231 0.341545, 0.706645, 0.129551,
00232 0.178336, 0.0713342, 0.939234,
00233
00234
00235 0.797675, 0.288040, 0.000000,
00236 0.135192, 0.711874, 0.000000,
00237 0.0313534, 0.000086, 0.825210,
00238
00239
00240 0.393555, 0.212395, 0.0187407,
00241 0.365253, 0.701049, 0.111932,
00242 0.191659, 0.0865558, 0.958297,
00243
00244
00245 0.412424, 0.212656, 0.0193324,
00246 0.357579, 0.715158, 0.119193,
00247 0.180464, 0.0721856, 0.950444,
00248
00249
00250 0.716105, 0.258187, 0.000000,
00251 0.100930, 0.724938, 0.0517813,
00252 0.147186, 0.0168748, 0.773429
00253
00254 };
00255
00256 return RGB_TO_XYZ[index];
00257 }
00258
00259 static double XYZ2RGB(int index)
00260 {
00261
00262
00263
00264
00265 static double XYZ_TO_RGB[]=
00266 {
00267
00268 2.04148, -0.969258, 0.0134455,
00269 -0.564977, 1.87599, -0.118373,
00270 -0.344713, 0.0415557, 1.01527,
00271
00272
00273 2.95176, -1.0851, 0.0854804,
00274 -1.28951, 1.99084, -0.269456,
00275 -0.47388, 0.0372023, 1.09113,
00276
00277
00278 1.75526, -0.544134, 0.00634681,
00279 -0.483679, 1.50688, -0.0175762,
00280 -0.253000, 0.0215528, 1.22570,
00281
00282
00283 1.68323, -0.771023, 0.0400012,
00284 -0.428236, 1.70656, -0.0885376,
00285 -0.236018, 0.0446899, 1.27236,
00286
00287
00288 2.74566, -0.969257, 0.0112707,
00289 -1.13589, 1.87599, -0.113959,
00290 -0.435057, 0.0415557, 1.01311,
00291
00292
00293 2.37067, -0.513885, 0.00529818,
00294 -0.900040, 1.42530, -0.0146949,
00295 -0.470634, 0.0885814, 1.00940,
00296
00297
00298 2.64229, -1.11198, 0.0821698,
00299 -1.22343, 2.05902, -0.280725,
00300 -0.393014, 0.0159614, 1.45599,
00301
00302
00303 1.76039, -0.712629, 0.00782072,
00304 -0.488120, 1.65274, -0.0347411,
00305 -0.253613, 0.0416715, 1.24477,
00306
00307
00308 1.78276, -0.959362, 0.0859318,
00309 -0.496985, 1.94780, -0.174467,
00310 -0.269010, -0.0275807, 1.32283,
00311
00312
00313 2.00438, -0.711029, 0.0381263,
00314 -0.730484, 1.62021, -0.0868780,
00315 -0.245005, 0.0792227, 1.27254,
00316
00317
00318 1.91049, -0.984310, 0.0583744,
00319 -0.532592, 1.99845, -0.118518,
00320 -0.288284, -0.0282980, 0.898611,
00321
00322
00323 3.06313, -0.969258, 0.0678674,
00324 -1.39328, 1.87599, -0.228821,
00325 -0.475788, 0.0415557, 1.06919,
00326
00327
00328 1.34594, -0.544599, 0.000000,
00329 -0.255608, 1.50817, 0.000000,
00330 -0.0511118, 0.0205351, 1.21181,
00331
00332
00333 3.50570, -1.06906, 0.0563117,
00334 -1.73964, 1.97781, -0.196994,
00335 -0.544011, 0.0351720, 1.05005,
00336
00337
00338 3.24071, -0.969258, 0.0556352,
00339 -1.53726, 1.87599, -0.203996,
00340 -0.498571, 0.0415557, 1.05707,
00341
00342
00343 1.46281, -0.521793, 0.0349342,
00344 -0.184062, 1.44724, -0.0968931,
00345 -0.274361, 0.0677228, 1.28841
00346
00347 };
00348
00349 return XYZ_TO_RGB[index];
00350 }
00351
00352 static double CA(int index)
00353 {
00354
00355
00356
00357
00358 static double CAmatrix[]=
00359 {
00360
00361 1.0, 0.0, 0.0,
00362 0.0, 1.0, 0.0,
00363 0.0, 0.0, 1.0,
00364
00365 1.0, 0.0, 0.0,
00366 0.0, 1.0, 0.0,
00367 0.0, 0.0, 1.0,
00368
00369 1.0, 0.0, 0.0,
00370 0.0, 1.0, 0.0,
00371 0.0, 0.0, 1.0,
00372
00373
00374 0.890600, -0.097037, 0.054012,
00375 -0.082873, 1.075262, -0.091063,
00376 0.268563, 0.088084, 2.486772,
00377
00378
00379 0.957515, -0.018042, 0.000000,
00380 -0.164247, 1.018522, 0.000000,
00381 0.290746, 0.003635, 2.397466,
00382
00383
00384 0.902065, 0.000000, 0.000000,
00385 0.000000, 1.000000, 0.000000,
00386 0.000000, 0.000000, 2.397474,
00387
00388
00389 0.853036, -0.123884, 0.091195,
00390 -0.113032, 1.085373, -0.155374,
00391 0.440458, 0.142587, 3.477780,
00392
00393
00394 0.941839, -0.024699, 0.000000,
00395 -0.224854, 1.025358, 0.000000,
00396 0.480676, 0.004974, 3.322435,
00397
00398
00399 0.892678, 0.000000, 0.000000,
00400 0.000000, 1.000000, 0.000000,
00401 0.000000, 0.000000, 3.322447,
00402
00403
00404 0.878034, -0.111621, 0.050313,
00405 -0.091487, 1.092265, -0.083964,
00406 0.257070, 0.085312, 2.402220,
00407
00408
00409 0.953214, -0.019868, 0.000000,
00410 -0.180875, 1.020397, 0.000000,
00411 0.276267, 0.004004, 2.321454,
00412
00413
00414 0.877936, 0.000000, 0.000000,
00415 0.000000, 1.000000, 0.000000,
00416 0.000000, 0.000000, 2.321462,
00417
00418
00419 0.864256, -0.122489, 0.061011,
00420 -0.102279, 1.098455, -0.102340,
00421 0.307550, 0.101476, 2.689914,
00422
00423
00424 0.947636, -0.022237, 0.000000,
00425 -0.202440, 1.022829, 0.000000,
00426 0.331718, 0.004481, 2.590505,
00427
00428
00429 0.870670, 0.000000, 0.000000,
00430 0.000000, 1.000000, 0.000000,
00431 0.000000, 0.000000, 2.590514,
00432
00433
00434 0.844763, -0.136524, 0.080011,
00435 -0.117903, 1.103952, -0.135190,
00436 0.395490, 0.129376, 3.196569,
00437
00438
00439 0.939518, -0.025685, 0.000000,
00440 -0.233826, 1.026369, 0.000000,
00441 0.428852, 0.005174, 3.063452,
00442
00443
00444 0.865414, 0.000000, 0.000000,
00445 0.000000, 1.000000, 0.000000,
00446 0.000000, 0.000000, 3.063462,
00447
00448
00449 0.830991, -0.145710, 0.095536,
00450 -0.129133, 1.106062, -0.162123,
00451 0.466601, 0.151821, 3.608682,
00452
00453
00454 0.933660, -0.028172, 0.000000,
00455 -0.256474, 1.028923, 0.000000,
00456 0.507632, 0.005674, 3.447762,
00457
00458
00459 0.864434, 0.000000, 0.000000,
00460 0.000000, 1.000000, 0.000000,
00461 0.000000, 0.000000, 3.447773,
00462
00463
00464 0.881682, -0.100560, 0.071051,
00465 -0.090783, 1.070733, -0.120888,
00466 0.344476, 0.111711, 2.933736,
00467
00468
00469 0.953314, -0.019826, 0.000000,
00470 -0.180491, 1.020355, 0.000000,
00471 0.375531, 0.003993, 2.813168,
00472
00473
00474 0.910515, 0.000000, 0.000000,
00475 0.000000, 1.000000, 0.000000,
00476 0.000000, 0.000000, 2.813177,
00477
00478
00479 1.138867, 0.104490, -0.020910,
00480 0.077128, 0.934300, 0.032538,
00481 -0.125725, -0.044379, 0.403234,
00482
00483
00484 1.047555, 0.018556, 0.000000,
00485 0.168937, 0.984806, 0.000000,
00486 -0.127296, -0.003743, 0.417104,
00487
00488
00489 1.108567, 0.000000, 0.000000,
00490 0.000000, 1.000000, 0.000000,
00491 0.000000, 0.000000, 0.417106,
00492
00493
00494 1.0, 0.0, 0.0,
00495 0.0, 1.0, 0.0,
00496 0.0, 0.0, 1.0,
00497
00498 1.0, 0.0, 0.0,
00499 0.0, 1.0, 0.0,
00500 0.0, 0.0, 1.0,
00501
00502 1.0, 0.0, 0.0,
00503 0.0, 1.0, 0.0,
00504 0.0, 0.0, 1.0,
00505
00506
00507 0.950475, -0.030658, 0.014905,
00508 -0.025481, 1.009149, -0.024973,
00509 0.075375, 0.024904, 1.397787,
00510
00511
00512 0.982455, -0.006847, 0.000000,
00513 -0.062331, 1.005606, 0.000000,
00514 0.081442, 0.001380, 1.385807,
00515
00516
00517 0.989593, 0.000000, 0.000000,
00518 0.000000, 1.000000, 0.000000,
00519 0.000000, 0.000000, 1.385811,
00520
00521
00522 0.985029, -0.014775, -0.001704,
00523 -0.009391, 1.014671, 0.003596,
00524 -0.002672, -0.000039, 0.966056,
00525
00526
00527 0.995186, -0.001879, 0.000000,
00528 -0.017098, 1.001537, 0.000000,
00529 -0.005430, 0.000380, 0.968292,
00530
00531
00532 0.973252, 0.000000, 0.000000,
00533 0.000000, 1.000000, 0.000000,
00534 0.000000, 0.000000, 0.968295,
00535
00536
00537 0.967155, -0.026843, 0.002545,
00538 -0.018894, 1.020141, -0.003387,
00539 0.019895, 0.007571, 1.081535,
00540
00541
00542 0.988943, -0.004315, 0.000000,
00543 -0.039278, 1.003532, 0.000000,
00544 0.018490, 0.000871, 1.080514,
00545
00546
00547 0.965197, 0.000000, 0.000000,
00548 0.000000, 1.000000, 0.000000,
00549 0.000000, 0.000000, 1.080518,
00550
00551
00552 0.941484, -0.042836, 0.010157,
00553 -0.032134, 1.025102, -0.016128,
00554 0.058499, 0.020341, 1.284904,
00555
00556
00557 0.979857, -0.007861, 0.000000,
00558 -0.071558, 1.006436, 0.000000,
00559 0.060156, 0.001586, 1.277783,
00560
00561
00562 0.959370, 0.000000, 0.000000,
00563 0.000000, 1.000000, 0.000000,
00564 0.000000, 0.000000, 1.277788,
00565
00566
00567 0.923139, -0.053546, 0.016407,
00568 -0.041374, 1.027096, -0.026684,
00569 0.089403, 0.030453, 1.450325,
00570
00571
00572 0.973300, -0.010419, 0.000000,
00573 -0.094851, 1.008531, 0.000000,
00574 0.093846, 0.002101, 1.438081,
00575
00576
00577 0.958283, 0.000000, 0.000000,
00578 0.000000, 1.000000, 0.000000,
00579 0.000000, 0.000000, 1.438086,
00580
00581
00582 0.987430, -0.004980, 0.006942,
00583 -0.005608, 0.996265, -0.012009,
00584 0.032084, 0.010171, 1.179413,
00585
00586
00587 0.995299, -0.001835, 0.000000,
00588 -0.016702, 1.001503, 0.000000,
00589 0.035959, 0.000370, 1.173388,
00590
00591
00592 1.009367, 0.000000, 0.000000,
00593 0.000000, 1.000000, 0.000000,
00594 0.000000, 0.000000, 1.173392,
00595
00596
00597 1.203987, 0.140744, -0.025283,
00598 0.102952, 0.928000, 0.038760,
00599 -0.156705, -0.055873, 0.289153,
00600
00601
00602 1.067896, 0.025724, 0.000000,
00603 0.234191, 0.980909, 0.000000,
00604 -0.154849, -0.005190, 0.300982,
00605
00606
00607 1.120225, 0.000000, 0.000000,
00608 0.000000, 1.000000, 0.000000,
00609 0.000000, 0.000000, 0.300983,
00610
00611
00612 1.053816, 0.032278, -0.010661,
00613 0.025192, 0.991268, 0.017441,
00614 -0.057275, -0.019402, 0.715681,
00615
00616
00617 1.018301, 0.006933, 0.000000,
00618 0.063126, 0.994853, 0.000000,
00619 -0.059908, -0.001398, 0.721597,
00620
00621
00622 1.010516, 0.000000, 0.000000,
00623 0.000000, 1.000000, 0.000000,
00624 0.000000, 0.000000, 0.721599,
00625
00626
00627 1.0, 0.0, 0.0,
00628 0.0, 1.0, 0.0,
00629 0.0, 0.0, 1.0,
00630
00631 1.0, 0.0, 0.0,
00632 0.0, 1.0, 0.0,
00633 0.0, 0.0, 1.0,
00634
00635 1.0, 0.0, 0.0,
00636 0.0, 1.0, 0.0,
00637 0.0, 0.0, 1.0,
00638
00639
00640 1.037765, 0.017182, -0.011978,
00641 0.015460, 1.005438, 0.020371,
00642 -0.058148, -0.018868, 0.691416,
00643
00644
00645 1.013279, 0.005031, 0.000000,
00646 0.045808, 0.996264, 0.000000,
00647 -0.063514, -0.001014, 0.698718,
00648
00649
00650 0.983487, 0.000000, 0.000000,
00651 0.000000, 1.000000, 0.000000,
00652 0.000000, 0.000000, 0.698721,
00653
00654
00655 1.018382, 0.004560, -0.008957,
00656 0.005982, 1.010689, 0.015570,
00657 -0.040789, -0.012837, 0.773954,
00658
00659
00660 1.006768, 0.002564, 0.000000,
00661 0.023348, 0.998095, 0.000000,
00662 -0.045848, -0.000516, 0.779698,
00663
00664
00665 0.975347, 0.000000, 0.000000,
00666 0.000000, 1.000000, 0.000000,
00667 0.000000, 0.000000, 0.779701,
00668
00669
00670 0.990490, -0.012269, -0.003515,
00671 -0.007115, 1.015427, 0.006679,
00672 -0.011434, -0.002878, 0.919313,
00673
00674
00675 0.997291, -0.001026, 0.000000,
00676 -0.009340, 1.000760, 0.000000,
00677 -0.015193, 0.000208, 0.922047,
00678
00679
00680 0.969459, 0.000000, 0.000000,
00681 0.000000, 1.000000, 0.000000,
00682 0.000000, 0.000000, 0.922050,
00683
00684
00685 0.970531, -0.023599, 0.000967,
00686 -0.016198, 1.017309, -0.000743,
00687 0.011914, 0.004934, 1.037548,
00688
00689
00690 0.990453, -0.003617, 0.000000,
00691 -0.032927, 1.002683, 0.000000,
00692 0.009543, 0.000730, 1.037718,
00693
00694
00695 0.968360, 0.000000, 0.000000,
00696 0.000000, 1.000000, 0.000000,
00697 0.000000, 0.000000, 1.037721,
00698
00699
00700 1.040046, 0.026802, -0.005645,
00701 0.019876, 0.987617, 0.008842,
00702 -0.033485, -0.011765, 0.843919,
00703
00704
00705 1.013396, 0.005075, 0.000000,
00706 0.046208, 0.996233, 0.000000,
00707 -0.033655, -0.001024, 0.846716,
00708
00709
00710 1.019981, 0.000000, 0.000000,
00711 0.000000, 1.000000, 0.000000,
00712 0.000000, 0.000000, 0.846719,
00713
00714
00715 1.157264, 0.119830, -0.020050,
00716 0.087174, 0.922061, 0.030403,
00717 -0.126938, -0.045569, 0.417348,
00718
00719
00720 1.052976, 0.020503, 0.000000,
00721 0.186659, 0.983644, 0.000000,
00722 -0.125633, -0.004137, 0.430762,
00723
00724
00725 1.139034, 0.000000, 0.000000,
00726 0.000000, 1.000000, 0.000000,
00727 0.000000, 0.000000, 0.430763,
00728
00729
00730 1.015344, 0.014785, 0.001735,
00731 0.009388, 0.985677, -0.003652,
00732 0.002809, 0.000081, 1.035142,
00733
00734
00735 1.004871, 0.001885, 0.000000,
00736 0.017164, 0.998496, 0.000000,
00737 0.005627, -0.000381, 1.032740,
00738
00739
00740 1.027483, 0.000000, 0.000000,
00741 0.000000, 1.000000, 0.000000,
00742 0.000000, 0.000000, 1.032743,
00743
00744
00745 0.964813, -0.016165, 0.017191,
00746 -0.016469, 0.994317, -0.029580,
00747 0.080692, 0.025774, 1.446947,
00748
00749
00750 0.987122, -0.004985, 0.000000,
00751 -0.045378, 1.003977, 0.000000,
00752 0.089662, 0.001004, 1.431183,
00753
00754
00755 1.016791, 0.000000, 0.000000,
00756 0.000000, 1.000000, 0.000000,
00757 0.000000, 0.000000, 1.431187,
00758
00759
00760 1.0, 0.0, 0.0,
00761 0.0, 1.0, 0.0,
00762 0.0, 0.0, 1.0,
00763
00764 1.0, 0.0, 0.0,
00765 0.0, 1.0, 0.0,
00766 0.0, 0.0, 1.0,
00767
00768 1.0, 0.0, 0.0,
00769 0.0, 1.0, 0.0,
00770 0.0, 0.0, 1.0,
00771
00772
00773 0.981751, -0.012159, 0.004411,
00774 -0.009617, 1.005251, -0.007265,
00775 0.023309, 0.007844, 1.119548,
00776
00777
00778 0.993685, -0.002444, 0.000000,
00779 -0.022249, 1.001949, 0.000000,
00780 0.024676, 0.000493, 1.115894,
00781
00782
00783 0.991724, 0.000000, 0.000000,
00784 0.000000, 1.000000, 0.000000,
00785 0.000000, 0.000000, 1.115898,
00786
00787
00788 0.955556, -0.028302, 0.012305,
00789 -0.023049, 1.009944, -0.020494,
00790 0.063197, 0.021018, 1.330084,
00791
00792
00793 0.984494, -0.006002, 0.000000,
00794 -0.054637, 1.004788, 0.000000,
00795 0.067667, 0.001210, 1.319622,
00796
00797
00798 0.985737, 0.000000, 0.000000,
00799 0.000000, 1.000000, 0.000000,
00800 0.000000, 0.000000, 1.319627,
00801
00802
00803 0.936847, -0.039129, 0.018781,
00804 -0.032442, 1.011771, -0.031445,
00805 0.095135, 0.031456, 1.501335,
00806
00807
00808 0.977862, -0.008569, 0.000000,
00809 -0.078007, 1.006836, 0.000000,
00810 0.102432, 0.001727, 1.485168,
00811
00812
00813 0.984620, 0.000000, 0.000000,
00814 0.000000, 1.000000, 0.000000,
00815 0.000000, 0.000000, 1.485174,
00816
00817
00818 1.002553, 0.009691, 0.008918,
00819 0.003624, 0.981912, -0.016079,
00820 0.035984, 0.010595, 1.220878,
00821
00822
00823 1.000115, 0.000044, 0.000000,
00824 0.000401, 0.999965, 0.000000,
00825 0.042744, -0.000010, 1.211809,
00826
00827
00828 1.037108, 0.000000, 0.000000,
00829 0.000000, 1.000000, 0.000000,
00830 0.000000, 0.000000, 1.211813,
00831
00832
00833 1.180601, 0.133653, -0.021693,
00834 0.097012, 0.918163, 0.032732,
00835 -0.138643, -0.049919, 0.373005,
00836
00837
00838 1.060184, 0.023049, 0.000000,
00839 0.209842, 0.982241, 0.000000,
00840 -0.136121, -0.004650, 0.386023,
00841
00842
00843 1.148540, 0.000000, 0.000000,
00844 0.000000, 1.000000, 0.000000,
00845 0.000000, 0.000000, 0.386024,
00846
00847
00848 1.034540, 0.027239, -0.002349,
00849 0.019098, 0.980736, 0.003026,
00850 -0.019163, -0.007366, 0.924635,
00851
00852
00853 1.011356, 0.004348, 0.000000,
00854 0.039593, 0.996649, 0.000000,
00855 -0.017339, -0.000878, 0.925479,
00856
00857
00858 1.036058, 0.000000, 0.000000,
00859 0.000000, 1.000000, 0.000000,
00860 0.000000, 0.000000, 0.925482,
00861
00862
00863 0.982433, -0.004287, 0.011457,
00864 -0.006610, 0.989199, -0.019977,
00865 0.051668, 0.016181, 1.292341,
00866
00867
00868 0.993339, -0.002552, 0.000000,
00869 -0.023228, 1.001966, 0.000000,
00870 0.058394, 0.000514, 1.282539,
00871
00872
00873 1.025276, 0.000000, 0.000000,
00874 0.000000, 1.000000, 0.000000,
00875 0.000000, 0.000000, 1.282543,
00876
00877
00878 1.018803, 0.012353, -0.003934,
00879 0.009594, 0.994842, 0.006418,
00880 -0.021278, -0.007227, 0.893255,
00881
00882
00883 1.006412, 0.002455, 0.000000,
00884 0.022357, 0.998107, 0.000000,
00885 -0.022266, -0.000495, 0.896136,
00886
00887
00888 1.008345, 0.000000, 0.000000,
00889 0.000000, 1.000000, 0.000000,
00890 0.000000, 0.000000, 0.896140,
00891
00892
00893 1.0, 0.0, 0.0,
00894 0.0, 1.0, 0.0,
00895 0.0, 0.0, 1.0,
00896
00897 1.0, 0.0, 0.0,
00898 0.0, 1.0, 0.0,
00899 0.0, 0.0, 1.0,
00900
00901 1.0, 0.0, 0.0,
00902 0.0, 1.0, 0.0,
00903 0.0, 0.0, 1.0,
00904
00905
00906 0.972990, -0.016440, 0.007051,
00907 -0.013357, 1.004598, -0.011734,
00908 0.036285, 0.012078, 1.187991,
00909
00910
00911 0.990671, -0.003573, 0.000000,
00912 -0.032527, 1.002753, 0.000000,
00913 0.038746, 0.000720, 1.182565,
00914
00915
00916 0.993963, 0.000000, 0.000000,
00917 0.000000, 1.000000, 0.000000,
00918 0.000000, 0.000000, 1.182570,
00919
00920
00921 0.953688, -0.027490, 0.012840,
00922 -0.022677, 1.006379, -0.021468,
00923 0.065280, 0.021618, 1.340903,
00924
00925
00926 0.983939, -0.006152, 0.000000,
00927 -0.056002, 1.004740, 0.000000,
00928 0.070060, 0.001240, 1.330918,
00929
00930
00931 0.992836, 0.000000, 0.000000,
00932 0.000000, 1.000000, 0.000000,
00933 0.000000, 0.000000, 1.330923,
00934
00935
00936 1.021308, 0.021962, 0.004085,
00937 0.013455, 0.977009, -0.008075,
00938 0.010784, 0.002161, 1.090481,
00939
00940
00941 1.006527, 0.002499, 0.000000,
00942 0.022756, 0.998075, 0.000000,
00943 0.016037, -0.000505, 1.085950,
00944
00945
00946 1.045763, 0.000000, 0.000000,
00947 0.000000, 1.000000, 0.000000,
00948 0.000000, 0.000000, 1.085953,
00949
00950
00951 1.216371, 0.153235, -0.023966,
00952 0.110931, 0.915343, 0.035935,
00953 -0.154983, -0.056006, 0.314346,
00954
00955
00956 1.071049, 0.026803, 0.000000,
00957 0.244014, 0.980413, 0.000000,
00958 -0.150348, -0.005408, 0.326427,
00959
00960
00961 1.155516, 0.000000, 0.000000,
00962 0.000000, 1.000000, 0.000000,
00963 0.000000, 0.000000, 0.326428,
00964
00965
00966 1.064164, 0.044624, -0.007852,
00967 0.032589, 0.976635, 0.012001,
00968 -0.048965, -0.017493, 0.778436,
00969
00970
00971 1.021142, 0.007975, 0.000000,
00972 0.072613, 0.994171, 0.000000,
00973 -0.048164, -0.001609, 0.782600,
00974
00975
00976 1.042351, 0.000000, 0.000000,
00977 0.000000, 1.000000, 0.000000,
00978 0.000000, 0.000000, 0.782603,
00979
00980
00981 1.009732, 0.012211, 0.003772,
00982 0.006993, 0.984871, -0.007129,
00983 0.012581, 0.003235, 1.087795,
00984
00985
00986 1.002728, 0.001028, 0.000000,
00987 0.009367, 0.999248, 0.000000,
00988 0.016519, -0.000208, 1.084536,
00989
00990
00991 1.031503, 0.000000, 0.000000,
00992 0.000000, 1.000000, 0.000000,
00993 0.000000, 0.000000, 1.084540,
00994
00995
00996 1.047835, 0.029556, -0.009238,
00997 0.022897, 0.990481, 0.015050,
00998 -0.050147, -0.017056, 0.752034,
00999
01000
01001 1.016089, 0.006069, 0.000000,
01002 0.055260, 0.995564, 0.000000,
01003 -0.052154, -0.001224, 0.757788,
01004
01005
01006 1.014470, 0.000000, 0.000000,
01007 0.000000, 1.000000, 0.000000,
01008 0.000000, 0.000000, 0.757790,
01009
01010
01011 1.028213, 0.016898, -0.005936,
01012 0.013304, 0.995522, 0.009754,
01013 -0.031540, -0.010637, 0.841840,
01014
01015
01016 1.009537, 0.003597, 0.000000,
01017 0.032756, 0.997370, 0.000000,
01018 -0.033098, -0.000726, 0.845614,
01019
01020
01021 1.006074, 0.000000, 0.000000,
01022 0.000000, 1.000000, 0.000000,
01023 0.000000, 0.000000, 0.845616,
01024
01025
01026 1.0, 0.0, 0.0,
01027 0.0, 1.0, 0.0,
01028 0.0, 0.0, 1.0,
01029
01030 1.0, 0.0, 0.0,
01031 0.0, 1.0, 0.0,
01032 0.0, 0.0, 1.0,
01033
01034 1.0, 0.0, 0.0,
01035 0.0, 1.0, 0.0,
01036 0.0, 0.0, 1.0,
01037
01038
01039 0.979823, -0.011388, 0.004880,
01040 -0.009251, 1.001719, -0.008121,
01041 0.025117, 0.008361, 1.128649,
01042
01043
01044 0.993120, -0.002596, 0.000000,
01045 -0.023629, 1.001897, 0.000000,
01046 0.026719, 0.000523, 1.125446,
01047
01048
01049 0.998867, 0.000000, 0.000000,
01050 0.000000, 1.000000, 0.000000,
01051 0.000000, 0.000000, 1.125450,
01052
01053
01054 1.050285, 0.039078, -0.002409,
01055 0.027087, 0.972947, 0.002652,
01056 -0.023276, -0.009266, 0.917968,
01057
01058
01059 1.016207, 0.006113, 0.000000,
01060 0.055662, 0.995532, 0.000000,
01061 -0.019769, -0.001234, 0.918297,
01062
01063
01064 1.052114, 0.000000, 0.000000,
01065 0.000000, 1.000000, 0.000000,
01066 0.000000, 0.000000, 0.918300,
01067
01068
01069 1.243649, 0.167322, -0.025407,
01070 0.120882, 0.914830, 0.037899,
01071 -0.165889, -0.060122, 0.278800,
01072
01073
01074 1.079173, 0.029548, 0.000000,
01075 0.269008, 0.979254, 0.000000,
01076 -0.159335, -0.005962, 0.290041,
01077
01078
01079 1.156827, 0.000000, 0.000000,
01080 0.000000, 1.000000, 0.000000,
01081 0.000000, 0.000000, 0.290042,
01082
01083
01084 1.086904, 0.056997, -0.011247,
01085 0.042021, 0.975291, 0.017469,
01086 -0.067883, -0.023992, 0.689828,
01087
01088
01089 1.028470, 0.010625, 0.000000,
01090 0.096735, 0.992539, 0.000000,
01091 -0.067258, -0.002144, 0.695366,
01092
01093
01094 1.043533, 0.000000, 0.000000,
01095 0.000000, 1.000000, 0.000000,
01096 0.000000, 0.000000, 0.695369,
01097
01098
01099 1.030774, 0.023916, -0.000943,
01100 0.016405, 0.983362, 0.000688,
01101 -0.011913, -0.004951, 0.963819,
01102
01103
01104 1.009762, 0.003643, 0.000000,
01105 0.033168, 0.997442, 0.000000,
01106 -0.009311, -0.000735, 0.963647,
01107
01108
01109 1.032673, 0.000000, 0.000000,
01110 0.000000, 1.000000, 0.000000,
01111 0.000000, 0.000000, 0.963650,
01112
01113
01114 1.070127, 0.041775, -0.012512,
01115 0.032186, 0.988978, 0.020311,
01116 -0.068484, -0.023368, 0.666442,
01117
01118
01119 1.023337, 0.008709, 0.000000,
01120 0.079295, 0.993884, 0.000000,
01121 -0.070673, -0.001757, 0.673320,
01122
01123
01124 1.015620, 0.000000, 0.000000,
01125 0.000000, 1.000000, 0.000000,
01126 0.000000, 0.000000, 0.673322,
01127
01128
01129 1.049904, 0.028885, -0.009591,
01130 0.022560, 0.993940, 0.015697,
01131 -0.051476, -0.017431, 0.745981,
01132
01133
01134 1.016680, 0.006225, 0.000000,
01135 0.056676, 0.995628, 0.000000,
01136 -0.053572, -0.001255, 0.751356,
01137
01138
01139 1.007215, 0.000000, 0.000000,
01140 0.000000, 1.000000, 0.000000,
01141 0.000000, 0.000000, 0.751359,
01142
01143
01144 1.020813, 0.011641, -0.004330,
01145 0.009243, 0.998329, 0.007144,
01146 -0.022785, -0.007655, 0.886059,
01147
01148
01149 1.006992, 0.002609, 0.000000,
01150 0.023758, 0.998167, 0.000000,
01151 -0.023919, -0.000526, 0.888531,
01152
01153
01154 1.001134, 0.000000, 0.000000,
01155 0.000000, 1.000000, 0.000000,
01156 0.000000, 0.000000, 0.888534,
01157
01158
01159 1.0, 0.0, 0.0,
01160 0.0, 1.0, 0.0,
01161 0.0, 0.0, 1.0,
01162
01163 1.0, 0.0, 0.0,
01164 0.0, 1.0, 0.0,
01165 0.0, 0.0, 1.0,
01166
01167 1.0, 0.0, 0.0,
01168 0.0, 1.0, 0.0,
01169 0.0, 0.0, 1.0,
01170
01171
01172 1.072560, 0.051258, -0.006403,
01173 0.036583, 0.971617, 0.009183,
01174 -0.044763, -0.016548, 0.813408,
01175
01176
01177 1.023456, 0.008754, 0.000000,
01178 0.079698, 0.993854, 0.000000,
01179 -0.041900, -0.001766, 0.815937,
01180
01181
01182 1.053308, 0.000000, 0.000000,
01183 0.000000, 1.000000, 0.000000,
01184 0.000000, 0.000000, 0.815940,
01185
01186
01187 1.154755, 0.110892, -0.023397,
01188 0.082246, 0.937839, 0.036653,
01189 -0.138722, -0.048732, 0.342214,
01190
01191
01192 1.052848, 0.020457, 0.000000,
01193 0.186247, 0.983669, 0.000000,
01194 -0.140810, -0.004127, 0.355469,
01195
01196
01197 1.098280, 0.000000, 0.000000,
01198 0.000000, 1.000000, 0.000000,
01199 0.000000, 0.000000, 0.355470,
01200
01201
01202 1.012951, 0.005123, -0.005910,
01203 0.005370, 1.003671, 0.010188,
01204 -0.027601, -0.008795, 0.847953,
01205
01206
01207 1.004757, 0.001841, 0.000000,
01208 0.016766, 0.998529, 0.000000,
01209 -0.030798, -0.000371, 0.852227,
01210
01211
01212 0.990720, 0.000000, 0.000000,
01213 0.000000, 1.000000, 0.000000,
01214 0.000000, 0.000000, 0.852230,
01215
01216
01217 0.962209, -0.026032, 0.006709,
01218 -0.019703, 1.012944, -0.010744,
01219 0.037905, 0.013088, 1.185066,
01220
01221
01222 0.987012, -0.005028, 0.000000,
01223 -0.045772, 1.004013, 0.000000,
01224 0.039174, 0.001014, 1.181026,
01225
01226
01227 0.980410, 0.000000, 0.000000,
01228 0.000000, 1.000000, 0.000000,
01229 0.000000, 0.000000, 1.181030,
01230
01231
01232 0.997754, -0.009768, -0.007417,
01233 -0.004163, 1.018316, 0.013442,
01234 -0.029371, -0.008549, 0.819186,
01235
01236
01237 0.999887, -0.000044, 0.000000,
01238 -0.000393, 1.000033, 0.000000,
01239 -0.035270, 0.000010, 0.825207,
01240
01241
01242 0.964220, 0.000000, 0.000000,
01243 0.000000, 1.000000, 0.000000,
01244 0.000000, 0.000000, 0.825210,
01245
01246
01247 0.979467, -0.022009, -0.003832,
01248 -0.013568, 1.023820, 0.007632,
01249 -0.009659, -0.001811, 0.917050,
01250
01251
01252 0.993574, -0.002488, 0.000000,
01253 -0.022644, 1.001984, 0.000000,
01254 -0.014684, 0.000503, 0.920847,
01255
01256
01257 0.956240, 0.000000, 0.000000,
01258 0.000000, 1.000000, 0.000000,
01259 0.000000, 0.000000, 0.920850,
01260
01261
01262 0.953167, -0.038259, 0.002612,
01263 -0.026600, 1.028843, -0.003042,
01264 0.023901, 0.009415, 1.089399,
01265
01266
01267 0.984385, -0.006045, 0.000000,
01268 -0.055029, 1.004824, 0.000000,
01269 0.021116, 0.001220, 1.088965,
01270
01271
01272 0.950467, 0.000000, 0.000000,
01273 0.000000, 1.000000, 0.000000,
01274 0.000000, 0.000000, 1.088969,
01275
01276
01277 0.934355, -0.049157, 0.007910,
01278 -0.035658, 1.030889, -0.011919,
01279 0.050694, 0.018268, 1.229589,
01280
01281
01282 0.977754, -0.008612, 0.000000,
01283 -0.078398, 1.006874, 0.000000,
01284 0.050039, 0.001738, 1.225576,
01285
01286
01287 0.949390, 0.000000, 0.000000,
01288 0.000000, 1.000000, 0.000000,
01289 0.000000, 0.000000, 1.225580,
01290
01291
01292 1.0, 0.0, 0.0,
01293 0.0, 1.0, 0.0,
01294 0.0, 0.0, 1.0,
01295
01296 1.0, 0.0, 0.0,
01297 0.0, 1.0, 0.0,
01298 0.0, 0.0, 1.0,
01299
01300 1.0, 0.0, 0.0,
01301 0.0, 1.0, 0.0,
01302 0.0, 0.0, 1.0
01303
01304 };
01305
01306 return CAmatrix[index];
01307 }
01308
01309
01310 public:
01311
01312 static double gamma(RGBSpaces rgb_space)
01313 {
01314 if (rgb_space == ADOBE_RGB)
01315 {
01316 return 2.2;
01317 }
01318 else if (rgb_space == APPLE_RGB)
01319 {
01320 return 1.8;
01321 }
01322 else if (rgb_space == BEST_RGB)
01323 {
01324 return 2.2;
01325 }
01326 else if (rgb_space == BETA_RGB)
01327 {
01328 return 2.2;
01329 }
01330 else if (rgb_space == BRUCE_RGB)
01331 {
01332 return 2.2;
01333 }
01334 else if (rgb_space == CIE_RGB)
01335 {
01336 return 2.2;
01337 }
01338 else if (rgb_space == DON_RGB4)
01339 {
01340 return 1.8;
01341 }
01342 else if (rgb_space == ECI_RGB)
01343 {
01344 return 2.2;
01345 }
01346 else if (rgb_space == EKTA_SPACE)
01347 {
01348 return 2.2;
01349 }
01350 else if (rgb_space == NTSC_RGB)
01351 {
01352 return 2.2;
01353 }
01354 else if (rgb_space == PAL_RGB)
01355 {
01356 return 2.2;
01357 }
01358 else if (rgb_space == PROPHOTO)
01359 {
01360 return 1.8;
01361 }
01362 else if (rgb_space == SMPTE_C)
01363 {
01364 return 2.2;
01365 }
01366 else if (rgb_space == SRGB)
01367 {
01368 return 2.2;
01369 }
01370 else if (rgb_space == WIDE_GAMUT)
01371 {
01372 return 2.2;
01373 }
01374 else
01375 {
01376 assert(false);
01377 return 0.0;
01378 }
01379 }
01380
01381 static Illuminant refIlluminant(RGBSpaces rgb_space)
01382 {
01383
01384
01385
01386
01387
01388 if (rgb_space == ADOBE_RGB)
01389 {
01390 return ILLUMINANT_D65;
01391 }
01392 else if (rgb_space == APPLE_RGB)
01393 {
01394 return ILLUMINANT_D65;
01395 }
01396 else if (rgb_space == BEST_RGB)
01397 {
01398 return ILLUMINANT_D50;
01399 }
01400 else if (rgb_space == BETA_RGB)
01401 {
01402 return ILLUMINANT_D50;
01403 }
01404 else if (rgb_space == BRUCE_RGB)
01405 {
01406 return ILLUMINANT_D65;
01407 }
01408 else if (rgb_space == CIE_RGB)
01409 {
01410 return ILLUMINANT_E;
01411 }
01412 else if (rgb_space == DON_RGB4)
01413 {
01414 return ILLUMINANT_D50;
01415 }
01416 else if (rgb_space == ECI_RGB)
01417 {
01418 return ILLUMINANT_D50;
01419 }
01420 else if (rgb_space == EKTA_SPACE)
01421 {
01422 return ILLUMINANT_D50;
01423 }
01424 else if (rgb_space == NTSC_RGB)
01425 {
01426 return ILLUMINANT_C;
01427 }
01428 else if (rgb_space == PAL_RGB)
01429 {
01430 return ILLUMINANT_D65;
01431 }
01432 else if (rgb_space == PROPHOTO)
01433 {
01434 return ILLUMINANT_D50;
01435 }
01436 else if (rgb_space == SMPTE_C)
01437 {
01438 return ILLUMINANT_D65;
01439 }
01440 else if (rgb_space == SRGB)
01441 {
01442 return ILLUMINANT_D65;
01443 }
01444 else if (rgb_space == WIDE_GAMUT)
01445 {
01446 return ILLUMINANT_D50;
01447 }
01448 else
01449 {
01450 assert(false);
01451 return ILLUMINANT_INVALID;
01452 }
01453 }
01454
01455 static Color4<T> RGBtoHSV(const Color4<T> & color)
01456 {
01457 double h,s,v;
01458 RGBtoHSV(static_cast<double>(color[0]), static_cast<double>(color[1]),
01459 static_cast<double>(color[2]), h,s,v);
01460 Color4<T> c(h,s,v,color[3]);
01461 return c;
01462 }
01463
01464 static void RGBtoHSV(double R, double G, double B, double &H, double &S, double &V)
01465 {
01466 double v_min = std::min(std::min(R, G), B);
01467 double v_max = std::max(std::max(R, G), B);
01468
01469 double delta = v_max - v_min;
01470
01471 V = v_max;
01472
01473 if (delta < 0.00000000001)
01474 {
01475 H = 0.0;
01476 S = 0.0;
01477 }
01478 else
01479 {
01480 S = delta / v_max;
01481
01482 double deltaR = (((v_max - R) / 6) + (delta/2.0) ) / delta;
01483 double deltaG = (((v_max - G) / 6) + (delta/2.0) ) / delta;
01484 double deltaB = (((v_max - B) / 6) + (delta/2.0) ) / delta;
01485
01486 if ( R == v_max )
01487 H = deltaB - deltaG;
01488 else if (G == v_max)
01489 H = (1.0 / 3.0) + deltaR - deltaB;
01490 else if (B == v_max)
01491 H = (2.0 / 3.0) + deltaG - deltaR;
01492 else H = 0;
01493
01494 if ( H < 0 ) H += 1.0;
01495 if ( H > 1 ) H -= 1.0;
01496 }
01497 }
01498
01499 static Color4<T> HSVtoRGB(const Color4<T> & color)
01500 {
01501 double r,g,b;
01502 HSVtoRGB(static_cast<double>(color[0]), static_cast<double>(color[1]),
01503 static_cast<double>(color[2]), r,g,b);
01504 Color4<T> c(r,g,b,color[3]);
01505 return c;
01506 }
01507
01508 static void HSVtoRGB(double H, double S, double V, double &R, double &G, double &B)
01509 {
01510 if (S == 0)
01511 {
01512 R = V;
01513 G = V;
01514 B = V;
01515 }
01516 else
01517 {
01518 double var_h = H * 6.0;
01519
01520 if (var_h == 6.0)
01521 var_h = 0.0;
01522
01523 int var_i = static_cast<int>(var_h);
01524 double var_1 = V * (1.0 - S);
01525 double var_2 = V * (1.0 - S * (var_h - var_i ));
01526 double var_3 = V * (1.0 - S * (1.0 - (var_h - var_i)));
01527
01528 double var_r, var_g, var_b;
01529
01530 if (var_i == 0)
01531 {
01532 var_r = V;
01533 var_g = var_3;
01534 var_b = var_1;
01535 }
01536 else if (var_i == 1)
01537 {
01538 var_r = var_2;
01539 var_g = V;
01540 var_b = var_1;
01541 }
01542 else if (var_i == 2)
01543 {
01544 var_r = var_1;
01545 var_g = V;
01546 var_b = var_3;
01547 }
01548 else if (var_i == 3)
01549 {
01550 var_r = var_1;
01551 var_g = var_2;
01552 var_b = V;
01553 }
01554 else if (var_i == 4)
01555 {
01556 var_r = var_3;
01557 var_g = var_1;
01558 var_b = V;
01559 }
01560 else
01561 {
01562 var_r = V;
01563 var_g = var_1;
01564 var_b = var_2;
01565 }
01566
01567 R = var_r;
01568 G = var_g;
01569 B = var_b;
01570 }
01571
01572 }
01573
01574 static Color4<T> XYZtoRGB(const Color4<T> & color, Illuminant src,
01575 RGBSpaces dest, ConeResponse response = BRADFORD)
01576 {
01577 double r,g,b;
01578 XYZtoRGB(static_cast<double>(color[0]), static_cast<double>(color[1]),
01579 static_cast<double>(color[2]), src, r,g,b, dest, response);
01580 Color4<T> c(r,g,b,color[3]);
01581 return c;
01582 }
01583
01584 static void XYZtoRGB(double X, double Y, double Z, Illuminant src,
01585 double &R, double &G, double &B, RGBSpaces space, ConeResponse response = BRADFORD)
01586 {
01587 double Xp, Yp, Zp;
01588 chromaticAdaptation(X, Y, Z, src, Xp, Yp, Zp, refIlluminant(space), response);
01589
01590 int index = static_cast<int>(space) * 3 * 3;
01591 double r = Xp * XYZ2RGB(index) + Yp * XYZ2RGB(index+3) + Zp * XYZ2RGB(index+6);
01592 double g = Xp * XYZ2RGB(index+1) + Yp * XYZ2RGB(index+4) + Zp * XYZ2RGB(index+7);
01593 double b = Xp * XYZ2RGB(index+2) + Yp * XYZ2RGB(index+5) + Zp * XYZ2RGB(index+8);
01594
01595
01596 if (space == SRGB)
01597 {
01598 if (r > 0.0031308)
01599 R = 1.055 * pow(r, 1.0/2.4) - 0.055;
01600 else
01601 R = 12.92 * r;
01602
01603 if (g > 0.0031308)
01604 G = 1.055 * pow(g, 1.0/2.4) - 0.055;
01605 else
01606 G = 12.92 * g;
01607
01608 if (b > 0.0031308)
01609 B = 1.055 * pow(b, 1.0/2.4) - 0.055;
01610 else
01611 B = 12.92 * b;
01612 }
01613 else
01614 {
01615 double lambda = gamma(space);
01616 R = pow(r, 1.0/lambda);
01617 G = pow(g, 1.0/lambda);
01618 B = pow(b, 1.0/lambda);
01619 }
01620 }
01621
01622 static Color4<T> RGBtoXYZ(const Color4<T> & color, RGBSpaces space,
01623 Illuminant dest, ConeResponse response = BRADFORD)
01624 {
01625 double x,y,z;
01626 RGBtoXYZ(static_cast<double>(color[0]), static_cast<double>(color[1]),
01627 static_cast<double>(color[2]), space, x,y,z, dest, response);
01628 Color4<T> c(x,y,z,color[3]);
01629 return c;
01630 }
01631
01632 static void RGBtoXYZ(double R, double G, double B, RGBSpaces space,
01633 double &X, double &Y, double &Z, Illuminant dest, ConeResponse response = BRADFORD)
01634 {
01635
01636 double r,g,b;
01637 if (space == SRGB)
01638 {
01639 if (R <= 0.04045)
01640 r = R / 12.92;
01641 else
01642 r = pow((R + 0.055) / 1.055, 2.4);
01643
01644 if (G <= 0.04045)
01645 g = G / 12.92;
01646 else
01647 g = pow((G + 0.055) / 1.055, 2.4);
01648
01649 if (B <= 0.04045)
01650 b = B / 12.92;
01651 else
01652 b = pow((B + 0.055) / 1.055, 2.4);
01653 }
01654 else
01655 {
01656 double lambda = gamma(space);
01657 r = pow(R, lambda);
01658 g = pow(G, lambda);
01659 b = pow(B, lambda);
01660 }
01661
01662 int index = static_cast<int>(space) * 3 * 3;
01663 double Xt = r * RGB2XYZ(index) + g * RGB2XYZ(index+3) + b * RGB2XYZ(index+6);
01664 double Yt = r * RGB2XYZ(index+1) + g * RGB2XYZ(index+4) + b * RGB2XYZ(index+7);
01665 double Zt = r * RGB2XYZ(index+2) + g * RGB2XYZ(index+5) + b * RGB2XYZ(index+8);
01666
01667
01668 chromaticAdaptation(Xt, Yt, Zt, refIlluminant(space), X, Y, Z, dest, response);
01669 }
01670
01671 static Color4<T> XYZtoCIELab(const Color4<T> & color, Illuminant ref)
01672 {
01673 double L,a,b;
01674 XYZtoCIELab(static_cast<double>(color[0]), static_cast<double>(color[1]),
01675 static_cast<double>(color[2]), L,a,b, ref);
01676 Color4<T> c(L,a,b,color[3]);
01677 return c;
01678 }
01679
01680 static void XYZtoCIELab(double X, double Y, double Z, double &L, double &a, double &b,
01681 Illuminant whiteRef)
01682 {
01683
01684
01685
01686 double Xr, Yr, Zr;
01687 RGBtoXYZ(1.0, 1.0, 1.0, SRGB, Xr, Yr, Zr, whiteRef);
01688
01689 double xr = X / Xr;
01690 double yr = Y / Yr;
01691 double zr = Z / Zr;
01692
01693 double cieEpsilon = CIE_EPSILON();
01694 double cieKi = CIE_KI();
01695
01696 double fx;
01697 if (xr > cieEpsilon)
01698 fx = pow(xr, 1.0/3.0);
01699 else
01700 fx = (cieKi * xr + 16.0) / 116.0;
01701
01702 double fy;
01703 if (yr > cieEpsilon)
01704 fy = pow(yr, 1.0/3.0);
01705 else
01706 fy = (cieKi * yr + 16.0) / 116.0;
01707
01708 double fz;
01709 if (zr > cieEpsilon)
01710 fz = pow(zr, 1.0/3.0);
01711 else fz = (cieKi * zr + 16.0) / 116.0;
01712
01713 L = 116.0 * fy - 16.0;
01714 a = 500.0 * (fx - fy);
01715 b = 200.0 * (fy - fz);
01716 }
01717
01718 static Color4<T> CIELabtoXYZ(const Color4<T> & color, Illuminant ref)
01719 {
01720 double x,y,z;
01721 CIELabtoXYZ(static_cast<double>(color[0]), static_cast<double>(color[1]),
01722 static_cast<double>(color[2]), x,y,z, ref);
01723 Color4<T> c(x,y,z,color[3]);
01724 return c;
01725 }
01726
01727 static void CIELabtoXYZ(double L, double a, double b, double &X, double &Y, double &Z,
01728 Illuminant whiteRef)
01729 {
01730 double cieEpsilon = CIE_EPSILON();
01731 double cieKi = CIE_KI();
01732
01733 double value;
01734
01735 double yr;
01736 if (L > cieKi * cieEpsilon)
01737 {
01738 value = (L + 16.0) / 116.0;
01739 yr = value * value * value;
01740 }
01741 else
01742 yr = L / cieKi;
01743
01744 double fy;
01745 if (yr > cieEpsilon)
01746 fy = (L + 16.0) / 116.0;
01747 else
01748 fy = (cieKi * yr + 16.0) / 116.0;
01749
01750 double fz = fy - (b / 200.0);
01751 double fz_cubed = fz * fz * fz;
01752
01753 double fx = (a / 500.0) + fy;
01754 double fx_cubed = fx * fx * fx;
01755
01756 double xr;
01757 if (fx_cubed > cieEpsilon)
01758 xr = fx_cubed;
01759 else
01760 xr = (116.0 * fx - 16.0) / cieKi;
01761
01762 double zr;
01763 if (fz_cubed > cieEpsilon)
01764 zr = fz_cubed;
01765 else
01766 zr = (116.0 * fz - 16.0) / cieKi;
01767
01768
01769
01770
01771 double Xr, Yr, Zr;
01772 RGBtoXYZ(1.0, 1.0, 1.0, SRGB, Xr, Yr, Zr, whiteRef);
01773
01774 X = xr * Xr;
01775 Y = yr * Yr;
01776 Z = zr * Zr;
01777 }
01778
01779
01780 static Color4<T> RGBtoHSL(const Color4<T> & color)
01781 {
01782 double h,s,l;
01783 RGBtoHSL(static_cast<double>(color[0]), static_cast<double>(color[1]),
01784 static_cast<double>(color[2]), h,s,l);
01785 Color4<T> c(h,s,l,color[3]);
01786 return c;
01787 }
01788
01789
01790 static void RGBtoHSL(double R, double G, double B, double &H, double &S, double &L)
01791 {
01792 double v = std::min(R,G);
01793 double v_min = std::min(v, B);
01794
01795 v = std::max(R,G);
01796 double v_max = std::max(v, B);
01797
01798 double delta = v_max - v_min;
01799
01800 L = (v_max + v_min) / 2.0;
01801
01802 if (delta == 0.0)
01803 {
01804 H = 0.0;
01805 S = 0.0;
01806 }
01807 else
01808 {
01809 if ( L < 0.5 )
01810 S = delta / (v_max + v_min);
01811 else
01812 S = delta / (2.0 - v_max - v_min);
01813
01814 double deltaR = (((v_max - R) / 6.0) + (delta/2.0)) / delta;
01815 double deltaG = (((v_max - G) / 6.0) + (delta/2.0)) / delta;
01816 double deltaB = (((v_max - B) / 6.0) + (delta/2.0)) / delta;
01817
01818 if (R == v_max)
01819 H = deltaB - deltaG;
01820 else if (G == v_max)
01821 H = (1.0 / 3.0) + deltaR - deltaB;
01822 else if (B == v_max)
01823 H = (2.0 / 3.0) + deltaG - deltaR;
01824
01825 if ( H < 0.0 )
01826 H += 1.0;
01827
01828 if ( H > 1.0 )
01829 H -= 1.0;
01830 }
01831 }
01832
01833 static Color4<T> HSLtoRGB(const Color4<T> & color)
01834 {
01835 double r,g,b;
01836 HSLtoRGB(static_cast<double>(color[0]), static_cast<double>(color[1]),
01837 static_cast<double>(color[2]), r,g,b);
01838 Color4<T> c(r,g,b,color[3]);
01839 return c;
01840 }
01841
01842
01843 static void HSLtoRGB(double H, double S, double L, double &R, double &G, double &B)
01844 {
01845 if (S == 0.0)
01846 {
01847 R = L;
01848 G = L;
01849 B = L;
01850 }
01851 else
01852 {
01853 double var_1, var_2;
01854
01855 if (L < 0.5)
01856 var_2 = L * ( 1 + S );
01857 else
01858 var_2 = ( L + S ) - ( S * L );
01859
01860 var_1 = 2 * L - var_2;
01861
01862 R = Hue2RGB(var_1, var_2, H + (1.0/3.0));
01863 G = Hue2RGB(var_1, var_2, H );
01864 B = Hue2RGB(var_1, var_2, H - (1.0/3.0));
01865 }
01866
01867 }
01868
01869 static double Hue2RGB(double v1, double v2, double vH)
01870 {
01871 if ( vH < 0 )
01872 vH += 1.0;
01873
01874 if ( vH > 1 )
01875 vH -= 1.0;
01876
01877 if ( (6.0 * vH) < 1.0)
01878 return (v1 + ( v2 - v1 ) * 6.0 * vH);
01879
01880 if ( (2.0 * vH) < 1.0)
01881 return v2;
01882
01883 if ( (3.0 * vH) < 2.0)
01884 return ( v1 + ( v2 - v1 ) * ((2.0/3.0) - vH) * 6.0);
01885
01886 return v1;
01887 }
01888
01889 static Color4<T> xyYtoXYZ(const Color4<T> & color)
01890 {
01891 double X,Y,Z;
01892 xyYtoXYZ(static_cast<double>(color[0]), static_cast<double>(color[1]),
01893 static_cast<double>(color[2]), X,Y,Z);
01894
01895 Color4<T> c(X,Y,Z,color[3]);
01896 return c;
01897 }
01898
01899
01900 static void xyYtoXYZ(double x, double y, double _Y, double &X, double &Y, double &Z)
01901 {
01902 X = x * (Y / y);
01903 Y = _Y;
01904 Z = (1.0 - x - y) * (Y / y);
01905 }
01906
01907 static Color4<T> XYZtoxyY(const Color4<T> & color)
01908 {
01909 double x,y,Y;
01910 XYZtoxyY(static_cast<double>(color[0]), static_cast<double>(color[1]),
01911 static_cast<double>(color[2]), x, y, Y);
01912
01913 Color4<T> c(x,y,Y,color[3]);
01914 return c;
01915 }
01916
01917
01918 static void XYZtoxyY(double X, double _Y, double Z, double &x, double &y, double &Y)
01919 {
01920 x = X / (X + Y + Z);
01921 y = Y / (X + Y + Z);
01922 Y = _Y;
01923 }
01924
01925
01926 static Color4<T> chromaticAdaptation(const Color4<T> & color, Illuminant src,
01927 Illuminant dst, ConeResponse response = BRADFORD)
01928 {
01929 double X,Y,Z;
01930 chromaticAdaptation(static_cast<double>(color[0]), static_cast<double>(color[1]),
01931 static_cast<double>(color[2]), src, X, Y, Z, dst, response);
01932
01933 Color4<T> c(X,Y,Z,color[3]);
01934 return c;
01935 }
01936
01937
01938 static void chromaticAdaptation(double Xi, double Yi, double Zi, Illuminant src,
01939 double &X, double &Y, double &Z, Illuminant dst, ConeResponse response = BRADFORD)
01940 {
01941 int index = static_cast<int>(src) * 8 * 3 * 3 * 3 + static_cast<int>(dst) * 3 * 3 * 3 +
01942 static_cast<int>(response) * 3 * 3;
01943
01944 X = CA(index) * Xi + CA(index+3) * Yi + CA(index+6) * Zi;
01945 Y = CA(index+1) * Xi + CA(index+4) * Yi + CA(index+7) * Zi;
01946 Z = CA(index+2) * Xi + CA(index+5) * Yi + CA(index+8) * Zi;
01947 }
01948
01949
01950 static Color4<T> RGBtoRGB(const Color4<T> & color, RGBSpaces rgbsrc, RGBSpaces rgbdest,
01951 ConeResponse response = BRADFORD)
01952 {
01953 double R,G,B;
01954 RGBtoRGB(static_cast<double>(color[0]), static_cast<double>(color[1]),
01955 static_cast<double>(color[2]), rgbsrc, R,G,B, rgbdest, response);
01956
01957 Color4<T> c(R,G,B,color[3]);
01958 return c;
01959 }
01960
01961
01962 static void RGBtoRGB(double Ri, double Gi, double Bi, RGBSpaces rgbsrc,
01963 double &R, double &G, double &B, RGBSpaces rgbdest, ConeResponse response = BRADFORD)
01964 {
01965 double X,Y,Z;
01966 RGBtoXYZ(Ri, Gi, Bi, rgbsrc, X,Y,Z, refIlluminant(rgbsrc));
01967 XYZtoRGB(X,Y,Z, refIlluminant(rgbsrc), R,G,B, rgbdest);
01968 }
01969
01970 };
01971
01972
01973 }
01974
01975 #endif