Chesto 0.9
A declarative and element-based library for creating GUIs on homebrew'd consoles
colorspaces.cpp
1#include "colorspaces.hpp"
2#include <cmath>
3#include <cstdlib>
4
5namespace Chesto {
6
7//quick and dirty RGB<->HSV conversion from https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
8
9hsv rgb2hsv(rgb in)
10{
11 hsv out;
12 double min, max, delta;
13
14 min = in.r < in.g ? in.r : in.g;
15 min = min < in.b ? min : in.b;
16
17 max = in.r > in.g ? in.r : in.g;
18 max = max > in.b ? max : in.b;
19
20 out.v = max; // v
21 delta = max - min;
22 if (delta < 0.00001)
23 {
24 out.s = 0;
25 out.h = 0; // undefined, maybe nan?
26 return out;
27 }
28 if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
29 out.s = (delta / max); // s
30 } else {
31 // if max is 0, then r = g = b = 0
32 // s = 0, h is undefined
33 out.s = 0.0;
34 out.h = NAN; // its now undefined
35 return out;
36 }
37 if( in.r >= max ) // > is bogus, just keeps compilor happy
38 out.h = ( in.g - in.b ) / delta; // between yellow & magenta
39 else
40 if( in.g >= max )
41 out.h = 2.0 + ( in.b - in.r ) / delta; // between cyan & yellow
42 else
43 out.h = 4.0 + ( in.r - in.g ) / delta; // between magenta & cyan
44
45 out.h *= 60.0; // degrees
46
47 if( out.h < 0.0 )
48 out.h += 360.0;
49
50 return out;
51}
52
53
54rgb hsv2rgb(hsv in)
55{
56 double hh, p, q, t, ff;
57 long i;
58 rgb out;
59
60 if(in.s <= 0.0) { // < is bogus, just shuts up warnings
61 out.r = in.v;
62 out.g = in.v;
63 out.b = in.v;
64 return out;
65 }
66 hh = in.h;
67 if(hh >= 360.0) hh = 0.0;
68 hh /= 60.0;
69 i = (long)hh;
70 ff = hh - i;
71 p = in.v * (1.0 - in.s);
72 q = in.v * (1.0 - (in.s * ff));
73 t = in.v * (1.0 - (in.s * (1.0 - ff)));
74
75 switch(i) {
76 case 0:
77 out.r = in.v;
78 out.g = t;
79 out.b = p;
80 break;
81 case 1:
82 out.r = q;
83 out.g = in.v;
84 out.b = p;
85 break;
86 case 2:
87 out.r = p;
88 out.g = in.v;
89 out.b = t;
90 break;
91
92 case 3:
93 out.r = p;
94 out.g = q;
95 out.b = in.v;
96 break;
97 case 4:
98 out.r = t;
99 out.g = p;
100 out.b = in.v;
101 break;
102 case 5:
103 default:
104 out.r = in.v;
105 out.g = p;
106 out.b = q;
107 break;
108 }
109 return out;
110}
111
112rgb fromRGB(int r, int g, int b)
113{
114 return { r/255.0, g/255.0, b/255.0 };
115}
116
117double randd() {
118 return (double)std::rand() / ((double)RAND_MAX + 1);
119}
120
121rgb randomColor()
122{
123 return (rgb){ randd(), randd(), randd() };
124}
125
126} // namespace Chesto