Skip to content

Commit

Permalink
Colormath opt, and D65 normalization
Browse files Browse the repository at this point in the history
  • Loading branch information
slackydev committed Jan 9, 2025
1 parent d619b1c commit db30237
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 56 deletions.
48 changes: 28 additions & 20 deletions Source/simba.colormath_conversion.pas
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ interface
simba.base, simba.math, simba.colormath;

const
XYZ_POW_2_4: array[0..255] of Single = (
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,
XYZ_GAMMA_LUT: array[0..255] of Single = (
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,
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,
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,
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,
Expand Down Expand Up @@ -97,13 +97,15 @@ class function TSimbaColorConversion.BGRAToRGB(const RGB: TColorBGRA): TColorRGB
class function TSimbaColorConversion.RGBToXYZ(const RGB: TColorRGB): TColorXYZ;
var
vR,vG,vB: Single;
const
// D65 White Point
D65_Xn: Single = 0.95047;
D65_Yn: Single = 1.00000;
D65_Zn: Single = 1.08883;
begin
if RGB.R > 10 then vR := XYZ_POW_2_4[RGB.R]
else vR := (RGB.R / 255.0) / 12.92;
if RGB.G > 10 then vG := XYZ_POW_2_4[RGB.G]
else vG := (RGB.G / 255.0) / 12.92;
if RGB.B > 10 then vB := XYZ_POW_2_4[RGB.B]
else vB := (RGB.B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[RGB.R];
vG := XYZ_GAMMA_LUT[RGB.G];
vB := XYZ_GAMMA_LUT[RGB.B];

vR := vR * 100;
vG := vG * 100;
Expand All @@ -113,23 +115,29 @@ class function TSimbaColorConversion.RGBToXYZ(const RGB: TColorRGB): TColorXYZ;
Result.X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Result.Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Result.Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);

// Normalize XYZ by D65 white point
Result.X /= D65_Xn;
Result.Y /= D65_Yn;
Result.Z /= D65_Zn;
end;

class function TSimbaColorConversion.RGBToLAB(const RGB: TColorRGB): TColorLAB;
var
vR,vG,vB, X,Y,Z: Single;
const
D65_Xn_Inv: Single = 1.0 / 0.95047;
D65_Yn_Inv: Single = 1.0 / 1.00000;
D65_Zn_Inv: Single = 1.0 / 1.08883;
begin
if RGB.R > 10 then vR := XYZ_POW_2_4[RGB.R]
else vR := (RGB.R / 255.0) / 12.92;
if RGB.G > 10 then vG := XYZ_POW_2_4[RGB.G]
else vG := (RGB.G / 255.0) / 12.92;
if RGB.B > 10 then vB := XYZ_POW_2_4[RGB.B]
else vB := (RGB.B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[RGB.R];
vG := XYZ_GAMMA_LUT[RGB.G];
vB := XYZ_GAMMA_LUT[RGB.B];

// Illuminant = D65
X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);
// Illuminant = D65 & Normalize D65
X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805) * D65_Xn_Inv;
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722) * D65_Yn_Inv;
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505) * D65_Zn_Inv;

// XYZ To LAB
if X > 0.008856 then X := Power(X, ONE_DIV_THREE)
Expand Down Expand Up @@ -389,9 +397,9 @@ class function TSimbaColorConversion.LABToXYZ(const LAB: TColorLAB): TColorXYZ;
if (vZ3 > 0.008856) then vZ := vZ3
else vZ := (vZ - 16 / 116) / 7.787;

Result.X := vX * 100.0;
Result.X := vX * 95.047;
Result.Y := vY * 100.0;
Result.Z := vZ * 100.0;
Result.Z := vZ * 108.883;
end;

class function TSimbaColorConversion.LABToRGB(const LAB: TColorLAB): TColorRGB;
Expand Down
76 changes: 40 additions & 36 deletions Source/simba.colormath_distance_unrolled.pas
Original file line number Diff line number Diff line change
Expand Up @@ -135,27 +135,28 @@ function DistanceXYZ_UnRolled(const C1: PColorXYZ; const C2: TColorBGRA; const m
var
vR,vG,vB: Single;
Color1, Color2: TColorXYZ;
const
D65_Xn_Inv: Single = 1.0 / 0.95047;
D65_Yn_Inv: Single = 1.0 / 1.00000;
D65_Zn_Inv: Single = 1.0 / 1.08883;
begin
Color1 := C1^;

// function RGBToXYZ
with C2 do
begin
if R > 10 then vR := XYZ_POW_2_4[R]
else vR := (R / 255.0) / 12.92;
if G > 10 then vG := XYZ_POW_2_4[G]
else vG := (G / 255.0) / 12.92;
if B > 10 then vB := XYZ_POW_2_4[B]
else vB := (B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[R];
vG := XYZ_GAMMA_LUT[G];
vB := XYZ_GAMMA_LUT[B];
end;

vR := vR * 100;
vG := vG * 100;
vB := vB * 100;

Color2.X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Color2.Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Color2.Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);
Color2.X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805) * D65_Xn_Inv;
Color2.Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722) * D65_Yn_Inv;
Color2.Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505) * D65_Zn_Inv;

// function DistanceXYZ
Result := Sqrt(Sqr((Color1.X - Color2.X) * mul[0]) + Sqr((Color1.Y - Color2.Y) * mul[1]) + Sqr((Color1.Z - Color2.Z) * mul[2]));
Expand All @@ -165,23 +166,24 @@ function DistanceLAB_UnRolled(const C1: PColorLAB; const C2: TColorBGRA; const m
var
vR,vG,vB, X,Y,Z: Single;
Color1, Color2: TColorLAB;
const
D65_Xn_Inv: Single = 1.0 / 0.95047;
D65_Yn_Inv: Single = 1.0 / 1.00000;
D65_Zn_Inv: Single = 1.0 / 1.08883;
begin
Color1 := C1^;

// function RGBToLAB
with C2 do
begin
if R > 10 then vR := XYZ_POW_2_4[R]
else vR := (R / 255.0) / 12.92;
if G > 10 then vG := XYZ_POW_2_4[G]
else vG := (G / 255.0) / 12.92;
if B > 10 then vB := XYZ_POW_2_4[B]
else vB := (B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[R];
vG := XYZ_GAMMA_LUT[G];
vB := XYZ_GAMMA_LUT[B];
end;

X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);
X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805) * D65_Xn_Inv;
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722) * D65_Yn_Inv;
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505) * D65_Zn_Inv;

if X > 0.008856 then X := Power(X, ONE_DIV_THREE)
else X := (7.787 * X) + 0.137931;
Expand All @@ -202,23 +204,24 @@ function DistanceLCH_UnRolled(const C1: PColorLCH; const C2: TColorBGRA; const m
var
vR,vG,vB, X,Y,Z, L,A,B, deltaH: Single;
Color1, Color2: TColorLCH;
const
D65_Xn_Inv: Single = 1.0 / 0.95047;
D65_Yn_Inv: Single = 1.0 / 1.00000;
D65_Zn_Inv: Single = 1.0 / 1.08883;
begin
Color1 := C1^;

// function RGBToLAB
with C2 do
begin
if R > 10 then vR := XYZ_POW_2_4[R]
else vR := (R / 255.0) / 12.92;
if G > 10 then vG := XYZ_POW_2_4[G]
else vG := (G / 255.0) / 12.92;
if B > 10 then vB := XYZ_POW_2_4[B]
else vB := (B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[R];
vG := XYZ_GAMMA_LUT[G];
vB := XYZ_GAMMA_LUT[B];
end;

X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);
X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805) * D65_Xn_Inv;
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722) * D65_Yn_Inv;
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505) * D65_Zn_Inv;

if X > 0.008856 then X := Power(X, ONE_DIV_THREE)
else X := (7.787 * X) + 0.137931;
Expand Down Expand Up @@ -265,23 +268,24 @@ function DistanceDeltaE_UnRolled(const C1: PColorLAB; const C2: TColorBGRA; cons
vR,vG,vB, X,Y,Z: Single;
xC1,xC2,xDL,xDC,xDE,xDH,xSC,xSH: Single;
Color1, Color2: TColorLAB;
const
D65_Xn_Inv: Single = 1.0 / 0.95047;
D65_Yn_Inv: Single = 1.0 / 1.00000;
D65_Zn_Inv: Single = 1.0 / 1.08883;
begin
Color1 := C1^;

// function RGBToLAB
with C2 do
begin
if R > 10 then vR := XYZ_POW_2_4[R]
else vR := (R / 255.0) / 12.92;
if G > 10 then vG := XYZ_POW_2_4[G]
else vG := (G / 255.0) / 12.92;
if B > 10 then vB := XYZ_POW_2_4[B]
else vB := (B / 255.0) / 12.92;
vR := XYZ_GAMMA_LUT[R];
vG := XYZ_GAMMA_LUT[G];
vB := XYZ_GAMMA_LUT[B];
end;

X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805);
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722);
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505);
X := (vR * 0.4124 + vG * 0.3576 + vB * 0.1805) * D65_Xn_Inv;
Y := (vR * 0.2126 + vG * 0.7152 + vB * 0.0722) * D65_Yn_Inv;
Z := (vR * 0.0193 + vG * 0.1192 + vB * 0.9505) * D65_Zn_Inv;

if X > 0.008856 then X := Power(X, ONE_DIV_THREE)
else X := (7.787 * X) + 0.137931;
Expand Down

0 comments on commit db30237

Please sign in to comment.