aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/colors/HSV.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/colors/HSV.hpp')
-rw-r--r--meowpp/colors/HSV.hpp131
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);
+ }
+}