@@ -20,8 +20,8 @@ interface
20
20
simba.base, simba.math, simba.colormath;
21
21
22
22
const
23
- XYZ_POW_2_4 : array [0 ..255 ] of Single = (
24
- 0.000834 , 0.000984 , 0.001148 , 0.001328 , 0.001523 , 0.001733 , 0.001960 , 0.002203 , 0.002463 , 0.002740 , 0.003035 , 0.003347 , 0.003677 , 0.004025 , 0.004391 , 0.004777 , 0.005182 , 0.005605 , 0.006049 , 0.006512 , 0.006995 , 0.007499 , 0.008023 , 0.008568 , 0.009134 , 0.009721 , 0.010330 , 0.010960 , 0.011612 , 0.012286 , 0.012983 , 0.013702 , 0.014444 , 0.015209 , 0.015996 , 0.016807 , 0.017642 , 0.018500 , 0.019382 , 0.020289 , 0.021219 , 0.022174 , 0.023153 , 0.024158 , 0.025187 , 0.026241 , 0.027321 , 0.028426 , 0.029557 , 0.030713 , 0.031896 , 0.033105 ,
23
+ XYZ_GAMMA_LUT : array [0 ..255 ] of Single = (
24
+ 0.000000 , 0.000304 , 0.000607 , 0.000911 , 0.001214 , 0.001518 , 0.001821 , 0.002125 , 0.002428 , 0.002732 , 0.003035 , 0.003345 , 0.003677 , 0.004025 , 0.004391 , 0.004777 , 0.005182 , 0.005605 , 0.006049 , 0.006512 , 0.006995 , 0.007499 , 0.008023 , 0.008568 , 0.009134 , 0.009721 , 0.010330 , 0.010960 , 0.011612 , 0.012286 , 0.012983 , 0.013702 , 0.014444 , 0.015209 , 0.015996 , 0.016807 , 0.017642 , 0.018500 , 0.019382 , 0.020289 , 0.021219 , 0.022174 , 0.023153 , 0.024158 , 0.025187 , 0.026241 , 0.027321 , 0.028426 , 0.029557 , 0.030713 , 0.031896 , 0.033105 ,
25
25
0.034340 , 0.035601 , 0.036889 , 0.038204 , 0.039546 , 0.040915 , 0.042311 , 0.043735 , 0.045186 , 0.046665 , 0.048172 , 0.049707 , 0.051269 , 0.052861 , 0.054480 , 0.056128 , 0.057805 , 0.059511 , 0.061246 , 0.063010 , 0.064803 , 0.066626 , 0.068478 , 0.070360 , 0.072272 , 0.074214 , 0.076185 , 0.078187 , 0.080220 , 0.082283 , 0.084376 , 0.086500 , 0.088656 , 0.090842 , 0.093059 , 0.095307 , 0.097587 , 0.099899 , 0.102242 , 0.104616 , 0.107023 , 0.109462 , 0.111932 , 0.114435 , 0.116971 , 0.119538 , 0.122139 , 0.124772 , 0.127438 , 0.130136 , 0.132868 , 0.135633 ,
26
26
0.138432 , 0.141263 , 0.144128 , 0.147027 , 0.149960 , 0.152926 , 0.155926 , 0.158961 , 0.162029 , 0.165132 , 0.168269 , 0.171441 , 0.174647 , 0.177888 , 0.181164 , 0.184475 , 0.187821 , 0.191202 , 0.194618 , 0.198069 , 0.201556 , 0.205079 , 0.208637 , 0.212231 , 0.215861 , 0.219526 , 0.223228 , 0.226966 , 0.230740 , 0.234551 , 0.238398 , 0.242281 , 0.246201 , 0.250158 , 0.254152 , 0.258183 , 0.262251 , 0.266356 , 0.270498 , 0.274677 , 0.278894 , 0.283149 , 0.287441 , 0.291771 , 0.296138 , 0.300544 , 0.304987 , 0.309469 , 0.313989 , 0.318547 , 0.323143 , 0.327778 ,
27
27
0.332452 , 0.337164 , 0.341914 , 0.346704 , 0.351533 , 0.356400 , 0.361307 , 0.366253 , 0.371238 , 0.376262 , 0.381326 , 0.386429 , 0.391572 , 0.396755 , 0.401978 , 0.407240 , 0.412543 , 0.417885 , 0.423268 , 0.428690 , 0.434154 , 0.439657 , 0.445201 , 0.450786 , 0.456411 , 0.462077 , 0.467784 , 0.473531 , 0.479320 , 0.485150 , 0.491021 , 0.496933 , 0.502886 , 0.508881 , 0.514918 , 0.520996 , 0.527115 , 0.533276 , 0.539479 , 0.545724 , 0.552011 , 0.558340 , 0.564712 , 0.571125 , 0.577580 , 0.584078 , 0.590619 , 0.597202 , 0.603827 , 0.610496 , 0.617207 , 0.623960 ,
@@ -97,13 +97,15 @@ class function TSimbaColorConversion.BGRAToRGB(const RGB: TColorBGRA): TColorRGB
97
97
class function TSimbaColorConversion.RGBToXYZ (const RGB: TColorRGB): TColorXYZ;
98
98
var
99
99
vR,vG,vB: Single;
100
+ const
101
+ // D65 White Point
102
+ D65_Xn: Single = 0.95047 ;
103
+ D65_Yn: Single = 1.00000 ;
104
+ D65_Zn: Single = 1.08883 ;
100
105
begin
101
- if RGB.R > 10 then vR := XYZ_POW_2_4[RGB.R]
102
- else vR := (RGB.R / 255.0 ) / 12.92 ;
103
- if RGB.G > 10 then vG := XYZ_POW_2_4[RGB.G]
104
- else vG := (RGB.G / 255.0 ) / 12.92 ;
105
- if RGB.B > 10 then vB := XYZ_POW_2_4[RGB.B]
106
- else vB := (RGB.B / 255.0 ) / 12.92 ;
106
+ vR := XYZ_GAMMA_LUT[RGB.R];
107
+ vG := XYZ_GAMMA_LUT[RGB.G];
108
+ vB := XYZ_GAMMA_LUT[RGB.B];
107
109
108
110
vR := vR * 100 ;
109
111
vG := vG * 100 ;
@@ -113,23 +115,29 @@ class function TSimbaColorConversion.RGBToXYZ(const RGB: TColorRGB): TColorXYZ;
113
115
Result.X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805 );
114
116
Result.Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722 );
115
117
Result.Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505 );
118
+
119
+ // Normalize XYZ by D65 white point
120
+ Result.X /= D65_Xn;
121
+ Result.Y /= D65_Yn;
122
+ Result.Z /= D65_Zn;
116
123
end ;
117
124
118
125
class function TSimbaColorConversion.RGBToLAB (const RGB: TColorRGB): TColorLAB;
119
126
var
120
127
vR,vG,vB, X,Y,Z: Single;
128
+ const
129
+ D65_Xn_Inv: Single = 1.0 / 0.95047 ;
130
+ D65_Yn_Inv: Single = 1.0 / 1.00000 ;
131
+ D65_Zn_Inv: Single = 1.0 / 1.08883 ;
121
132
begin
122
- if RGB.R > 10 then vR := XYZ_POW_2_4[RGB.R]
123
- else vR := (RGB.R / 255.0 ) / 12.92 ;
124
- if RGB.G > 10 then vG := XYZ_POW_2_4[RGB.G]
125
- else vG := (RGB.G / 255.0 ) / 12.92 ;
126
- if RGB.B > 10 then vB := XYZ_POW_2_4[RGB.B]
127
- else vB := (RGB.B / 255.0 ) / 12.92 ;
133
+ vR := XYZ_GAMMA_LUT[RGB.R];
134
+ vG := XYZ_GAMMA_LUT[RGB.G];
135
+ vB := XYZ_GAMMA_LUT[RGB.B];
128
136
129
- // Illuminant = D65
130
- X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805 );
131
- Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722 );
132
- Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505 );
137
+ // Illuminant = D65 & Normalize D65
138
+ X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805 ) * D65_Xn_Inv ;
139
+ Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722 ) * D65_Yn_Inv ;
140
+ Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505 ) * D65_Zn_Inv ;
133
141
134
142
// XYZ To LAB
135
143
if X > 0.008856 then X := Power(X, ONE_DIV_THREE)
@@ -389,9 +397,9 @@ class function TSimbaColorConversion.LABToXYZ(const LAB: TColorLAB): TColorXYZ;
389
397
if (vZ3 > 0.008856 ) then vZ := vZ3
390
398
else vZ := (vZ - 16 / 116 ) / 7.787 ;
391
399
392
- Result.X := vX * 100.0 ;
400
+ Result.X := vX * 95.047 ;
393
401
Result.Y := vY * 100.0 ;
394
- Result.Z := vZ * 100.0 ;
402
+ Result.Z := vZ * 108.883 ;
395
403
end ;
396
404
397
405
class function TSimbaColorConversion.LABToRGB (const LAB: TColorLAB): TColorRGB;
0 commit comments