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