pub trait ColorSpace:
Clone
+ Copy
+ 'static {
const WHITE_COMPONENTS: [f32; 3];
const IS_LINEAR: bool = false;
const LAYOUT: ColorSpaceLayout = ColorSpaceLayout::Rectangular;
const TAG: Option<ColorSpaceTag> = None;
const WHITE_POINT: Chromaticity = Chromaticity::D65;
// Required methods
fn to_linear_srgb(src: [f32; 3]) -> [f32; 3];
fn from_linear_srgb(src: [f32; 3]) -> [f32; 3];
fn clip(src: [f32; 3]) -> [f32; 3];
// Provided methods
fn convert<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3] { ... }
fn to_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3] { ... }
fn from_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3] { ... }
fn convert_absolute<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3] { ... }
fn chromatically_adapt(
src: [f32; 3],
from: Chromaticity,
to: Chromaticity,
) -> [f32; 3] { ... }
fn scale_chroma(src: [f32; 3], scale: f32) -> [f32; 3] { ... }
}
Expand description
The main trait for color spaces.
This can be implemented by clients for conversions in and out of new color spaces. It is expected to be a zero-sized type.
The linear sRGB color space is central, and other color spaces are defined as conversions in and out of that. A color space does not explicitly define a gamut, so generally conversions will succeed and round-trip, subject to numerical precision.
White point is handled implicitly in the general conversion methods. For color spaces with a
white point other than D65 (the native white point for sRGB), use a linear Bradford chromatic
adaptation, following CSS Color 4. The conversion methods suffixed with _absolute
do not
perform chromatic adaptation.
See the XYZ-D65 color space documentation for some background information on color spaces.
§Implementing ColorSpace
When implementing a custom color space, take care to set the associated constants correctly. The following is an example implementation of the Rec. 709 color space.
Note:
ColorSpace::convert
can be implemented to specialize specific conversions;- implement
ColorSpace::scale_chroma
if your color space has a natural representation of chroma.
use color::{ColorSpace, ColorSpaceLayout};
/// The Rec. 709 color space, using the electro-optical transfer function
/// defined in ITU-R BT.1886.
///
/// Rec. 709 is very similar to sRGB, having the same natural gamut, but
/// does have a different transfer function.
///
/// See https://www.color.org/chardata/rgb/BT709.xalter.
#[derive(Clone, Copy, Debug)]
pub struct Rec709;
impl ColorSpace for Rec709 {
const IS_LINEAR: bool = false;
const LAYOUT: ColorSpaceLayout = ColorSpaceLayout::Rectangular;
const WHITE_COMPONENTS: [f32; 3] = [1., 1., 1.];
fn to_linear_srgb(src: [f32; 3]) -> [f32; 3] {
src.map(|x| x.powf(2.4))
}
fn from_linear_srgb(src: [f32; 3]) -> [f32; 3] {
src.map(|x| x.powf(1. / 2.4))
}
fn clip([r, g, b]: [f32; 3]) -> [f32; 3] {
[r.clamp(0., 1.), g.clamp(0., 1.), b.clamp(0., 1.)]
}
}
Required Associated Constants§
Sourceconst WHITE_COMPONENTS: [f32; 3]
const WHITE_COMPONENTS: [f32; 3]
The component values for the color white within this color space.
Provided Associated Constants§
Sourceconst IS_LINEAR: bool = false
const IS_LINEAR: bool = false
Whether the color space is linear.
Calculations in linear color spaces can sometimes be simplified, for example it is not necessary to undo premultiplication when converting.
Sourceconst LAYOUT: ColorSpaceLayout = ColorSpaceLayout::Rectangular
const LAYOUT: ColorSpaceLayout = ColorSpaceLayout::Rectangular
The layout of the color space.
The layout primarily identifies the hue channel for cylindrical color spaces, which is important because hue is not premultiplied.
Sourceconst TAG: Option<ColorSpaceTag> = None
const TAG: Option<ColorSpaceTag> = None
The tag corresponding to this color space, if a matching tag exists.
Sourceconst WHITE_POINT: Chromaticity = Chromaticity::D65
const WHITE_POINT: Chromaticity = Chromaticity::D65
The white point of the color space.
See the XYZ-D65 color space documentation for some background information on the meaning of “white point.”
Required Methods§
Sourcefn to_linear_srgb(src: [f32; 3]) -> [f32; 3]
fn to_linear_srgb(src: [f32; 3]) -> [f32; 3]
Convert an opaque color to linear sRGB.
Values are likely to exceed [0, 1] for wide-gamut and HDR colors.
This performs chromatic adaptation from the source color space’s reference white to the
target color space’s reference white; see the XYZ-D65 color space documentation
for some background information on the meaning of “reference white.” Use
ColorSpace::to_linear_srgb_absolute
to convert the absolute color instead.
Sourcefn from_linear_srgb(src: [f32; 3]) -> [f32; 3]
fn from_linear_srgb(src: [f32; 3]) -> [f32; 3]
Convert an opaque color from linear sRGB.
In general, this method should not do any gamut clipping.
Sourcefn clip(src: [f32; 3]) -> [f32; 3]
fn clip(src: [f32; 3]) -> [f32; 3]
Clip the color’s components to fit within the natural gamut of the color space.
There are many possible ways to map colors outside of a color space’s gamut to colors inside the gamut. Some methods are perceptually better than others (for example, preserving the mapped color’s hue is usually preferred over preserving saturation). This method will generally do the mathematically simplest thing, namely clamping the individual color components’ values to the color space’s natural limits of those components, bringing out-of-gamut colors just onto the gamut boundary. The resultant color may be perceptually quite distinct from the original color.
§Examples
use color::{ColorSpace, Srgb, XyzD65};
assert_eq!(Srgb::clip([0.4, -0.2, 1.2]), [0.4, 0., 1.]);
assert_eq!(XyzD65::clip([0.4, -0.2, 1.2]), [0.4, -0.2, 1.2]);
Provided Methods§
Sourcefn convert<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3]
fn convert<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3]
Convert to a different color space.
The default implementation is a no-op if the color spaces
are the same, otherwise converts from the source to linear
sRGB, then from that to the target. Implementations are
encouraged to specialize further (using the TypeId
of
the color spaces), effectively finding a shortest path in
the conversion graph.
Sourcefn to_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3]
fn to_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3]
Convert an opaque color to linear sRGB, without chromatic adaptation.
For most use-cases you should consider using the chromatically-adapting
ColorSpace::to_linear_srgb
instead.
Values are likely to exceed [0, 1] for wide-gamut and HDR colors.
This does not perform chromatic adaptation from the source color space’s reference white to sRGB’s standard reference white; thereby representing the same absolute color in sRGB. See the XYZ-D65 color space documentation for some background information on the meaning of “reference white.”
§Note to implementers
The default implementation undoes the chromatic adaptation performed by
ColorSpace::to_linear_srgb
. This can be overridden for better performance and greater
calculation accuracy.
Sourcefn from_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3]
fn from_linear_srgb_absolute(src: [f32; 3]) -> [f32; 3]
Convert an opaque color from linear sRGB, without chromatic adaptation.
For most use-cases you should consider using the chromatically-adapting
ColorSpace::from_linear_srgb
instead.
In general, this method should not do any gamut clipping.
This does not perform chromatic adaptation to the destination color space’s reference white from sRGB’s standard reference white; thereby representing the same absolute color in the target color space. See the XYZ-D65 color space documentation for some background information on the meaning of “reference white.”
§Note to implementers
The default implementation undoes the chromatic adaptation performed by
ColorSpace::from_linear_srgb
. This can be overridden for better performance and greater
calculation accuracy.
Sourcefn convert_absolute<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3]
fn convert_absolute<TargetCS: ColorSpace>(src: [f32; 3]) -> [f32; 3]
Convert to a different color space, without chromatic adaptation.
For most use-cases you should consider using the chromatically-adapting
ColorSpace::convert
instead.
This does not perform chromatic adaptation from the source color space’s reference white to the destination color space’s reference white; thereby representing the same absolute color in the destination color space. See the XYZ-D65 color space documentation for some background information on the meaning of “reference white.”
The default implementation is a no-op if the color spaces are the same, otherwise converts
from the source to linear sRGB, then from that to the target, without chromatic adaptation.
Implementations are encouraged to specialize further (using the TypeId
of the color
spaces), effectively finding a shortest path in the conversion graph.
Sourcefn chromatically_adapt(
src: [f32; 3],
from: Chromaticity,
to: Chromaticity,
) -> [f32; 3]
fn chromatically_adapt( src: [f32; 3], from: Chromaticity, to: Chromaticity, ) -> [f32; 3]
Chromatically adapt the color between the given white point chromaticities.
The color is assumed to be under a reference white point of from
and is chromatically
adapted to the given white point to
. The linear Bradford transform is used to perform the
chromatic adaptation.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.