use rgb::RGB8;
pub fn hsv_to_rgb(hue: u8, saturation: u8, value: u8) -> RGB8 {
if saturation == 0 {
return RGB8::new(value, value, value);
}
let h = hue as u16 * 6;
let sector = (h >> 8) as u8; let fraction = (h & 0xFF) as u8;
let s = saturation as u16;
let v = value as u16;
let p = ((v * (255 - s)) / 255) as u8;
let q = ((v * (255 - (s * fraction as u16) / 255)) / 255) as u8;
let t = ((v * (255 - (s * (255 - fraction as u16)) / 255)) / 255) as u8;
match sector {
0 => RGB8::new(value, t, p), 1 => RGB8::new(q, value, p), 2 => RGB8::new(p, value, t), 3 => RGB8::new(p, q, value), 4 => RGB8::new(t, p, value), _ => RGB8::new(value, p, q), }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_red_at_hue_0() {
let color = hsv_to_rgb(0, 255, 255);
assert_eq!(color, RGB8::new(255, 0, 0));
}
#[test]
fn test_green_at_hue_85() {
let color = hsv_to_rgb(85, 255, 255);
assert!(color.g > color.r);
assert!(color.g > color.b);
assert_eq!(color.g, 255);
}
#[test]
fn test_blue_at_hue_170() {
let color = hsv_to_rgb(170, 255, 255);
assert!(color.b > color.r);
assert!(color.b > color.g);
assert_eq!(color.b, 255);
}
#[test]
fn test_white_with_zero_saturation() {
let color = hsv_to_rgb(0, 0, 255);
assert_eq!(color, RGB8::new(255, 255, 255));
}
#[test]
fn test_gray_with_zero_saturation() {
let color = hsv_to_rgb(0, 0, 128);
assert_eq!(color, RGB8::new(128, 128, 128));
}
#[test]
fn test_black_with_zero_value() {
let color = hsv_to_rgb(0, 255, 0);
assert_eq!(color, RGB8::new(0, 0, 0));
}
#[test]
fn test_black_with_any_hue_zero_value() {
for hue in [0, 42, 85, 128, 170, 213, 255] {
let color = hsv_to_rgb(hue, 255, 0);
assert_eq!(color, RGB8::new(0, 0, 0), "hue {} should be black", hue);
}
}
#[test]
fn test_half_brightness_red() {
let color = hsv_to_rgb(0, 255, 128);
assert_eq!(color.r, 128);
assert_eq!(color.g, 0);
assert_eq!(color.b, 0);
}
#[test]
fn test_half_saturation_red() {
let color = hsv_to_rgb(0, 128, 255);
assert_eq!(color.r, 255);
assert!(color.g > 100 && color.g < 140);
assert!(color.b > 100 && color.b < 140);
}
#[test]
fn test_hue_wraps_around() {
let color_255 = hsv_to_rgb(255, 255, 255);
let color_0 = hsv_to_rgb(0, 255, 255);
assert!(color_255.r > 200);
assert_eq!(color_0.r, 255);
}
}