Allolib  1.0
C++ Components For Interactive Multimedia
al_Color.hpp
1 #ifndef INCLUDE_AL_COLOR_HPP
2 #define INCLUDE_AL_COLOR_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  RGBA, HSV, CIE_XYZ, Lab, HCLab, Luv, and HCLuv color classes
40 
41  Color conversion code for CIE_XYZ, Lab, HCLab, Luv, HCLuv was adapted from
42  psuedo-code and formulas found at http://www.easyrgb.com/ and
43  http://brucelindbloom.com/
44 
45  File author(s):
46  Lance Putnam, 2010, putnam.lance@gmail.com
47  Owen Campbell, 2014, owen.campbell@gmail.com
48 */
49 
50 #include <cstdint> // uint8_t
51 
52 namespace al {
53 
54 struct RGB;
55 struct HSV;
56 struct Color;
57 struct Colori;
58 
59 struct CIE_XYZ;
60 struct Lab;
61 struct HCLab;
62 struct Luv;
63 struct HCLuv;
64 
68 struct Color {
69  union {
70  struct {
71  float r;
72  float g;
73  float b;
74  float a;
75  };
76  float components[4];
77  };
78 
83  Color(float r, float g, float b, float a = 1.f) : r(r), g(g), b(b), a(a) {}
84 
86  template <class T>
87  Color(const T *rgba) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {}
88 
91  Color(float gray = 1.f, float a = 1.f) : r(gray), g(gray), b(gray), a(a) {}
92 
94  Color(const Colori &c) { *this = c; }
95 
98  Color(const HSV &hsv, float a = 1.f) : a(a) { *this = hsv; }
99 
102  Color(const RGB &rgb, float a = 1.f) : a(a) { *this = rgb; }
103 
106  Color(const CIE_XYZ &xyz, float a = 1.f) : a(a) { *this = xyz; }
107 
110  Color(const Lab &lab, float a = 1.f) : a(a) { *this = lab; }
111 
114  Color(const HCLab &hclab, float a = 1.f) : a(a) { *this = hclab; }
115 
118  Color(const Luv &luv, float a = 1.f) : a(a) { *this = luv; }
119 
122  Color(const HCLuv &hcluv, float a = 1.f) : a(a) { *this = hcluv; }
123 
125  float &operator[](int i) { return components[i]; }
126 
128  const float &operator[](int i) const { return components[i]; }
129 
130  RGB &rgb() { return *(RGB *)(components); }
131  const RGB &rgb() const { return *(const RGB *)(components); }
132 
134  Color &set(const Color &c, float al) {
135  a = al;
136  return set(c.r, c.g, c.b);
137  }
138 
140  Color &set(float re, float gr, float bl, float al) {
141  a = al;
142  return set(re, gr, bl);
143  }
144 
146  Color &set(float re, float gr, float bl) {
147  r = re;
148  g = gr;
149  b = bl;
150  return *this;
151  }
152 
154  Color &set(float v) { return set(v, v, v); }
155 
157  Color &set(float v, float al) { return set(v, v, v, al); }
158 
160  template <class T>
161  Color &set(const T *rgba) {
162  return set(rgba[0], rgba[1], rgba[2], rgba[3]);
163  }
164 
166  Color &operator=(float v) { return set(v); }
167  Color &operator=(double v) { return set(static_cast<float>(v)); }
168 
170  Color &operator=(const Colori &v);
171 
173  Color &operator=(const HSV &v);
174 
176  Color &operator=(const RGB &v);
177 
179  Color &operator=(const CIE_XYZ &v);
180 
182  Color &operator=(const Lab &v);
183 
185  Color &operator=(const HCLab &v);
186 
188  Color &operator=(const Luv &v);
189 
191  Color &operator=(const HCLuv &v);
192 
194  bool operator==(const Color &v) const {
195  return v.r == r && v.g == g && v.b == b && v.a == a;
196  }
197 
199  bool operator!=(const Color &v) const { return !(*this == v); }
200 
201  Color &operator+=(const Color &v) {
202  return set(r + v.r, g + v.g, b + v.b, a + v.a);
203  }
204  Color &operator-=(const Color &v) {
205  return set(r - v.r, g - v.g, b - v.b, a - v.a);
206  }
207  Color &operator*=(const Color &v) {
208  return set(r * v.r, g * v.g, b * v.b, a * v.a);
209  }
210  Color &operator/=(const Color &v) {
211  return set(r / v.r, g / v.g, b / v.b, a / v.a);
212  }
213  Color &operator+=(float v) { return set(r + v, g + v, b + v, a + v); }
214  Color &operator-=(float v) { return set(r - v, g - v, b - v, a - v); }
215  Color &operator*=(float v) { return set(r * v, g * v, b * v, a * v); }
216  Color &operator/=(float v) { return set(r / v, g / v, b / v, a / v); }
217 
218  Color operator-() const { return Color(-r, -g, -b, -a); }
219  Color operator+(const Color &v) const { return Color(*this) += v; }
220  Color operator-(const Color &v) const { return Color(*this) -= v; }
221  Color operator*(const Color &v) const { return Color(*this) *= v; }
222  Color operator/(const Color &v) const { return Color(*this) /= v; }
223  Color operator+(float v) const { return Color(*this) += v; }
224  Color operator-(float v) const { return Color(*this) -= v; }
225  Color operator*(float v) const { return Color(*this) *= v; }
226  Color operator/(float v) const { return Color(*this) /= v; }
227 
229  Color &clamp(float max = 1.f) {
230  for (int i = 0; i < 4; ++i) {
231  float &v = components[i];
232  v < 0.f ? v = 0.f : (v > max ? v = max : 0);
233  }
234  return *this;
235  }
236 
238  Color inverse() const { return Color(*this).invert(); }
239 
241  Color &invert();
242 
244  float luminance() const;
245 
246  Color blackAndWhite() const;
247 
249  Color mix(const Color &c, float amt = 0.5f) const {
250  return (c - *this) * amt + *this;
251  }
252 
253  private:
254  float tof(uint8_t v) { return float(v) * (1.f / 255.f); }
255 };
256 
259 
265 struct Colori {
266  union {
267  struct {
268  uint8_t r;
269  uint8_t g;
270  uint8_t b;
271  uint8_t a;
272  };
273  uint8_t components[4];
274  uint32_t rgba;
275  };
276 
281  Colori(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255)
282  : r(r), g(g), b(b), a(a) {}
283 
285  template <class T>
286  Colori(const T *rgba) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {}
287 
290  Colori(uint8_t gray = 255, uint8_t a = 255)
291  : r(gray), g(gray), b(gray), a(a) {}
292 
294  Colori(const Color &c) { *this = c; }
295 
298  Colori(const HSV &hsv, uint8_t a = 255) : a(a) { *this = hsv; }
299 
302  Colori(const RGB &rgb, uint8_t a = 255) : a(a) { *this = rgb; }
303 
306  Colori(const CIE_XYZ &xyz, float a = 1.f) : a(static_cast<uint8_t>(a * 255)) {
307  *this = xyz;
308  }
309 
312  Colori(const Lab &lab, float a = 1.f) : a(static_cast<uint8_t>(a * 255)) {
313  *this = lab;
314  }
315 
318  Colori(const HCLab &hclab, float a = 1.f) : a(static_cast<uint8_t>(a * 255)) {
319  *this = hclab;
320  }
321 
324  Colori(const Luv &luv, float a = 1.f) : a(static_cast<uint8_t>(a * 255)) {
325  *this = luv;
326  }
327 
330  Colori(const HCLuv &hcluv, float a = 1.f) : a(static_cast<uint8_t>(a * 255)) {
331  *this = hcluv;
332  }
333 
335  uint8_t &operator[](int i) { return components[i]; }
336 
338  const uint8_t &operator[](int i) const { return components[i]; }
339 
341  Colori &operator=(const Color &v) {
342  return set(toi(v.r), toi(v.g), toi(v.b), toi(v.a));
343  }
344 
346  Colori &operator=(const HSV &v);
347 
349  Colori &operator=(const RGB &v);
350 
353 
355  Colori &operator=(const Lab &v);
356 
358  Colori &operator=(const HCLab &v);
359 
361  Colori &operator=(const Luv &v);
362 
364  Colori &operator=(const HCLuv &v);
365 
367  Colori &set(uint8_t re, uint8_t gr, uint8_t bl) {
368  r = re;
369  g = gr;
370  b = bl;
371  return *this;
372  }
373 
375  Colori &set(uint8_t re, uint8_t gr, uint8_t bl, uint8_t al) {
376  a = al;
377  return set(re, gr, bl);
378  }
379 
381  Colori &set(uint8_t v) { return set(v, v, v); }
382 
384  Colori &set(uint8_t v, uint8_t al) { return set(v, v, v, al); }
385 
387  Colori inverse() const { return Colori(*this).invert(); }
388 
390  Colori &invert() { return set(255 - r, 255 - g, 255 - b); }
391 
392  private:
393  uint8_t toi(float v) { return uint8_t(v * 255.f); }
394 };
395 
397 struct HSV {
398  union {
399  struct {
400  float h;
401  float s;
402  float v;
403  };
404  float components[3];
405  };
406 
410  HSV(float h = 0, float s = 1, float v = 1) : h(h), s(s), v(v) {}
411 
413  template <class T>
414  HSV(const T *hsv) : h(hsv[0]), s(hsv[1]), v(hsv[2]) {}
415 
417  HSV(const Color &v) { *this = v; }
418 
420  HSV(const Colori &v) { *this = v; }
421 
423  HSV(const RGB &v) { *this = v; }
424 
426  HSV(const CIE_XYZ &xyz) { *this = xyz; }
427 
429  HSV(const Lab &lab) { *this = lab; }
430 
432  HSV(const HCLab &hclab) { *this = hclab; }
433 
435  HSV(const Luv &luv) { *this = luv; }
436 
438  HSV(const HCLuv &hcluv) { *this = hcluv; }
439 
441  float &operator[](int i) { return components[i]; }
442 
444  const float &operator[](int i) const { return components[i]; }
445 
447  HSV &operator=(const Color &v) { return *this = v.rgb(); }
448 
450  HSV &operator=(const Colori &v) { return *this = Color(v); }
451 
453  HSV &operator=(const RGB &v);
454 
456  HSV &operator=(const CIE_XYZ &v);
457 
459  HSV &operator=(const Lab &v);
460 
462  HSV &operator=(const HCLab &v);
463 
465  HSV &operator=(const Luv &v);
466 
468  HSV &operator=(const HCLuv &v);
469 
471  HSV operator*(float a) const { return HSV(*this) *= a; }
472 
474  HSV &operator*=(float a) {
475  v *= a;
476  return *this;
477  }
478 
480  HSV &rotateHue(float dh) {
481  h += dh;
482  return wrapHue();
483  }
484 
487  if (h > 1) {
488  h -= int(h);
489  } else if (h < 0) {
490  h -= int(h) - 1;
491  }
492  return *this;
493  }
494 };
495 
497 
500 #ifdef RGB /* Windows related fix */
501 #undef RGB
502 #endif
503 struct RGB {
504  union {
505  struct {
506  float r;
507  float g;
508  float b;
509  };
510  float components[3];
511  };
512 
516  RGB(float r, float g, float b) : r(r), g(g), b(b) {}
517 
519  template <class T>
520  RGB(const T *rgb) : r(rgb[0]), g(rgb[1]), b(rgb[2]) {}
521 
523  RGB(float gray = 1.f) : r(gray), g(gray), b(gray) {}
524 
526  RGB(const Color &v) { *this = v; }
527 
529  RGB(const Colori &v) { *this = v; }
530 
532  RGB(const HSV &hsv) { *this = hsv; }
533 
535  RGB(const CIE_XYZ &xyz) { *this = xyz; }
536 
538  RGB(const Lab &lab) { *this = lab; }
539 
541  RGB(const HCLab &hclab) { *this = hclab; }
542 
544  RGB(const Luv &luv) { *this = luv; }
545 
547  RGB(const HCLuv &hcluv) { *this = hcluv; }
548 
550  float &operator[](int i) { return components[i]; }
551 
553  const float &operator[](int i) const { return components[i]; }
554 
556  RGB &set(const RGB &v) { return set(v.r, v.g, v.b); }
557 
559  RGB &set(float re, float gr, float bl) {
560  r = re;
561  g = gr;
562  b = bl;
563  return *this;
564  }
565 
567  RGB &set(float v) { return set(v, v, v); }
568 
570  template <class T>
571  RGB &set(const T *rgb) {
572  return set(rgb[0], rgb[1], rgb[2]);
573  }
574 
576  RGB &operator=(float v) { return set(v); }
577  RGB &operator=(double v) { return set(static_cast<float>(v)); }
578 
580  RGB &operator=(const HSV &v);
581 
583  RGB &operator=(const Color &v) { return set(v.rgb()); }
584 
586  RGB &operator=(const Colori &v);
587 
589  RGB &operator=(const CIE_XYZ &v);
590 
592  RGB &operator=(const Lab &v);
593 
595  RGB &operator=(const HCLab &v);
596 
598  RGB &operator=(const Luv &v);
599 
601  RGB &operator=(const HCLuv &v);
602 
604  bool operator==(const RGB &v) const {
605  return v.r == r && v.g == g && v.b == b;
606  }
607 
609  bool operator!=(const RGB &v) const { return !(*this == v); }
610 
611  RGB &operator+=(const RGB &v) { return set(r + v.r, g + v.g, b + v.b); }
612  RGB &operator-=(const RGB &v) { return set(r - v.r, g - v.g, b - v.b); }
613  RGB &operator*=(const RGB &v) { return set(r * v.r, g * v.g, b * v.b); }
614  RGB &operator/=(const RGB &v) { return set(r / v.r, g / v.g, b / v.b); }
615  RGB &operator+=(float v) { return set(r + v, g + v, b + v); }
616  RGB &operator-=(float v) { return set(r - v, g - v, b - v); }
617  RGB &operator*=(float v) { return set(r * v, g * v, b * v); }
618  RGB &operator/=(float v) { return set(r / v, g / v, b / v); }
619 
620  RGB operator-() const { return RGB(-r, -g, -b); }
621  RGB operator+(const RGB &v) const { return RGB(*this) += v; }
622  RGB operator-(const RGB &v) const { return RGB(*this) -= v; }
623  RGB operator*(const RGB &v) const { return RGB(*this) *= v; }
624  RGB operator/(const RGB &v) const { return RGB(*this) /= v; }
625  RGB operator+(float v) const { return RGB(*this) += v; }
626  RGB operator-(float v) const { return RGB(*this) -= v; }
627  RGB operator*(float v) const { return RGB(*this) *= v; }
628  RGB operator/(float v) const { return RGB(*this) /= v; }
629 
631  RGB &clamp(float max = 1.f) {
632  for (int i = 0; i < 3; ++i) {
633  float &v = components[i];
634  v < 0.f ? v = 0.f : (v > max ? v = max : 0);
635  }
636  return *this;
637  }
638 
640  RGB inverse() const { return RGB(*this).invert(); }
641 
643  RGB &invert() { return set(1.f - r, 1.f - g, 1.f - b); }
644 
646  float luminance() const { return r * 0.299f + g * 0.587f + b * 0.114f; }
647 
649  RGB mix(const RGB &v, float amt = 0.5f) const {
650  return (v - *this) * amt + *this;
651  }
652 };
653 
654 struct CIE_XYZ {
655  union {
656  struct {
657  float x;
658  float y;
659  float z;
660  };
661  float components[3];
662  };
663 
667  CIE_XYZ(float x = 0, float y = 1, float z = 1) : x(x), y(y), z(z) {}
668 
670  template <class T>
671  CIE_XYZ(const T *xyz) : x(xyz[0]), y(xyz[1]), z(xyz[2]) {}
672 
674  CIE_XYZ(const Color &v) { *this = v; }
675 
677  CIE_XYZ(const Colori &v) { *this = v; }
678 
680  CIE_XYZ(const RGB &v) { *this = v; }
681 
683  CIE_XYZ(const HSV &v) { *this = v; }
684 
686  CIE_XYZ(const Lab &v) { *this = v; }
687 
689  CIE_XYZ(const Luv &v) { *this = v; }
690 
692  float &operator[](int i) { return components[i]; }
693 
695  const float &operator[](int i) const { return components[i]; }
696 
698  CIE_XYZ &operator=(const Color &v) { return *this = v.rgb(); }
699 
701  CIE_XYZ &operator=(const Colori &v) { return *this = Color(v); }
702 
704  CIE_XYZ &operator=(const RGB &v);
705 
707  CIE_XYZ &operator=(const HSV &v) { return *this = RGB(v); }
708 
710  CIE_XYZ &operator=(const Lab &v);
711 
713  CIE_XYZ &operator=(const Luv &v);
714 };
715 
719 struct Lab {
720  union {
721  struct {
722  float l;
723  float a;
725  float b;
730  };
731  float components[3];
732  };
733 
737  Lab(float l = 1, float a = 1, float b = 1) : l(l), a(a), b(b) {}
738 
740  template <class T>
741  Lab(const T *Lab) : l(Lab[0]), a(Lab[1]), b(Lab[2]) {}
742 
744  Lab(const Color &v) { *this = v; }
745 
747  Lab(const Colori &v) { *this = v; }
748 
750  Lab(const RGB &v) { *this = v; }
751 
753  Lab(const HSV &v) { *this = v; }
754 
756  Lab(const CIE_XYZ &v) { *this = v; }
757 
759  Lab(const HCLab &v) { *this = v; }
760 
762  float &operator[](int i) { return components[i]; }
763 
765  const float &operator[](int i) const { return components[i]; }
766 
768  Lab &operator=(const Color &v) { return *this = v.rgb(); }
769 
771  Lab &operator=(const Colori &v) { return *this = Color(v); }
772 
774  Lab &operator=(const CIE_XYZ &v);
775 
777  Lab &operator=(const RGB &v) { return *this = CIE_XYZ(v); }
778 
780  Lab &operator=(const HSV &v) { return *this = CIE_XYZ(v); }
781 
782  Lab &operator=(const HCLab &v);
783 
785  Lab operator*(float c) const { return Lab(*this) *= c; }
786 
788  Lab &operator*=(float c) {
789  l *= c;
790  return *this;
791  }
792 };
793 
797 struct HCLab {
798  union {
799  struct {
802  float h;
803  float c;
805  float l;
807  };
808  float components[3];
809  };
810 
814  HCLab(float h = 1, float c = 1, float l = 1) : h(h), c(c), l(l) {}
815 
817  template <class T>
818  HCLab(const T *HCLab) : h(HCLab[0]), c(HCLab[1]), l(HCLab[2]) {}
819 
821  HCLab(const Color &v) { *this = v; }
822 
824  HCLab(const Colori &v) { *this = v; }
825 
827  HCLab(const RGB &v) { *this = v; }
828 
830  HCLab(const HSV &v) { *this = v; }
831 
833  HCLab(const CIE_XYZ &v) { *this = v; }
834 
836  HCLab(const Lab &v) { *this = v; }
837 
839  float &operator[](int i) { return components[i]; }
840 
842  const float &operator[](int i) const { return components[i]; }
843 
845  HCLab &operator=(const Color &v) { return *this = v.rgb(); }
846 
848  HCLab &operator=(const Colori &v) { return *this = Color(v); }
849 
851  HCLab &operator=(const RGB &v) { return *this = Lab(v); }
852 
854  HCLab &operator=(const HSV &v) { return *this = Lab(v); }
855 
857  HCLab &operator=(const CIE_XYZ &v) { return *this = Lab(v); }
858 
860  HCLab &operator=(const Lab &v);
861 
863  HCLab operator*(float a) const { return HCLab(*this) *= a; }
864 
866  HCLab &operator*=(float a) {
867  l *= a;
868  return *this;
869  }
870 
872  HCLab &rotateHue(float dh) {
873  h += dh;
874  return wrapHue();
875  }
876 
879  if (h > 1) {
880  h -= int(h);
881  } else if (h < 0) {
882  h -= int(h) - 1;
883  }
884  return *this;
885  }
886 };
887 
891 struct Luv {
892  union {
893  struct {
894  float l;
895  float u;
897  float v;
902  };
903  float components[3];
904  };
905 
909  Luv(float l = 1, float u = 1, float v = 1) : l(l), u(u), v(v) {}
910 
912  template <class T>
913  Luv(const T *Luv) : l(Luv[0]), u(Luv[1]), v(Luv[2]) {}
914 
916  Luv(const Color &w) { *this = w; }
917 
919  Luv(const Colori &w) { *this = w; }
920 
922  Luv(const RGB &w) { *this = w; }
923 
925  Luv(const HSV &w) { *this = w; }
926 
928  Luv(const CIE_XYZ &w) { *this = w; }
929 
931  Luv(const HCLuv &w) { *this = w; }
932 
934  float &operator[](int i) { return components[i]; }
935 
937  const float &operator[](int i) const { return components[i]; }
938 
940  Luv &operator=(const Color &w) { return *this = w.rgb(); }
941 
943  Luv &operator=(const Colori &w) { return *this = Color(w); }
944 
946  Luv &operator=(const CIE_XYZ &w);
947 
949  Luv &operator=(const HCLuv &w);
950 
952  Luv &operator=(const RGB &w) { return *this = CIE_XYZ(w); }
953 
955  Luv &operator=(const HSV &w) { return *this = CIE_XYZ(w); }
956 
958  Luv operator*(float a) const { return Luv(*this) *= a; }
959 
961  Luv &operator*=(float a) {
962  l *= a;
963  return *this;
964  }
965 };
966 
970 struct HCLuv {
971  union {
972  struct {
973  // ranges normalized to 8-bit RGB gamut using
974  // 16million RGB color image from http://brucelindbloom.com
975  float h;
976  float c;
978  float l;
980  };
981  float components[3];
982  };
983 
987  HCLuv(float h = 1, float c = 1, float l = 1) : h(h), c(c), l(l) {}
988 
990  template <class T>
991  HCLuv(const T *HCLuv) : h(HCLuv[0]), c(HCLuv[1]), l(HCLuv[2]) {}
992 
994  HCLuv(const Color &w) { *this = w; }
995 
997  HCLuv(const Colori &w) { *this = w; }
998 
1000  HCLuv(const RGB &w) { *this = w; }
1001 
1003  HCLuv(const HSV &w) { *this = w; }
1004 
1006  HCLuv(const CIE_XYZ &w) { *this = w; }
1007 
1009  HCLuv(const Luv &w) { *this = w; }
1010 
1012  float &operator[](int i) { return components[i]; }
1013 
1015  const float &operator[](int i) const { return components[i]; }
1016 
1018  HCLuv &operator=(const Color &w) { return *this = w.rgb(); }
1019 
1021  HCLuv &operator=(const Colori &w) { return *this = Color(w); }
1022 
1024  HCLuv &operator=(const RGB &w) { return *this = Luv(w); }
1025 
1027  HCLuv &operator=(const HSV &w) { return *this = Luv(w); }
1028 
1030  HCLuv &operator=(const CIE_XYZ &w) { return *this = Luv(w); }
1031 
1033  HCLuv &operator=(const Luv &w);
1034 
1036  HCLuv operator*(float a) const { return HCLuv(*this) *= a; }
1037 
1039  HCLuv &operator*=(float a) {
1040  l *= a;
1041  return *this;
1042  }
1043 
1045  HCLuv &rotateHue(float dh) {
1046  h += dh;
1047  return wrapHue();
1048  }
1049 
1052  if (h > 1) {
1053  h -= int(h);
1054  } else if (h < 0) {
1055  h -= int(h) - 1;
1056  }
1057  return *this;
1058  }
1059 };
1060 
1061 // Implementation --------------------------------------------------------------
1062 
1063 inline RGB operator+(float s, const RGB &c) { return c + s; }
1064 inline RGB operator-(float s, const RGB &c) { return -c + s; }
1065 inline RGB operator*(float s, const RGB &c) { return c * s; }
1066 inline RGB operator/(float s, const RGB &c) {
1067  return RGB(s / c.r, s / c.g, s / c.b);
1068 }
1069 
1070 inline RGB &RGB::operator=(const Colori &v) {
1071  return set(float(v.r) / 255.f, float(v.g) / 255.f, float(v.b) / 255.f);
1072 }
1073 
1074 inline Color operator+(float s, const Color &c) { return c + s; }
1075 inline Color operator-(float s, const Color &c) { return -c + s; }
1076 inline Color operator*(float s, const Color &c) { return c * s; }
1077 inline Color operator/(float s, const Color &c) {
1078  return Color(s / c.r, s / c.g, s / c.b, s / c.a);
1079 }
1080 
1081 inline Color &Color::operator=(const Colori &v) {
1082  r = tof(v.r);
1083  g = tof(v.g);
1084  b = tof(v.b);
1085  a = tof(v.a);
1086  return *this;
1087 }
1088 
1089 inline Color &Color::operator=(const HSV &v) {
1090  rgb() = v;
1091  return *this;
1092 }
1093 inline Color &Color::operator=(const RGB &v) {
1094  rgb() = v;
1095  return *this;
1096 }
1097 
1099  rgb().invert();
1100  return *this;
1101 }
1102 
1103 inline float Color::luminance() const { return rgb().luminance(); }
1104 
1105 inline Color Color::blackAndWhite() const {
1106  return Color(luminance() > 0.5f ? 1.f : 0.f);
1107 }
1108 
1109 inline Colori &Colori::operator=(const HSV &v) { return *this = RGB(v); }
1110 
1111 inline Colori &Colori::operator=(const RGB &v) {
1112  return set(toi(v.r), toi(v.g), toi(v.b), 255);
1113 }
1114 
1115 inline HSV operator*(float s, const HSV &c) { return c * s; }
1116 
1117 } // namespace al
1118 
1119 #endif
T max(const T &v1, const T &v2, const T &v3)
Definition: al_App.hpp:23
float z
< green component in [0, 1]
Definition: al_Color.hpp:659
CIE_XYZ(float x=0, float y=1, float z=1)
Definition: al_Color.hpp:667
float y
< red component in [0, 1]
Definition: al_Color.hpp:658
CIE_XYZ & operator=(const Lab &v)
Set from Lab color.
CIE_XYZ(const Color &v)
Definition: al_Color.hpp:674
CIE_XYZ(const Colori &v)
Definition: al_Color.hpp:677
CIE_XYZ(const Luv &v)
Definition: al_Color.hpp:689
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:692
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:695
CIE_XYZ(const RGB &v)
Definition: al_Color.hpp:680
CIE_XYZ(const HSV &v)
Definition: al_Color.hpp:683
CIE_XYZ & operator=(const Luv &v)
Set from Luv color.
CIE_XYZ(const Lab &v)
Definition: al_Color.hpp:686
CIE_XYZ & operator=(const RGB &v)
Set from RGB color.
CIE_XYZ & operator=(const Color &v)
Set from RGBA color.
Definition: al_Color.hpp:698
CIE_XYZ & operator=(const Colori &v)
Set from RGBA color.
Definition: al_Color.hpp:701
CIE_XYZ & operator=(const HSV &v)
Set from HSV color.
Definition: al_Color.hpp:707
float components[3]
CIE_XYZ component vector.
Definition: al_Color.hpp:661
CIE_XYZ(const T *xyz)
Definition: al_Color.hpp:671
float a
Alpha component in [0, 1].
Definition: al_Color.hpp:74
Color & operator=(const HCLab &v)
Set RGB components from HCLab.
Color & operator=(const CIE_XYZ &v)
Set RGB components from CIE_XYZ.
Color & set(float re, float gr, float bl, float al)
Set RGBA components.
Definition: al_Color.hpp:140
Color(const Luv &luv, float a=1.f)
Definition: al_Color.hpp:118
float r
Red component in [0, 1].
Definition: al_Color.hpp:71
Color(float gray=1.f, float a=1.f)
Definition: al_Color.hpp:91
Color(const HCLab &hclab, float a=1.f)
Definition: al_Color.hpp:114
Color(const T *rgba)
Definition: al_Color.hpp:87
Color & set(const T *rgba)
Set from an array of RGBA components.
Definition: al_Color.hpp:161
Color(const CIE_XYZ &xyz, float a=1.f)
Definition: al_Color.hpp:106
float b
Blue component in [0, 1].
Definition: al_Color.hpp:73
Color & operator=(const Luv &v)
Set RGB components from Luv.
Color & set(float re, float gr, float bl)
Set RGB components.
Definition: al_Color.hpp:146
float g
Green component in [0, 1].
Definition: al_Color.hpp:72
Color & set(const Color &c, float al)
Set RGB from another color and alpha from argument.
Definition: al_Color.hpp:134
Color inverse() const
Returns inverted color.
Definition: al_Color.hpp:238
float components[4]
RGBA component vector.
Definition: al_Color.hpp:76
Color & operator=(const HCLuv &v)
Set RGB components from HCLuv.
Color(const HSV &hsv, float a=1.f)
Definition: al_Color.hpp:98
Color(const Colori &c)
Definition: al_Color.hpp:94
Color(const RGB &rgb, float a=1.f)
Definition: al_Color.hpp:102
Color & operator=(const Lab &v)
Set RGB components from Lab.
Color & set(float v)
Set from gray value.
Definition: al_Color.hpp:154
Color & set(float v, float al)
Set from gray value and alpha.
Definition: al_Color.hpp:157
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:128
Color blackAndWhite() const
Returns nearest black or white color.
Definition: al_Color.hpp:1105
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:125
bool operator!=(const Color &v) const
Return true if components are not equal, false otherwise.
Definition: al_Color.hpp:199
float luminance() const
Returns luminance value.
Definition: al_Color.hpp:1103
Color & clamp(float max=1.f)
Clamp all components into [0,max] range.
Definition: al_Color.hpp:229
Color(const HCLuv &hcluv, float a=1.f)
Definition: al_Color.hpp:122
Color(const Lab &lab, float a=1.f)
Definition: al_Color.hpp:110
bool operator==(const Color &v) const
Return true if all components are equal, false otherwise.
Definition: al_Color.hpp:194
Color & invert()
Invert RGB components.
Definition: al_Color.hpp:1098
Color(float r, float g, float b, float a=1.f)
Definition: al_Color.hpp:83
Color mix(const Color &c, float amt=0.5f) const
Returns self linearly mixed with another color (0 = none)
Definition: al_Color.hpp:249
Color & operator=(float v)
Set from gray value.
Definition: al_Color.hpp:166
uint8_t r
Red component in [0, 255].
Definition: al_Color.hpp:268
Colori(const Lab &lab, float a=1.f)
Definition: al_Color.hpp:312
Colori(const HSV &hsv, uint8_t a=255)
Definition: al_Color.hpp:298
Colori & set(uint8_t re, uint8_t gr, uint8_t bl, uint8_t al)
Set RGBA components.
Definition: al_Color.hpp:375
Colori & set(uint8_t v)
Set from gray value.
Definition: al_Color.hpp:381
Colori(const T *rgba)
Definition: al_Color.hpp:286
Colori inverse() const
Returns inverted color.
Definition: al_Color.hpp:387
Colori & set(uint8_t v, uint8_t al)
Set from gray value and alpha.
Definition: al_Color.hpp:384
Colori(const HCLab &hclab, float a=1.f)
Definition: al_Color.hpp:318
Colori & set(uint8_t re, uint8_t gr, uint8_t bl)
Set RGB components.
Definition: al_Color.hpp:367
Colori & operator=(const Color &v)
Set from floating-point color.
Definition: al_Color.hpp:341
uint32_t rgba
RGBA components packed into 32-bit integer.
Definition: al_Color.hpp:274
uint8_t g
Green component in [0, 255].
Definition: al_Color.hpp:269
Colori & operator=(const HCLab &v)
Set RGB components from HCLab.
Colori & operator=(const Luv &v)
Set RGB components from Luv.
const uint8_t & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:338
Colori(const Color &c)
Definition: al_Color.hpp:294
Colori & operator=(const Lab &v)
Set RGB components from Lab.
uint8_t & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:335
Colori(const CIE_XYZ &xyz, float a=1.f)
Definition: al_Color.hpp:306
Colori & operator=(const CIE_XYZ &v)
Set RGB components from CIE_XYZ.
Colori & operator=(const HCLuv &v)
Set RGB components from HCLuv.
Colori(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Definition: al_Color.hpp:281
Colori(const RGB &rgb, uint8_t a=255)
Definition: al_Color.hpp:302
Colori & invert()
Invert RGB components.
Definition: al_Color.hpp:390
uint8_t b
Blue component in [0, 255].
Definition: al_Color.hpp:270
uint8_t a
Alpha component in [0, 255].
Definition: al_Color.hpp:271
uint8_t components[4]
RGBA component vector.
Definition: al_Color.hpp:273
Colori(const Luv &luv, float a=1.f)
Definition: al_Color.hpp:324
Colori(const HCLuv &hcluv, float a=1.f)
Definition: al_Color.hpp:330
Colori(uint8_t gray=255, uint8_t a=255)
Definition: al_Color.hpp:290
HCLab & operator=(const HSV &v)
Set from HSV color.
Definition: al_Color.hpp:854
HCLab(const Lab &v)
Definition: al_Color.hpp:836
float c
< hue component in [0, 1]
Definition: al_Color.hpp:803
HCLab(const T *HCLab)
Definition: al_Color.hpp:818
HCLab operator*(float a) const
Get new HCLab with value component multiplied by a scalar.
Definition: al_Color.hpp:863
float l
Definition: al_Color.hpp:805
HCLab & operator=(const Colori &v)
Set from RGBA color.
Definition: al_Color.hpp:848
HCLab & wrapHue()
Wrap hue value into valid interval [0, 1)
Definition: al_Color.hpp:878
HCLab & operator=(const Color &v)
Set from RGBA color.
Definition: al_Color.hpp:845
HCLab & rotateHue(float dh)
Rotate hue in interval [0, 1)
Definition: al_Color.hpp:872
HCLab(const Colori &v)
Definition: al_Color.hpp:824
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:842
HCLab & operator=(const RGB &v)
Set from RGB color.
Definition: al_Color.hpp:851
HCLab(const RGB &v)
Definition: al_Color.hpp:827
HCLab(const CIE_XYZ &v)
Definition: al_Color.hpp:833
HCLab & operator=(const Lab &v)
Set from Lab color.
HCLab & operator*=(float a)
Multiply luminance component by a scalar.
Definition: al_Color.hpp:866
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:839
HCLab & operator=(const CIE_XYZ &v)
Set from CIE_XYZ color.
Definition: al_Color.hpp:857
float h
Definition: al_Color.hpp:802
HCLab(float h=1, float c=1, float l=1)
Definition: al_Color.hpp:814
HCLab(const Color &v)
Definition: al_Color.hpp:821
HCLab(const HSV &v)
Definition: al_Color.hpp:830
HCLuv(const HSV &w)
Definition: al_Color.hpp:1003
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:1012
HCLuv(const Color &w)
Definition: al_Color.hpp:994
HCLuv & operator=(const RGB &w)
Set from RGB color.
Definition: al_Color.hpp:1024
float c
< hue component in [0, 1]
Definition: al_Color.hpp:976
HCLuv operator*(float a) const
Get new HCLuv with value component multiplied by a scalar.
Definition: al_Color.hpp:1036
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:1015
float l
Definition: al_Color.hpp:978
HCLuv & rotateHue(float dh)
Rotate hue in interval [0, 1)
Definition: al_Color.hpp:1045
HCLuv & operator=(const Colori &w)
Set from RGBA color.
Definition: al_Color.hpp:1021
HCLuv & operator=(const CIE_XYZ &w)
Set from CIE_XYZ color.
Definition: al_Color.hpp:1030
HCLuv(const CIE_XYZ &w)
Definition: al_Color.hpp:1006
HCLuv(const Colori &w)
Definition: al_Color.hpp:997
HCLuv(float h=1, float c=1, float l=1)
Definition: al_Color.hpp:987
HCLuv(const RGB &w)
Definition: al_Color.hpp:1000
HCLuv(const T *HCLuv)
Definition: al_Color.hpp:991
HCLuv & operator=(const Luv &w)
Set from Luv color.
HCLuv & operator=(const Color &w)
Set from RGBA color.
Definition: al_Color.hpp:1018
HCLuv & operator=(const HSV &w)
Set from HSV color.
Definition: al_Color.hpp:1027
HCLuv(const Luv &w)
Definition: al_Color.hpp:1009
HCLuv & operator*=(float a)
Multiply luminance component by a scalar.
Definition: al_Color.hpp:1039
HCLuv & wrapHue()
Wrap hue value into valid interval [0, 1)
Definition: al_Color.hpp:1051
Color represented by hue, saturation, and value.
Definition: al_Color.hpp:397
HSV(const Colori &v)
Definition: al_Color.hpp:420
HSV & operator=(const HCLuv &v)
Set from HCLuv color.
float h
Hue component in [0, 1].
Definition: al_Color.hpp:400
HSV & operator*=(float a)
Multiply value component by a scalar.
Definition: al_Color.hpp:474
HSV & wrapHue()
Wrap hue value into valid interval [0, 1)
Definition: al_Color.hpp:486
HSV operator*(float a) const
Get new HSV with value component multiplied by a scalar.
Definition: al_Color.hpp:471
HSV & operator=(const HCLab &v)
Set from HCLab color.
HSV(const Lab &lab)
Definition: al_Color.hpp:429
HSV(float h=0, float s=1, float v=1)
Definition: al_Color.hpp:410
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:441
HSV(const RGB &v)
Definition: al_Color.hpp:423
float components[3]
HSV component vector.
Definition: al_Color.hpp:404
HSV(const T *hsv)
Definition: al_Color.hpp:414
HSV & operator=(const Color &v)
Set from RGBA color.
Definition: al_Color.hpp:447
HSV & operator=(const RGB &v)
Set from RGB color.
float v
Value component in [0, 1].
Definition: al_Color.hpp:402
HSV & operator=(const Luv &v)
Set from Luv color.
HSV & operator=(const CIE_XYZ &v)
Set from CIE_XYZ color.
HSV(const HCLuv &hcluv)
Definition: al_Color.hpp:438
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:444
HSV & operator=(const Colori &v)
Set from RGBA color.
Definition: al_Color.hpp:450
HSV & rotateHue(float dh)
Rotate hue in interval [0, 1)
Definition: al_Color.hpp:480
HSV(const Luv &luv)
Definition: al_Color.hpp:435
HSV(const CIE_XYZ &xyz)
Definition: al_Color.hpp:426
HSV(const HCLab &hclab)
Definition: al_Color.hpp:432
HSV(const Color &v)
Definition: al_Color.hpp:417
float s
Saturation component in [0, 1].
Definition: al_Color.hpp:401
HSV & operator=(const Lab &v)
Set from Lab color.
Lab(const T *Lab)
Definition: al_Color.hpp:741
Lab & operator=(const Colori &v)
Set from RGBA color.
Definition: al_Color.hpp:771
Lab & operator*=(float c)
Multiply lightness component by a scalar.
Definition: al_Color.hpp:788
Lab operator*(float c) const
Get new Lab with value component multiplied by a scalar.
Definition: al_Color.hpp:785
Lab & operator=(const CIE_XYZ &v)
Set from CIE_XYZ color.
Lab(const RGB &v)
Definition: al_Color.hpp:750
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:765
Lab(const CIE_XYZ &v)
Definition: al_Color.hpp:756
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:762
float a
< Lightness component in [0, 100]
Definition: al_Color.hpp:723
Lab(float l=1, float a=1, float b=1)
Definition: al_Color.hpp:737
Lab & operator=(const Color &v)
Set from RGBA color.
Definition: al_Color.hpp:768
Lab(const Color &v)
Definition: al_Color.hpp:744
Lab(const Colori &v)
Definition: al_Color.hpp:747
Lab & operator=(const HSV &v)
Set from HSV color.
Definition: al_Color.hpp:780
float b
Definition: al_Color.hpp:725
Lab(const HSV &v)
Definition: al_Color.hpp:753
Lab & operator=(const RGB &v)
Set from RGB color.
Definition: al_Color.hpp:777
Lab(const HCLab &v)
Definition: al_Color.hpp:759
Luv(const CIE_XYZ &w)
Definition: al_Color.hpp:928
Luv & operator=(const HCLuv &w)
Set from HCLuv color.
float v
Definition: al_Color.hpp:897
float u
< Lightness component in [0, 100]
Definition: al_Color.hpp:895
Luv & operator=(const HSV &w)
Set from HSV color.
Definition: al_Color.hpp:955
Luv & operator*=(float a)
Multiply lightness component by a scalar.
Definition: al_Color.hpp:961
Luv(const Colori &w)
Definition: al_Color.hpp:919
Luv(const T *Luv)
Definition: al_Color.hpp:913
Luv operator*(float a) const
Get new Luv with value component multiplied by a scalar.
Definition: al_Color.hpp:958
Luv & operator=(const Colori &w)
Set from RGBA color.
Definition: al_Color.hpp:943
Luv & operator=(const RGB &w)
Set from RGB color.
Definition: al_Color.hpp:952
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:937
Luv(const HCLuv &w)
Definition: al_Color.hpp:931
Luv(const HSV &w)
Definition: al_Color.hpp:925
Luv(const RGB &w)
Definition: al_Color.hpp:922
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:934
Luv & operator=(const Color &w)
Set from RGBA color.
Definition: al_Color.hpp:940
Luv(const Color &w)
Definition: al_Color.hpp:916
Luv & operator=(const CIE_XYZ &w)
Set from CIE_XYZ color.
Luv(float l=1, float u=1, float v=1)
Definition: al_Color.hpp:909
Color represented by red, green, and blue components.
Definition: al_Color.hpp:503
RGB & operator=(float v)
Set from gray value.
Definition: al_Color.hpp:576
RGB & operator=(const CIE_XYZ &v)
Set RGB components from CIE_XYZ.
RGB inverse() const
Returns inverted color.
Definition: al_Color.hpp:640
RGB(const HCLuv &hcluv)
Definition: al_Color.hpp:547
RGB & operator=(const Lab &v)
Set RGB components from Lab.
RGB & operator=(const Color &v)
Set RGB components from Color.
Definition: al_Color.hpp:583
RGB(const Colori &v)
Definition: al_Color.hpp:529
RGB(const Luv &luv)
Definition: al_Color.hpp:544
bool operator==(const RGB &v) const
Return true if all components are equal, false otherwise.
Definition: al_Color.hpp:604
float luminance() const
Returns luminance value (following ITU-R BT.601)
Definition: al_Color.hpp:646
const float & operator[](int i) const
Get color component at index with no bounds checking.
Definition: al_Color.hpp:553
float b
Blue component in [0, 1].
Definition: al_Color.hpp:508
float r
Red component in [0, 1].
Definition: al_Color.hpp:506
RGB & operator=(const Luv &v)
Set RGB components from Luv.
RGB(const HCLab &hclab)
Definition: al_Color.hpp:541
RGB(const Lab &lab)
Definition: al_Color.hpp:538
RGB(float r, float g, float b)
Definition: al_Color.hpp:516
RGB & clamp(float max=1.f)
Clamp all components into [0,max] range.
Definition: al_Color.hpp:631
RGB(const T *rgb)
Definition: al_Color.hpp:520
RGB mix(const RGB &v, float amt=0.5f) const
Returns self linearly mixed with another color (0 = none)
Definition: al_Color.hpp:649
RGB & set(const T *rgb)
Set from an array of RGB components.
Definition: al_Color.hpp:571
RGB & operator=(const HCLuv &v)
Set RGB components from HCLuv.
RGB & set(float re, float gr, float bl)
Set from RGB components.
Definition: al_Color.hpp:559
float & operator[](int i)
Set color component at index with no bounds checking.
Definition: al_Color.hpp:550
RGB & set(const RGB &v)
Set from another RGB.
Definition: al_Color.hpp:556
RGB(const Color &v)
Definition: al_Color.hpp:526
RGB(const CIE_XYZ &xyz)
Definition: al_Color.hpp:535
RGB & operator=(const HCLab &v)
Set RGB components from HCLab.
RGB & operator=(const HSV &v)
Set RGB components from HSV.
RGB & invert()
Invert RGB components.
Definition: al_Color.hpp:643
float g
Green component in [0, 1].
Definition: al_Color.hpp:507
RGB & set(float v)
Set from gray value.
Definition: al_Color.hpp:567
RGB(const HSV &hsv)
Definition: al_Color.hpp:532
RGB(float gray=1.f)
Definition: al_Color.hpp:523
bool operator!=(const RGB &v) const
Return true if components are not equal, false otherwise.
Definition: al_Color.hpp:609
float components[3]
RGB component vector.
Definition: al_Color.hpp:510