App
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_ */