farbraum/lib.rs
1#![allow(clippy::float_cmp)]
2
3//! # farbraum
4//!
5//! Rust crate to convert between color spaces. "Farbraum"
6//! [/ˈfarbraʊ̯m/](http://ipa-reader.xyz/?text=%CB%88farbra%CA%8A%CC%AFm&voice=Marlene)
7//! is German for "color space".
8//!
9//! Most conversion functions are ported from the [culori](https://culorijs.org)
10//! javascript library. Some parts were modified to make the results more accurate.
11//!
12//! ## Usage
13//!
14//! Colors are created with `Color::new()`, the last argument is the color space.
15//! The `.into()` method is used to convert between color spaces:
16//!
17//! ```
18//! use farbraum::{Color, spaces::{Srgb, LinearSrgb, Hsv}};
19//!
20//! let hsv = Color::new(120.0, 1.0, 1.0, Hsv);
21//! let lrgb = hsv.into(Srgb).into(LinearSrgb);
22//! let (r, g, b) = lrgb.tuple();
23//! ```
24//!
25//! ## Color spaces
26//!
27//! Farbraum supports 24 color spaces:
28//!
29//! * sRGB, Linear sRGB
30//! * Adobe RGB (1998)
31//! * CMY, CMYK<sup>1</sup>
32//! * sRGB-derived color spaces (HSL, HSV, HSI, HWB)
33//! * CIE XYZ (supports D50 and D65 illumination)
34//! * CIELAB, CIELCh (supports D50 and D65 illumination)
35//! * CIELUV, CIELCh<sub>uv</sub> (D50 illumination)
36//! * Oklab, Oklch
37//! * DIN99 Lab, DIN99 LCh
38//! * J<sub>z</sub>a<sub>z</sub>b<sub>z</sub>, J<sub>z</sub>C<sub>z</sub>h<sub>z</sub>
39//! * Cubehelix
40//!
41//! All color spaces use the
42//! [D65 standard illuminate](https://en.wikipedia.org/wiki/Illuminant_D65)
43//! unless stated otherwise. CIE XYZ, CIELAB and CIELCh are available
44//! with both D50 and D65 illuminant.
45//!
46//! <sup>1</sup> Since CMYK has 4 components instead of 3, it must be
47//! represented as a tuple instead of a `Color`. Use the `{to,from}_cmyk()`
48//! methods to convert between `Color<CMY>` and `(C, M, Y, K)`.
49//!
50//! ## Dynamic color spaces
51//!
52//! The color spaces are zero-sized types, so they don't exist at runtime. If you
53//! want to choose a color space at runtime, you'll need to create an enum such as:
54//!
55//! ```
56//! #[derive(Debug, Clone, Copy)]
57//! enum AnyColorSpace {
58//! CieXyzD50,
59//! Srgb,
60//! Hsl,
61//! CieLabD50,
62//! OkLab,
63//! }
64//! ```
65//!
66//! This can be used instead of the `farbraum`'s builtin color spaces. However,
67//! you'll need to implement conversions for this enum to make it useful:
68//!
69//! ```
70//! use farbraum::{
71//! Color, illuminate::D50,
72//! spaces::{Srgb, CieXyz, Hsl, CieLab, OkLab},
73//! };
74//! #
75//! # #[derive(Debug, Clone, Copy)]
76//! # enum AnyColorSpace {
77//! # CieXyzD50,
78//! # Srgb,
79//! # Hsl,
80//! # CieLabD50,
81//! # OkLab,
82//! # }
83//!
84//! // Convert any color space to sRGB
85//! fn any_to_srgb(any: Color<AnyColorSpace>) -> Color<Srgb> {
86//! let (a, b, c) = any.tuple();
87//! match any.space() {
88//! AnyColorSpace::Srgb => Color::new(a, b, c, Srgb),
89//! AnyColorSpace::CieXyzD50 => Color::new(a, b, c, CieXyz(D50)).into(Srgb),
90//! AnyColorSpace::Hsl => Color::new(a, b, c, Hsl).into(Srgb),
91//! AnyColorSpace::CieLabD50 => Color::new(a, b, c, CieLab(D50)).into(Srgb),
92//! AnyColorSpace::OkLab => Color::new(a, b, c, OkLab).into(Srgb),
93//! }
94//! }
95//! ```
96//!
97//! ## Cargo features
98//!
99//! - `double-precision`: Components are floating-point values, by default `f64`. If
100//! you disable the `double-precision` feature, `f32` is used instead.
101//! - `serde`: Enable this feature to serialize and deserialize `Color` values.
102//!
103//! ## License
104//!
105//! Dual-licensed under the **Apache 2.0** and **MIT** license.
106
107#[cfg(feature = "double-precision")]
108macro_rules! float {
109 () => {
110 f64
111 };
112 ($lit:literal) => {
113 $lit as f64
114 };
115 ($constant:ident) => {
116 std::f64::consts::$constant
117 };
118}
119
120#[cfg(not(feature = "double-precision"))]
121macro_rules! float {
122 () => {
123 f32
124 };
125 ($lit:literal) => {
126 $lit as f32
127 };
128 ($constant:ident) => {
129 std::f32::consts::$constant
130 };
131}
132
133#[cfg(test)]
134mod test_util;
135
136mod color;
137
138/// The color component type, `f64` by default.
139///
140/// If you disable the `double-precision` feature, `f32` is used instead.
141pub type Float = float!();
142pub use color::Color;
143
144pub mod illuminate;
145pub mod spaces;
146
147/// Trait for color space conversions.
148pub trait Into<SPACE> {
149 fn into(self, space: SPACE) -> Color<SPACE>;
150}