cgv
Loading...
Searching...
No Matches
color.h
1#pragma once
2
3#include <iostream>
4#include <limits>
5#include <cgv/defines/assert.h>
6#include <cgv/type/func/promote.h>
7#include <cgv/type/func/promote_const.h>
8#include <cgv/type/traits/max.h>
9#include <cgv/type/info/type_name.h>
10#include "color_model.h"
11#include <math.h>
12
13namespace cgv {
14namespace media {
15
16template <typename T>
18{
19 static T value() { return type::traits::max<T>::value; }
20};
21template <>
22struct color_one<float>
23{
24 static float value() { return 1.0f; }
25};
26template <>
27struct color_one<double>
28{
29 static double value() { return 1.0; }
30};
31template <ColorModel cm>
33 static const unsigned int nr_components = 3;
34};
35template <>
36struct color_model_traits<LUM> {
37 static const unsigned int nr_components = 1;
38};
39template <AlphaModel am>
41 static const unsigned int nr_components = 1;
42};
43template <>
44struct alpha_model_traits<NO_ALPHA> {
45 static const unsigned int nr_components = 0;
46};
47
49template <typename T, ColorModel cm, AlphaModel am = NO_ALPHA>
51{
52public:
60 typedef T component_type;
64 template <typename T2, ColorModel cm2, AlphaModel am2>
66 convert_color(c2, *this);
67 }
69 T& at(unsigned int i) { return components[i]; }
71 const T& at(unsigned int i) const { return components[i]; }
73 T& alpha() { return components[nr_color_components]; }
75 const T& alpha() const { return components[nr_color_components]; }
76protected:
77 T components[nr_components];
78};
79
80// forward declaration of color class
81template <typename T, ColorModel cm = RGB, AlphaModel = NO_ALPHA>
82class color;
83
85template <typename T, AlphaModel am>
87{
88 T& alpha_ref;
89 template <ColorModel cm>
90 alpha_reference(color_base<T, cm, am>& c) : alpha_ref(c.alpha()) {}
91};
93template <typename T>
94struct alpha_reference<T,NO_ALPHA>
95{
96 T& ref_dummy_alpha() { static T dummy_alpha = color_one<T>::value(); return dummy_alpha; }
97 T& alpha_ref;
98 template <ColorModel cm>
99 alpha_reference(color_base<T,cm,NO_ALPHA>& c) : alpha_ref(ref_dummy_alpha()) {}
100};
102template <typename T, AlphaModel am>
104{
105 const T& alpha_ref;
106 template <ColorModel cm>
107 const_alpha_reference(const color_base<T, cm, am>& c) : alpha_ref(c.alpha()) {}
108};
110template <typename T>
111struct const_alpha_reference<T,NO_ALPHA>
112{
113 const T& ref_dummy_alpha() { static T dummy_alpha = color_one<T>::value(); return dummy_alpha; }
114 const T& alpha_ref;
115 template <ColorModel cm>
116 const_alpha_reference(const color_base<T,cm,NO_ALPHA>& c) : alpha_ref(ref_dummy_alpha()) {}
117};
118
119/*********************************************************************
120**
121** component type conversion
122**
123*********************************************************************/
124
126template <typename T1, typename T2>
127inline void convert_color_component(const T1& from, T2& to) {
128 to = (T2)((typename type::func::promote<T1,T2>::type)(from)*color_one<T2>::value()/color_one<T1>::value());
129}
131template <>
132inline void convert_color_component(const unsigned int& from, unsigned short& to) {
133 to = from >> 16;
134}
136template <>
137inline void convert_color_component(const unsigned int& from, unsigned char& to) {
138 to = from >> 24;
139}
141template <>
142inline void convert_color_component(const unsigned short& from, unsigned char& to) {
143 to = from >> 8;
144}
146template <>
147inline void convert_color_component(const unsigned short& from, unsigned int& to) {
148 to = (unsigned int) from << 16;
149}
151template <>
152inline void convert_color_component(const unsigned char& from, unsigned int& to) {
153 to = (unsigned int)from << 24;
154}
156template <>
157inline void convert_color_component(const unsigned char& from, unsigned short& to) {
158 to = (unsigned short)from << 8;
159}
160
161/*********************************************************************
162** alpha model conversion
163*********************************************************************/
165template <typename T1, AlphaModel am1, typename T2, AlphaModel am2>
166inline void convert_alpha_model(const_alpha_reference<T1,am1> from, alpha_reference<T2,am2> to)
167{
168 color<typename type::func::promote<T1,T2>::type,LUM,OPACITY> tmp;
169 alpha_reference<typename type::func::promote<T1, T2>::type, OPACITY> ref(tmp);
170 convert_alpha_model(from,tmp);
171 convert_alpha_model(tmp,to);
172}
174template <typename T1, typename T2>
175void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, OPACITY> to)
176{
177 to.alpha_ref = color_one<T2>::value();
178}
180template <typename T1, typename T2>
181void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, TRANSPARENCY> to)
182{
183 to.alpha_ref = T2(0);
184}
186template <typename T1, typename T2>
187void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, EXTINCTION> to)
188{
189 to.alpha_ref = color_one<T2>::value();
190}
192template <typename T1, typename T2>
193void convert_alpha_model(const_alpha_reference<T1, OPACITY> from, alpha_reference<T2, TRANSPARENCY> to)
194{
195 convert_color_component(from.alpha_ref, to.alpha_ref);
196 to.alpha_ref = color_one<T2>::value() - to.alpha_ref;
197}
199template <typename T1, typename T2>
200void convert_alpha_model(const_alpha_reference<T1, TRANSPARENCY> from, alpha_reference<T2, OPACITY> to)
201{
202 convert_color_component(from.alpha_ref, to.alpha_ref);
203 to.alpha_ref = color_one<T2>::value() - to.alpha_ref;
204}
206template <typename T1, typename T2>
207void convert_alpha_model(const_alpha_reference<T1, OPACITY> from, alpha_reference<T2, EXTINCTION> to)
208{
209 double tmp;
210 convert_color_component(from.alpha_ref, tmp);
211 tmp = -log(1 - tmp);
212 convert_color_component(tmp, to.alpha_ref);
213}
215template <typename T1, typename T2>
216void convert_alpha_model(const_alpha_reference<T1, EXTINCTION> from, alpha_reference<T2, OPACITY> to)
217{
218 double tmp;
219 convert_color_component(from.alpha_ref, tmp);
220 tmp = 1 - exp(-tmp);
221 convert_color_component(tmp, to.alpha_ref);
222}
224template <typename T1, AlphaModel am1, typename T2>
225void convert_alpha_model(const_alpha_reference<T1, am1> from, alpha_reference<T2, NO_ALPHA> to)
226{
227}
229template <typename T1, typename T2>
230void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, NO_ALPHA> to)
231{
232}
234template <typename T1, AlphaModel am, typename T2>
235void convert_alpha_model(const_alpha_reference<T1, am> from, alpha_reference<T2, am> to)
236{
237 convert_color_component(from.alpha_ref, to.alpha_ref);
238}
239
240/*********************************************************************
241**
242** color model conversions
243**
244*********************************************************************/
246template <typename T1, ColorModel cm1, typename T2, ColorModel cm2>
247inline void convert_color_model(const color_base<T1, cm1>& from, color_base<T2, cm2>& to)
248{
249 color_base<typename type::func::promote<T1, T2>::type, XYZ> tmp;
250 convert_color_model(from, tmp);
251 convert_color_model(tmp, to);
252}
254template <typename T1, ColorModel cm, typename T2>
255void convert_color_model(const color_base<T1, cm>& from, color_base<T2, cm>& to)
256{
257 for (unsigned int i = 0; i < color_base<T1, cm>::nr_components; ++i)
258 convert_color_component(from.at(i), to.at(i));
259}
261template <typename T1, ColorModel cm1, typename T2>
262void convert_color_model(const color_base<T1, cm1>& from, color_base<T2, XYZ>& to)
263{
264 std::cerr << "conversion not implemented" << std::endl;
265}
267template <typename T1, ColorModel cm2, typename T2>
268void convert_color_model(const color_base<T1, XYZ>& from, color_base<T2, cm2>& to)
269{
270 std::cerr << "conversion not implemented" << std::endl;
271}
273template <typename T1, typename T2>
274void convert_color_model(const color_base<T1, LUM>& c1, color_base<T2, XYZ>& c2) {
275 c2.at(0) = 0;
276 c2.at(2) = 0;
277 convert_color_component(c1.at(0), c2.at(1));
278}
280template <typename T1, typename T2>
281void convert_color_model(const color_base<T1, XYZ>& c1, color_base<T2, LUM>& c2) {
282 convert_color_component(c1.at(1), c2.at(0));
283}
285template <typename T1, typename T2>
286void convert_color_model(const color_base<T1, RGB>& _c1, color_base<T2, XYZ>& c2) {
287 color_base<double, RGB> c1;
288 convert_color_model(_c1,c1);
289 convert_color_component(0.412453 * c1.at(0) + 0.357580 * c1.at(1) + 0.180423 * c1.at(2), c2.at(0));
290 convert_color_component(0.212671 * c1.at(0) + 0.715160 * c1.at(1) + 0.072169 * c1.at(2), c2.at(1));
291 convert_color_component(0.019334 * c1.at(0) + 0.119193 * c1.at(1) + 0.950227 * c1.at(2), c2.at(2));
292}
294template <typename T1, typename T2>
295void convert_color_model(const color_base<T1, XYZ>& _c1, color_base<T2, RGB>& c2) {
296 color_base<double, XYZ> c1(_c1);
297 convert_color_model(_c1, c1);
298 convert_color_component(3.2404813432 * c1.at(0) - 1.5371515163 * c1.at(1) - 0.4985363262 * c1.at(2), c2.at(0));
299 convert_color_component(-0.9692549500 * c1.at(0) + 1.8759900015 * c1.at(1) + 0.0415559266 * c1.at(2), c2.at(1));
300 convert_color_component(0.0556466391 * c1.at(0) - 0.2040413384 * c1.at(1) + 1.0573110696 * c1.at(2), c2.at(2));
301}
303template <typename T1, typename T2>
304void convert_color_model(const color_base<T1, RGB>& rgb, color_base<T2, HLS>& hls) {
305 double mx, mn;
306 convert_color_component(std::max(rgb.at(0), std::max(rgb.at(1), rgb.at(2))), mx);
307 convert_color_component(std::min(rgb.at(0), std::min(rgb.at(1), rgb.at(2))), mn);
308 double LL = (mx + mn) / 2;
309 if (mn == mx) {
310 hls.at(0) = hls.at(2) = 0;
311 convert_color_component(LL, hls.at(1));
312 }
313 else {
314 double DM = mx - mn;
315 double SM = mx + mn;
316 double SS = (LL <= 0.5) ? DM / SM : DM / (2 - SM);
317 color_base<double, RGB> c;
318 convert_color_model(rgb, c);
319 double HH;
320 if (c.at(0) == mx) HH = (c.at(1) - c.at(2)) / DM;
321 else if (c.at(1) == mx) HH = 2 + (c.at(2) - c.at(0)) / DM;
322 else HH = 4 + (c.at(0) - c.at(1)) / DM;
323 if (HH < 0) HH += 6;
324 HH /= 6;
325 convert_color_component(HH, hls.at(0));
326 convert_color_component(LL, hls.at(1));
327 convert_color_component(SS, hls.at(2));
328 }
329}
331template <typename T1, typename T2>
332void convert_color_model(const color_base<T1, HLS>& hls, color_base<T2, RGB>& rgb) {
333 double HH, LL, SS;
334 convert_color_component(hls.at(0), HH); HH *= 6;
335 convert_color_component(hls.at(1), LL);
336 convert_color_component(hls.at(2), SS);
337 int I = (int)HH;
338 double F = HH - I;
339 while (I >= 6) I -= 6;
340 double mx = (LL <= 0.5) ? LL * (1 + SS) : LL + SS - LL * SS;
341 double mn = 2 * LL - mx;
342 double DM = mx - mn;
343 if (SS == 0) {
344 T2 tmp;
345 convert_color_component(LL, tmp);
346 rgb.at(0) = rgb.at(1) = rgb.at(2) = tmp;
347 }
348 else {
349 switch (I) {
350 case 0:
351 convert_color_component(mx, rgb.at(0));
352 convert_color_component(mn + F * DM, rgb.at(1));
353 convert_color_component(mn, rgb.at(2));
354 break;
355 case 1:
356 convert_color_component(mn + (1 - F) * DM, rgb.at(0));
357 convert_color_component(mx, rgb.at(1));
358 convert_color_component(mn, rgb.at(2));
359 break;
360 case 2:
361 convert_color_component(mn, rgb.at(0));
362 convert_color_component(mx, rgb.at(1));
363 convert_color_component(mn + F * DM, rgb.at(2));
364 break;
365 case 3:
366 convert_color_component(mn, rgb.at(0));
367 convert_color_component(mn + (1 - F) * DM, rgb.at(1));
368 convert_color_component(mx, rgb.at(2));
369 break;
370 case 4:
371 convert_color_component(mn + F * DM, rgb.at(0));
372 convert_color_component(mn, rgb.at(1));
373 convert_color_component(mx, rgb.at(2));
374 break;
375 case 5:
376 convert_color_component(mx, rgb.at(0));
377 convert_color_component(mn, rgb.at(1));
378 convert_color_component(mn + (1 - F) * DM, rgb.at(2));
379 break;
380 }
381 }
382}
384template <typename T1, typename T2>
385void convert_color_model(const color_base<T1, HLS>& c1, color_base<T2, XYZ>& c2) {
386 color_base<typename type::func::promote<T1, T2>::type, RGB> tmp;
387 convert_color_model(c1, tmp);
388 convert_color_model(tmp, c2);
389}
391template <typename T1, typename T2>
392void convert_color_model(const color_base<T1, XYZ>& c1, color_base<T2, HLS>& c2) {
393 color_base<typename type::func::promote<T1, T2>::type, RGB> tmp;
394 convert_color_model(c1, tmp);
395 convert_color_model(tmp, c2);
396}
397
399template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
400inline void convert_color(const color_base<T1,cm1,am1>& from, color_base<T2,cm2,am2>& to)
401{
402 convert_color_model(reinterpret_cast<const color_base<T1,cm1>&>(from),reinterpret_cast<color_base<T2,cm2>&>(to));
403 convert_alpha_model(const_alpha_reference<T1,am1>(from),alpha_reference<T2,am2>(to));
404}
405
407template <typename ta_derived> struct rgb_color_interface {};
409template <typename T, ColorModel cm, AlphaModel am>
410struct rgb_color_interface<color<T,cm,am> > : public color_base<T,cm,am>
411{
413 T R() const { return color_base<T,RGB>(*this).at(0); }
415 T G() const { return color_base<T, RGB>(*this).at(1); }
417 T B() const { return color_base<T, RGB>(*this).at(2); }
418};
420template <typename T, AlphaModel am>
421struct rgb_color_interface<color<T,RGB,am> > : public color_base<T, RGB,am>
422{
424 T& R() { return this->at(0); }
426 const T& R() const { return this->at(0); }
428 T& G() { return this->at(1); }
430 const T& G() const { return this->at(1); }
432 T& B() { return this->at(2); }
434 const T& B() const { return this->at(2); }
435};
436
438template <typename ta_derived> struct hls_color_interface {};
440template <typename T, ColorModel cm, AlphaModel am>
441struct hls_color_interface<color<T,cm,am> > : public rgb_color_interface<color<T, cm, am> >
442{
444 T H() const { return color_base<T, HLS>(*this).at(0); }
446 T L() const { return color_base<T, HLS>(*this).at(1); }
448 T S() const { return color_base<T, HLS>(*this).at(2); }
449};
451template <typename T, AlphaModel am>
452struct hls_color_interface<color<T,HLS,am> > : public rgb_color_interface<color<T, HLS, am> >
453{
455 T& H() { return this->at(0); }
457 const T& H() const { return this->at(0); }
459 T& L() { return this->at(1); }
461 const T& L() const { return this->at(1); }
463 T& S() { return this->at(2); }
465 const T& S() const { return this->at(2); }
466};
467
469template <typename ta_derived> struct xyz_color_interface {};
471template <typename T, ColorModel cm, AlphaModel am>
472struct xyz_color_interface<color<T,cm,am> > : public hls_color_interface<color<T, cm, am> >
473{
475 T X() const { return color_base<T,XYZ>(*this).at(0); }
477 T Y() const { return color_base<T, XYZ>(*this).at(1); }
479 T Z() const { return color_base<T, XYZ>(*this).at(2); }
480};
482template <typename T, AlphaModel am>
483struct xyz_color_interface<color<T,XYZ,am> > : public hls_color_interface<color<T, XYZ, am> >
484{
486 T& X() { return this->at(0); }
488 const T& X() const { return this->at(0); }
490 T& Y() { return this->at(1); }
492 const T& Y() const { return this->at(1); }
494 T& Z() { return this->at(2); }
496 const T& Z() const { return this->at(2); }
497};
498
500template <typename ta_derived> struct opacity_alpha_interface {};
502template <typename T, ColorModel cm, AlphaModel am>
503struct opacity_alpha_interface<color<T,cm,am> > : public xyz_color_interface<color<T, cm, am> >
504{
506 T opacity() const {
508 alpha_reference<T, OPACITY> opa_ref(opa);
509 convert_alpha_model(const_alpha_reference<T, am>(*this), opa_ref);
510 return opa_ref.alpha_ref;
511 }
512};
514template <typename T, ColorModel cm>
515struct opacity_alpha_interface<color<T,cm,OPACITY> > :public xyz_color_interface<color<T, cm, OPACITY> >
516{
518 T& opacity() { return this->alpha(); }
520 const T& opacity() const { return this->alpha(); }
521};
522
524template <typename ta_derived> struct transparency_alpha_interface{};
526template <typename T, ColorModel cm, AlphaModel am>
527struct transparency_alpha_interface<color<T,cm,am> > : public opacity_alpha_interface<color<T, cm, am> >
528{
530 T transparency() const {
533 convert_alpha_model(const_alpha_reference<T, am>(*this), tra_ref);
534 return tra_ref.alpha_ref;
535 }
536};
538template <typename T, ColorModel cm>
539struct transparency_alpha_interface<color<T,cm,TRANSPARENCY> > : public opacity_alpha_interface<color<T, cm, TRANSPARENCY> >
540{
542 T& transparency() { return this->alpha(); }
544 const T& transparency() const { return this->alpha(); }
545};
546
548template <typename ta_derived> struct extinction_alpha_interface {};
550template <typename T, ColorModel cm, AlphaModel am>
551struct extinction_alpha_interface<color<T,cm,am> > : public transparency_alpha_interface<color<T, cm, am> >
552{
554 T extinction() const {
557 convert_alpha_model(const_alpha_reference<T, am>(*this), ext_ref);
558 return ext_ref.alpha_ref;
559 }
560};
562template <typename T, ColorModel cm>
563struct extinction_alpha_interface<color<T,cm,EXTINCTION> > : public transparency_alpha_interface<color<T, cm, EXTINCTION> >
564{
566 T& extinction() { return this->alpha(); }
568 const T& extinction() const { return this->alpha(); }
569};
570
572template <typename T, ColorModel cm, AlphaModel am>
573class color : public extinction_alpha_interface<color<T,cm,am> >
574{
575public:
577 static const ColorModel clr_mod = cm;
579 static const AlphaModel alp_mod = am;
587 typedef T component_type;
589 color() { }
591 color(const T& c) { *this = c; }
593 color(const T& c0, const T& c1) {
594 this->components[0] = c0;
595 if (nr_components > 1)
596 this->components[1] = c1;
597 }
599 color(const T& c0, const T& c1, const T& c2) {
600 this->components[0] = c0;
601 if (nr_components > 1)
602 this->components[1] = c1;
603 if (nr_components > 2)
604 this->components[2] = c2;
605 }
607 color(const T& c0, const T& c1, const T& c2, const T& c3) {
608 this->components[0] = c0;
609 if (nr_components > 1)
610 this->components[1] = c1;
611 if (nr_components > 2)
612 this->components[2] = c2;
613 if (nr_components > 3)
614 this->components[3] = c3;
615 }
617 color(const color<T, cm>& c, T a) {
618 this->at(nr_components - 1) = a; // looks bit like a hack but avoids invalid access for NO_ALPHA
619 for (unsigned i = 0; i < nr_color_components; ++i)
620 this->at(i) = c[i];
621 }
623 template <typename T2, ColorModel cm2, AlphaModel am2>
625 convert_color(c2, *this);
626 }
628 template <typename T2, ColorModel cm2, AlphaModel am2>
630 convert_color(c2, *this);
631 return *this;
632 }
635 std::fill(this->components, this->components+nr_components, c);
636 return *this;
637 }
639 color<T,cm>& drop_alpha() { return *((color<T,cm>*)this); }
640 const color<T,cm>& drop_alpha() const { return *((const color<T,cm>*)this); }
642 template <typename T2, ColorModel cm2, AlphaModel am2>
644 color<T,cm,am> tmp(c2);
645 for (int i=0; i<nr_components; ++i)
646 this->at(i) *= tmp[i];
647 return *this;
648 }
650 template <typename T2, ColorModel cm2, AlphaModel am2>
652 color<T,cm,am> res(*this);
653 res *= c2;
654 return res;
655 }
658 for (unsigned i=0; i<nr_components; ++i)
659 this->at(i) *= c;
660 return *this;
661 }
663 template <typename T2>
666 for (unsigned i=0; i<nr_components; ++i)
667 res[i] = this->at(i)*c;
668 return res;
669 }
671 template <typename T2, ColorModel cm2, AlphaModel am2>
673 color<T,cm,am> tmp(c2);
674 for (unsigned i=0; i<nr_components; ++i)
675 this->at(i) += tmp[i];
676 return *this;
677 }
679 template <typename T2, ColorModel cm2, AlphaModel am2>
681 color<T,cm,am> res(*this);
682 res += c2;
683 return res;
684 }
687 for (unsigned i=0; i<nr_components; ++i)
688 this->at(i) += c;
689 return *this;
690 }
693 color<T,cm,am> res(*this);
694 res += c;
695 return res;
696 }
698 template <typename T2, ColorModel cm2, AlphaModel am2>
700 color<T, cm, am> tmp(c2);
701 for(unsigned i = 0; i < nr_components; ++i)
702 this->at(i) -= tmp[i];
703 return *this;
704 }
706 template <typename T2, ColorModel cm2, AlphaModel am2>
708 color<T, cm, am> res(*this);
709 res -= c2;
710 return res;
711 }
714 for(unsigned i = 0; i < nr_components; ++i)
715 this->at(i) -= c;
716 return *this;
717 }
720 color<T, cm, am> res(*this);
721 res -= c;
722 return res;
723 }
725 void clamp(const T& mn = 0, const T& mx = color_one<T>::value(), bool skip_alpha = false) {
726 unsigned nr = skip_alpha ? nr_color_components : nr_components;
727 for (unsigned i = 0; i < nr; ++i)
728 if (this->at(i) < mn)
729 this->at(i) = mn;
730 else if (this->at(i) > mx)
731 this->at(i) = mx;
732 }
734 T& operator [] (unsigned int i) { return this->at(i); }
736 const T& operator [] (unsigned int i) const { return this->at(i); }
737};
738
740#define CGV_MEDIA_COLOR_DECLARED
741
742/*********************************************************************
743**
744** operators
745**
746*********************************************************************/
747
749template <typename T, ColorModel cm, AlphaModel am>
750bool operator == (const color<T,cm,am>& c1, const color<T,cm,am>& c2) {
751 for (unsigned int i=0; i<color<T,cm,am>::nr_components; ++i)
752 if (c1[i] != c2[i])
753 return false;
754 return true;
755}
757template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
758color<typename type::func::promote<T1,T2>::type,cm1,am1> operator * (const color<T1,cm1,am1>& c1, const color<T2,cm2,am2>& c2) {
759 color<typename type::func::promote<T1,T2>::type,cm1,am1> res(c1);
760 res *= c2;
761 return res;
762}
764template <typename T1, typename T2, ColorModel cm2, AlphaModel am2>
765color<typename type::func::promote<T1,T2>::type,cm2,am2> operator * (const T1& c1, const color<T2,cm2,am2>& c2) {
766 color<typename type::func::promote<T1,T2>::type,cm2,am2> res(c2);
767 res *= c1;
768 return res;
769}
771template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
772color<typename type::func::promote<T1,T2>::type,cm1,am1> operator + (const color<T1,cm1,am1>& c1, const color<T2,cm2,am2>& c2) {
773 color<typename type::func::promote<T1,T2>::type,cm1,am1> res(c1);
774 res += c2;
775 return res;
776}
778template <typename T1, ColorModel cm1, AlphaModel am1>
779std::ostream& operator << (std::ostream& os, const color<T1,cm1,am1>& c) {
780 os << c[0];
781 for (unsigned int i=1; i<color<T1,cm1,am1>::nr_components; ++i)
782 os << " " << c[i];
783 return os;
784}
786template <typename T1, ColorModel cm1, AlphaModel am1>
787std::istream& operator >> (std::istream& is, color<T1,cm1,am1>& c) {
788 is >> c[0];
789 for (unsigned int i=1; i<color<T1,cm1,am1>::nr_components; ++i)
790 is >> c[i];
791 return is;
792}
794template <ColorModel cm, AlphaModel am>
795std::ostream& operator << (std::ostream& os, const color<unsigned char,cm,am>& c) {
796 os << (int)c[0];
797 for (unsigned int i=1; i<color<unsigned char,cm,am>::nr_components; ++i)
798 os << " " << (int)c[i];
799 return os;
800}
802template <ColorModel cm, AlphaModel am>
803std::istream& operator >> (std::istream& is, color<unsigned char,cm,am>& c) {
804 int tmp;
805 is >> tmp;
806 c[0] = (unsigned char)tmp;
807 for (unsigned int i=1; i<color<unsigned char,cm,am>::nr_components; ++i) {
808 is >> tmp;
809 c[i] = (unsigned char)tmp;
810 }
811 return is;
812}
813
814/*********************************************************************
815**
816** functions
817**
818*********************************************************************/
819
821template <typename T, ColorModel cm, AlphaModel am>
822const color<T,cm,am> lerp(const color<T,cm,am>& c1, const color<T,cm,am>& c2, T t) {
823 return ((T)1 - t) * c1 + t * c2;
824}
828template <typename T1, typename T2, AlphaModel am,
829 typename std::enable_if<std::is_integral<T1>::value, bool>::type = true,
830 typename std::enable_if<std::is_floating_point<T2>::value, bool>::type = true>
831const color<T1,RGB,am> pow(const color<T1,RGB,am>& c, T2 e) {
832 constexpr T2 m = static_cast<T2>(std::numeric_limits<T1>::max());
833 color<T1,RGB,am> x = c;
834 for(unsigned int i=0; i<color<T1,RGB,am>::nr_color_components; ++i)
835 x[i] = static_cast<T1>(std::pow(static_cast<T2>(c[i]) / m, e) * m);
836 return x;
837}
839template<typename T, AlphaModel am, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
840const color<T,RGB,am> pow(const color<T,RGB,am>& c, T e) {
841 color<T,RGB,am> x = c;
842 for(unsigned int i=0; i<color<T,RGB,am>::nr_color_components; ++i)
843 x[i] = std::pow(x[i], e);
844 return x;
845}
846
847} // namespace media
848
851
860
862
863} // namespace cgv
minimal data interface for color used to implement conversion.
Definition color.h:51
color_base()
standard constructor does not initialize components
Definition color.h:62
color_base(const color_base< T2, cm2, am2 > &c2)
copy constructor uses color conversion if necessary
Definition color.h:65
static const unsigned int nr_alpha_components
static and const access to number of alpha components
Definition color.h:56
const T & at(unsigned int i) const
const access to components
Definition color.h:71
T component_type
type of color components
Definition color.h:60
T & alpha()
return alpha component
Definition color.h:73
T & at(unsigned int i)
access to components
Definition color.h:69
static const unsigned int nr_color_components
static and const access to number of color components
Definition color.h:54
static const unsigned int nr_components
static and const access to total number of components
Definition color.h:58
const T & alpha() const
return alpha component
Definition color.h:75
represent a color with components of given type and color and alpha model as specified.
Definition color.h:574
color< T, cm, am > operator-(const color< T2, cm2, am2 > &c2)
subtract color
Definition color.h:707
static const unsigned int nr_alpha_components
static and const access to number of alpha components
Definition color.h:583
static const unsigned int nr_color_components
static and const access to number of color components
Definition color.h:581
void clamp(const T &mn=0, const T &mx=color_one< T >::value(), bool skip_alpha=false)
clamp to the given range, which defaults to [0,1] of the component type
Definition color.h:725
color(const T &c0, const T &c1, const T &c2)
set first three components to given values
Definition color.h:599
static const unsigned int nr_components
static and const access to total number of components
Definition color.h:585
static const AlphaModel alp_mod
static and const access to alpha model
Definition color.h:579
color(const T &c0, const T &c1, const T &c2, const T &c3)
set all four components to given values
Definition color.h:607
color< T, cm, am > & operator=(const color< T2, cm2, am2 > &c2)
assign to color with potential color conversion
Definition color.h:629
color(const T &c)
set all components to given value
Definition color.h:591
static const ColorModel clr_mod
static and const access to color model
Definition color.h:577
color< T, cm, am > operator*(const color< T2, cm2, am2 > &c2)
post multiply with color
Definition color.h:651
color< T, cm > & drop_alpha()
drop the alpha component if any by a cast operator
Definition color.h:639
color()
standard constructor does not initialize components
Definition color.h:589
color< T, cm, am > & operator+=(const color< T2, cm2, am2 > &c2)
add color
Definition color.h:672
T component_type
type of color components
Definition color.h:587
color(const color< T, cm > &c, T a)
construct from non-alpha color plus alpha
Definition color.h:617
color(const color< T2, cm2, am2 > &c2)
copy constructor uses color conversion if necessary
Definition color.h:624
color< T, cm, am > & operator-=(const color< T2, cm2, am2 > &c2)
subtract color
Definition color.h:699
color< T, cm, am > operator+(const color< T2, cm2, am2 > &c2)
add color
Definition color.h:680
color(const T &c0, const T &c1)
set first two components to given values
Definition color.h:593
T & operator[](unsigned int i)
access to components
Definition color.h:734
color< T, cm, am > & operator*=(const color< T2, cm2, am2 > &c2)
multiply with color
Definition color.h:643
the cgv namespace
Definition print.h:11
cgv::media::color< cgv::type::uint8_type, cgv::media::RGB, cgv::media::OPACITY > rgba8
declare rgba color type with 8 bit components
Definition color.h:859
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
Definition color.h:855
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:853
cgv::media::color< cgv::type::uint8_type, cgv::media::RGB > rgb8
declare rgb color type with 8 bit components
Definition color.h:857
captures reference to alpha component of color
Definition color.h:87
captures reference to alpha component of color
Definition color.h:104
const T & extinction() const
read access to extinction component
Definition color.h:568
T & extinction()
write access to extinction component
Definition color.h:566
T extinction() const
convert alpha to extinction
Definition color.h:554
the extinction_alpha_interface adds access function to the opacity, where write access is only grante...
Definition color.h:548
const T & L() const
read access to L component of HLS color
Definition color.h:461
T & H()
write access to H component of HLS color
Definition color.h:455
const T & S() const
read access to S component of HLS color
Definition color.h:465
const T & H() const
read access to H component of HLS color
Definition color.h:457
T & S()
write access to S component of HLS color
Definition color.h:463
T & L()
write access to L component of HLS color
Definition color.h:459
T H() const
convert color to HLS and return H component
Definition color.h:444
T S() const
convert color to HLS and return S component
Definition color.h:448
T L() const
convert color to HLS and return L component
Definition color.h:446
the hls_color_interface adds access function to the H, L, and S-channels of the color,...
Definition color.h:438
const T & opacity() const
read access to opacity component
Definition color.h:520
T & opacity()
write access to opacity component
Definition color.h:518
T opacity() const
convert alpha to opacity
Definition color.h:506
the opacity_alpha_interface adds access function to the opacity, where write access is only granted f...
Definition color.h:500
const T & R() const
read access to R component of RGB color
Definition color.h:426
const T & G() const
read access to G component of RGB color
Definition color.h:430
T & R()
write access to R component of RGB color
Definition color.h:424
T & B()
write access to B component of RGB color
Definition color.h:432
const T & B() const
read access to B component of RGB color
Definition color.h:434
T & G()
write access to G component of RGB color
Definition color.h:428
T B() const
convert color to RGB and return B component
Definition color.h:417
T R() const
convert color to RGB and return R component
Definition color.h:413
T G() const
convert color to RGB and return G component
Definition color.h:415
the rgb_color_interface adds access function to the R, G, and B-channels of the color,...
Definition color.h:407
T & transparency()
write access to transparency component
Definition color.h:542
const T & transparency() const
read access to transparency component
Definition color.h:544
T transparency() const
convert alpha to transparency
Definition color.h:530
the transparency_alpha_interface adds access function to the opacity, where write access is only gran...
Definition color.h:524
const T & X() const
read access to X component of XYZ color
Definition color.h:488
T & Y()
write access to Y component of XYZ color
Definition color.h:490
T & X()
write access to X component of XYZ color
Definition color.h:486
const T & Y() const
read access to Y component of XYZ color
Definition color.h:492
const T & Z() const
read access to Z component of XYZ color
Definition color.h:496
T & Z()
write access to Z component of XYZ color
Definition color.h:494
T Y() const
convert color to XYZ and return Y component
Definition color.h:477
T X() const
convert color to XYZ and return X component
Definition color.h:475
T Z() const
convert color to XYZ and return Z component
Definition color.h:479
the xyz_color_interface adds access function to the X, Y, and Z-channels of the color,...
Definition color.h:469
the max traits defines for each type in the static const member value, what the maximum value is.
Definition max.h:37