libcvd
rgb_components.h
1 #ifndef CVD_RGB_TRAITS_H
2 #define CVD_RGB_TRAITS_H
3 
4 #include <cvd/argb.h>
5 #include <cvd/bgrx.h>
6 #include <cvd/internal/builtin_components.h>
7 #include <cvd/internal/pixel_traits.h>
8 #include <cvd/la.h>
9 #include <cvd/rgb.h>
10 #include <cvd/rgb8.h>
11 #include <cvd/rgba.h>
12 
13 namespace CVD
14 {
15 namespace Pixel
16 {
17 
18  template <class P>
19  struct Component<Rgb<P>>
20  {
21  typedef P type;
22  static const size_t count = 3;
23 
24  //This version is much faster, with -funroll-loops
25  static const P& get(const Rgb<P>& pixel, size_t i)
26  {
27  return *(reinterpret_cast<const P*>(&pixel) + i);
28  //return i == 0 ? pixel.red : (i==1 ? pixel.green : pixel.blue);
29  }
30 
31  static P& get(Rgb<P>& pixel, size_t i)
32  {
33  return *(reinterpret_cast<P*>(&pixel) + i);
34  // return i == 0 ? pixel.red : (i==1 ? pixel.green : pixel.blue);
35  }
36  };
37 
38  template <class P>
39  struct Component<Bgrx<P>>
40  {
41  typedef P type;
42  static const size_t count = 3;
43 
44  //This version is much faster, with -funroll-loops
45  static const P& get(const Bgrx<P>& pixel, size_t i)
46  {
47  return *(reinterpret_cast<const P*>(&pixel) + i);
48  //return i == 0 ? pixel.blue : (i==1 ? pixel.green : pixel.red);
49  }
50 
51  static P& get(Bgrx<P>& pixel, size_t i)
52  {
53  return *(reinterpret_cast<P*>(&pixel) + i);
54  // return i == 0 ? pixel.blue : (i==1 ? pixel.green : pixel.red);
55  }
56  };
57 
58  template <>
59  struct Component<Rgb8>
60  {
61  typedef unsigned char type;
62  static const size_t count = 3;
63 
64  static const type& get(const Rgb8& pixel, size_t i)
65  {
66  return *(reinterpret_cast<const unsigned char*>(&pixel) + i);
67  //return i == 0 ? pixel.red : (i==1 ? pixel.green : pixel.blue);
68  }
69 
70  static type& get(Rgb8& pixel, size_t i)
71  {
72  return *(reinterpret_cast<unsigned char*>(&pixel) + i);
73  //return i == 0 ? pixel.red : (i==1 ? pixel.green : pixel.blue);
74  }
75  };
76 
77  template <class P>
78  struct Component<Rgba<P>>
79  {
80  typedef P type;
81  static const size_t count = 4;
82 
83  static const P& get(const Rgba<P>& pixel, size_t i)
84  {
85  return *(reinterpret_cast<const P*>(&pixel) + i);
86  //return i == 0 ? pixel.red : (i==1 ? pixel.green : (i==2 ?pixel.blue: pixel.alpha));
87  }
88 
89  static P& get(Rgba<P>& pixel, size_t i)
90  {
91  return *(reinterpret_cast<P*>(&pixel) + i);
92  //return i == 0 ? pixel.red : (i==1 ? pixel.green : (i==2 ?pixel.blue: pixel.alpha));
93  }
94  };
95 
96  template <class P>
97  struct Component<La<P>>
98  {
99  typedef P type;
100  static const size_t count = 2;
101 
102  static const P& get(const La<P>& pixel, size_t i)
103  {
104  return *(reinterpret_cast<const P*>(&pixel) + i);
105  }
106 
107  static P& get(La<P>& pixel, size_t i)
108  {
109  return *(reinterpret_cast<P*>(&pixel) + i);
110  }
111  };
112 
113  template <class P>
114  struct Component<Argb<P>>
115  {
116  typedef P type;
117  static const size_t count = 4;
118 
119  static const P& get(const Argb<P>& pixel, size_t i)
120  {
121  //return *(reinterpret_cast<const P*>(&pixel)+i);
122  return i == 0 ? pixel.red : (i == 1 ? pixel.green : (i == 2 ? pixel.blue : pixel.alpha));
123  }
124 
125  static P& get(Argb<P>& pixel, size_t i)
126  {
127  //return *(reinterpret_cast<P*>(&pixel)+i);
128  return i == 0 ? pixel.red : (i == 1 ? pixel.green : (i == 2 ? pixel.blue : pixel.alpha));
129  }
130  };
131 
132  template <class T>
133  struct is_Rgb
134  {
135  enum
136  {
137  value = 0
138  };
139  };
140  template <class T>
141  struct is_Rgb<Rgb<T>>
142  {
143  enum
144  {
145  value = 1
146  };
147  };
148  template <>
149  struct is_Rgb<Rgb8>
150  {
151  enum
152  {
153  value = 1
154  };
155  };
156  template <class T>
157  struct is_Rgb<Rgba<T>>
158  {
159  enum
160  {
161  value = 1
162  };
163  };
164  template <class T>
165  struct is_Rgb<Argb<T>>
166  {
167  enum
168  {
169  value = 1
170  };
171  };
172 
173  template <class T, int LIFT>
174  struct traits<Rgb<T>, LIFT>
175  {
178  };
179 
180  template <class T, int LIFT>
181  struct traits<Rgba<T>, LIFT>
182  {
185  };
186 
187  template <class T, int LIFT>
188  struct traits<La<T>, LIFT>
189  {
192  };
193 
194  template <int LIFT>
195  struct traits<Rgb8, LIFT>
196  {
197  typedef Rgb<int> wider_type;
198  typedef Rgb<float> float_type;
199  };
200 
201 }
202 template <class T>
203 struct Rgb_ops
204 {
205  template <class S>
206  static inline T sum(const T& a, const S& b) { return T(a.red + b.red, a.green + b.green, a.blue + b.blue); }
207  template <class S>
208  static inline void add(T& a, const S& b)
209  {
210  a.red += b.red;
211  a.green += b.green;
212  a.blue += b.blue;
213  }
214  template <class S>
215  static inline T diff(const T& a, const S& b) { return T(a.red - b.red, a.green - b.green, a.blue - b.blue); }
216  template <class S>
217  static inline void sub(T& a, const S& b)
218  {
219  a.red -= b.red;
220  a.green -= b.green;
221  a.blue -= b.blue;
222  }
223  template <class S>
224  static inline T prod(const T& a, const S& b) { return T(a.red * b, a.green * b, a.blue * b); }
225  template <class S>
226  static inline void mul(T& a, const S& b)
227  {
228  a.red *= b;
229  a.green *= b;
230  a.blue *= b;
231  }
232  template <class S>
233  static inline T quot(const T& a, const S& b) { return T(a.red / b, a.green / b, a.blue / b); }
234  template <class S>
235  static inline void div(T& a, const S& b)
236  {
237  a.red /= b;
238  a.green /= b;
239  a.blue /= b;
240  }
241  template <class S>
242  static inline void assign(T& a, const S& b)
243  {
244  a.red = b.red;
245  a.green = b.green;
246  a.blue = b.blue;
247  }
248 };
249 
250 template <class T, class S>
251 inline Rgb<T> operator+(const Rgb<T>& a, const Rgb<S>& b) { return Rgb_ops<Rgb<T>>::sum(a, b); }
252 template <class T, class S>
253 inline Rgb<T>& operator+=(Rgb<T>& a, const Rgb<S>& b)
254 {
255  Rgb_ops<Rgb<T>>::add(a, b);
256  return a;
257 }
258 template <class T, class S>
259 inline Rgb<T> operator-(const Rgb<T>& a, const Rgb<S>& b) { return Rgb_ops<Rgb<T>>::diff(a, b); }
260 template <class T, class S>
261 inline Rgb<T>& operator-=(Rgb<T>& a, const Rgb<S>& b)
262 {
263  Rgb_ops<Rgb<T>>::sub(a, b);
264  return a;
265 }
266 template <class T, class S>
267 inline Rgb<T> operator*(const Rgb<T>& a, const S& b) { return Rgb_ops<Rgb<T>>::prod(a, b); }
268 template <class T, class S>
269 inline Rgb<T> operator*(const S& b, const Rgb<T>& a) { return Rgb_ops<Rgb<T>>::prod(a, b); }
270 template <class T, class S>
271 inline Rgb<T>& operator*=(Rgb<T>& a, const S& b)
272 {
273  Rgb_ops<Rgb<T>>::mul(a, b);
274  return a;
275 }
276 template <class T, class S>
277 inline Rgb<T> operator/(const Rgb<T>& a, const S& b) { return Rgb_ops<Rgb<T>>::quot(a, b); }
278 template <class T, class S>
279 inline Rgb<T> operator/(const S& b, const Rgb<T>& a) { return Rgb_ops<Rgb<T>>::quot(a, b); }
280 template <class T, class S>
281 inline Rgb<T>& operator/=(Rgb<T>& a, const S& b)
282 {
283  Rgb_ops<Rgb<T>>::div(a, b);
284  return a;
285 }
286 
287 template <class T>
288 struct Rgba_ops
289 {
290  template <class S>
291  static inline T sum(const T& a, const S& b) { return T(a.red + b.red, a.green + b.green, a.blue + b.blue, a.alpha + b.alpha); }
292  template <class S>
293  static inline void add(T& a, const S& b)
294  {
295  a.red += b.red;
296  a.green += b.green;
297  a.blue += b.blue;
298  a.alpha += b.alpha;
299  }
300  template <class S>
301  static inline T diff(const T& a, const S& b) { return T(a.red - b.red, a.green - b.green, a.blue - b.blue, a.alpha - b.alpha); }
302  template <class S>
303  static inline void sub(T& a, const S& b)
304  {
305  a.red -= b.red;
306  a.green -= b.green;
307  a.blue -= b.blue;
308  a.alpha -= b.alpha;
309  }
310  template <class S>
311  static inline T prod(const T& a, const S& b) { return T(a.red * b, a.green * b, a.blue * b, a.alpha * b); }
312  template <class S>
313  static inline void mul(T& a, const S& b)
314  {
315  a.red *= b;
316  a.green *= b;
317  a.blue *= b;
318  a.alpha *= b;
319  }
320  template <class S>
321  static inline T quot(const T& a, const S& b) { return T(a.red / b, a.green / b, a.blue / b, a.alpha / b); }
322  template <class S>
323  static inline void div(T& a, const S& b)
324  {
325  a.red /= b;
326  a.green /= b;
327  a.blue /= b;
328  a.alpha /= b;
329  }
330  template <class S>
331  static inline void assign(T& a, const S& b)
332  {
333  a.red = b.red;
334  a.green = b.green;
335  a.blue = b.blue;
336  a.alpha = b.alpha;
337  }
338 };
339 
340 template <class T, class S>
341 inline Rgba<T> operator+(const Rgba<T>& a, const Rgba<S>& b) { return Rgba_ops<Rgba<T>>::sum(a, b); }
342 template <class T, class S>
343 inline Rgba<T>& operator+=(Rgba<T>& a, const Rgba<S>& b)
344 {
345  Rgba_ops<Rgba<T>>::add(a, b);
346  return a;
347 }
348 template <class T, class S>
349 inline Rgba<T> operator-(const Rgba<T>& a, const Rgba<S>& b) { return Rgba_ops<Rgba<T>>::diff(a, b); }
350 template <class T, class S>
351 inline Rgba<T>& operator-=(Rgba<T>& a, const Rgba<S>& b)
352 {
353  Rgba_ops<Rgba<T>>::sub(a, b);
354  return a;
355 }
356 template <class T, class S>
357 inline Rgba<T> operator*(const Rgba<T>& a, const S& b) { return Rgba_ops<Rgba<T>>::prod(a, b); }
358 template <class T, class S>
359 inline Rgba<T> operator*(const S& b, const Rgba<T>& a) { return Rgba_ops<Rgba<T>>::prod(a, b); }
360 template <class T, class S>
361 inline Rgba<T>& operator*=(Rgba<T>& a, const S& b)
362 {
363  Rgba_ops<Rgba<T>>::mul(a, b);
364  return a;
365 }
366 template <class T, class S>
367 inline Rgba<T> operator/(const Rgba<T>& a, const S& b) { return Rgba_ops<Rgba<T>>::quot(a, b); }
368 template <class T, class S>
369 inline Rgba<T> operator/(const S& b, const Rgba<T>& a) { return Rgba_ops<Rgba<T>>::quot(a, b); }
370 template <class T, class S>
371 inline Rgba<T>& operator/=(Rgba<T>& a, const S& b)
372 {
373  Rgba_ops<Rgba<T>>::div(a, b);
374  return a;
375 }
376 
377 template <class T>
378 struct La_ops
379 {
380  template <class S>
381  static inline T sum(const T& a, const S& b) { return T(a.luminance + b.luminance, a.alpha + b.alpha); }
382  template <class S>
383  static inline void add(T& a, const S& b)
384  {
385  a.luminance += b.luminance;
386  a.alpha += b.alpha;
387  }
388  template <class S>
389  static inline T diff(const T& a, const S& b) { return T(a.luminance - b.luminance, a.alpha - b.alpha); }
390  template <class S>
391  static inline void sub(T& a, const S& b)
392  {
393  a.luminance -= b.luminance;
394  a.alpha -= b.alpha;
395  }
396  template <class S>
397  static inline T prod(const T& a, const S& b) { return T(a.luminance * b, a.alpha * b); }
398  template <class S>
399  static inline void mul(T& a, const S& b)
400  {
401  a.luminance *= b;
402  a.alpha *= b;
403  }
404  template <class S>
405  static inline T quot(const T& a, const S& b) { return T(a.luminance / b, a.alpha / b); }
406  template <class S>
407  static inline void div(T& a, const S& b)
408  {
409  a.luminance /= b;
410  a.alpha /= b;
411  }
412  template <class S>
413  static inline void assign(T& a, const S& b)
414  {
415  a.luminance = b.luminance;
416  a.alpha = b.alpha;
417  }
418 };
419 
420 template <class T, class S>
421 inline La<T> operator+(const La<T>& a, const La<S>& b) { return La_ops<La<T>>::sum(a, b); }
422 template <class T, class S>
423 inline La<T>& operator+=(La<T>& a, const La<S>& b)
424 {
425  La_ops<La<T>>::add(a, b);
426  return a;
427 }
428 template <class T, class S>
429 inline La<T> operator-(const La<T>& a, const La<S>& b) { return La_ops<La<T>>::diff(a, b); }
430 template <class T, class S>
431 inline La<T>& operator-=(La<T>& a, const La<S>& b)
432 {
433  La_ops<La<T>>::sub(a, b);
434  return a;
435 }
436 template <class T, class S>
437 inline La<T> operator*(const La<T>& a, const S& b) { return La_ops<La<T>>::prod(a, b); }
438 template <class T, class S>
439 inline La<T> operator*(const S& b, const La<T>& a) { return La_ops<La<T>>::prod(a, b); }
440 template <class T, class S>
441 inline La<T>& operator*=(La<T>& a, const S& b)
442 {
443  La_ops<La<T>>::mul(a, b);
444  return a;
445 }
446 template <class T, class S>
447 inline La<T> operator/(const La<T>& a, const S& b) { return La_ops<La<T>>::quot(a, b); }
448 template <class T, class S>
449 inline La<T> operator/(const S& b, const La<T>& a) { return La_ops<La<T>>::quot(a, b); }
450 template <class T, class S>
451 inline La<T>& operator/=(La<T>& a, const S& b)
452 {
453  La_ops<La<T>>::div(a, b);
454  return a;
455 }
456 
457 }
458 #endif
A colour consisting of red, green and blue components.
Definition: rgb.h:25
Definition: rgb_components.h:288
All classes and functions are within the CVD namespace.
Definition: argb.h:6
A colour consisting of red, green, blue and dummy components, in the order bgr dummy in memory...
Definition: bgrx.h:16
A colour consisting of red, green, blue and alpha components.
Definition: argb.h:17
A colour consisting of luminance and alpha components.
Definition: la.h:17
Definition: rgb_components.h:203
Definition: rgb_components.h:378
A 32-bit colour.
Definition: rgb8.h:11
A colour consisting of red, green, blue and alpha components.
Definition: rgba.h:17
T red
The red component.
Definition: argb.h:44
Definition: builtin_components.h:38
Definition: pixel_traits.h:16
Definition: rgb_components.h:133