Skip to content

Commit 1760beb

Browse files
authored
Update chromatic adaptation matrices to higher precision (#1179)
1 parent 5bf215a commit 1760beb

51 files changed

Lines changed: 95 additions & 91 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/color-helpers/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to Color Helpers
22

3+
### Unreleased (patch)
4+
5+
- Use higher precision color conversion matrices.
6+
37
### 3.0.2
48

59
_September 2, 2023_

packages/color-helpers/dist/index.cjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ function lin_sRGB(t){return t.map((function(t){const _=t<0?-1:1,o=Math.abs(t);re
8989
*
9090
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
9191
*/
92-
function D50_to_D65(t){return multiplyMatrices([[.9554734527042182,-.023098536874261423,.0632593086610217],[-.028369706963208136,1.0099954580058226,.021041398966943008],[.012314001688319899,-.020507696433477912,1.3303659366080753]],t)}
92+
function D50_to_D65(t){return multiplyMatrices([[.955473421488075,-.02309845494876471,.06325924320057072],[-.0283697093338637,1.0099953980813041,.021041441191917323],[.012314014864481998,-.020507649298898964,1.330365926242124]],t)}
9393
/**
9494
* Bradford chromatic adaptation from D65 to D50
9595
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
9696
*
9797
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
9898
*
9999
* @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
100-
*/function D65_to_D50(t){return multiplyMatrices([[1.0479298208405488,.022946793341019088,-.05019222954313557],[.029627815688159344,.990434484573249,-.01707382502938514],[-.009243058152591178,.015055144896577895,.7518742899580008]],t)}
100+
*/function D65_to_D50(t){return multiplyMatrices([[1.0479297925449969,.022946870601609652,-.05019226628920524],[.02962780877005599,.9904344267538799,-.017073799063418826],[-.009243040646204504,.015055191490298152,.7518742814281371]],t)}
101101
/**
102102
* Convert an array of linear-light rec2020 RGB in the range 0.0-1.0
103103
* to gamma corrected form ITU-R BT.2020-2 p.4
@@ -301,7 +301,7 @@ function OKLab_to_OKLCH(t){const _=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0]
301301
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
302302
*
303303
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
304-
*/function OKLab_to_XYZ(t){const _=multiplyMatrices([[.9999999984505198,.39633779217376786,.2158037580607588],[1.0000000088817609,-.10556134232365635,-.06385417477170591],[1.0000000546724108,-.08948418209496575,-1.2914855378640917]],t);return multiplyMatrices([[1.2268798733741557,-.5578149965554813,.28139105017721583],[-.04057576262431372,1.1122868293970594,-.07171106666151701],[-.07637294974672142,-.4214933239627914,1.5869240244272418]],_.map((t=>t**3)))}
304+
*/function OKLab_to_XYZ(t){const _=multiplyMatrices([[1,.3963377773761749,.2158037573099136],[1,-.1055613458156586,-.0638541728258133],[1,-.0894841775298119,-1.2914855480194092]],t);return multiplyMatrices([[1.2268798758459243,-.5578149944602171,.2813910456659647],[-.0405757452148008,1.112286803280317,-.0717110580655164],[-.0763729366746601,-.4214933324022432,1.5869240198367816]],_.map((t=>t**3)))}
305305
/**
306306
* Convert an array of gamma-corrected sRGB values in the 0.0 to 1.0 range to HSL.
307307
*
@@ -367,7 +367,7 @@ function XYZ_to_Lab(t){const _=t.map(((t,_)=>t/r[_])).map((t=>t>.008856451679035
367367
*
368368
* XYZ <-> LMS matrices recalculated for consistent reference white
369369
* @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484
370-
*/function XYZ_to_OKLab(t){const _=multiplyMatrices([[.8190224432164319,.3619062562801221,-.12887378261216414],[.0329836671980271,.9292868468965546,.03614466816999844],[.048177199566046255,.26423952494422764,.6335478258136937]],t);return multiplyMatrices([[.2104542553,.793617785,-.0040720468],[1.9779984951,-2.428592205,.4505937099],[.0259040371,.7827717662,-.808675766]],_.map((t=>Math.cbrt(t))))}
370+
*/function XYZ_to_OKLab(t){const _=multiplyMatrices([[.819022437996703,.3619062600528904,-.1288737815209879],[.0329836539323885,.9292868615863434,.0361446663506424],[.0481771893596242,.2642395317527308,.6335478284694309]],t);return multiplyMatrices([[.210454268309314,.7936177747023054,-.0040720430116193],[1.9779985324311684,-2.42859224204858,.450593709617411],[.0259040424655478,.7827717124575296,-.8086757549230774]],_.map((t=>Math.cbrt(t))))}
371371
/**
372372
* Convert an array of three XYZ values to u*,v* chromaticity coordinates
373373
*

packages/color-helpers/dist/index.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ function lin_sRGB(t){return t.map((function(t){const _=t<0?-1:1,o=Math.abs(t);re
8989
*
9090
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
9191
*/
92-
function D50_to_D65(t){return multiplyMatrices([[.9554734527042182,-.023098536874261423,.0632593086610217],[-.028369706963208136,1.0099954580058226,.021041398966943008],[.012314001688319899,-.020507696433477912,1.3303659366080753]],t)}
92+
function D50_to_D65(t){return multiplyMatrices([[.955473421488075,-.02309845494876471,.06325924320057072],[-.0283697093338637,1.0099953980813041,.021041441191917323],[.012314014864481998,-.020507649298898964,1.330365926242124]],t)}
9393
/**
9494
* Bradford chromatic adaptation from D65 to D50
9595
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
9696
*
9797
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
9898
*
9999
* @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
100-
*/function D65_to_D50(t){return multiplyMatrices([[1.0479298208405488,.022946793341019088,-.05019222954313557],[.029627815688159344,.990434484573249,-.01707382502938514],[-.009243058152591178,.015055144896577895,.7518742899580008]],t)}
100+
*/function D65_to_D50(t){return multiplyMatrices([[1.0479297925449969,.022946870601609652,-.05019226628920524],[.02962780877005599,.9904344267538799,-.017073799063418826],[-.009243040646204504,.015055191490298152,.7518742814281371]],t)}
101101
/**
102102
* Convert an array of linear-light rec2020 RGB in the range 0.0-1.0
103103
* to gamma corrected form ITU-R BT.2020-2 p.4
@@ -301,7 +301,7 @@ function OKLab_to_OKLCH(t){const _=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0]
301301
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
302302
*
303303
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
304-
*/function OKLab_to_XYZ(t){const _=multiplyMatrices([[.9999999984505198,.39633779217376786,.2158037580607588],[1.0000000088817609,-.10556134232365635,-.06385417477170591],[1.0000000546724108,-.08948418209496575,-1.2914855378640917]],t);return multiplyMatrices([[1.2268798733741557,-.5578149965554813,.28139105017721583],[-.04057576262431372,1.1122868293970594,-.07171106666151701],[-.07637294974672142,-.4214933239627914,1.5869240244272418]],_.map((t=>t**3)))}
304+
*/function OKLab_to_XYZ(t){const _=multiplyMatrices([[1,.3963377773761749,.2158037573099136],[1,-.1055613458156586,-.0638541728258133],[1,-.0894841775298119,-1.2914855480194092]],t);return multiplyMatrices([[1.2268798758459243,-.5578149944602171,.2813910456659647],[-.0405757452148008,1.112286803280317,-.0717110580655164],[-.0763729366746601,-.4214933324022432,1.5869240198367816]],_.map((t=>t**3)))}
305305
/**
306306
* Convert an array of gamma-corrected sRGB values in the 0.0 to 1.0 range to HSL.
307307
*
@@ -367,7 +367,7 @@ function XYZ_to_Lab(t){const _=t.map(((t,_)=>t/r[_])).map((t=>t>.008856451679035
367367
*
368368
* XYZ <-> LMS matrices recalculated for consistent reference white
369369
* @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484
370-
*/function XYZ_to_OKLab(t){const _=multiplyMatrices([[.8190224432164319,.3619062562801221,-.12887378261216414],[.0329836671980271,.9292868468965546,.03614466816999844],[.048177199566046255,.26423952494422764,.6335478258136937]],t);return multiplyMatrices([[.2104542553,.793617785,-.0040720468],[1.9779984951,-2.428592205,.4505937099],[.0259040371,.7827717662,-.808675766]],_.map((t=>Math.cbrt(t))))}
370+
*/function XYZ_to_OKLab(t){const _=multiplyMatrices([[.819022437996703,.3619062600528904,-.1288737815209879],[.0329836539323885,.9292868615863434,.0361446663506424],[.0481771893596242,.2642395317527308,.6335478284694309]],t);return multiplyMatrices([[.210454268309314,.7936177747023054,-.0040720430116193],[1.9779985324311684,-2.42859224204858,.450593709617411],[.0259040424655478,.7827717124575296,-.8086757549230774]],_.map((t=>Math.cbrt(t))))}
371371
/**
372372
* Convert an array of three XYZ values to u*,v* chromaticity coordinates
373373
*

packages/color-helpers/scripts/hashes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[
22
"384d52db3fcd98381e18743e1eba590a",
3-
"f736dea5b83ebcd853449a02255f747e",
3+
"b6577238c494767f36e2904d3edea5cb",
44
"094c9859b0960c4e394947cc4832b54f",
55
"c9e2f2a3b2cba543a01cb8aa5d77c04a",
66
"840ef26f992267c924230a26f939eaad",

packages/color-helpers/src/conversions/d50-to-d65.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { multiplyMatrices } from 'calculations/multiply-matrices';
1010
*/
1111
export function D50_to_D65(XYZ: Color): Color {
1212
const M = [
13-
[0.9554734527042182, -0.023098536874261423, 0.0632593086610217],
14-
[-0.028369706963208136, 1.0099954580058226, 0.021041398966943008],
15-
[0.012314001688319899, -0.020507696433477912, 1.3303659366080753],
13+
[0.955473421488075, -0.02309845494876471, 0.06325924320057072],
14+
[-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],
15+
[0.012314014864481998, -0.020507649298898964, 1.330365926242124],
1616
];
1717

1818
return multiplyMatrices(M, XYZ) as Color;

packages/color-helpers/src/conversions/d65-to-d50.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ export function D65_to_D50(XYZ: Color): Color {
1515
// - scale components from one reference white to another
1616
// - convert back to XYZ
1717
const M = [
18-
[1.0479298208405488, 0.022946793341019088, -0.05019222954313557],
19-
[0.029627815688159344, 0.990434484573249, -0.01707382502938514],
20-
[-0.009243058152591178, 0.015055144896577895, 0.7518742899580008],
18+
[1.0479297925449969, 0.022946870601609652, -0.05019226628920524],
19+
[0.02962780877005599, 0.9904344267538799, -0.017073799063418826],
20+
[-0.009243040646204504, 0.015055191490298152, 0.7518742814281371],
2121
];
2222

2323
return multiplyMatrices(M, XYZ) as Color;

packages/color-helpers/src/conversions/oklab-to-xyz.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import { multiplyMatrices } from 'calculations/multiply-matrices';
1313

1414
export function OKLab_to_XYZ(OKLab: Color): Color {
1515
const LMStoXYZ = [
16-
[1.2268798733741557, -0.5578149965554813, 0.28139105017721583],
17-
[-0.04057576262431372, 1.1122868293970594, -0.07171106666151701],
18-
[-0.07637294974672142, -0.4214933239627914, 1.5869240244272418],
16+
[1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
17+
[-0.0405757452148008, 1.1122868032803170, -0.0717110580655164],
18+
[-0.0763729366746601, -0.4214933324022432, 1.5869240198367816],
1919
];
2020
const OKLabtoLMS = [
21-
[0.99999999845051981432, 0.39633779217376785678, 0.21580375806075880339],
22-
[1.0000000088817607767, -0.1055613423236563494, -0.063854174771705903402],
23-
[1.0000000546724109177, -0.089484182094965759684, -1.2914855378640917399],
21+
[1.0000000000000000, 0.3963377773761749, 0.2158037573099136],
22+
[1.0000000000000000, -0.1055613458156586, -0.0638541728258133],
23+
[1.0000000000000000, -0.0894841775298119, -1.2914855480194092],
2424
];
2525

2626
const LMSnl = multiplyMatrices(OKLabtoLMS, OKLab) as Color;

packages/color-helpers/src/conversions/xyz-to-oklab.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import { multiplyMatrices } from 'calculations/multiply-matrices';
1212
export function XYZ_to_OKLab(XYZ: Color): Color {
1313
// Given XYZ relative to D65, convert to OKLab
1414
const XYZtoLMS = [
15-
[0.8190224432164319, 0.3619062562801221, -0.12887378261216414],
16-
[0.0329836671980271, 0.9292868468965546, 0.03614466816999844],
17-
[0.048177199566046255, 0.26423952494422764, 0.6335478258136937],
15+
[0.8190224379967030, 0.3619062600528904, -0.1288737815209879],
16+
[0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
17+
[0.0481771893596242, 0.2642395317527308, 0.6335478284694309],
1818
];
1919
const LMStoOKLab = [
20-
[0.2104542553, 0.7936177850, -0.0040720468],
21-
[1.9779984951, -2.4285922050, 0.4505937099],
22-
[0.0259040371, 0.7827717662, -0.8086757660],
20+
[0.2104542683093140, 0.7936177747023054, -0.0040720430116193],
21+
[1.9779985324311684, -2.4285922420485799, 0.4505937096174110],
22+
[0.0259040424655478, 0.7827717124575296, -0.8086757549230774],
2323
];
2424

2525
const LMS = multiplyMatrices(XYZtoLMS, XYZ) as Color;

packages/css-color-parser/test/basic/color-mix-function-oklch.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { serialize_OKLCH_data } from '../util/serialize.mjs';
66
const tests = [
77
['color-mix(in oklch, oklch(100% 0% 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 0)'],
88
['color-mix(in oklch, rgb(255, 255, 255), rgb(180, 6, 95))', 'oklch(0.75031 0.10016 359.858)'],
9-
['color-mix(in lch, oklch(75% 0% 60deg), oklch(75% 50% 0deg))', 'oklch(0.74979 0.09824 0.1059)'],
9+
['color-mix(in lch, oklch(75% 0% 60deg), oklch(75% 50% 0deg))', 'oklch(0.74979 0.09824 0.10588)'],
1010
['color-mix(in oklch, oklch(100% 0% none), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 0)'],
1111
['color-mix(in oklch, oklch(100% none 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.2 0)'],
1212
];

packages/css-color-parser/test/wpt/color-computed-lab.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const tests = [
4444
['oklab(0.2 0 0.1/50%)', 'rgba(31, 20, 0, 0.5)', 'color(display-p3 0.11443 0.08142 0 / 0.5)'],
4545
['oklab(4 0 0.1/50%)', 'rgba(255, 255, 255, 0.5)', 'color(display-p3 1 1 1 / 0.5)'],
4646
['oklab(0.5 -1.6 1.6)', 'rgb(53, 117, 0)', 'color(display-p3 0.25974 0.45977 0)'],
47-
['oklab(0.5 -2 2)', 'rgb(55, 117, 0)', 'color(display-p3 0.25973 0.45977 0)'],
47+
['oklab(0.5 -2 2)', 'rgb(55, 117, 0)', 'color(display-p3 0.25974 0.45977 0)'],
4848
['oklab(0 0 0 / -10%)', 'rgba(0, 0, 0, 0)', 'color(display-p3 0 0 0 / 0)'],
4949
['oklab(0 0 0 / 110%)', 'rgb(0, 0, 0)', 'color(display-p3 0 0 0)'],
5050
['oklab(0 0 0 / 300%)', 'rgb(0, 0, 0)', 'color(display-p3 0 0 0)'],

0 commit comments

Comments
 (0)