diff options
Diffstat (limited to 'meowpp/colors/HSV.hpp')
-rw-r--r-- | meowpp/colors/HSV.hpp | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/meowpp/colors/HSV.hpp b/meowpp/colors/HSV.hpp new file mode 100644 index 0000000..f7a3004 --- /dev/null +++ b/meowpp/colors/HSV.hpp @@ -0,0 +1,131 @@ +#include "HSV.h" + +#include "RGB.h" +#include "YUV.h" +#include "HSL.h" + +#include "../utility.h" + +namespace meow{ + template<class T> + inline HSV<T>::HSV(){ } + template<class T> + inline HSV<T>::HSV(T const& h, T const& s, T const& v){ + hsv_[0] = h; hsv_[1] = s; hsv_[2] = v; + } + template<class T> + inline HSV<T>::HSV(T const* hsv){ + for(int i = 0; i < 3; i++) hsv_[i] = hsv[i]; + } + + template<class T> + inline T HSV<T>::h() const { return hsv_[0]; } + template<class T> + inline T HSV<T>::s() const { return hsv_[1]; } + template<class T> + inline T HSV<T>::v() const { return hsv_[2]; } + template<class T> + inline T HSV<T>::hsv(size_t i) const { + return hsv_[std::min((size_t)3 - 1, i)]; + } + template<class T> + inline T HSV<T>::vsh(size_t i)const{return hsv(2-i);} + template<class T> + inline T HSV<T>::h(T const& val){return (hsv_[0]=val);} + template<class T> + inline T HSV<T>::s(T const& val){return (hsv_[1]=val);} + template<class T> + inline T HSV<T>::v(T const& val){return (hsv_[2]=val);} + template<class T> + inline T HSV<T>::hsv(size_t i, T const& val){ + return (hsv_[std::min((size_t)3 - 1, i)] = val); + } + template<class T> + inline T HSV<T>::vsh(size_t i, T const& val){ + return hsv(2 - i, val); + } + + + + + + inline HSVf:: HSVf(): HSV(){ } + inline HSVf::~HSVf(){ } + inline HSVf::HSVf(double const&h,double const&s,double const&v):HSV(h,s,v){} + inline HSVf::HSVf(double const* hsv):HSV(hsv){} + inline double HSVf::hMin() const { return 0.0; } + inline double HSVf::hMax() const { return 2.0 * PI; } + inline double HSVf::sMin() const { return 0.0; } + inline double HSVf::sMax() const { return 1.0; } + inline double HSVf::vMin() const { return 0.0; } + inline double HSVf::vMax() const { return 1.0; } + + + + + template<class RGB_T, class HSV_T> + inline void RGB_to_HSV(RGB<RGB_T> const& rgb, HSV<HSV_T>* hsv){ + double r = normalize(rgb.rMin(), rgb.rMax(), rgb.r()); + double g = normalize(rgb.gMin(), rgb.gMax(), rgb.g()); + double b = normalize(rgb.bMin(), rgb.bMax(), rgb.b()); + double mx = std::max(std::max(r, g), b); + double mn = std::min(std::min(r, g), b); + double h, s, v; + if (mx == mn ) h = 0; + else if(mx == r && g >= b) h = PI/3.0 * (g-b) / (mx-mn); + else if(mx == r && g < b) h = PI/3.0 * (g-b) / (mx-mn) + PI * 2.0; + else if(mx == g ) h = PI/3.0 * (b-r) / (mx-mn) + PI/3.0*2.0; + else h = PI/3.0 * (r-g) / (mx-mn) + PI/3.0*4.0; + if(mx == 0) s = 0; + else s = 1 - mn / mx; + v = mx; + hsv->h(h); + hsv->s(s); + hsv->v(v); + } + template<class HSV_T, class RGB_T> + inline void HSV_to_RGB(HSV<HSV_T> const& hsv, RGB<RGB_T>* rgb){ + double h = normalize(hsv.hMin(), hsv.hMax(), hsv.h()) * 360; + double s = normalize(hsv.sMin(), hsv.sMax(), hsv.s()); + double v = normalize(hsv.vMin(), hsv.vMax(), hsv.v()); + int hi = (int)h / 60 % 6; + double f = h / 60.0 - hi; + double p = v * (1 - s); + double q = v * (1 - f * s); + double t = v * (1 - (1 - f) * s); + double r, g, b; + if (hi == 0){ r = v; g = t; b = p; } + else if(hi == 1){ r = q; g = v; b = p; } + else if(hi == 2){ r = p; g = v; b = t; } + else if(hi == 3){ r = p; g = q; b = v; } + else if(hi == 4){ r = t; g = p; b = v; } + else { r = v; g = p; b = q; } + rgb->r(denormalize(rgb->rMin(), rgb->rMax(), r)); + rgb->g(denormalize(rgb->gMin(), rgb->gMax(), g)); + rgb->b(denormalize(rgb->bMin(), rgb->bMax(), b)); + } + template<class YUV_T, class HSV_T> + inline void YUV_to_HSV(YUV<YUV_T> const& yuv, HSV<HSV_T>* hsv){ + RGBf tmp; + YUV_to_RGB(yuv, &tmp); + RGB_to_HSV(tmp, hsv); + } + template<class HSV_T, class YUV_T> + inline void HSV_to_YUV(HSV<HSV_T> const& hsv, YUV<YUV_T>* yuv){ + RGBf tmp; + HSV_to_RGB(hsv, &tmp); + RGB_to_YUV(tmp, yuv); + } + template<class HSL_T, class HSV_T> + inline void HSL_to_HSV(HSL<HSL_T> const& hsl, HSV<HSV_T>* hsv){ + RGBf tmp; + HSL_to_RGB(hsl, &tmp); + RGB_to_HSV(tmp, hsv); + } + template<class HSV_T, class HSL_T> + inline void HSV_to_HSL(HSV<HSV_T> const& hsv, HSL<HSL_T>* hsl){ + RGBf tmp; + HSV_to_RGB(hsv, &tmp); + RGB_to_HSL(tmp, hsl); + } +} |