| Bsoft 2.0.5 Bernard's software package

Color.h
Go to the documentation of this file.
1
9 #include "Bstring.h"
10
11 template <typename Type> class RGBA;
12 template <typename Type> class CMYK;
13
14 #ifndef _COLOR_
15 #define _COLOR_
16 /************************************************************************
17 @Object: class RGB
18 @Description:
19 Class for an RGB color object.
20 @Features:
21 The internal variables are an array of 3 numbers.
22 *************************************************************************/
23 template <typename Type>
24 class RGB {
25 private:
26 Type data[3];
27 public:
28 RGB() { for ( int i=0; i<3; i++ ) data[i] = 0; }
29 RGB(const RGB& c) { for ( int i=0; i<3; i++ ) data[i] = c.data[i]; }
30 RGB(const double d[3]) { for ( int i=0; i<3; i++ ) data[i] = d[i]; }
31 RGB(const double rr, const double gg, const double bb) {
32 data[0] = (Type) rr; data[1] = (Type) gg; data[2] = (Type) bb; }
33 RGB operator=(const RGB& c) {
34 for ( int i=0; i<3; i++ ) data[i] = c.data[i];
35 return *this;
36 }
37 RGB operator-(const RGB& c) {
38 for ( int i=0; i<3; i++ ) data[i] -= c.data[i];
39 return *this;
40 }
41 Type& operator[](const unsigned int i) {
42 if ( i < 3 ) return data[i];
43 else return data[0];
44 }
45 Type r() { return data[0]; }
46 Type g() { return data[1]; }
47 Type b() { return data[2]; }
48 void red() { data[0] = 1; data[1] = data[2] = 0; }
49 template <typename T2> RGB operator=(RGBA<T2>& c) {
50 for ( int i=0; i<3; i++ ) data[i] = c[i];
51 return *this;
52 }
53 template <typename T2> operator RGB<T2>() const {
54 return RGB<T2>(data[0], data[1], data[2]);
55 }
56 RGB(RGBA<Type>& c) { for ( int i=0; i<3; i++ ) data[i] = c[i]; }
57 RGB(CMYK<Type>& cmyk) {
58 double r, g, b, k, k1;
59 double max = 255;
60 if ( sizeof(Type) > 1 ) max = 1;
61 k = cmyk.k();
62 k1 = 1 - k/max;
63 r = cmyk.c()*k1 + k;
64 g = cmyk.m()*k1 + k;
65 b = cmyk[1]*k1 + k;
66 if ( r > max ) r = max;
67 if ( g > max ) g = max;
68 if ( b > max ) b = max;
69 data[0] = (Type) (max - r);
70 data[1] = (Type) (max - g);
71 data[2] = (Type) (max - b);
72 }
73 RGB(Bstring& hex) {
74 int i;
75 for ( i=0; i<3; i++ ) data[i] = 255;
76 if ( hex != "white" )
77 sscanf(hex.c_str(), "#%2x%2x%2x", &data[0], &data[1], &data[2]);
78 if ( sizeof(Type) > 1 ) for ( i=0; i<3; i++ ) data[i] /= 255.0;
79 }
80 Bstring hex() {
81 int i, s=1;
82 Bstring hex("#");
83 if ( sizeof(Type) > 1 ) s = 255;
84 for ( i=0; i<3; i++ ) hex += Bstring(s*data[i], "%02x");
85 return hex;
86 }
87 double average() { return ((double)data[0] + (double)data[1] + (double)data[2])/3; }
88 double rms() { return sqrt(((double)data[0]*data[0] + (double)data[1]*data[1] + (double)data[2]*data[2])/3); }
89 void spectrum(double value, double cmin, double cmax ) {
90 if ( fabs(cmin - cmax) < 1e-6 ) {
91 cmin -= 1e-6;
92 cmax += 1e-6;
93 }
94
95 double type_max = ( sizeof(Type) > 1 )? 1: 255;
96 double red, blu, grn;
97 double mid = 0.5*(cmax + cmin);
98 double scale = 2*type_max/(cmax - cmin);
99
100 red = scale*(value - mid);
101 if ( red < 0 ) red = 0;
102 if ( red > type_max ) red = type_max;
103 blu = scale*(mid - value);
104 if ( blu < 0 ) blu = 0;
105 if ( blu > type_max ) blu = type_max;
106 grn = type_max - red - blu;
107 if ( grn < 0 ) grn = 0;
108 if ( grn > type_max ) grn = type_max;
109
110 data[0] = (Type) red;
111 data[1] = (Type) grn;
112 data[2] = (Type) blu;
113 }
114 void phase(double phi, double amp_ratio) {
115 if ( amp_ratio > 255 ) amp_ratio = 255;
116 if ( sizeof(Type) > 1 ) if ( amp_ratio > 1 ) amp_ratio = 1;
117 double red, grn, blu;
118
119 phi /= M_PI;
120 if ( phi > 0 ) { // Positive angles
121 red = 2 - 3*phi;
122 grn = 3*phi;
123 blu = 3*phi - 2;
124 } else { // Negative angles
125 red = 2 + 3*phi;
126 grn = -3*phi - 2;
127 blu = -3*phi;
128 }
129 if ( red < 0 ) red = 0; // Clip to range
130 if ( grn < 0 ) grn = 0;
131 if ( blu < 0 ) blu = 0;
132 if ( red > 1 ) red = 1;
133 if ( grn > 1 ) grn = 1;
134 if ( blu > 1 ) blu = 1;
135
136 data[0] = (Type) (amp_ratio*red);
137 data[1] = (Type) (amp_ratio*grn);
138 data[2] = (Type) (amp_ratio*blu);
139 }
140 void random_color() {
141 data[0] = (Type) (random()*255/RAND_MAX);
142 data[1] = (Type) (random()*255/RAND_MAX);
143 data[2] = (Type) (random()*255/RAND_MAX);
144 }
145 } ;
146
147 template <typename Type>
148 ostream& operator<<(ostream& output, RGB<Type> rgb) {
149 output.setf(ios::fixed, ios::floatfield);
150 output << rgb.r() << tab << rgb.g() << tab << rgb.b();
151 return output;
152 }
153
154 /************************************************************************
155 @Object: class RGBA
156 @Description:
157 Class for an RGBA color object.
158 @Features:
159 The internal variables are an array of 3 numbers.
160 *************************************************************************/
161 template <typename Type>
162 class RGBA {
163 private:
164 Type data[4];
165 public:
166 RGBA() { for ( int i=0; i<4; i++ ) data[i] = 0; }
167 RGBA(const RGBA& c) { for ( int i=0; i<4; i++ ) data[i] = c.data[i]; }
168 RGBA(const double d[4]) { for ( int i=0; i<4; i++ ) data[i] = d[i]; }
169 RGBA(const double rr, const double gg, const double bb) {
170 data[0] = (Type) rr; data[1] = (Type) gg; data[2] = (Type) bb; data[3] = 0; }
171 RGBA(const double rr, const double gg, const double bb, const double aa) {
172 data[0] = (Type) rr; data[1] = (Type) gg; data[2] = (Type) bb; data[3] = (Type) aa; }
173 RGBA operator=(const RGBA& c) {
174 for ( int i=0; i<4; i++ ) data[i] = c.data[i];
175 return *this;
176 }
177 template <typename T2> RGBA operator=(RGB<T2>& c) {
178 for ( int i=0; i<3; i++ ) data[i] = c[i];
179 return *this;
180 }
181 template <typename T2> operator RGBA<T2>() const {
182 return RGBA<T2>(data[0], data[1], data[2], data[3]);
183 }
184 RGBA operator+(const RGBA& c) {
185 return RGBA(data[0] + c.data[0], data[1] + c.data[1], data[2] + c.data[2], data[3] + c.data[3]);
186 }
187 RGBA operator/(const double d) {
188 return RGBA(data[0]/d, data[1] /d, data[2]/d, data[3]/d);
189 }
190 RGBA(RGB<Type>& c) { for ( int i=0; i<3; i++ ) data[i] = c[i]; data[3] = 0; }
191 RGBA(CMYK<Type>& cmyk) {
192 RGB<Type> rgb(cmyk);
193 for ( int i=0; i<3; i++ ) data[i] = rgb[i];
194 data[3] = 0;
195 }
196 Type& operator[](const unsigned int i) {
197 if ( i < 4 ) return data[i];
198 else return data[0];
199 }
200 Type r() { return data[0]; }
201 Type g() { return data[1]; }
202 Type b() { return data[2]; }
203 Type a() { return data[3]; }
204 void red() { data[0] = data[3] = 1; data[1] = data[2] = 0; }
205 RGBA(Bstring& hex) {
206 int i;
207 unsigned int urgb[3];
208 for ( i=0; i<4; i++ ) data[i] = 255;
209 if ( hex != "white" )
210 sscanf(hex.c_str(), "#%2x%2x%2x", &urgb[0], &urgb[1], &urgb[2]);
211 for ( i=0; i<3; i++ ) data[i] = urgb[i];
212 if ( sizeof(Type) > 1 ) for ( i=0; i<4; i++ ) data[i] /= 255.0;
213 }
214 Bstring hex() {
215 int i, s=1;
216 Bstring hex("#");
217 if ( sizeof(Type) > 1 ) s = 255;
218 for ( i=0; i<3; i++ ) hex += Bstring((int)(s*data[i]), "%02x");
219 return hex;
220 }
221 void spectrum(double value, double cmin, double cmax ) {
222 if ( fabs(cmin - cmax) < 1e-6 ) {
223 cmin -= 1e-6;
224 cmax += 1e-6;
225 }
226
227 double type_max = ( sizeof(Type) > 1 )? 1: 255;
228 double red, blu, grn;
229 double mid = 0.5*(cmax + cmin);
230 double scale = 2*type_max/(cmax - cmin);
231
232 red = scale*(value - mid);
233 if ( red < 0 ) red = 0;
234 if ( red > type_max ) red = type_max;
235 blu = scale*(mid - value);
236 if ( blu < 0 ) blu = 0;
237 if ( blu > type_max ) blu = type_max;
238 grn = type_max - red - blu;
239 if ( grn < 0 ) grn = 0;
240 if ( grn > type_max ) grn = type_max;
241
242 data[0] = (Type) red;
243 data[1] = (Type) grn;
244 data[2] = (Type) blu;
245 data[3] = (Type) type_max;
246 }
247 } ;
248
249 template <typename Type>
250 ostream& operator<<(ostream& output, RGBA<Type> rgba) {
251 output.setf(ios::fixed, ios::floatfield);
252 output << rgba.r() << tab << rgba.g() << tab << rgba.b() << tab << rgba.a();
253 return output;
254 }
255
256 /************************************************************************
257 @Object: class CMYK
258 @Description:
259 Class for a CMYK color object.
260 @Features:
261 The internal variables are an array of 3 numbers.
262 *************************************************************************/
263 template <typename Type>
264 class CMYK {
265 private:
266 Type data[4];
267 public:
268 CMYK() { for ( int i=0; i<4; i++ ) data[i] = 0; }
269 CMYK(const CMYK& col) { for ( int i=0; i<4; i++ ) data[i] = col.data[i]; }
270 CMYK(const double d[4]) { for ( int i=0; i<4; i++ ) data[i] = d[i]; }
271 CMYK(const double cc, const double mm, const double yy, const double kk) {
272 data[0] = (Type) cc; data[1] = (Type) mm; data[2] = (Type) yy; data[3] = (Type) kk; }
273 CMYK operator=(const CMYK& col) {
274 for ( int i=0; i<4; i++ ) data[i] = col.data[i];
275 return *this;
276 }
277 CMYK(RGB<Type>& rgb) {
278 double r1, g1, b1, k, k1, c, m, y;
279 double max = 255;
280 if ( sizeof(Type) > 1 ) max = 1;
281 r1 = max - rgb.r();
282 g1 = max - rgb.g();
283 b1 = max - rgb.b();
284 k = r1;
285 if ( k > g1 ) k = g1;
286 if ( k > b1 ) k = b1;
287 k1 = max/(max - k);
288 c = (r1 - k)*k1;
289 m = (g1 - k)*k1;
290 y = (b1 - k)*k1;
291 if ( c > max ) c = max;
292 if ( m > max ) m = max;
293 if ( y > max ) y = max;
294 data[0] = (Type) c; data[1] = (Type) m; data[2] = (Type) y; data[3] = (Type) k;
295 }
296 Type& operator[](const unsigned int i) {
297 if ( i < 4 ) return data[i];
298 return data[0];
299 }
300 Type c() { return data[0]; }
301 Type m() { return data[1]; }
302 Type y() { return data[2]; }
303 Type k() { return data[3]; }
304 } ;
305
306 template <typename Type>
307 ostream& operator<<(ostream& output, CMYK<Type> cmyk) {
308 output.setf(ios::fixed, ios::floatfield);
309 output << cmyk.c() << tab << cmyk.m() << tab << cmyk[1] << tab << cmyk.k();
310 return output;
311 }
312
313 #endif
314
RGBA::RGBA
RGBA(RGB< Type > &c)
Definition: Color.h:190
CMYK::operator=
CMYK operator=(const CMYK &col)
Definition: Color.h:273
RGB::operator=
RGB operator=(const RGB &c)
Definition: Color.h:33
RGBA::a
Type a()
Definition: Color.h:203
CMYK::y
Type y()
Definition: Color.h:302
RGB::g
Type g()
Definition: Color.h:46
RGBA::RGBA
RGBA(Bstring &hex)
Definition: Color.h:205
RGBA
Definition: Color.h:11
RGB::operator-
RGB operator-(const RGB &c)
Definition: Color.h:37
RGB::rms
double rms()
Definition: Color.h:88
RGBA::hex
Bstring hex()
Definition: Color.h:214
RGB::hex
Bstring hex()
Definition: Color.h:80
CMYK::CMYK
CMYK(const double cc, const double mm, const double yy, const double kk)
Definition: Color.h:271
RGB::RGB
RGB(const double d[3])
Definition: Color.h:30
RGBA::red
void red()
Definition: Color.h:204
RGB::red
void red()
Definition: Color.h:48
CMYK::m
Type m()
Definition: Color.h:301
RGBA::b
Type b()
Definition: Color.h:202
RGB::RGB
RGB(Bstring &hex)
Definition: Color.h:73
RGB::operator=
RGB operator=(RGBA< T2 > &c)
Definition: Color.h:49
M_PI
#define M_PI
Definition: utilities.h:59
CMYK::CMYK
CMYK(RGB< Type > &rgb)
Definition: Color.h:277
RGB::RGB
RGB(CMYK< Type > &cmyk)
Definition: Color.h:57
RGBA::RGBA
RGBA(CMYK< Type > &cmyk)
Definition: Color.h:191
RGB
Definition: Color.h:24
RGBA::RGBA
RGBA(const double rr, const double gg, const double bb, const double aa)
Definition: Color.h:171
RGBA::RGBA
RGBA(const double rr, const double gg, const double bb)
Definition: Color.h:169
RGBA::operator=
RGBA operator=(RGB< T2 > &c)
Definition: Color.h:177
RGBA::spectrum
void spectrum(double value, double cmin, double cmax)
Definition: Color.h:221
CMYK::operator[]
Type & operator[](const unsigned int i)
Definition: Color.h:296
RGBA::operator+
RGBA operator+(const RGBA &c)
Definition: Color.h:184
operator<<
ostream & operator<<(ostream &output, RGB< Type > rgb)
Definition: Color.h:148
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
RGB::r
Type r()
Definition: Color.h:45
RGB::operator[]
Type & operator[](const unsigned int i)
Definition: Color.h:41
Bstring
Definition: Bstring.h:29
CMYK::CMYK
CMYK(const CMYK &col)
Definition: Color.h:269
RGBA::r
Type r()
Definition: Color.h:200
CMYK::CMYK
CMYK()
Definition: Color.h:268
RGB::RGB
RGB()
Definition: Color.h:28
RGB::average
double average()
Definition: Color.h:87
Bstring.h
Header file for the string class.
RGBA::g
Type g()
Definition: Color.h:201
RGB::spectrum
void spectrum(double value, double cmin, double cmax)
Definition: Color.h:89
RGB::random_color
void random_color()
Definition: Color.h:140
CMYK::k
Type k()
Definition: Color.h:303
RGB::RGB
RGB(const RGB &c)
Definition: Color.h:29
RGBA::operator=
RGBA operator=(const RGBA &c)
Definition: Color.h:173
RGBA::operator[]
Type & operator[](const unsigned int i)
Definition: Color.h:196
RGBA::operator/
RGBA operator/(const double d)
Definition: Color.h:187
RGBA::RGBA
RGBA(const double d[4])
Definition: Color.h:168
CMYK::CMYK
CMYK(const double d[4])
Definition: Color.h:270
RGBA::RGBA
RGBA(const RGBA &c)
Definition: Color.h:167
RGB::phase
void phase(double phi, double amp_ratio)
Definition: Color.h:114
RGBA::RGBA
RGBA()
Definition: Color.h:166
CMYK
Definition: Color.h:12
RGB::b
Type b()
Definition: Color.h:47
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
RGB::RGB
RGB(RGBA< Type > &c)
Definition: Color.h:56
RGB::RGB
RGB(const double rr, const double gg, const double bb)
Definition: Color.h:31
CMYK::c
Type c()
Definition: Color.h:300