colorspace.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2006                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
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 // definitions
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 // private methods
00155 private:
00156 
00157     static double CIE_EPSILON()
00158     {
00159         return 0.008856;  // Intent of the CIE Standard --> 216/24389
00160     }
00161 
00162     static double CIE_KI()
00163     {
00164         return 903.3;     // Intent of the CIE Standard --> 24389/27
00165     }
00166 
00167     static double RGB2XYZ(int index)
00168     {
00169         // RGB WORKING SPACE DATA (RGB TO XYZ CONVERSION MATRIX)
00170         //
00171         //  144 elements (16 RGB spaces x matrices of 3 x 3)
00172         //
00173         static double RGB_TO_XYZ[]=
00174         {
00175             // Adobe RGB (1998)  (ref. D65)
00176             0.576700, 0.297361,  0.0270328,
00177             0.185556, 0.627355,  0.0706879,
00178             0.188212, 0.0752847, 0.991248,
00179 
00180             // Apple RGB  (ref. D65)
00181             0.449695, 0.244634,  0.0251829,
00182             0.316251, 0.672034,  0.141184,
00183             0.18452,  0.0833318, 0.922602,
00184 
00185             // BestRGB  (ref. D50)
00186             0.632670, 0.228457,  0.000000,
00187             0.204556, 0.737352,  0.00951424,
00188             0.126995, 0.0341908, 0.815696,
00189 
00190             // Beta RGB  (ref. D50)
00191             0.671254, 0.303273,  0.000000,
00192             0.174583, 0.663786,  0.040701,
00193             0.118383, 0.0329413, 0.784509,
00194 
00195             // BruceRGB  (ref. D65)
00196             0.467384, 0.240995,  0.0219086,
00197             0.294454, 0.683554,  0.0736135,
00198             0.188629, 0.0754517, 0.993447,
00199 
00200             // CIE  (ref. E)
00201             0.488718, 0.176204,  0.000000,
00202             0.310680, 0.812985,  0.0102048,
00203             0.200602, 0.0108109, 0.989795,
00204 
00205             // ColorMatch  (ref. D50)
00206             0.509344, 0.274884,  0.0242545,
00207             0.320907, 0.658132,  0.108782,
00208             0.133969, 0.0669845, 0.692174,
00209 
00210             // DonRGB4  (ref. D50)
00211             0.645771,   0.278350,   0.00371134,
00212             0.193351,   0.687970,   0.0179862,
00213             0.125098,   0.0336802,  0.803513,
00214 
00215             // ECI  (ref. D50)
00216             0.650204, 0.320250,  0.000000,
00217             0.178077, 0.602071,  0.0678390,
00218             0.135938, 0.0776791, 0.757371,
00219 
00220             // Ekta Space PS5  (ref. D50)
00221             0.593891,  0.260629,   0.000000,
00222             0.272980,  0.734946,   0.0419970,
00223             0.0973486, 0.00442493, 0.783213,
00224 
00225             // NTSC  (ref. C)
00226             0.606734, 0.298839, 0.000000,
00227             0.173564, 0.586811, 0.0661196,
00228             0.200112, 0.114350, 1.11491,
00229 
00230             // PAL / SECAM  (ref. D65)
00231             0.430587, 0.222021,  0.0201837,
00232             0.341545, 0.706645,  0.129551,
00233             0.178336, 0.0713342, 0.939234,
00234 
00235             // ProPhoto  (ref. D50)
00236             0.797675,  0.288040, 0.000000,
00237             0.135192,  0.711874, 0.000000,
00238             0.0313534, 0.000086, 0.825210,
00239 
00240             // SMPTE-C  (ref. D65)
00241             0.393555, 0.212395,  0.0187407,
00242             0.365253, 0.701049,  0.111932,
00243             0.191659, 0.0865558, 0.958297,
00244 
00245             // sRGB  (ref. D65)
00246             0.412424, 0.212656,  0.0193324,
00247             0.357579, 0.715158,  0.119193,
00248             0.180464, 0.0721856, 0.950444,
00249 
00250             // WideGamut  (ref. D50)
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         // RGB WORKING SPACE DATA (XYZ TO RGB CONVERSION MATRIX)
00263         //
00264         //  144 elements (16 RGB spaces x matrices of 3 x 3)
00265         //
00266         static double XYZ_TO_RGB[]=
00267         {
00268             // Adobe RGB (1998)  (ref. D65)
00269             2.04148,   -0.969258,   0.0134455,
00270             -0.564977,   1.87599,  -0.118373,
00271             -0.344713,   0.0415557,  1.01527,
00272 
00273             // Apple RGB  (ref. D65)
00274             2.95176, -1.0851,   0.0854804,
00275             -1.28951, 1.99084,  -0.269456,
00276             -0.47388, 0.0372023,   1.09113,
00277 
00278             // BestRGB  (ref. D50)
00279             1.75526,  -0.544134,   0.00634681,
00280             -0.483679, 1.50688,  -0.0175762,
00281             -0.253000, 0.0215528, 1.22570,
00282 
00283             // Beta RGB  (ref. D50)
00284             1.68323,   -0.771023, 0.0400012,
00285             -0.428236, 1.70656,  -0.0885376,
00286             -0.236018, 0.0446899, 1.27236,
00287 
00288             // BruceRGB  (ref. D65)
00289             2.74566,  -0.969257,   0.0112707,
00290             -1.13589,  1.87599,  -0.113959,
00291             -0.435057, 0.0415557, 1.01311,
00292 
00293             // CIE  (ref. E)
00294             2.37067,  -0.513885,  0.00529818,
00295             -0.900040, 1.42530,  -0.0146949,
00296             -0.470634, 0.0885814, 1.00940,
00297 
00298             // ColorMatch  (ref. D50)
00299             2.64229,  -1.11198,   0.0821698,
00300             -1.22343,  2.05902,  -0.280725,
00301             -0.393014, 0.0159614, 1.45599,
00302 
00303             // DonRGB4  (ref. D50)
00304             1.76039,  -0.712629,   0.00782072,
00305             -0.488120, 1.65274,  -0.0347411,
00306             -0.253613, 0.0416715, 1.24477,
00307 
00308             // ECI  (ref. D50)
00309             1.78276,   -0.959362,  0.0859318,
00310             -0.496985,  1.94780,  -0.174467,
00311             -0.269010, -0.0275807, 1.32283,
00312 
00313             // Ekta Space PS5  (ref. D50)
00314             2.00438,  -0.711029,   0.0381263,
00315             -0.730484, 1.62021,  -0.0868780,
00316             -0.245005,  0.0792227, 1.27254,
00317 
00318             // NTSC  (ref. C)
00319             1.91049,   -0.984310,  0.0583744,
00320             -0.532592,  1.99845,  -0.118518,
00321             -0.288284, -0.0282980, 0.898611,
00322 
00323             // PAL / SECAM  (ref. D65)
00324             3.06313,   -0.969258,   0.0678674,
00325             -1.39328,   1.87599,  -0.228821,
00326             -0.475788,  0.0415557, 1.06919,
00327 
00328             // ProPhoto  (ref. D50)
00329             1.34594,   -0.544599,   0.000000,
00330             -0.255608,  1.50817,   0.000000,
00331             -0.0511118, 0.0205351, 1.21181,
00332 
00333             // SMPTE-C  (ref. D65)
00334             3.50570,   -1.06906,   0.0563117,
00335             -1.73964,   1.97781,  -0.196994,
00336             -0.544011,  0.0351720, 1.05005,
00337 
00338             // sRGB  (ref. D65)
00339             3.24071,  -0.969258,   0.0556352,
00340             -1.53726,  1.87599,   -0.203996,
00341             -0.498571, 0.0415557,  1.05707,
00342 
00343             // WideGamut  (ref. D50)
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         // CHROMATIC ADAPTATION MATRIX
00356         //
00357         //  196 (8 x 8 illuminants x 3 cone response) matrices of 3 x 3 elements
00358         //
00359         static double CAmatrix[]=
00360         {
00361             // A -> A
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             // A -> B (Bradford)
00375             0.890600, -0.097037, 0.054012,
00376             -0.082873, 1.075262, -0.091063,
00377             0.268563, 0.088084, 2.486772,
00378 
00379             // A -> B (Von Kries)
00380             0.957515, -0.018042, 0.000000,
00381             -0.164247, 1.018522, 0.000000,
00382             0.290746, 0.003635, 2.397466,
00383 
00384             // A -> B (XYZ scaling)
00385             0.902065, 0.000000, 0.000000,
00386             0.000000, 1.000000, 0.000000,
00387             0.000000, 0.000000, 2.397474,
00388 
00389             // A -> C (Bradford)
00390             0.853036, -0.123884, 0.091195,
00391             -0.113032, 1.085373, -0.155374,
00392             0.440458, 0.142587, 3.477780,
00393 
00394             // A -> C (Von Kries)
00395             0.941839, -0.024699, 0.000000,
00396             -0.224854, 1.025358,  0.000000,
00397             0.480676, 0.004974, 3.322435,
00398 
00399             // A -> C (XYZ scaling)
00400             0.892678, 0.000000, 0.000000,
00401             0.000000, 1.000000, 0.000000,
00402             0.000000, 0.000000, 3.322447,
00403 
00404             // A -> D50 (Bradford)
00405             0.878034, -0.111621, 0.050313,
00406             -0.091487, 1.092265, -0.083964,
00407             0.257070, 0.085312, 2.402220,
00408 
00409             // A -> D50 (Von Kries)
00410             0.953214, -0.019868, 0.000000,
00411             -0.180875, 1.020397, 0.000000,
00412             0.276267, 0.004004, 2.321454,
00413 
00414             // A -> D50 (XYZ scaling)
00415             0.877936, 0.000000, 0.000000,
00416             0.000000, 1.000000, 0.000000,
00417             0.000000, 0.000000, 2.321462,
00418 
00419             // A -> D55 (Bradford)
00420             0.864256, -0.122489, 0.061011,
00421             -0.102279, 1.098455, -0.102340,
00422             0.307550, 0.101476, 2.689914,
00423 
00424             // A -> D55 (Von Kries)
00425             0.947636, -0.022237, 0.000000,
00426             -0.202440, 1.022829, 0.000000,
00427             0.331718, 0.004481, 2.590505,
00428 
00429             // A -> D55 (XYZ Scaling)
00430             0.870670, 0.000000, 0.000000,
00431             0.000000, 1.000000, 0.000000,
00432             0.000000, 0.000000, 2.590514,
00433 
00434             // A -> D65 (Bradford)
00435             0.844763, -0.136524, 0.080011,
00436             -0.117903, 1.103952, -0.135190,
00437             0.395490, 0.129376, 3.196569,
00438 
00439             // A -> D65 (Von Kries)
00440             0.939518, -0.025685, 0.000000,
00441             -0.233826, 1.026369, 0.000000,
00442             0.428852, 0.005174, 3.063452,
00443 
00444             // A -> D65 (XYZ Scaling)
00445             0.865414, 0.000000, 0.000000,
00446             0.000000, 1.000000, 0.000000,
00447             0.000000, 0.000000, 3.063462,
00448 
00449             // A -> D75 (Bradford)
00450             0.830991, -0.145710,  0.095536,
00451             -0.129133,  1.106062, -0.162123,
00452             0.466601,  0.151821,  3.608682,
00453 
00454             // A -> D75 (Von Kries)
00455             0.933660, -0.028172, 0.000000,
00456             -0.256474, 1.028923, 0.000000,
00457             0.507632, 0.005674, 3.447762,
00458 
00459             // A -> D75 (XYZ Scaling)
00460             0.864434,  0.000000,  0.000000,
00461             0.000000,  1.000000,  0.000000,
00462             0.000000,  0.000000,  3.447773,
00463 
00464             // A -> E (Bradford)
00465             0.881682, -0.100560,  0.071051,
00466             -0.090783,  1.070733, -0.120888,
00467             0.344476,  0.111711,  2.933736,
00468 
00469             // A -> E (Von Kries)
00470             0.953314, -0.019826, 0.000000,
00471             -0.180491, 1.020355, 0.000000,
00472             0.375531, 0.003993, 2.813168,
00473 
00474             // A -> E (XYZ Scaling)
00475             0.910515, 0.000000, 0.000000,
00476             0.000000, 1.000000, 0.000000,
00477             0.000000, 0.000000, 2.813177,
00478 
00479             // B ->     A (Bradford)
00480             1.138867,  0.104490, -0.020910,
00481             0.077128,  0.934300,  0.032538,
00482             -0.125725, -0.044379,  0.403234,
00483 
00484             // B -> A (Von Kries)
00485             1.047555, 0.018556, 0.000000,
00486             0.168937, 0.984806, 0.000000,
00487             -0.127296, -0.003743, 0.417104,
00488 
00489             // B -> A (XYZ Scaling)
00490             1.108567, 0.000000, 0.000000,
00491             0.000000, 1.000000, 0.000000,
00492             0.000000, 0.000000, 0.417106,
00493 
00494             // B -> B
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             // B -> C (Bradford)
00508             0.950475, -0.030658,  0.014905,
00509             -0.025481,  1.009149, -0.024973,
00510             0.075375,  0.024904,  1.397787,
00511 
00512             // B -> C (Von Kries)
00513             0.982455, -0.006847, 0.000000,
00514             -0.062331, 1.005606, 0.000000,
00515             0.081442, 0.001380, 1.385807,
00516 
00517             // B -> C (XYZ Scaling)
00518             0.989593, 0.000000, 0.000000,
00519             0.000000, 1.000000, 0.000000,
00520             0.000000, 0.000000, 1.385811,
00521 
00522             // B -> D50 (Bradford)
00523             0.985029, -0.014775, -0.001704,
00524             -0.009391,  1.014671,  0.003596,
00525             -0.002672, -0.000039,  0.966056,
00526 
00527             // B -> D50 (Von Kries)
00528             0.995186, -0.001879, 0.000000,
00529             -0.017098, 1.001537, 0.000000,
00530             -0.005430, 0.000380, 0.968292,
00531 
00532             // B -> D50 (XYZ Scaling)
00533             0.973252, 0.000000, 0.000000,
00534             0.000000, 1.000000, 0.000000,
00535             0.000000, 0.000000, 0.968295,
00536 
00537             // B -> D55 (Bradford)
00538             0.967155, -0.026843,  0.002545,
00539             -0.018894,  1.020141, -0.003387,
00540             0.019895,  0.007571,  1.081535,
00541 
00542             // B -> D55 (Von Kries)
00543             0.988943, -0.004315,  0.000000,
00544             -0.039278, 1.003532,  0.000000,
00545             0.018490,  0.000871,  1.080514,
00546 
00547             // B -> D55 (XYZ Scaling)
00548             0.965197, 0.000000, 0.000000,
00549             0.000000, 1.000000, 0.000000,
00550             0.000000, 0.000000, 1.080518,
00551 
00552             // B -> D65 (Bradford)
00553             0.941484, -0.042836,  0.010157,
00554             -0.032134,  1.025102, -0.016128,
00555             0.058499,  0.020341,  1.284904,
00556 
00557             // B -> D65 (Von Kries)
00558             0.979857, -0.007861, 0.000000,
00559             -0.071558, 1.006436, 0.000000,
00560             0.060156, 0.001586, 1.277783,
00561 
00562             // B -> D65 (XYZ Scaling)
00563             0.959370, 0.000000, 0.000000,
00564             0.000000, 1.000000, 0.000000,
00565             0.000000, 0.000000, 1.277788,
00566 
00567             // B -> D75 (Bradford)
00568             0.923139, -0.053546, 0.016407,
00569             -0.041374, 1.027096, -0.026684,
00570             0.089403, 0.030453, 1.450325,
00571 
00572             // B -> D75 (Von Kries)
00573             0.973300, -0.010419, 0.000000,
00574             -0.094851, 1.008531, 0.000000,
00575             0.093846, 0.002101, 1.438081,
00576 
00577             // B -> D75 (XYZ Scaling)
00578             0.958283, 0.000000, 0.000000,
00579             0.000000, 1.000000, 0.000000,
00580             0.000000, 0.000000, 1.438086,
00581 
00582             // B -> E (Bradford)
00583             0.987430, -0.004980, 0.006942,
00584             -0.005608, 0.996265, -0.012009,
00585             0.032084, 0.010171, 1.179413,
00586 
00587             // B -> E (Von kries)
00588             0.995299, -0.001835, 0.000000,
00589             -0.016702, 1.001503, 0.000000,
00590             0.035959, 0.000370, 1.173388,
00591 
00592             // B -> E (XYZ Scaling)
00593             1.009367, 0.000000, 0.000000,
00594             0.000000, 1.000000, 0.000000,
00595             0.000000, 0.000000, 1.173392,
00596 
00597             // C ->     A (Bradford)
00598             1.203987, 0.140744, -0.025283,
00599             0.102952, 0.928000, 0.038760,
00600             -0.156705, -0.055873, 0.289153,
00601 
00602             // C -> A (Von Kries)
00603             1.067896, 0.025724, 0.000000,
00604             0.234191, 0.980909, 0.000000,
00605             -0.154849, -0.005190, 0.300982,
00606 
00607             // C -> A (XYZ Scaling)
00608             1.120225, 0.000000, 0.000000,
00609             0.000000, 1.000000, 0.000000,
00610             0.000000, 0.000000, 0.300983,
00611 
00612             // C -> B (Bradford)
00613             1.053816,   0.032278, -0.010661,
00614             0.025192,   0.991268,  0.017441,
00615             -0.057275, -0.019402,  0.715681,
00616 
00617             // C -> B (Von Kries)
00618             1.018301,   0.006933, 0.000000,
00619             0.063126,   0.994853, 0.000000,
00620             -0.059908, -0.001398, 0.721597,
00621 
00622             // C -> B (XYZ Scaling)
00623             1.010516, 0.000000, 0.000000,
00624             0.000000, 1.000000, 0.000000,
00625             0.000000, 0.000000, 0.721599,
00626 
00627             // C -> C
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             // C -> D50 (Bradford)
00641             1.037765, 0.017182, -0.011978,
00642             0.015460, 1.005438, 0.020371,
00643             -0.058148, -0.018868, 0.691416,
00644 
00645             // C -> D50 (Von Kries)
00646             1.013279, 0.005031, 0.000000,
00647             0.045808, 0.996264, 0.000000,
00648             -0.063514, -0.001014, 0.698718,
00649 
00650             // C -> D50 (XYZ Scaling)
00651             0.983487, 0.000000, 0.000000,
00652             0.000000, 1.000000, 0.000000,
00653             0.000000, 0.000000, 0.698721,
00654 
00655             // C -> D55 (Bradford)
00656             1.018382, 0.004560, -0.008957,
00657             0.005982, 1.010689, 0.015570,
00658             -0.040789, -0.012837, 0.773954,
00659 
00660             // C -> D55 (Von Kries)
00661             1.006768, 0.002564, 0.000000,
00662             0.023348, 0.998095, 0.000000,
00663             -0.045848, -0.000516, 0.779698,
00664 
00665             // C -> D55 (XYZ Scaling)
00666             0.975347, 0.000000, 0.000000,
00667             0.000000, 1.000000, 0.000000,
00668             0.000000, 0.000000, 0.779701,
00669 
00670             // C -> D65 (Bradford)
00671             0.990490, -0.012269, -0.003515,
00672             -0.007115, 1.015427, 0.006679,
00673             -0.011434, -0.002878, 0.919313,
00674 
00675             // C -> D65 (Von Kries)
00676             0.997291, -0.001026, 0.000000,
00677             -0.009340, 1.000760, 0.000000,
00678             -0.015193, 0.000208, 0.922047,
00679 
00680             // C -> D65 (XYZ Scaling)
00681             0.969459, 0.000000, 0.000000,
00682             0.000000, 1.000000, 0.000000,
00683             0.000000, 0.000000, 0.922050,
00684 
00685             // C -> D75 (Bradford)
00686             0.970531, -0.023599,  0.000967,
00687             -0.016198, 1.017309, -0.000743,
00688             0.011914,  0.004934,  1.037548,
00689 
00690             // C -> D75 (Von Kries)
00691             0.990453, -0.003617, 0.000000,
00692             -0.032927, 1.002683, 0.000000,
00693             0.009543, 0.000730, 1.037718,
00694 
00695             // C -> D75 (XYZ Scaling)
00696             0.968360, 0.000000, 0.000000,
00697             0.000000, 1.000000, 0.000000,
00698             0.000000, 0.000000, 1.037721,
00699 
00700             // C -> E (Bradford)
00701             1.040046, 0.026802, -0.005645,
00702             0.019876, 0.987617, 0.008842,
00703             -0.033485, -0.011765, 0.843919,
00704 
00705             // C -> E (Von Kries)
00706             1.013396, 0.005075, 0.000000,
00707             0.046208, 0.996233, 0.000000,
00708             -0.033655, -0.001024, 0.846716,
00709 
00710             // C -> E (XYZ Scaling)
00711             1.019981, 0.000000, 0.000000,
00712             0.000000, 1.000000, 0.000000,
00713             0.000000, 0.000000, 0.846719,
00714 
00715             // D50 ->   A (Bradford)
00716             1.157264,   0.119830, -0.020050,
00717             0.087174,   0.922061,  0.030403,
00718             -0.126938, -0.045569,  0.417348,
00719 
00720             // D50 -> A (Von Kries)
00721             1.052976, 0.020503, 0.000000,
00722             0.186659, 0.983644, 0.000000,
00723             -0.125633, -0.004137, 0.430762,
00724 
00725             // D50 -> A (XYZ Scaling)
00726             1.139034, 0.000000, 0.000000,
00727             0.000000, 1.000000, 0.000000,
00728             0.000000, 0.000000, 0.430763,
00729 
00730             // D50 -> B (Bradford)
00731             1.015344, 0.014785, 0.001735,
00732             0.009388, 0.985677, -0.003652,
00733             0.002809, 0.000081, 1.035142,
00734 
00735             // D50 -> B (Von Kries)
00736             1.004871, 0.001885, 0.000000,
00737             0.017164, 0.998496, 0.000000,
00738             0.005627, -0.000381, 1.032740,
00739 
00740             // D50 -> B (XYZ Scaling)
00741             1.027483, 0.000000, 0.000000,
00742             0.000000, 1.000000, 0.000000,
00743             0.000000, 0.000000, 1.032743,
00744 
00745             // D50 -> C (Bradford)
00746             0.964813, -0.016165,  0.017191,
00747             -0.016469,  0.994317, -0.029580,
00748             0.080692,  0.025774,  1.446947,
00749 
00750             // D50 -> C (Von Kries)
00751             0.987122, -0.004985, 0.000000,
00752             -0.045378, 1.003977, 0.000000,
00753             0.089662, 0.001004, 1.431183,
00754 
00755             // D50 -> C (XYZ Scaling)
00756             1.016791, 0.000000, 0.000000,
00757             0.000000, 1.000000, 0.000000,
00758             0.000000, 0.000000, 1.431187,
00759 
00760             // D50 -> D50
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             // D50 -> D55 (Bradford)
00774             0.981751, -0.012159, 0.004411,
00775             -0.009617, 1.005251, -0.007265,
00776             0.023309, 0.007844, 1.119548,
00777 
00778             // D50 -> D55 (Von Kries)
00779             0.993685, -0.002444,  0.000000,
00780             -0.022249, 1.001949,  0.000000,
00781             0.024676,  0.000493,  1.115894,
00782 
00783             // D50 -> D55 (XYZ Scaling)
00784             0.991724, 0.000000, 0.000000,
00785             0.000000, 1.000000, 0.000000,
00786             0.000000, 0.000000, 1.115898,
00787 
00788             // D50 -> D65 (Bradford)
00789             0.955556, -0.028302, 0.012305,
00790             -0.023049, 1.009944, -0.020494,
00791             0.063197, 0.021018, 1.330084,
00792 
00793             // D50 -> D65 (Von Kries)
00794             0.984494, -0.006002, 0.000000,
00795         -0.054637, 1.004788, 0.000000,
00796             0.067667, 0.001210, 1.319622,
00797 
00798             // D50 -> D65 (XYZ Scaling)
00799             0.985737, 0.000000, 0.000000,
00800             0.000000, 1.000000, 0.000000,
00801             0.000000, 0.000000, 1.319627,
00802 
00803             // D50 -> D75 (Bradford)
00804             0.936847, -0.039129, 0.018781,
00805             -0.032442, 1.011771, -0.031445,
00806             0.095135, 0.031456, 1.501335,
00807 
00808             // D50 -> D75 (Von Kries)
00809             0.977862, -0.008569, 0.000000,
00810             -0.078007, 1.006836, 0.000000,
00811             0.102432, 0.001727, 1.485168,
00812 
00813             // D50 -> D75 (XYZ Scaling)
00814             0.984620, 0.000000, 0.000000,
00815             0.000000, 1.000000, 0.000000,
00816             0.000000, 0.000000, 1.485174,
00817 
00818             // D50 -> E (Bradford)
00819             1.002553, 0.009691, 0.008918,
00820             0.003624, 0.981912, -0.016079,
00821             0.035984, 0.010595, 1.220878,
00822 
00823             // D50 -> E (Von Kries)
00824             1.000115, 0.000044, 0.000000,
00825             0.000401, 0.999965, 0.000000,
00826             0.042744, -0.000010, 1.211809,
00827 
00828             // D50 -> E (XYZ Scaling)
00829             1.037108, 0.000000, 0.000000,
00830             0.000000, 1.000000, 0.000000,
00831             0.000000, 0.000000, 1.211813,
00832 
00833             // D55 -> A (Bradford)
00834             1.180601, 0.133653, -0.021693,
00835             0.097012, 0.918163, 0.032732,
00836             -0.138643, -0.049919, 0.373005,
00837 
00838             // D55 -> A (Von Kries)
00839             1.060184, 0.023049, 0.000000,
00840             0.209842, 0.982241, 0.000000,
00841             -0.136121, -0.004650, 0.386023,
00842 
00843             // D55 -> A (XYZ Scaling)
00844             1.148540, 0.000000, 0.000000,
00845             0.000000, 1.000000, 0.000000,
00846             0.000000, 0.000000, 0.386024,
00847 
00848             // D55 -> B (Bradford)
00849             1.034540, 0.027239, -0.002349,
00850             0.019098, 0.980736, 0.003026,
00851             -0.019163, -0.007366, 0.924635,
00852 
00853             // D55 -> B (Von Kries)
00854             1.011356, 0.004348, 0.000000,
00855             0.039593, 0.996649, 0.000000,
00856             -0.017339, -0.000878, 0.925479,
00857 
00858             // D55 -> B (XYZ Scaling)
00859             1.036058, 0.000000, 0.000000,
00860             0.000000, 1.000000, 0.000000,
00861             0.000000, 0.000000, 0.925482,
00862 
00863             // D55 -> C (Bradford)
00864             0.982433, -0.004287,  0.011457,
00865             -0.006610, 0.989199, -0.019977,
00866             0.051668,  0.016181,  1.292341,
00867 
00868             // D55 -> C (Von Kries)
00869             0.993339, -0.002552, 0.000000,
00870             -0.023228, 1.001966, 0.000000,
00871             0.058394, 0.000514, 1.282539,
00872 
00873             // D55 -> C (XYZ Scaling)
00874             1.025276, 0.000000, 0.000000,
00875             0.000000, 1.000000, 0.000000,
00876             0.000000, 0.000000, 1.282543,
00877 
00878             // D55 -> D50 (Bradford)
00879             1.018803, 0.012353, -0.003934,
00880             0.009594, 0.994842, 0.006418,
00881             -0.021278, -0.007227, 0.893255,
00882 
00883             // D55 -> D50 (Von Kries)
00884             1.006412, 0.002455, 0.000000,
00885             0.022357, 0.998107, 0.000000,
00886             -0.022266, -0.000495, 0.896136,
00887 
00888             // D55 -> D50 (XYZ Scaling)
00889             1.008345, 0.000000, 0.000000,
00890             0.000000, 1.000000, 0.000000,
00891             0.000000, 0.000000, 0.896140,
00892 
00893             // D55 -> D55
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             // D55 -> D65 (Bradford)
00907             0.972990, -0.016440, 0.007051,
00908             -0.013357, 1.004598, -0.011734,
00909             0.036285, 0.012078, 1.187991,
00910 
00911             // D55 -> D65 (Von Kries)
00912             0.990671, -0.003573, 0.000000,
00913             -0.032527, 1.002753, 0.000000,
00914             0.038746, 0.000720, 1.182565,
00915 
00916             // D55 -> D65 (XYZ Scaling)
00917             0.993963, 0.000000, 0.000000,
00918             0.000000, 1.000000, 0.000000,
00919             0.000000, 0.000000, 1.182570,
00920 
00921             // D55 -> D75 (Bradford)
00922             0.953688, -0.027490, 0.012840,
00923             -0.022677, 1.006379, -0.021468,
00924             0.065280, 0.021618, 1.340903,
00925 
00926             // D55 -> D75 (Von Kries)
00927             0.983939, -0.006152, 0.000000,
00928             -0.056002, 1.004740, 0.000000,
00929             0.070060, 0.001240, 1.330918,
00930 
00931             // D55 -> D75 (XYZ Scaling)
00932             0.992836, 0.000000, 0.000000,
00933             0.000000, 1.000000, 0.000000,
00934             0.000000, 0.000000, 1.330923,
00935 
00936             // D55 -> E (Bradford)
00937             1.021308, 0.021962,  0.004085,
00938             0.013455, 0.977009, -0.008075,
00939             0.010784, 0.002161,  1.090481,
00940 
00941             // D55 -> E (Von Kries)
00942             1.006527, 0.002499, 0.000000,
00943             0.022756, 0.998075, 0.000000,
00944             0.016037, -0.000505, 1.085950,
00945 
00946             // D55 -> E (XYZ Scaling)
00947             1.045763, 0.000000, 0.000000,
00948             0.000000, 1.000000, 0.000000,
00949             0.000000, 0.000000, 1.085953,
00950 
00951             // D65 -> A (Bradford)
00952             1.216371, 0.153235, -0.023966,
00953             0.110931, 0.915343, 0.035935,
00954             -0.154983, -0.056006, 0.314346,
00955 
00956             // D65 -> A (Von kries)
00957             1.071049, 0.026803, 0.000000,
00958             0.244014, 0.980413, 0.000000,
00959             -0.150348, -0.005408, 0.326427,
00960 
00961             // D65 -> A (XYZ Scaling)
00962             1.155516, 0.000000, 0.000000,
00963             0.000000, 1.000000, 0.000000,
00964             0.000000, 0.000000, 0.326428,
00965 
00966             // D65 -> B (Bradford)
00967             1.064164, 0.044624, -0.007852,
00968             0.032589, 0.976635, 0.012001,
00969             -0.048965, -0.017493, 0.778436,
00970 
00971             // D65 -> B (Von Kries)
00972             1.021142, 0.007975, 0.000000,
00973             0.072613, 0.994171, 0.000000,
00974             -0.048164, -0.001609, 0.782600,
00975 
00976             // D65 -> B (XYZ Scaling)
00977             1.042351, 0.000000, 0.000000,
00978             0.000000, 1.000000, 0.000000,
00979             0.000000, 0.000000, 0.782603,
00980 
00981             // D65 -> C (Bradford)
00982             1.009732, 0.012211, 0.003772,
00983             0.006993, 0.984871, -0.007129,
00984             0.012581, 0.003235, 1.087795,
00985 
00986             // D65 -> C (Von Kries)
00987             1.002728, 0.001028, 0.000000,
00988             0.009367, 0.999248, 0.000000,
00989             0.016519, -0.000208, 1.084536,
00990 
00991             // D65 -> C (XYZ Scaling)
00992             1.031503, 0.000000, 0.000000,
00993             0.000000, 1.000000, 0.000000,
00994             0.000000, 0.000000, 1.084540,
00995 
00996             // D65 -> D50 (Bradford)
00997             1.047835, 0.029556, -0.009238,
00998             0.022897, 0.990481, 0.015050,
00999             -0.050147, -0.017056, 0.752034,
01000 
01001             // D65 -> D50 (Von Kries)
01002             1.016089, 0.006069, 0.000000,
01003             0.055260, 0.995564, 0.000000,
01004             -0.052154, -0.001224, 0.757788,
01005 
01006             // D65 -> D50 (XYZ Scaling)
01007             1.014470, 0.000000, 0.000000,
01008             0.000000, 1.000000, 0.000000,
01009             0.000000, 0.000000, 0.757790,
01010 
01011             // D65 -> D55 (Bradford)
01012             1.028213, 0.016898, -0.005936,
01013             0.013304, 0.995522, 0.009754,
01014             -0.031540, -0.010637, 0.841840,
01015 
01016             // D65 -> D55 (Von Kries)
01017             1.009537, 0.003597, 0.000000,
01018             0.032756, 0.997370, 0.000000,
01019             -0.033098, -0.000726, 0.845614,
01020 
01021             // D65 -> D55 (XYZ Scaling)
01022             1.006074, 0.000000, 0.000000,
01023             0.000000, 1.000000, 0.000000,
01024             0.000000, 0.000000, 0.845616,
01025 
01026             // D65 -> D65
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             // D65 -> D75 (Bradford)
01040             0.979823, -0.011388,  0.004880,
01041             -0.009251, 1.001719, -0.008121,
01042             0.025117,  0.008361,  1.128649,
01043 
01044             // D65 -> D75 (Von Kries)
01045             0.993120, -0.002596, 0.000000,
01046             -0.023629, 1.001897, 0.000000,
01047             0.026719, 0.000523, 1.125446,
01048 
01049             // D65 -> D75 (XYZ Scaling)
01050             0.998867, 0.000000, 0.000000,
01051             0.000000, 1.000000, 0.000000,
01052             0.000000, 0.000000, 1.125450,
01053 
01054             // D65 -> E (Bradford)
01055             1.050285, 0.039078, -0.002409,
01056             0.027087, 0.972947, 0.002652,
01057             -0.023276, -0.009266, 0.917968,
01058 
01059             // D65 -> E (Von kries)
01060             1.016207, 0.006113, 0.000000,
01061             0.055662, 0.995532, 0.000000,
01062             -0.019769, -0.001234, 0.918297,
01063 
01064             // D65 -> E (XYZ Scaling)
01065             1.052114, 0.000000, 0.000000,
01066             0.000000, 1.000000, 0.000000,
01067             0.000000, 0.000000, 0.918300,
01068 
01069             // D75 -> A (Bradford)
01070             1.243649, 0.167322, -0.025407,
01071             0.120882, 0.914830, 0.037899,
01072             -0.165889, -0.060122, 0.278800,
01073 
01074             // D75 -> A (Von Kries)
01075             1.079173, 0.029548, 0.000000,
01076             0.269008, 0.979254, 0.000000,
01077             -0.159335, -0.005962, 0.290041,
01078 
01079             // D75 -> A (XYZ Scaling)
01080             1.156827, 0.000000, 0.000000,
01081             0.000000, 1.000000, 0.000000,
01082             0.000000, 0.000000, 0.290042,
01083 
01084             // D75 -> B (Bradford)
01085             1.086904, 0.056997, -0.011247,
01086             0.042021, 0.975291, 0.017469,
01087             -0.067883, -0.023992, 0.689828,
01088 
01089             // D75 -> B (Von Kries)
01090             1.028470, 0.010625, 0.000000,
01091             0.096735, 0.992539, 0.000000,
01092             -0.067258, -0.002144, 0.695366,
01093 
01094             // D75 -> B (XYZ Scaling)
01095             1.043533, 0.000000, 0.000000,
01096             0.000000, 1.000000, 0.000000,
01097             0.000000, 0.000000, 0.695369,
01098 
01099             // D75 -> C (Bradford)
01100             1.030774,   0.023916, -0.000943,
01101             0.016405,   0.983362,  0.000688,
01102             -0.011913, -0.004951,  0.963819,
01103 
01104             // D75 -> C (Von Kries)
01105             1.009762, 0.003643, 0.000000,
01106             0.033168, 0.997442, 0.000000,
01107             -0.009311, -0.000735,  0.963647,
01108 
01109             // D75 -> C (XYZ Scaling)
01110             1.032673, 0.000000, 0.000000,
01111             0.000000, 1.000000, 0.000000,
01112             0.000000, 0.000000, 0.963650,
01113 
01114             // D75 -> D50 (Bradford)
01115             1.070127, 0.041775, -0.012512,
01116             0.032186, 0.988978, 0.020311,
01117             -0.068484, -0.023368, 0.666442,
01118 
01119             // D75 -> D50 (Von Kries)
01120             1.023337, 0.008709, 0.000000,
01121             0.079295, 0.993884, 0.000000,
01122             -0.070673, -0.001757, 0.673320,
01123 
01124             // D75 -> D50 (XYZ Scaling)
01125             1.015620, 0.000000, 0.000000,
01126             0.000000, 1.000000, 0.000000,
01127             0.000000, 0.000000, 0.673322,
01128 
01129             // D75 -> D55 (Bradford)
01130             1.049904, 0.028885, -0.009591,
01131             0.022560, 0.993940, 0.015697,
01132             -0.051476, -0.017431, 0.745981,
01133 
01134             // D75 -> D55 (Von Kries)
01135             1.016680, 0.006225, 0.000000,
01136             0.056676, 0.995628, 0.000000,
01137             -0.053572, -0.001255, 0.751356,
01138 
01139             // D75 -> D55 (XYZ Scaling)
01140             1.007215, 0.000000, 0.000000,
01141             0.000000, 1.000000, 0.000000,
01142             0.000000, 0.000000, 0.751359,
01143 
01144             // D75 -> D65 (Bradford)
01145             1.020813, 0.011641, -0.004330,
01146             0.009243, 0.998329, 0.007144,
01147             -0.022785, -0.007655, 0.886059,
01148 
01149             // D75 -> D65 (Von Kries)
01150             1.006992, 0.002609, 0.000000,
01151             0.023758, 0.998167, 0.000000,
01152             -0.023919, -0.000526,  0.888531,
01153 
01154             // D75 -> D65 (XYZ Scaling)
01155             1.001134, 0.000000, 0.000000,
01156             0.000000, 1.000000, 0.000000,
01157             0.000000, 0.000000, 0.888534,
01158 
01159             // D75 -> D75
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             // D75 -> E (Bradford)
01173             1.072560, 0.051258, -0.006403,
01174             0.036583, 0.971617, 0.009183,
01175             -0.044763, -0.016548, 0.813408,
01176 
01177             // D75 -> E (Von Kries)
01178             1.023456, 0.008754, 0.000000,
01179             0.079698, 0.993854, 0.000000,
01180         -0.041900, -0.001766, 0.815937,
01181 
01182             // D75 -> E (XYZ Scaling)
01183             1.053308, 0.000000, 0.000000,
01184             0.000000, 1.000000, 0.000000,
01185             0.000000, 0.000000, 0.815940,
01186 
01187             // E ->     A (Bradford)
01188             1.154755, 0.110892, -0.023397,
01189             0.082246, 0.937839, 0.036653,
01190             -0.138722, -0.048732, 0.342214,
01191 
01192             // E -> A (Von Kries)
01193             1.052848, 0.020457, 0.000000,
01194             0.186247, 0.983669, 0.000000,
01195             -0.140810, -0.004127, 0.355469,
01196 
01197             // E -> A (XYZ Scaling)
01198             1.098280, 0.000000, 0.000000,
01199             0.000000, 1.000000, 0.000000,
01200             0.000000, 0.000000, 0.355470,
01201 
01202             // E -> B (Bradford)
01203             1.012951, 0.005123, -0.005910,
01204             0.005370, 1.003671, 0.010188,
01205             -0.027601, -0.008795, 0.847953,
01206 
01207             // E -> B (Von Kries)
01208             1.004757, 0.001841, 0.000000,
01209             0.016766, 0.998529, 0.000000,
01210             -0.030798, -0.000371, 0.852227,
01211 
01212             // E -> B (XYZ Scaling)
01213             0.990720, 0.000000, 0.000000,
01214             0.000000, 1.000000, 0.000000,
01215             0.000000, 0.000000, 0.852230,
01216 
01217             // E -> C (Bradford)
01218             0.962209, -0.026032, 0.006709,
01219             -0.019703, 1.012944, -0.010744,
01220             0.037905, 0.013088, 1.185066,
01221 
01222             // E -> C (Von Kries)
01223             0.987012, -0.005028, 0.000000,
01224             -0.045772, 1.004013, 0.000000,
01225             0.039174, 0.001014, 1.181026,
01226 
01227             // E -> C (XYZ Scaling)
01228             0.980410, 0.000000, 0.000000,
01229             0.000000, 1.000000, 0.000000,
01230             0.000000, 0.000000, 1.181030,
01231 
01232             // E -> D50 (Bradford)
01233             0.997754, -0.009768, -0.007417,
01234             -0.004163, 1.018316, 0.013442,
01235             -0.029371, -0.008549, 0.819186,
01236 
01237             // E -> D50 (Von Kries)
01238             0.999887, -0.000044, 0.000000,
01239             -0.000393, 1.000033, 0.000000,
01240             -0.035270, 0.000010, 0.825207,
01241 
01242             // E -> D50 (XYZ Scaling)
01243             0.964220, 0.000000, 0.000000,
01244             0.000000, 1.000000, 0.000000,
01245             0.000000, 0.000000, 0.825210,
01246 
01247             // E -> D55 (Bradford)
01248             0.979467, -0.022009, -0.003832,
01249             -0.013568, 1.023820, 0.007632,
01250             -0.009659, -0.001811, 0.917050,
01251 
01252             // E -> D55 (Von Kries)
01253             0.993574, -0.002488, 0.000000,
01254             -0.022644, 1.001984, 0.000000,
01255             -0.014684, 0.000503, 0.920847,
01256 
01257             // E -> D55 (XYZ Scaling)
01258             0.956240, 0.000000, 0.000000,
01259             0.000000, 1.000000, 0.000000,
01260             0.000000, 0.000000, 0.920850,
01261 
01262             // E -> D65 (Bradford)
01263             0.953167, -0.038259, 0.002612,
01264             -0.026600, 1.028843, -0.003042,
01265             0.023901, 0.009415, 1.089399,
01266 
01267             // E -> D65 (Von Kries)
01268             0.984385, -0.006045, 0.000000,
01269             -0.055029, 1.004824, 0.000000,
01270             0.021116, 0.001220, 1.088965,
01271 
01272             // E -> D65 (XYZ Scaling)
01273             0.950467, 0.000000, 0.000000,
01274             0.000000, 1.000000, 0.000000,
01275             0.000000, 0.000000, 1.088969,
01276 
01277             // E -> D75 (Bradford)
01278             0.934355, -0.049157, 0.007910,
01279             -0.035658, 1.030889, -0.011919,
01280             0.050694, 0.018268, 1.229589,
01281 
01282             // E -> D75 (Von Kries)
01283             0.977754, -0.008612, 0.000000,
01284             -0.078398, 1.006874, 0.000000,
01285             0.050039, 0.001738, 1.225576,
01286 
01287             // E -> D75 (XYZ Scaling)
01288             0.949390, 0.000000, 0.000000,
01289             0.000000, 1.000000, 0.000000,
01290             0.000000, 0.000000, 1.225580,
01291 
01292             // E -> E
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 // public methods
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; // about 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         // RGB WORKING SPACE DATA
01385         //
01386         // Illuminant Reference for each RGB Space.
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);  // Min value of RGB
01468     double v_max = std::max(std::max(R, G), B);  // Max value of RGB
01469 
01470         double delta = v_max - v_min;   //Delta RGB value
01471 
01472         V = v_max;
01473 
01474         if (delta < 0.00000000001)   // This is a gray, no chroma...
01475         {
01476             H = 0.0;                   // HSV results = 0 ÷ 1
01477             S = 0.0;
01478         }
01479         else                         // Chromatic data...
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; // this final branch should never happen...
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;     // H must be < 1
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         // Account for gamma correction
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         // Account for Gamma Correction
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         // Convert from reference illuminant to the desired one
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         // Reference white computation
01685         // Note: The reference white depends only on the illuminant
01686         //       (it is independent on the RGB Working Space)
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         // Reference white computation
01770         // Note: The reference white depends only on the illuminant
01771         //       (it is independent on the RGB Working Space)
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     // RGB --> HSL
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     // RGB --> HSL
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);    // Min value of RGB
01795 
01796         v = std::max(R,G);
01797         double v_max = std::max(v, B);    // Max value of RGB
01798 
01799         double delta = v_max - v_min;         // Delta RGB value
01800 
01801         L = (v_max + v_min) / 2.0;
01802 
01803         if (delta == 0.0)                     // This is a gray, no chroma...
01804         {
01805             H = 0.0;
01806             S = 0.0;
01807         }
01808         else                                  // Chromatic data...
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     // HSL --> RGB
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     // CIE xyY --> CIE XYZ
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     // CIE XYZ --> CIE xyY
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     // XYZ (Illuminant src) --> XYZ (Illuminant dest) - [ILLUMINANT CHANGE]
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     // XYZ (Illuminant src) --> XYZ (Illuminant dest) - [ILLUMINANT CHANGE]
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     // RGB (working space src) --> RGB (working space dest) - [RGB WORKING SPACE CHANGE]
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     // RGB (working space src) --> RGB (working space dest) - [RGB WORKING SPACE CHANGE]
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 } // end of NameSpace VCG
01975 
01976 #endif /*  __VCGLIB_COLORSPACE */


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:29:38