App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

TPixel.hpp
Go to the documentation of this file.
1
6 namespace app {
7 template<typename TPIXEL, typename TCHANNEL> class TPixel;
8 }
9
10 #ifndef TPIXEL_HPP_
11 #define TPIXEL_HPP_
12
13 #include "../typedefs.hpp"
14
15 namespace app {
16
28 template<typename TPIXEL, typename TCHANNEL>
29 class TPixel {
30 public:
31 static const TCHANNEL maxChannel;
32 TPIXEL value;
33
34 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
35
37 TPixel() { value = 0; }
38
40
44 TPixel(TPIXEL val) { value = val; }
45
47
54 TPixel(TCHANNEL ch0, TCHANNEL ch1, TCHANNEL ch2, TCHANNEL ch3) { setChannels(ch0, ch1, ch2, ch3); }
55
57 ~TPixel() { }
58
59 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
60
62
67 TCHANNEL getChannel(unsigned index) {
68 return *(((TCHANNEL *) &value) + index);
69 }
70
72
77 void setChannel(unsigned index, TCHANNEL newVal) {
78 *(((TCHANNEL *) &value) + index) = newVal;
79 }
80
81 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
82
84
91 void setChannels(TCHANNEL ch0, TCHANNEL ch1, TCHANNEL ch2, TCHANNEL ch3) {
92 TCHANNEL * ptr = (TCHANNEL *) &value;
93 *ptr = ch0; ptr++;
94 *ptr = ch1; ptr++;
95 *ptr = ch2; ptr++;
96 *ptr = ch3;
97 }
98
100
108 static void getNormalized(double &ch0, double &ch1, double &ch2, double &ch3, TPIXEL const * src) {
109 TCHANNEL const * ptr = (TCHANNEL *) src;
110 ch0 = *ptr / (double) maxChannel; ptr++;
111 ch1 = *ptr / (double) maxChannel; ptr++;
112 ch2 = *ptr / (double) maxChannel; ptr++;
113 ch3 = *ptr / (double) maxChannel;
114 }
115
117
124 void getNormalized(double &ch0, double &ch1, double &ch2, double &ch3) {
125 getNormalized(ch0, ch1, ch2, ch3, &value);
126 }
127
128
129 // static void getNormalized(double * dst, TPIXEL const * src) {
130 // TCHANNEL * const ptr = (TCHANNEL *) src;
131 // *dst = *ptr / (double) maxChannel; dst++; ptr++;
132 // *dst = *ptr / (double) maxChannel; dst++; ptr++;
133 // *dst = *ptr / (double) maxChannel; dst++; ptr++;
134 // *dst = *ptr / (double) maxChannel;
135 // }
136 //
137 // void getNormalized(double * dst) {
138 // getNormalized(dst, &value);
139 // }
140
142
150 static void setNormalized(TPIXEL * dst, const double &ch0, const double &ch1, const double &ch2, const double &ch3) {
151 TCHANNEL * ptr = (TCHANNEL *) dst;
152 *ptr = ch0 * maxChannel + 0.5; ptr++;
153 *ptr = ch1 * maxChannel + 0.5; ptr++;
154 *ptr = ch2 * maxChannel + 0.5; ptr++;
155 *ptr = ch3 * maxChannel + 0.5;
156 }
157
159
166 void setNormalized(const double &ch0, const double &ch1, const double &ch2, const double &ch3) {
167 setNormalized(&value, ch0, ch1, ch2, ch3);
168 }
169
170
171 // static void setNormalized(TPIXEL * dst, double const * src) {
172 // TCHANNEL * ptr = (TCHANNEL *) dst;
173 // *ptr = *src * maxChannel + 0.5; ptr++; src++;
174 // *ptr = *src * maxChannel + 0.5; ptr++; src++;
175 // *ptr = *src * maxChannel + 0.5; ptr++; src++;
176 // *ptr = *src * maxChannel + 0.5;
177 // }
178 //
179 // void setNormalized(double const * src) {
180 // setNormalized(&value, src);
181 // }
182
183 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
184
186
195 static void RGB_HSV_normalized(double &r, double &g, double &b, double &h, double &s, double &v) {
196 double cHigh, cLow, cRng; int max;
197 if (r > g) {
198 if (r > b) { cHigh = r; max = 1; } else { cHigh = b; max = 3; }
199 cLow = (g < b) ? g : b;
200 } else {
201 if (g > b) { cHigh = g; max = 2; } else { cHigh = b; max = 3; }
202 cLow = (r < b) ? r : b;
203 }
204 cRng = cHigh - cLow;
205 v = cHigh; // s = (cHigh > 0) ? (cRng / cHigh) : 0; // S // staré z PoDIP, EasyRGB.com to dělá takto...
206 if (cHigh <= 0) { s = 0; h = 0; return; }
207 s = cRng / cHigh;
208 r = (cHigh - r) / cRng; g = (cHigh - g) / cRng; b = (cHigh - b) / cRng;
209 switch (max) {
210 case 1: h = b - g; break;
211 case 2: h = r - b + 2; break;
212 case 3: h = g - r + 4; break;
213 }
214 h = (h < 0) ? h + 6 : h; h /= 6; // EasyRGB to dělá trochu jinak, ale má 2 ify...
215 }
216
218 void RGB_HSV() {
219 double r, g, b, h, s, v, a;
220 getNormalized(r, g, b, a);
221 RGB_HSV_normalized(r, g, b, h, s, v);
222 setNormalized(h, s, v, a);
223 }
224
226
235 static void HSV_RGB_normalized(double &h, double &s, double &v, double &r, double &g, double &b) {
236 int c1; double c2, x, y, z;
237 h *= 6; h = h - (int) (h / 6); // h = (6 * h) % 6; // Takto je to z definice, ale C++ prská nad zbytkem.
238 c1 = h; c2 = h - c1;
239 x = (1 - s) * v; y = (1 - (s * c2)) * v; z = (1 - s * (1 - c2)) * v;
240 switch (c1) {
241 case 0: r = v; g = z; b = x; break;
242 case 1: r = y; g = v; b = x; break;
243 case 2: r = x; g = v; b = z; break;
244 case 3: r = x; g = y; b = v; break;
245 case 4: r = z; g = x; b = v; break;
246 case 5: r = v; g = x; b = y; break;
247 }
248 }
249
251 void HSV_RGB() {
252 double r, g, b, h, s, v, a;
253 getNormalized(h, s, v, a);
254 HSV_RGB_normalized(h, s, v, r, g, b);
255 setNormalized(r, g, b, a);
256 }
257
258 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
259
261
270 static void RGB_HLS_normalized (double &r, double &g, double &b, double &h, double &l, double &s) {
271 double cHigh, cLow, cRng; int max;
272
273 if (r > g) {
274 if (r > b) { cHigh = r; max = 1; } else { cHigh = b; max = 3; }
275 cLow = (g < b) ? g : b;
276 } else { if (g > b) { cHigh = g; max = 2; } else { cHigh = b; max = 3; }
277 cLow = (r < b) ? r : b;
278 }
279 cRng = cHigh - cLow;
280 l = (cHigh + cLow) / 2;
281 if ((l == 0) || (l == 1)) {
282 s = 0;
283 } else if (l <= 0.5) {
284 s = 0.5 * cRng / l;
285 } else {
286 s = 0.5 * cRng / (1 - l);
287 }
288 r = (cHigh - r) / cRng; g = (cHigh - g) / cRng; b = (cHigh - b) / cRng;
289 switch (max) {
290 case 1: h = b - g; break;
291 case 2: h = r - b + 2; break;
292 case 3: h = g - r + 4; break;
293 }
294 h = (h < 0) ? h + 6 : h; h /= 6;
295 }
296
298 void RGB_HLS () {
299 double r, g, b, h, s, v, a;
300 getNormalized(r, g, b, a);
301 RGB_HLS_normalized(r, g, b, h, s, v);
302 setNormalized(h, s, v, a);
303 }
304
305 static void HLS_RGB_normalized(double &h, double &l, double &s, double &r, double &g, double &b) {
306 int c1; double c2, d, w, x, y, z;
307 if (l == 0) { r = 0; g = 0; b = 0; return; }
308 if (l == 1) { r = 1; g = 1; b = 1; return; }
309 h *= 6; h = (h) - (int) (h / 6);
310 c1 = h; c2 = h - c1;
311 d = (l <= 0.5) ? s * l : s * (1 - l);
312 w = l + d; x = l - d; y = w - (w - x) * c2; z = x + (w - x) * c2;
313 switch (c1) {
314 case 0: r = w; g = z; b = x; break;
315 case 1: r = y; g = w; b = x; break;
316 case 2: r = x; g = w; b = z; break;
317 case 3: r = x; g = y; b = w; break;
318 case 4: r = z; g = x; b = w; break;
319 case 5: r = w; g = x; b = y; break;
320 }
321 }
322
324
333 void HLS_RGB() {
334 double r, g, b, h, l, s, a;
335 getNormalized(h, l, s, a);
336 HLS_RGB_normalized(h, l, s, r, g, b);
337 setNormalized(r, g, b, a);
338 }
339
340 //-------------------------------------------------------------------------------------------------------------------------------------------------------------
341
342
343 };
344
345 template<typename TPIXEL, typename TCHANNEL>
346 const TCHANNEL TPixel<TPIXEL, TCHANNEL>::maxChannel = ~0; // Uvažujeme unsigned proto samé jedničky.
347
348 } /* namespace app */
349 #endif /* TPIXEL_HPP_ */