diff --git a/src/color/hsv.rs b/src/color/hsv.rs index 41537c1..65b2fe0 100644 --- a/src/color/hsv.rs +++ b/src/color/hsv.rs @@ -45,36 +45,32 @@ impl ToHSV for HSV { impl ToRGB for HSV { pub fn to_rgb(&self) -> RGB { - to_rgb(self.to_hsv::()).to_rgb::() + // Algorithm taken from the Wikipedia article on HSL and HSV: + // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV + + let chr = (*self).v * (*self).s; + let h = (*self).h / num::cast(60); + + // the 2nd largest component + let x = chr * (one!(T) - ((h % two!(T)) - one!(T)).abs()); + + let mut rgb = cond! ( + (h < num::cast(1)) { RGB::new(chr.clone(), x, zero!(T)) } + (h < num::cast(2)) { RGB::new(x, chr.clone(), zero!(T)) } + (h < num::cast(3)) { RGB::new(zero!(T), chr.clone(), x) } + (h < num::cast(4)) { RGB::new(zero!(T), x, chr.clone()) } + (h < num::cast(5)) { RGB::new(x, zero!(T), chr.clone()) } + (h < num::cast(6)) { RGB::new(chr.clone(), zero!(T), x) } + _ { RGB::new(zero!(T), zero!(T), zero!(T)) } + ); + + // match the value by adding the same amount to each component + let mn = (*self).v - chr; + + rgb.r = rgb.r + mn; + rgb.g = rgb.g + mn; + rgb.b = rgb.b + mn; + + rgb.to_rgb::() } } - -priv fn to_rgb(color: HSV) -> RGB { - // Algorithm taken from the Wikipedia article on HSL and HSV: - // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV - - let chr = color.v * color.s; - let h = color.h / num::cast(60); - - // the 2nd largest component - let x = chr * (one!(T) - ((h % two!(T)) - one!(T)).abs()); - - let mut color_rgb = cond! ( - (h < num::cast(1)) { RGB::new(chr.clone(), x, zero!(T)) } - (h < num::cast(2)) { RGB::new(x, chr.clone(), zero!(T)) } - (h < num::cast(3)) { RGB::new(zero!(T), chr.clone(), x) } - (h < num::cast(4)) { RGB::new(zero!(T), x, chr.clone()) } - (h < num::cast(5)) { RGB::new(x, zero!(T), chr.clone()) } - (h < num::cast(6)) { RGB::new(chr.clone(), zero!(T), x) } - _ { RGB::new(zero!(T), zero!(T), zero!(T)) } - ); - - // match the value by adding the same amount to each component - let mn = color.v - chr; - - color_rgb.r = color_rgb.r + mn; - color_rgb.g = color_rgb.g + mn; - color_rgb.b = color_rgb.b + mn; - - color_rgb -} diff --git a/src/color/rgb.rs b/src/color/rgb.rs index 0156724..2c9c5e0 100644 --- a/src/color/rgb.rs +++ b/src/color/rgb.rs @@ -44,33 +44,31 @@ impl ToRGB for RGB { } } -impl ToHSV for RGB { +impl ToHSV for RGB { #[inline] pub fn to_hsv(&self) -> HSV { - to_hsv(self.to_rgb::()) - } -} - -priv fn to_hsv(color: RGB) -> HSV { - // Algorithm taken from the Wikipedia article on HSL and HSV: - // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV - - let mx = color.r.max(&color.g).max(&color.b); - let mn = color.r.min(&color.g).min(&color.b); - let chr = mx - mn; - - if chr != zero!(T) { - let h = cond! ( - (color.r == mx) { ((color.g - color.b) / chr) % num::cast(6) } - (color.g == mx) { ((color.b - color.r) / chr) + num::cast(2) } - _ /* color.b == mx */ { ((color.r - color.g) / chr) + num::cast(4) } - ) * num::cast(60); - - let s = chr / mx; - - HSV::new(h, s, mx) - - } else { - HSV::new(zero!(T), zero!(T), mx) + // Algorithm taken from the Wikipedia article on HSL and HSV: + // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV + + let rgb_u = self.to_rgb::(); + + let mx = rgb_u.r.max(&rgb_u.g).max(&rgb_u.b); + let mn = rgb_u.r.min(&rgb_u.g).min(&rgb_u.b); + let chr = mx - mn; + + if chr != zero!(U) { + let h = cond! ( + (rgb_u.r == mx) { ((rgb_u.g - rgb_u.b) / chr) % num::cast(6) } + (rgb_u.g == mx) { ((rgb_u.b - rgb_u.r) / chr) + num::cast(2) } + _ /* rgb_u.b == mx */ { ((rgb_u.r - rgb_u.g) / chr) + num::cast(4) } + ) * num::cast(60); + + let s = chr / mx; + + HSV::new(h, s, mx) + + } else { + HSV::new(zero!(U), zero!(U), mx) + } } }