1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//! Prisma - The Rust Color Library
//! ===============================
//!
//! ## Table of Contents:
//! * [**Overview**](#overview)
//! - [**Color Models**](#color-models)
//! - [**Why Prisma?**](#why-prisma)
//! - [**A Tour by Example**](#a-tour-by-example)
//! * [**Details**](#details)
//! * [**Definitions**](#definitions)
//!
//! <a name="overview"></a>
//! ## Overview:
//! Prisma is a rust library aimed to be a comprehensive set of color representations, manipulations,
//! conversions and algorithms that are easy to use for projects of all levels. Prisma follows a model
//! of "opt-in" complexity, meaning that if you just want a library to convert from Rgb to Hsv and back,
//! prisma will let you do it with minimal knowledge of color science. If you need to access the CIE spaces
//! or do color space conversions however, prisma also provides that functionality with wrappers to
//! use the type system to enforce validity.
//!
//! Prisma aims to be the go-to source for color conversions and color science in rust. It is currently
//! a work in progress, and any contributions or feature requests are appreciated.
//!
//! <a name="color-models"></a>
//! ### Color Models:
//!
//! Currently prisma supports the following color models:
//!
//! #### Device Dependent:
//! * **[`Rgb`](struct.Rgb.html)** - The standard color model for displays
//! * **[`Rgi`](struct.Rgi.html)** - A chromaticity model constructed from Rgb that decouples chromaticity and lightness
//! * **[`Hsv`](struct.Hsv.html)** - Hue, saturation, value: a more intuitive polar Rgb model
//! * **[`Hsl`](struct.Hsl.html)** - Hue, saturation, lightness: an alternate to Hsv fulfilling similar roles
//! * **[`Hsi`](struct.Hsi.html)** - Hue, saturation, intensity: a hue-based model without distortion
//! * **[`eHsi`](struct.eHsi.html)** - An extension to `Hsi` that rescaled saturation to avoid going out of gamut in Rgb
//! * **[`Hwb`](struct.Hwb.html)** - Hue, whiteness, blackness: a hue-based model made to be easy for users to select colors in
//! * **[`YCbCr`](ycbcr/struct.YCbCr.html)** - A representation of the various YUV and YIQ models used in display and broadcast
//!
//! #### Device Independent:
//! * **[`Xyz`](struct.Xyz.html)** - The "parent" absolute color space other color spaces are defined in terms of
//! * **[`Lms`](lms/struct.Lms.html)** - A color space simulating human cone response
//! * **[`Lab`](struct.Lab.html)** - A uniform perception color space transformation of XYZ
//! * **[`Lchab`](struct.Lchab.html)** - A polar transformation of Lab. A uniform perception analog of Hsl
//! * **[`Luv`](struct.Luv.html)** - An alternative uniform perception color space useful in lighting calculations
//! * **[`Lchuv`](struct.Lchuv.html)** - A polar transformation of Luv
//!
//! Prisma also supports these color spaces with an alpha channel via the [`Alpha`](struct.Alpha.html) type.
//!
//! <a name="why-prisma"></a>
//! ### Why Prisma?
//! Currently, there are two main color libraries for rust:
//!
//! * **color** -- `color` is a very old library that hasn't been updated in several years. While it
//! works for conversion through a few color spaces, and is easy to use, it has a very minimal set of features.
//!
//! * **palette** -- `palette` has significantly more features and can go into a few of the CIE spaces,
//! but requiring all computations to be done in linear encoding is a serious drawback, as if you just
//! want a nice looking gradient in a game, linear Hsv will *not* get you that. It also is built on
//! predefined models and doesn't support dynamic configuration. `prisma` supports
//! considerably more color spaces, as well as multiple encodings and spaces which can be built
//! at runtime. `prisma` also does not require you to specify a color space, as most applications
//! don't really care and use the device color space or sRgb.
//!
//! Prisma aims to support all the features of the above libraries, while making it up to the user how
//! much complexity they need.
//!
//! <a name="a-tour-by-example"></a>
//! ### A Tour by Example:
//!
//! ##### Converting from Rgb to Hsv, manipulating hue, and converting back
//!
//! ```rust
//! #[macro_use] extern crate approx;
//! extern crate angular_units as angle;
//! # extern crate prisma;
//!
//! use prisma::{Rgb, Hsv, FromColor};
//! use angle::Deg;
//!
//! let rgb = Rgb::new(0.5, 0.75, 1.0);
//! let mut hsv = Hsv::from_color(&rgb);
//! hsv.set_hue(Deg(180.0));
//! let rgb = Rgb::from_color(&hsv);
//! assert_relative_eq!(rgb, Rgb::new(0.5, 1.0, 1.0), epsilon=1e-6);
//! ```
//!
//! ##### Interpolating between two colors in Hsl.
//!
//! ```rust
//! #[macro_use] extern crate approx;
//! extern crate angular_units as angle;
//! # extern crate prisma;
//!
//! use prisma::{Rgb, Hsl, FromColor, Lerp};
//! use angle::Deg;
//!
//! let rgb1 = Rgb::new(0.8, 0.25, 0.0f32);
//! let rgb2 = Rgb::new(0.5, 0.66, 1.0);
//! // Specify the hue channel should use degrees
//! let hsl1: Hsl<_, Deg<f32>> = Hsl::from_color(&rgb1);
//! let hsl2 = Hsl::from_color(&rgb2);
//! // Note that hue channels will interpolate in the shortest direction. This is usually
//! // the expected behavior, but you can always go forward with `lerp_flat`.
//! let rgb_out = Rgb::from_color(&hsl1.lerp(&hsl2, 0.35));
//! assert_relative_eq!(rgb_out, Rgb::new(1.0, 0.045, 0.62648), epsilon=1e-4);
//! ```
//!
//! ##### Converting from Rgb<u8> to Rgb<f32>
//!
//! ```rust
//! #[macro_use] extern crate approx;
//! # extern crate prisma;
//!
//! use prisma::Rgb;
//!
//! let rgb_in = Rgb::new(100, 200, 255u8);
//! let rgb_out: Rgb<f32> = rgb_in.color_cast();
//! assert_relative_eq!(rgb_out, Rgb::new(0.39216, 0.78431, 1.0), epsilon=1e-4);
//! ```
//!
//! ##### Convert from sRgb encoded to linear encoded Rgb
//!
//! ```rust
//! #[macro_use] extern crate approx;
//! # extern crate prisma;
//!
//! use prisma::Rgb;
//! use prisma::encoding::{EncodableColor, TranscodableColor, SrgbEncoding};
//!
//! // This returns a `EncodedColor<Rgb<f32>, SrgbEncoding>`
//! // Note: no encodind is done. `srgb_encoded` says that this value is already in sRgb encoding.
//! let rgb_srgb = Rgb::new(0.5, 1.0, 0.25f32).srgb_encoded();
//! // Decode goes from an encoding to linear.
//! let rgb_linear = rgb_srgb.clone().decode();
//! assert_relative_eq!(rgb_linear, Rgb::new(0.21404, 1.0, 0.05088).linear(), epsilon=1e-4);
//! // We can then go back with `encode`
//! let rgb_out = rgb_linear.encode(SrgbEncoding);
//! assert_relative_eq!(rgb_out, rgb_srgb, epsilon=1e-6);
//! ```
//!
//! ##### Going to XYZ
//!
//! ```rust
//! #[macro_use] extern crate approx;
//! # extern crate prisma;
//!
//! use prisma::{Rgb, Xyz};
//! use prisma::encoding::{EncodableColor, TranscodableColor};
//! use prisma::color_space::{ColorSpace, EncodedColorSpace, ConvertToXyz};
//! use prisma::color_space::named::SRgb;
//!
//! let rgb = Rgb::new(0.25, 0.5, 0.75f32).srgb_encoded();
//! let color_space = SRgb::new();
//! // In this case, since rgb and color_space know their own encodings, the conversion to linear
//! // is automatic.
//! let xyz = color_space.convert_to_xyz(&rgb);
//! assert_relative_eq!(xyz, Xyz::new(0.191803, 0.201605, 0.523050), epsilon=1e-5);
//! ```
//! <a name="definitions"></a>
extern crate angular_units as angle;
pub use crate;
pub use crate;
pub use crateChromaticityCoordinates;
pub use crate;
pub use crateeHsi;
pub use crate;
pub use crateHsl;
pub use crateHsv;
pub use crateHwb;
pub use crateLab;
pub use crateLchab;
pub use crateLchuv;
pub use crateMatrix3;
pub use crateLuv;
pub use crateRgb;
pub use crateRgi;
pub use crateXyY;
pub use crateXyz;