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