#![cfg_attr(feature = "libm", doc = "[libm]: libm")]
#![cfg_attr(not(feature = "libm"), doc = "[libm]: https://crates.io/crates/libm")]
#![warn(unused_crate_dependencies)]
#![warn(clippy::print_stdout, clippy::print_stderr)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![no_std]
pub mod cache_key;
mod chromaticity;
mod color;
mod colorspace;
mod dynamic;
mod flags;
mod gradient;
pub mod palette;
mod rgba8;
mod serialize;
mod tag;
mod x11_colors;
mod parse;
#[cfg(feature = "bytemuck")]
mod impl_bytemuck;
#[cfg(all(not(feature = "std"), not(test)))]
mod floatfuncs;
pub use chromaticity::Chromaticity;
pub use color::{AlphaColor, HueDirection, OpaqueColor, PremulColor};
pub use colorspace::{
A98Rgb, Aces2065_1, AcesCg, ColorSpace, ColorSpaceLayout, DisplayP3, Hsl, Hwb, Lab, Lch,
LinearSrgb, Oklab, Oklch, ProphotoRgb, Rec2020, Srgb, XyzD50, XyzD65,
};
pub use dynamic::{DynamicColor, Interpolator, UnpremultipliedInterpolator};
pub use flags::{Flags, Missing};
pub use gradient::{gradient, gradient_unpremultiplied, GradientIter, UnpremultipliedGradientIter};
pub use parse::{parse_color, parse_color_prefix, ParseError};
pub use rgba8::{PremulRgba8, Rgba8};
pub use tag::ColorSpaceTag;
const fn u8_to_f32(x: u8) -> f32 {
x as f32 * (1.0 / 255.0)
}
const fn matvecmul(m: &[[f32; 3]; 3], x: [f32; 3]) -> [f32; 3] {
[
m[0][0] * x[0] + m[0][1] * x[1] + m[0][2] * x[2],
m[1][0] * x[0] + m[1][1] * x[1] + m[1][2] * x[2],
m[2][0] * x[0] + m[2][1] * x[1] + m[2][2] * x[2],
]
}
const fn matmatmul(ma: &[[f32; 3]; 3], mb: &[[f32; 3]; 3]) -> [[f32; 3]; 3] {
[
[
ma[0][0] * mb[0][0] + ma[0][1] * mb[1][0] + ma[0][2] * mb[2][0],
ma[0][0] * mb[0][1] + ma[0][1] * mb[1][1] + ma[0][2] * mb[2][1],
ma[0][0] * mb[0][2] + ma[0][1] * mb[1][2] + ma[0][2] * mb[2][2],
],
[
ma[1][0] * mb[0][0] + ma[1][1] * mb[1][0] + ma[1][2] * mb[2][0],
ma[1][0] * mb[0][1] + ma[1][1] * mb[1][1] + ma[1][2] * mb[2][1],
ma[1][0] * mb[0][2] + ma[1][1] * mb[1][2] + ma[1][2] * mb[2][2],
],
[
ma[2][0] * mb[0][0] + ma[2][1] * mb[1][0] + ma[2][2] * mb[2][0],
ma[2][0] * mb[0][1] + ma[2][1] * mb[1][1] + ma[2][2] * mb[2][1],
ma[2][0] * mb[0][2] + ma[2][1] * mb[1][2] + ma[2][2] * mb[2][2],
],
]
}
const fn matdiagmatmul(ma: &[[f32; 3]; 3], mb: [f32; 3]) -> [[f32; 3]; 3] {
[
[ma[0][0] * mb[0], ma[0][1] * mb[1], ma[0][2] * mb[2]],
[ma[1][0] * mb[0], ma[1][1] * mb[1], ma[1][2] * mb[2]],
[ma[2][0] * mb[0], ma[2][1] * mb[1], ma[2][2] * mb[2]],
]
}
impl AlphaColor<Srgb> {
pub const fn from_rgba8(r: u8, g: u8, b: u8, a: u8) -> Self {
let components = [u8_to_f32(r), u8_to_f32(g), u8_to_f32(b), u8_to_f32(a)];
Self::new(components)
}
pub const fn from_rgb8(r: u8, g: u8, b: u8) -> Self {
let components = [u8_to_f32(r), u8_to_f32(g), u8_to_f32(b), 1.];
Self::new(components)
}
}
impl OpaqueColor<Srgb> {
pub const fn from_rgb8(r: u8, g: u8, b: u8) -> Self {
let components = [u8_to_f32(r), u8_to_f32(g), u8_to_f32(b)];
Self::new(components)
}
}
impl PremulColor<Srgb> {
pub const fn from_rgba8(r: u8, g: u8, b: u8, a: u8) -> Self {
let components = [u8_to_f32(r), u8_to_f32(g), u8_to_f32(b), u8_to_f32(a)];
Self::new(components)
}
pub const fn from_rgb8(r: u8, g: u8, b: u8) -> Self {
let components = [u8_to_f32(r), u8_to_f32(g), u8_to_f32(b), 1.];
Self::new(components)
}
}
#[cfg(feature = "libm")]
#[expect(unused, reason = "keep clippy happy")]
fn ensure_libm_dependency_used() -> f32 {
libm::sqrtf(4_f32)
}