use image::Rgb;
const ONE_HALF: f32 = 1.0 / 2.0;
const ONE_THIRD: f32 = 1.0 / 3.0;
const TWO_THIRD: f32 = 2.0 / 3.0;
const ONE_SIXTH: f32 = 1.0 / 6.0;
const fn convert_color_component(value: f32) -> u8 {
(value * 255.0 + 0.5) as u8
}
const fn convert_color_components(red: f32, green: f32, blue: f32) -> [u8; 3] {
[
convert_color_component(red),
convert_color_component(green),
convert_color_component(blue),
]
}
fn hue_to_rgb(a: f32, b: f32, hue: f32) -> f32 {
let hue = if hue < 0.0 {
hue + 1.0
} else if hue > 1.0 {
hue - 1.0
} else {
hue
};
if hue < ONE_SIXTH {
a + (b - a) * 6.0 * hue
} else if hue < ONE_HALF {
b
} else if hue < TWO_THIRD {
a + (b - a) * (TWO_THIRD - hue) * 6.0
} else {
a
}
}
pub(crate) fn convert_hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> Rgb<u8> {
let hue = hue / 360.0;
let saturation = saturation / 100.0;
let lightness = lightness / 100.0;
let b = if lightness <= 0.5 {
lightness * (saturation + 1.0)
} else {
lightness + saturation - lightness * saturation
};
let a = lightness * 2.0 - b;
let red = hue_to_rgb(a, b, hue + ONE_THIRD);
let green = hue_to_rgb(a, b, hue);
let blue = hue_to_rgb(a, b, hue - ONE_THIRD);
Rgb {
data: convert_color_components(red, green, blue),
}
}
#[test]
fn test_convert_hsl_to_rgb_black() {
let rgb = convert_hsl_to_rgb(0.0, 0.0, 0.0);
assert_eq!(rgb.data, [0, 0, 0]);
}
#[test]
fn test_convert_hsl_to_rgb_white() {
let rgb = convert_hsl_to_rgb(0.0, 0.0, 100.0);
assert_eq!(rgb.data, [255, 255, 255]);
}
#[test]
fn test_convert_hsl_to_rgb_red() {
let rgb = convert_hsl_to_rgb(0.0, 100.0, 50.0);
assert_eq!(rgb.data, [255, 0, 0]);
}
#[test]
fn test_convert_hsl_to_rgb_green() {
let rgb = convert_hsl_to_rgb(120.0, 100.0, 50.0);
assert_eq!(rgb.data, [0, 255, 0]);
}
#[test]
fn test_convert_hsl_to_rgb_blue() {
let rgb = convert_hsl_to_rgb(240.0, 100.0, 50.0);
assert_eq!(rgb.data, [0, 0, 255]);
}