Skip to content

Commit 3ba5741

Browse files
committed
use bikeshed file inclusion, not manual copy
1 parent 00f8468 commit 3ba5741

File tree

1 file changed

+4
-347
lines changed

1 file changed

+4
-347
lines changed

css-color-4/Overview.bs

Lines changed: 4 additions & 347 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,354 +2595,11 @@ Default Style Rules</h2>
25952595

25962596
<em>This section is not normative.</em>
25972597

2598-
<pre class="lang-javascript">
2599-
<!-- imported 30 Oct 2019-->
2600-
// Sample code for color conversions
2601-
// Conversion can also be done using ICC profiles and a Color Management System
2602-
// For clarity, a library is used for matrix manipulations
2603-
2604-
// sRGB-related functions
2605-
2606-
function lin_sRGB(RGB) {
2607-
// convert an array of sRGB values in the range 0.0 - 1.0
2608-
// to linear light (un-companded) form.
2609-
// https://en.wikipedia.org/wiki/SRGB
2610-
return RGB.map(function (val) {
2611-
if (val < 0.04045) {
2612-
return val / 12.92;
2613-
}
2614-
2615-
return Math.pow((val + 0.055) / 1.055, 2.4);
2616-
});
2617-
}
2618-
2619-
function gam_sRGB(RGB) {
2620-
// convert an array of linear-light sRGB values in the range 0.0-1.0
2621-
// to gamma corrected form
2622-
// https://en.wikipedia.org/wiki/SRGB
2623-
return RGB.map(function (val) {
2624-
if (val > 0.0031308) {
2625-
return 1.055 * Math.pow(val, 1/2.4) - 0.055;
2626-
}
2627-
2628-
return 12.92 * val;
2629-
});
2630-
}
2631-
2632-
function lin_sRGB_to_XYZ(rgb) {
2633-
// convert an array of linear-light sRGB values to CIE XYZ
2634-
// using sRGB's own white, D65 (no chromatic adaptation)
2635-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2636-
var M = math.matrix([
2637-
[0.4124564, 0.3575761, 0.1804375],
2638-
[0.2126729, 0.7151522, 0.0721750],
2639-
[0.0193339, 0.1191920, 0.9503041]
2640-
]);
2641-
2642-
return math.multiply(M, rgb).valueOf();
2643-
}
2644-
2645-
function XYZ_to_lin_sRGB(XYZ) {
2646-
// convert XYZ to linear-light sRGB
2647-
var M = math.matrix([
2648-
[ 3.2404542, -1.5371385, -0.4985314],
2649-
[-0.9692660, 1.8760108, 0.0415560],
2650-
[ 0.0556434, -0.2040259, 1.0572252]
2651-
]);
2652-
2653-
return math.multiply(M, XYZ).valueOf();
2654-
}
2655-
2656-
// image-3-related functions
2657-
2658-
2659-
function lin_P3(RGB) {
2660-
// convert an array of image-p3 RGB values in the range 0.0 - 1.0
2661-
// to linear light (un-companded) form.
2662-
2663-
return lin_sRGB(RGB); // same as sRGB
2664-
}
2665-
2666-
function gam_P3(RGB) {
2667-
// convert an array of linear-light image-p3 RGB in the range 0.0-1.0
2668-
// to gamma corrected form
2669-
2670-
return gam_sRGB(RGB); // same as sRGB
2671-
}
2672-
2673-
function lin_P3_to_XYZ(rgb) {
2674-
// convert an array of linear-light image-p3 values to CIE XYZ
2675-
// using D65 (no chromatic adaptation)
2676-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2677-
var M = math.matrix([
2678-
[0.4865709486482162, 0.26566769316909306, 0.1982172852343625],
2679-
[0.2289745640697488, 0.6917385218365064, 0.079286914093745],
2680-
[0.0000000000000000, 0.04511338185890264, 1.043944368900976]
2681-
]);
2682-
// 0 was computed as -3.972075516933488e-17
2683-
2684-
return math.multiply(M, rgb).valueOf();
2685-
}
2686-
2687-
function XYZ_to_lin_P3(XYZ) {
2688-
// convert XYZ to linear-light P3
2689-
var M = math.matrix([
2690-
[ 2.493496911941425, -0.9313836179191239, -0.40271078445071684],
2691-
[-0.8294889695615747, 1.7626640603183463, 0.023624685841943577],
2692-
[ 0.03584583024378447, -0.07617238926804182, 0.9568845240076872]
2693-
]);
2694-
2695-
return math.multiply(M, XYZ).valueOf();
2696-
}
2697-
2698-
// prophoto-rgb functions
2699-
2700-
function lin_ProPhoto(RGB) {
2701-
// convert an array of prophoto-rgb values in the range 0.0 - 1.0
2702-
// to linear light (un-companded) form.
2703-
// Transfer curve is gamma 1.8 with a small linear portion
2704-
return RGB.map(function (val) {
2705-
if (val < 0.031248) {
2706-
return val / 16;
2707-
}
2708-
2709-
return Math.pow(val, 1.8);
2710-
});
2711-
}
2712-
2713-
function gam_ProPhoto(RGB) {
2714-
// convert an array of linear-light prophoto-rgb in the range 0.0-1.0
2715-
// to gamma corrected form
2716-
// Transfer curve is gamma 1.8 with a small linear portion
2717-
return RGB.map(function (val) {
2718-
if (val > 0.001953) {
2719-
return Math.pow(val, 1/1.8);
2720-
}
2721-
2722-
return 16 * val;
2723-
});
2724-
}
2725-
2726-
function lin_ProPhoto_to_XYZ(rgb) {
2727-
// convert an array of linear-light prophoto-rgb values to CIE XYZ
2728-
// using D50 (so no chromatic adaptation needed afterwards)
2729-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2730-
var M = Math.matrix([
2731-
[ 0.7977604896723027, 0.13518583717574031, 0.0313493495815248 ],
2732-
[ 0.2880711282292934, 0.7118432178101014, 0.00008565396060525902 ],
2733-
[ 0.0, 0.0, 0.8251046025104601 ]
2734-
]);
2735-
2736-
return Math.multiply(M, rgb).valueOf();
2737-
}
2738-
2739-
function XYZ_to_lin_ProPhoto(XYZ) {
2740-
// convert XYZ to linear-light prophoto-rgb
2741-
var M = Math.matrix([
2742-
[ 1.3457989731028281, -0.25558010007997534, -0.05110628506753401 ],
2743-
[ -0.5446224939028347, 1.5082327413132781, 0.02053603239147973 ],
2744-
[ 0.0, 0.0, 1.2119675456389454 ]
2745-
]);
2746-
2747-
return Math.multiply(M, XYZ).valueOf();
2748-
}
2749-
2750-
// a98-rgb functions
2751-
2752-
function lin_a98rgb(RGB) {
2753-
// convert an array of a98-rgb values in the range 0.0 - 1.0
2754-
// to linear light (un-companded) form.
2755-
return RGB.map(function (val) {
2756-
return Math.pow(val, 563/256);
2757-
});
2758-
}
2759-
2760-
function gam_a98rgb(RGB) {
2761-
// convert an array of linear-light a98-rgb in the range 0.0-1.0
2762-
// to gamma corrected form
2763-
return RGB.map(function (val) {
2764-
return Math.pow(val, 256/563);
2765-
});
2766-
}
2767-
2768-
function lin_a98rgb_to_XYZ(rgb) {
2769-
// convert an array of linear-light a98-rgb values to CIE XYZ
2770-
// using D50 (so no chromatic adaptation needed afterwards)
2771-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2772-
// which has greater numerical precsion than section 4.3.5.3 of
2773-
// https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
2774-
var M = Math.matrix([
2775-
[ 0.5766690429101305, 0.1855582379065463, 0.1882286462349947 ],
2776-
[ 0.29734497525053605, 0.6273635662554661, 0.07529145849399788 ],
2777-
[ 0.02703136138641234, 0.07068885253582723, 0.9913375368376388 ]
2778-
]);
2779-
2780-
return Math.multiply(M, rgb).valueOf();
2781-
}
2782-
2783-
function XYZ_to_lin_a98rgb(XYZ) {
2784-
// convert XYZ to linear-light a98-rgb
2785-
var M = Math.matrix([
2786-
[ 2.0415879038107465, -0.5650069742788596, -0.34473135077832956 ],
2787-
[ -0.9692436362808795, 1.8759675015077202, 0.04155505740717557 ],
2788-
[ 0.013444280632031142, -0.11836239223101838, 1.0151749943912054 ]
2789-
]);
2790-
2791-
return Math.multiply(M, XYZ).valueOf();
2792-
}
2793-
2794-
//Rec. 2020-related functions
2795-
2796-
function lin_2020(RGB) {
2797-
// convert an array of rec-2020 RGB values in the range 0.0 - 1.0
2798-
// to linear light (un-companded) form.
2799-
const α = 1.09929682680944 ;
2800-
const β = 0.018053968510807;
2801-
2802-
return RGB.map(function (val) {
2803-
if (val < β * 4.5 ) {
2804-
return val / 4.5;
2805-
}
2806-
2807-
return Math.pow((val + α -1 ) / α, 2.4);
2808-
});
2809-
}
2810-
//check with standard this really is 2.4 and 1/2.4, not 0.45 was wikipedia claims
2811-
2812-
function gam_2020(RGB) {
2813-
// convert an array of linear-light rec-2020 RGB in the range 0.0-1.0
2814-
// to gamma corrected form
2815-
const α = 1.09929682680944 ;
2816-
const β = 0.018053968510807;
2817-
2818-
return RGB.map(function (val) {
2819-
if (val > β ) {
2820-
return α * Math.pow(val, 1/2.4) - (α - 1);
2821-
}
2822-
2823-
return 4.5 * val;
2824-
});
2825-
}
2826-
2827-
function lin_2020_to_XYZ(rgb) {
2828-
// convert an array of linear-light rec-2020 values to CIE XYZ
2829-
// using D65 (no chromatic adaptation)
2830-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2831-
var M = math.matrix([
2832-
[0.6369580483012914, 0.14461690358620832, 0.1688809751641721],
2833-
[0.2627002120112671, 0.6779980715188708, 0.05930171646986196],
2834-
[0.000000000000000, 0.028072693049087428, 1.060985057710791]
2835-
]);
2836-
// 0 is actually calculated as 4.994106574466076e-17
2837-
2838-
return math.multiply(M, rgb).valueOf();
2839-
}
2840-
2841-
function XYZ_to_lin_2020(XYZ) {
2842-
// convert XYZ to linear-light rec-2020
2843-
var M = math.matrix([
2844-
[1.7166511879712674, -0.35567078377639233, -0.25336628137365974],
2845-
[-0.6666843518324892, 1.6164812366349395, 0.01576854581391113],
2846-
[0.017639857445310783, -0.042770613257808524, 0.9421031212354738]
2847-
]);
2848-
2849-
return math.multiply(M, XYZ).valueOf();
2850-
}
2851-
2852-
// Chromatic adaptation
2853-
2854-
function D65_to_D50(XYZ) {
2855-
// Bradford chromatic adaptation from D65 to D50
2856-
// The matrix below is the result of three operations:
2857-
// - convert from XYZ to retinal cone domain
2858-
// - scale components from one reference white to another
2859-
// - convert back to XYZ
2860-
// http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
2861-
var M = math.matrix([
2862-
[ 1.0478112, 0.0228866, -0.0501270],
2863-
[ 0.0295424, 0.9904844, -0.0170491],
2864-
[-0.0092345, 0.0150436, 0.7521316]
2865-
]);
2866-
2867-
return math.multiply(M, XYZ).valueOf();
2868-
}
2869-
2870-
function D50_to_D65(XYZ) {
2871-
// Bradford chromatic adaptation from D50 to D65
2872-
var M = math.matrix([
2873-
[ 0.9555766, -0.0230393, 0.0631636],
2874-
[-0.0282895, 1.0099416, 0.0210077],
2875-
[ 0.0122982, -0.0204830, 1.3299098]
2876-
]);
2877-
2878-
return math.multiply(M, XYZ).valueOf();
2879-
}
2880-
2881-
// Lab and LCH
2882-
2883-
function XYZ_to_Lab(XYZ) {
2884-
// Assuming XYZ is relative to D50, convert to CIE Lab
2885-
// from CIE standard, which now defines these as a rational fraction
2886-
var ε = 216/24389; // 6^3/29^3
2887-
var κ = 24389/27; // 29^3/3^3
2888-
var white = [0.96422, 1.00000, 0.82521]; // D50 reference white
2889-
2890-
// compute xyz, which is XYZ scaled relative to reference white
2891-
var xyz = XYZ.map((value, i) => value / white[i]);
2892-
2893-
// now compute f
2894-
var f = xyz.map(value => value > ε ? Math.cbrt(value) : (κ * value + 16)/116);
2895-
2896-
return [
2897-
(116 * f[1]) - 16, // L
2898-
500 * (f[0] - f[1]), // a
2899-
200 * (f[1] - f[2]) // b
2900-
];
2901-
}
2902-
2903-
function Lab_to_XYZ(Lab) {
2904-
// Convert Lab to D50-adapted XYZ
2905-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
2906-
var κ = 24389/27; // 29^3/3^3
2907-
var ε = 216/24389; // 6^3/29^3
2908-
var white = [0.96422, 1.00000, 0.82521]; // D50 reference white
2909-
var f = [];
2910-
2911-
// compute f, starting with the luminance-related term
2912-
f[1] = (Lab[0] + 16)/116;
2913-
f[0] = Lab[1]/500 + f[1];
2914-
f[2] = f[1] - Lab[2]/200;
2915-
2916-
// compute xyz
2917-
var xyz = [
2918-
Math.pow(f[0],3) > ε ? Math.pow(f[0],3) : (116*f[0]-16)/κ,
2919-
Lab[0] > κ * ε ? Math.pow((Lab[0]+16)/116,3) : Lab[0]/κ,
2920-
Math.pow(f[2],3) > ε ? Math.pow(f[2],3) : (116*f[2]-16)/κ
2921-
];
2922-
2923-
// Compute XYZ by scaling xyz by reference white
2924-
return xyz.map((value, i) => value * white[i]);
2925-
}
2926-
2927-
function Lab_to_LCH(Lab) {
2928-
// Convert to polar form
2929-
var hue = Math.atan2(Lab[2], Lab[1]) * 180 / Math.PI;
2930-
return [
2931-
Lab[0], // L is still L
2932-
Math.sqrt(Math.pow(Lab[1], 2) + Math.pow(Lab[2], 2)), // Chroma
2933-
hue >= 0 ? hue : hue + 360 // Hue, in degrees [0 to 360)
2934-
];
2935-
}
2936-
2937-
function LCH_to_Lab(LCH) {
2938-
// Convert from polar form
2939-
return [
2940-
LCH[0], // L is still L
2941-
LCH[1] * Math.cos(LCH[2] * Math.PI / 180), // a
2942-
LCH[1] * Math.sin(LCH[2] * Math.PI / 180) // b
2943-
];
2944-
}
2598+
For clarity, a library is used for matrix multiplication.
29452599

2600+
<pre class="include-code lang-javascript">
2601+
path: conversions.js
2602+
highlight: js
29462603
</pre>
29472604

29482605
<h2 id="deprecated-system-colors" class="no-num">

0 commit comments

Comments
 (0)