colorimetry/lib.rs
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2// Copyright (c) 2024-2025, Harbers Bik LLC
3
4/*!
5This is a Rust library for working with color and light — great for projects in lighting, imaging, or anything that needs accurate color handling.
6It includes tools to simulate how colors look under different lights, convert between color spaces, and follow well-known standards from groups like the CIE, ICC, and IES.
7You can use it to build lighting tools, visualize spectra, or get the right transforms for your color profiles.
8
9It also has early support for JavaScript and WebAssembly, so you can run it in the browser, and use it with JavaScript Runtimes such as Deno.
10
11# Usage
12
13To use this library in a Rust application, run the command:
14
15 ```bash
16 cargo add colorimetry
17```
18
19or add this line to the dependencies in your Cargo.toml file:
20
21```text
22 colorimetry = "0.0.7"
23```
24
25# Examples
26
27<details>
28<summary><strong>Calculate Tristimulus Values for Illuminants</strong></summary>
29
30This example calculates the XYZ tristimulus values of the D65 illuminant for both the CIE 1931 2º standard observer and the CIE 2015 10º observer.
31
32```
33 use colorimetry::illuminant::D65;
34# use approx::assert_abs_diff_eq as check;
35
36 // D65 Tristimulus values, using the CIE1931 standard observer by default
37 let xyz_d65 = D65.xyz(None).set_illuminance(100.0);
38
39 let [x, y, z] = xyz_d65.values();
40 // [95.04, 100.0, 108.86]
41# check!([x, y, z].as_ref(), [95.04, 100.0, 108.86].as_ref(), epsilon = 5E-3);
42
43 // D65 Tristimulus values using the CIE2015 10º observer
44 use colorimetry::observer::Observer::Cie2015_10;
45 let xyz_d65_10 = D65
46 .xyz(Some(Cie2015_10)).set_illuminance(100.0);
47
48 let [x_10, y_10, z_10] = xyz_d65_10.values();
49 //[94.72, 100.0, 107.143]
50# check!([x_10, y_10, z_10].as_ref(), [94.72, 100.0, 107.143].as_ref(), epsilon = 5E-3);
51```
52
53</details>
54
55<details>
56<summary><strong>Calculate Correlated Color Temperature and Tint</strong></summary>
57
58The correlated color temperature (CCT) of an illuminant, typically expressed in kelvin (K),
59describes whether a light source appears warm (low CCT) or cool (high CCT). It is a key parameter
60for characterizing the visual appearance of white light .
61This example calculates both the correlated color temperature and the deviation from the Planckian
62locus, often referred to as the tint.
63
64```
65# #[cfg(feature="cie-illuminants")]
66 use colorimetry::illuminant::A;
67# use approx::assert_abs_diff_eq as check;
68
69 // Calculate CCT and Duv for the A illuminant
70 // Requires `cct`, and `cie-illuminants` features
71# #[cfg(all(feature="cct", feature="cie-illuminants"))]
72 let [cct, duv] = A.cct().unwrap().values();
73# #[cfg(all(feature="cct", feature="cie-illuminants"))]
74# check!([cct, duv].as_ref(), [2855.4977, 0.0].as_ref(), epsilon = 5E-4);
75 // [2855.4977, 0.0]
76```
77
78</details>
79
80<details>
81<summary><strong>Calculate Color Fidelity Index for Illuminants</strong></summary>
82
83The CIE has announced that the Color Fidelity Index (CFI) will replace the Color Rendering Index
84(CRI) as the standard metric for evaluating color rendering. Both indices aim to quantify how
85accurately a light source reproduces the colors of illuminated objects. However, the CFI offers a
86significant improvement in accuracy by using 99 reference color samples and more advanced color
87difference metrics, compared to the CRI’s use of only 8 samples.
88Below is an example calculation of the general Color Fidelity Index for the CIE F2 illuminant:
89
90```
91# #[cfg(feature = "cie-illuminants")]
92 use colorimetry::illuminant::F2;
93# use approx::assert_abs_diff_eq as check;
94
95# #[cfg(all(feature = "cfi", feature = "cie-illuminants"))]
96# {
97 // Calculate the Color Fidelity Index of the CIE F2 standard illuminant
98 // Requires `cfi`, and `cie-illuminants` features
99 let cf_f2 = F2.cfi().unwrap();
100 let cf = cf_f2.general_color_fidelity_index();
101 // 70.3
102# check!(cf, 70.3, epsilon = 1E-1);
103# }
104```
105
106</details>
107
108<details>
109
110<summary><strong>Calculate Spectral Locus to Plot in Diagrams</strong></summary>
111
112The spectral locus is the boundary in a chromaticity diagram that encloses all perceivable,
113physically realizable colors. Due to its shape, it is sometimes informally referred to as the
114"horseshoe."
115Below, we compute the chromaticity coordinates that define the spectral locus.
116
117```
118 use colorimetry::observer::Observer::Cie1931;
119 let mut locus = Vec::new();
120 let wavelength_range = Cie1931.spectral_locus_wavelength_range();
121 for wavelength in wavelength_range {
122 // unwrap OK because nm is in range
123 let xyz = Cie1931.xyz_at_wavelength(wavelength).unwrap();
124 let chromaticity = xyz.chromaticity();
125 locus.push([wavelength as f64, chromaticity.x(), chromaticity.y()]);
126 }
127 println!("{locus:?}");
128```
129
130</details>
131
132<details>
133<summary><strong>Calculate XYZ/RGB Transformation Matrices, for any Observer, for use in Color Profiles</strong></summary>
134
135This is usually done with the CIE 1931 Standard Observer, but this library supports any observer—as long as both the color space and the data use the same one.
136Instead of fixed XYZ values, it computes conversions from the spectral definitions of the primaries to be able to do so.
137Here, we compute transformation matrices for the `DisplayP3` color space using both the `Cie1931` and `Cie2015` observers.
138
139```
140# use approx::assert_abs_diff_eq as check;
141 use colorimetry::observer::Observer;
142 use colorimetry::rgb::RgbSpace::DisplayP3;
143
144 let xyz2rgb_31 = Observer::Cie1931.xyz2rgb_matrix(DisplayP3);
145# let want31 = nalgebra::Matrix3::new(
146# 2.4933, -0.9313, -0.4027,
147# -0.8298, 1.7629, 0.0236,
148# 0.0355, -0.076, 0.9574
149# );
150# check!(xyz2rgb_31, &want31, epsilon=5E-4);
151 // 2.4933, -0.9313, -0.4027,
152 // -0.8298, 1.7629, 0.0236,
153 // 0.0355, -0.076, 0.9574
154
155 let rgb2xyz_31 = Observer::Cie1931.rgb2xyz_matrix(DisplayP3);
156# let want31inv = nalgebra::Matrix3::new(
157# 0.4866, 0.2656, 0.1981,
158# 0.2291, 0.6917, 0.0792,
159# 0.0001, 0.0451, 1.0433,
160# );
161# check!(rgb2xyz_31, &want31inv, epsilon=5E-4);
162 // 0.4866, 0.2656, 0.1981,
163 // 0.2291, 0.6917, 0.0792,
164 // 0.0001, 0.0451, 1.0433,
165
166 use colorimetry::observer::Observer::Cie2015;
167
168 let xyz2rgb_15 = Cie2015.xyz2rgb_matrix(DisplayP3).clone();
169# let want15 = nalgebra::Matrix3::new(
170# 2.5258, -1.0009, -0.3649,
171# -0.9006, 1.8546, -0.0011,
172# 0.0279, -0.0574, 0.95874
173# );
174# check!(xyz2rgb_15, want15, epsilon=5E-4);
175 // 2.5258, -1.0009, -0.3649,
176 // -0.9006, 1.8546, -0.0011,
177 // 0.0279, -0.0574, 0.95874
178```
179
180</details>
181
182<details>
183<summary><strong>Find the closest spectral match in the Munsell Color Book</strong></summary>
184
185This example finds the best matching color in the Munsell Color Book for a given sample—in this case, the R9 test color used in the CRI color rendering method.
186It uses the `CieCam16::de_ucs` color difference metric and the `Cie2015_10` standard observer to calculate perceptual similarity.
187
188The closest match identified is Munsell "5R 5/14", a vivid red hue, with a color difference of just 3 ΔE.
189In practical terms, a ΔE of 3 is considered a close match—just at the threshold where most observers might start to notice a difference under controlled viewing conditions.
190
191```
192# #[cfg(all(feature= "cri", feature = "munsell"))]
193# {
194# use approx::assert_abs_diff_eq as check;
195 // requires `cri` and `munsell` features
196 use colorimetry::observer::Observer::Cie2015_10;
197 use colorimetry::colorant::{MunsellCollection, TCS};
198
199 let cri_r9 = &TCS[8];
200 let (key, delta_e) = MunsellCollection::match_ciecam16(
201 cri_r9,
202 None,
203 None,
204 Some(Cie2015_10),
205 ).unwrap();
206# assert_eq!(key, "5R4/14");
207# check!(delta_e, 2.85, epsilon = 5e-2);
208 // ("5R4/14", 2.85)
209# }
210```
211
212</details>
213
214<details>
215<summary><strong>Match a paint color to a <i>sRGB</i> display value under realistic viewing conditions</strong></summary>
216
217This example matches the Munsell paint chip <i>5 BG 5/8</i>—a teal/blue-green color—
218to its nearest <i>sRGB</i>
219<span style="display: inline-block; width: 1em; height: 1em; background-color: rgb(0, 113, 138);
220border-radius: 50%; vertical-align: middle; border: 1px solid #000;"></span>
221<span>rgb(0, 113, 138)</span>
222equivalent, mimicking real-world viewing conditions.
223
224Instead of the traditional <i>CIE 1931 2°</i> observer, this match uses the <i>CIE 2015 10° observer</i>,
225which more accurately reflects how paint colors appear on walls. The illumination is based on the warm-white
226<i>LED_B2</i> standard illuminant (≈ 3000 K). Together, these adjustments help the display color reflect
227what you'd actually see on a freshly painted surface.
228
229```
230# #[cfg(all(feature = "munsell", feature = "cie-illuminants"))]
231# {
232 // requires `cie-illuminants`, and `munsell` features
233 use colorimetry::{
234 cam::{ViewConditions, CIE248_HOME_SCREEN},
235 colorant::Munsell,
236 illuminant::LED_B2,
237 observer::Observer::{Cie1931, Cie2015_10},
238 rgb::RgbSpace::SRGB,
239 };
240
241 let paint = Munsell::try_new("5BG5/8").unwrap();
242 let vc = ViewConditions::average_surround(6.0);
243 let cam_paint = Cie2015_10.ciecam16(&LED_B2, &paint, vc);
244 let rgb_2015 = cam_paint
245 .rgb(SRGB, Some(CIE248_HOME_SCREEN))
246 .unwrap()
247 .compress();
248
249 // Use a spectral representation of the Cie2015_10 RGB pixel, using the `Rgb`'s Light trait,
250 // and calculate its XYZ tristimulus and RGB values for the CIE 1931 standard observer, the
251 // observer
252 // required for the sRGB color space.
253 let xyz_1931 = Cie1931.xyz(&rgb_2015, None);
254 let rgb_1931 = xyz_1931.rgb(SRGB).compress();
255 let [r, g, b]: [u8; 3] = rgb_1931.into();
256 // (0, 113, 138)
257# assert!(r == 0 && g == 113 && b == 138);
258# }
259```
260
261</details>
262
263# Capabilities
264
265- Uses a Standard fixed-grid spectral representation [`Spectrum`], with a wavelength domain ranging from 380 to 780 nanometers, with 1-nanometer intervals, ensuring high precision in capturing fine spectral details critical for accurate colorimetry calculations.
266
267 - Uses [`nalgebra`] vector and matrix types for fast integration and transformations, chosen for its high performance, numerical stability, and compatibility with other mathematical libraries.
268 - Supports interpolation from irregular spectral data using [`Spectrum::linear_interpolate`] and [`Spectrum::sprague_interpolate`].
269 - Optional smoothing using a Gaussian filter via [`Spectrum::smooth`], which is typically used to reduce noise in spectral data or to smooth out irregularities in measured spectra for better analysis.
270
271- Generate spectral distributions from analytical models:
272
273 - [`Illuminant::planckian`] Planck’s law for blackbody radiators
274 - [`Illuminant::led`] Spectral power distribution of a LED
275 - [`Colorant::gaussian`] Gaussian color filters
276 - [`Stimulus::from_rgb`] Spectral distribution of an RGB color pixel using Gaussian spectral primaries
277
278- Includes Spectral Representations CIE Standard Illuminants (optional):
279
280 - Daylight: [`D65`], [`D50`]
281 - Incandescent: [`A`]
282 - Fluorescent: [`F1`], [`F2`], [`F3`], [`F4`], [`F5`], [`F6`], [`F7`], [`F8`], [`F9`], [`F10`], [`F11`], [`F12`]
283 - Extended fluorescent set: [`F3_1`], [`F3_2`], [`F3_3`], [`F3_4`], [`F3_5`], [`F3_6`], [`F3_7`], [`F3_8`], [`F3_9`], [`F3_10`], [`F3_11`], [`F3_12`], [`F3_13`], [`F3_14`], [`F3_15`]
284 - LED: [`LED_B1`], [`LED_B2`], [`LED_B3`], [`LED_B4`], [`LED_B5`], [`LED_BH1`], [`LED_RGB1`], [`LED_V1`]
285
286- Includes Various Colorant Collections (optional):
287
288 - Munsell Color System [`MunsellCollection`], with over 1,000 colors
289 - Color Evaluation Samples [`CES`], a set of 99 test colors used in the Color Fidelity Index (CFI) calculations
290
291- Calculate Illuminant metrics:
292
293 - [`CCT`] Correlated color temperature, including distance to the blackbody locus for tint indication[^1]
294 - [`CRI`] Color rendering index[^2]
295 - [`CFI`] Color fidelity index[^3]
296
297- Use Advanced color (appearance) models:
298
299 - [`CieLab`], [`CieCam02`], [`CieCam16`]
300 - Color difference methods: [`CieLab::ciede`], [`CieLab::ciede2000`], [`CieCam02::de_ucs`], [`CieCam16::de_ucs`]
301
302- Work with Spectrally based RGB color spaces, with support for non-CIE 1931 observers and generic transformations between [`Rgb`] and [`XYZ`]:
303
304 - RGB Color Spaces [`RgbSpace::SRGB`], [`RgbSpace::Adobe`], [`RgbSpace::DisplayP3`]
305 - Define RGB colors using spectral primaries, allowing switching observers
306
307- Includes Multiple CIE Standard Observers (see [`Observer`]), with transformations to [`XYZ`]:
308
309 - [`Observer::Cie1931`] the CIE 1931 2º standard observer
310 - [`Observer::Cie1964`] the CIE 1964 10º standard observer (optional, enabled by default)1
311 - [`Observer::Cie2015`] the CIE 2015 2º cone fundamentals-based observer (optional, enabled by default)
312 - [`Observer::Cie2015_10`] the CIE 2015 10º cone fundamentals-based observer (optional, enabled by default)
313
314- Compute gamut boundaries for CIE XYZ ([`RelXYZGamut`]) and CIELAB ([`CieLChGamut`]) using optimal colors ([`OptimalColors`]).
315
316 - Estimate the total number of perceptually distinct colors.
317 - Plot CIE LCh iso-hue lines and iso-lightness contours on chromaticity diagrams.
318 - Plot maximum luminance value contours on chromaticity diagrams.
319 - Use in hue-neutral gamut-compression algorithms.
320
321[^1]: McCamy, C. S. (1992). Correlated color temperature as an explicit function of chromaticity coordinates. Color Research & Application, 17(2), 142-144.
322[^2]: Wyszecki, G., & Stiles, W. S. (2000). Color science: concepts and methods, quantitative data and formulae. John Wiley & Sons.
323[^3]: Li, C., Luo, M. R., & Cui, G. (2020). The CIE 2017 colour fidelity index for accurate scientific use. Optics express, 28(5), 6589-6609.
324
325# Features
326
327- `cie-illuminants`
328 The `D65` and `D50` illuminants are always included - if you want to use one of the other CIE illuminants, set this feature flag.
329- `munsell`
330 Include reflection spectra for Munsell colors.
331
332- `cct`
333 Calculates correlated color temperatures (CCT) for illuminants.
334 Generates a 4096-entry lookup table (each entry containing three `f64` values).
335 Memory is reserved at compile time but computed on demand.
336 (Included automatically if the `cri` feature is enabled).
337
338- `cri`
339 Enables Color Rendering Index (CRI) calculations, providing Ra and R1–R14 values for illuminants.
340 Loads an additional 14 test color sample spectra.
341
342- `cfi`
343 Enables Color Fidelity Index (CRI) calculations, providing R<sub>f</sub> and R<sub>f,1</sub>–R<sub>f,99</sub> values for illuminants.
344 Loads the 99 CES test color sample spectra.
345
346<details>
347<summary>How to enable a feature?</summary>
348
349To enable a feature, such as `cri` and `munsell`, use
350
351```bash
352cargo add colorimetry -F cri,munsell
353```
354
355or, if you prefer to use the `cargo add` command with the `--features` flag, you can run:
356
357```bash
358cargo add colorimetry --features cri,munsell
359```
360
361Alternatively, configure features manually in your `Cargo.toml`:
362
363```toml
364colorimetry = { version = "0.0.7", features = ["cri", "munsell"] }
365```
366
367</details>
368
369# Command Line Tool
370
371This library has an associated command-line tool, named `color`, contained in the "colorimetry-cli" crate.
372It provides a convenient way to perform colorimetric calculations, convert spectral data, and make color plots directly from the terminal.
373
374To use it you have to install it using `cargo`, which in turn requires that you have Rust and Cargo installed.
375Install them first by following the instructions at <https://www.rust-lang.org/tools/install>.
376After having done this, run the following command:
377
378```bash
379cargo install colorimetry-cli
380```
381
382That should be it, you can now use the `color` command in your terminal.
383Run the following command to see the available options and features for the `colorimetry` tool:
384```bash
385color --help
386```
387
388# Color Plots
389
390The `colorimetry` library includes a plotting module, in an associated `colorimetry-plot` crate
391that can be used to generate a number of color diagrams, spectral plots, and color rendering visulizations.
392It's ouput is in SVG format, which can be viewed in any modern web browser or vector graphics editor, such as Inkscape.
393The `colorimetry-plot` crate is not included by default, so you need to add it to your project using the following command:
394
395```bash
396cargo add colorimetry-plot
397```
398You can then use the `colorimetry-plot` crate to generate color plots.
399
400# Developer Tasks with `xtask`
401
402This project uses a Rust-based `xtask` utility for common development tasks:
403
404- `cargo xtask check` – to run clippy, fmt, check, and readme verification,
405- `cargo xtask test` – test various feature configurations,
406- `cargo xtask doc` – build and open project documentation (fails on warnings), and,
407- `cargo xtask wasm` – to generate the web-assembly files in `pkg` (requires `wasm-pack` and `wasm-opt`)
408
409More commands will be added as the project evolves.
410
411# License
412
413All content ©2025 Harbers Bik LLC, and licensed under either of the
414
415- Apache License, Version 2.0,
416 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>), or the
417- MIT license
418 [LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>,
419
420at your option.
421
422# Contribution
423
424Unless you explicitly state otherwise, any Contribution intentionally submitted
425for inclusion in the Work by you, as defined in the Apache-2.0 license, shall be
426dual licensed as above, without any additional terms or conditions.
427
428[`nalgebra`]:https://docs.rs/nalgebra/latest/nalgebra/
429[`Spectrum`]: https://docs.rs/colorimetry/latest/colorimetry/spectrum/struct.Spectrum.html
430[`Spectrum::linear_interpolate`]: https://docs.rs/colorimetry/latest/colorimetry/spectrum/struct.Spectrum.html#method.linear_interpolate
431[`Spectrum::sprague_interpolate`]: https://docs.rs/colorimetry/latest/colorimetry/spectrum/struct.Spectrum.html#method.sprague_interpolate
432[`Spectrum::smooth`]: https://docs.rs/colorimetry/latest/colorimetry/spectrum/struct.Spectrum.html#method.smooth
433[`Illuminant::planckian`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/struct.Illuminant.html#method.planckian
434[`Illuminant::led`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/struct.Illuminant.html#method.led
435[`CieLab`]: https://docs.rs/colorimetry/latest/colorimetry/lab/struct.CieLab.html
436[`CieLab::ciede`]: https://docs.rs/colorimetry/latest/colorimetry/lab/struct.CieLab.html#method.ciede
437[`CieLab::ciede2000`]: https://docs.rs/colorimetry/latest/colorimetry/lab/struct.CieLab.html#method.ciede2000
438[`CieCam02`]: https://docs.rs/colorimetry/latest/colorimetry/cam/struct.CieCam02.html
439[`CieCam02::de_ucs`]: https://docs.rs/colorimetry/latest/colorimetry/cam/struct.CieCam02.html#method.de_ucs
440[`CieCam16`]: https://docs.rs/colorimetry/latest/colorimetry/cam/struct.CieCam16.html
441[`CieCam16::de_ucs`]: https://docs.rs/colorimetry/latest/colorimetry/cam/struct.CieCam16.html#method.de_ucs
442[`CCT`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/struct.CCT.html
443[`CRI`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/struct.CRI.html
444[`CFI`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/struct.CFI.html
445[`Colorant::gaussian`]: https://docs.rs/colorimetry/latest/colorimetry/colorant/struct.Colorant.html#method.gaussian
446[`Stimulus::from_rgb`]: https://docs.rs/colorimetry/latest/colorimetry/stimulus/struct.Stimulus.html#method.from_rgb
447[`Observer`]: https://docs.rs/colorimetry/latest/colorimetry/observer/enum.Observer.html
448[`Observer::Cie1931`]: https://docs.rs/colorimetry/latest/colorimetry/observer/enum.Observer.html#variant.Cie1931
449[`Observer::Cie1964`]: https://docs.rs/colorimetry/latest/colorimetry/observer/enum.Observer.html#variant.Cie1964
450[`Observer::Cie2015`]: https://docs.rs/colorimetry/latest/colorimetry/observer/enum.Observer.html#variant.Ci2015e
451[`Observer::Cie2015_10`]: https://docs.rs/colorimetry/latest/colorimetry/observer/enum.Observer.html#variant.Cie2015_10
452[`XYZ`]: https://docs.rs/colorimetry/latest/colorimetry/xyz/struct.XYZ.html
453[`Rgb`]: https://docs.rs/colorimetry/latest/colorimetry/rgb/struct.RGB.html
454[`RgbSpace::SRGB`]: https://docs.rs/colorimetry/latest/colorimetry/rgb/enum.RgbSpace.html#variant.SRGB
455[`RgbSpace::Adobe`]: https://docs.rs/colorimetry/latest/colorimetry/rgb/enum.RgbSpace.html#variant.Adobe
456[`RgbSpace::DisplayP3`]: https://docs.rs/colorimetry/latest/colorimetry/rgb/enum.RgbSpace.html#variant.DisplayP3
457[`CieLChGamut`]: https://docs.rs/colorimetry/latest/colorimetry/lab/struct.CieLchGamut.html
458[`RelXYZGamut`]: https://docs.rs/colorimetry/latest/colorimetry/xyz/struct.RelXYZGamut.html
459[`OptimalColors`]: https://docs.rs/colorimetry/latest/colorimetry/observer/struct.OptimalColors.html
460
461[`CES`]: https://docs.rs/colorimetry/latest/colorimetry/colorant/static.CES.html
462[`MunsellCollection`]: https://docs.rs/colorimetry/latest/colorimetry/colorant/struct.MunsellCollection.html
463
464[`D65`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.D65.html
465[`D50`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.D50.html
466[`A`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.A.html
467[`F1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F1.html
468[`F2`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F2.html
469[`F3`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3.html
470[`F4`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F4.html
471[`F5`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F5.html
472[`F6`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F6.html
473[`F7`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F7.html
474[`F8`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F8.html
475[`F9`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F9.html
476[`F10`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F10.html
477[`F11`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F11.html
478[`F12`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F12.html
479[`F3_1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_1.html
480[`F3_2`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_2.html
481[`F3_3`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_3.html
482[`F3_4`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_4.html
483[`F3_5`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_5.html
484[`F3_6`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_6.html
485[`F3_7`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_7.html
486[`F3_8`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_8.html
487[`F3_9`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_9.html
488[`F3_10`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_10.html
489[`F3_11`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_11.html
490[`F3_12`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_12.html
491[`F3_13`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_13.html
492[`F3_14`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_14.html
493[`F3_15`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.F3_15.html
494[`LED_B1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_B1.html
495[`LED_B2`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_B2.html
496[`LED_B3`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_B3.html
497[`LED_B4`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_B4.html
498[`LED_B5`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_B5.html
499[`LED_BH1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_BH1.html
500[`LED_RGB1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_RGB1.html
501[`LED_V1`]: https://docs.rs/colorimetry/latest/colorimetry/illuminant/static.LED_V1.html
502
503*/
504
505// This library defines many floating-point constants for colorimetry.
506// Clippy's `approx_constant` lint would otherwise generate numerous false positives
507// by flagging constants close to standard values.
508// To suppress these, `#![allow(clippy::approx_constant)]` is applied.
509#![allow(clippy::approx_constant)]
510
511pub mod cam;
512pub mod colorant;
513mod error;
514pub mod illuminant;
515pub mod lab;
516pub mod math;
517pub mod observer;
518pub mod rgb;
519pub mod spectrum;
520pub mod stimulus;
521pub mod traits;
522pub mod xyz;
523
524pub use error::Error;