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 <cgv/utils/scan.h>
11#include "color_model.h"
12#include <math.h>
13
14namespace cgv {
15namespace media {
16
17template <typename T>
19{
20 static T value() { return type::traits::max<T>::value; }
21};
22template <>
23struct color_one<float>
24{
25 static float value() { return 1.0f; }
26};
27template <>
28struct color_one<double>
29{
30 static double value() { return 1.0; }
31};
32template <ColorModel cm>
34 static const unsigned int nr_components = 3;
35};
36template <>
37struct color_model_traits<LUM> {
38 static const unsigned int nr_components = 1;
39};
40template <AlphaModel am>
42 static const unsigned int nr_components = 1;
43};
44template <>
45struct alpha_model_traits<NO_ALPHA> {
46 static const unsigned int nr_components = 0;
47};
48
50template <typename T, ColorModel cm, AlphaModel am = NO_ALPHA>
52{
53public:
61 typedef T component_type;
65 template <typename T2, ColorModel cm2, AlphaModel am2>
67 convert_color(c2, *this);
68 }
70 T& at(unsigned int i) { return components[i]; }
72 const T& at(unsigned int i) const { return components[i]; }
74 T& alpha() { return components[nr_color_components]; }
76 const T& alpha() const { return components[nr_color_components]; }
77protected:
78 T components[nr_components];
79};
80
81// forward declaration of color class
82template <typename T, ColorModel cm = RGB, AlphaModel = NO_ALPHA>
83class color;
84
86template <typename T, AlphaModel am>
88{
89 T& alpha_ref;
90 template <ColorModel cm>
91 alpha_reference(color_base<T, cm, am>& c) : alpha_ref(c.alpha()) {}
92};
94template <typename T>
95struct alpha_reference<T,NO_ALPHA>
96{
97 T& ref_dummy_alpha() { static T dummy_alpha = color_one<T>::value(); return dummy_alpha; }
98 T& alpha_ref;
99 template <ColorModel cm>
100 alpha_reference(color_base<T,cm,NO_ALPHA>& c) : alpha_ref(ref_dummy_alpha()) {}
101};
103template <typename T, AlphaModel am>
105{
106 const T& alpha_ref;
107 template <ColorModel cm>
108 const_alpha_reference(const color_base<T, cm, am>& c) : alpha_ref(c.alpha()) {}
109};
111template <typename T>
112struct const_alpha_reference<T,NO_ALPHA>
113{
114 const T& ref_dummy_alpha() { static T dummy_alpha = color_one<T>::value(); return dummy_alpha; }
115 const T& alpha_ref;
116 template <ColorModel cm>
117 const_alpha_reference(const color_base<T,cm,NO_ALPHA>& c) : alpha_ref(ref_dummy_alpha()) {}
118};
119
120/*********************************************************************
121**
122** component type conversion
123**
124*********************************************************************/
125
127template <typename T1, typename T2>
128inline void convert_color_component(const T1& from, T2& to) {
129 to = (T2)((typename type::func::promote<T1,T2>::type)(from)*color_one<T2>::value()/color_one<T1>::value());
130}
132template <>
133inline void convert_color_component(const unsigned int& from, unsigned short& to) {
134 to = from >> 16;
135}
137template <>
138inline void convert_color_component(const unsigned int& from, unsigned char& to) {
139 to = from >> 24;
140}
142template <>
143inline void convert_color_component(const unsigned short& from, unsigned char& to) {
144 to = from >> 8;
145}
147template <>
148inline void convert_color_component(const unsigned short& from, unsigned int& to) {
149 to = (unsigned int) from << 16;
150}
152template <>
153inline void convert_color_component(const unsigned char& from, unsigned int& to) {
154 to = (unsigned int)from << 24;
155}
157template <>
158inline void convert_color_component(const unsigned char& from, unsigned short& to) {
159 to = (unsigned short)from << 8;
160}
161
162/*********************************************************************
163** alpha model conversion
164*********************************************************************/
166template <typename T1, AlphaModel am1, typename T2, AlphaModel am2>
167inline void convert_alpha_model(const_alpha_reference<T1,am1> from, alpha_reference<T2,am2> to)
168{
169 color<typename type::func::promote<T1,T2>::type,LUM,OPACITY> tmp;
170 alpha_reference<typename type::func::promote<T1, T2>::type, OPACITY> ref(tmp);
171 convert_alpha_model(from,tmp);
172 convert_alpha_model(tmp,to);
173}
175template <typename T1, typename T2>
176void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, OPACITY> to)
177{
178 to.alpha_ref = color_one<T2>::value();
179}
181template <typename T1, typename T2>
182void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, TRANSPARENCY> to)
183{
184 to.alpha_ref = T2(0);
185}
187template <typename T1, typename T2>
188void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, EXTINCTION> to)
189{
190 to.alpha_ref = color_one<T2>::value();
191}
193template <typename T1, typename T2>
194void convert_alpha_model(const_alpha_reference<T1, OPACITY> from, alpha_reference<T2, TRANSPARENCY> to)
195{
196 convert_color_component(from.alpha_ref, to.alpha_ref);
197 to.alpha_ref = color_one<T2>::value() - to.alpha_ref;
198}
200template <typename T1, typename T2>
201void convert_alpha_model(const_alpha_reference<T1, TRANSPARENCY> from, alpha_reference<T2, OPACITY> to)
202{
203 convert_color_component(from.alpha_ref, to.alpha_ref);
204 to.alpha_ref = color_one<T2>::value() - to.alpha_ref;
205}
207template <typename T1, typename T2>
208void convert_alpha_model(const_alpha_reference<T1, OPACITY> from, alpha_reference<T2, EXTINCTION> to)
209{
210 double tmp;
211 convert_color_component(from.alpha_ref, tmp);
212 tmp = -log(1 - tmp);
213 convert_color_component(tmp, to.alpha_ref);
214}
216template <typename T1, typename T2>
217void convert_alpha_model(const_alpha_reference<T1, EXTINCTION> from, alpha_reference<T2, OPACITY> to)
218{
219 double tmp;
220 convert_color_component(from.alpha_ref, tmp);
221 tmp = 1 - exp(-tmp);
222 convert_color_component(tmp, to.alpha_ref);
223}
225template <typename T1, AlphaModel am1, typename T2>
226void convert_alpha_model(const_alpha_reference<T1, am1> from, alpha_reference<T2, NO_ALPHA> to)
227{
228}
230template <typename T1, typename T2>
231void convert_alpha_model(const_alpha_reference<T1, NO_ALPHA> from, alpha_reference<T2, NO_ALPHA> to)
232{
233}
235template <typename T1, AlphaModel am, typename T2>
236void convert_alpha_model(const_alpha_reference<T1, am> from, alpha_reference<T2, am> to)
237{
238 convert_color_component(from.alpha_ref, to.alpha_ref);
239}
240
241/*********************************************************************
242**
243** color model conversions
244**
245*********************************************************************/
247template <typename T1, ColorModel cm1, typename T2, ColorModel cm2>
248inline void convert_color_model(const color_base<T1, cm1>& from, color_base<T2, cm2>& to)
249{
250 color_base<typename type::func::promote<T1, T2>::type, XYZ> tmp;
251 convert_color_model(from, tmp);
252 convert_color_model(tmp, to);
253}
255template <typename T1, ColorModel cm, typename T2>
256void convert_color_model(const color_base<T1, cm>& from, color_base<T2, cm>& to)
257{
258 for (unsigned int i = 0; i < color_base<T1, cm>::nr_components; ++i)
259 convert_color_component(from.at(i), to.at(i));
260}
262template <typename T1, ColorModel cm1, typename T2>
263void convert_color_model(const color_base<T1, cm1>& from, color_base<T2, XYZ>& to)
264{
265 std::cerr << "conversion not implemented" << std::endl;
266}
268template <typename T1, ColorModel cm2, typename T2>
269void convert_color_model(const color_base<T1, XYZ>& from, color_base<T2, cm2>& to)
270{
271 std::cerr << "conversion not implemented" << std::endl;
272}
274template <typename T1, typename T2>
275void convert_color_model(const color_base<T1, LUM>& c1, color_base<T2, XYZ>& c2) {
276 c2.at(0) = 0;
277 c2.at(2) = 0;
278 convert_color_component(c1.at(0), c2.at(1));
279}
281template <typename T1, typename T2>
282void convert_color_model(const color_base<T1, XYZ>& c1, color_base<T2, LUM>& c2) {
283 convert_color_component(c1.at(1), c2.at(0));
284}
286template <typename T1, typename T2>
287void convert_color_model(const color_base<T1, RGB>& _c1, color_base<T2, XYZ>& c2) {
288 color_base<double, RGB> c1;
289 convert_color_model(_c1,c1);
290 convert_color_component(0.412453 * c1.at(0) + 0.357580 * c1.at(1) + 0.180423 * c1.at(2), c2.at(0));
291 convert_color_component(0.212671 * c1.at(0) + 0.715160 * c1.at(1) + 0.072169 * c1.at(2), c2.at(1));
292 convert_color_component(0.019334 * c1.at(0) + 0.119193 * c1.at(1) + 0.950227 * c1.at(2), c2.at(2));
293}
295template <typename T1, typename T2>
296void convert_color_model(const color_base<T1, XYZ>& _c1, color_base<T2, RGB>& c2) {
297 color_base<double, XYZ> c1(_c1);
298 convert_color_model(_c1, c1);
299 convert_color_component(3.2404813432 * c1.at(0) - 1.5371515163 * c1.at(1) - 0.4985363262 * c1.at(2), c2.at(0));
300 convert_color_component(-0.9692549500 * c1.at(0) + 1.8759900015 * c1.at(1) + 0.0415559266 * c1.at(2), c2.at(1));
301 convert_color_component(0.0556466391 * c1.at(0) - 0.2040413384 * c1.at(1) + 1.0573110696 * c1.at(2), c2.at(2));
302}
304template <typename T1, typename T2>
305void convert_color_model(const color_base<T1, RGB>& rgb, color_base<T2, HLS>& hls) {
306 double mx, mn;
307 convert_color_component(std::max(rgb.at(0), std::max(rgb.at(1), rgb.at(2))), mx);
308 convert_color_component(std::min(rgb.at(0), std::min(rgb.at(1), rgb.at(2))), mn);
309 double LL = (mx + mn) / 2;
310 if (mn == mx) {
311 hls.at(0) = hls.at(2) = 0;
312 convert_color_component(LL, hls.at(1));
313 }
314 else {
315 double DM = mx - mn;
316 double SM = mx + mn;
317 double SS = (LL <= 0.5) ? DM / SM : DM / (2 - SM);
318 color_base<double, RGB> c;
319 convert_color_model(rgb, c);
320 double HH;
321 if (c.at(0) == mx) HH = (c.at(1) - c.at(2)) / DM;
322 else if (c.at(1) == mx) HH = 2 + (c.at(2) - c.at(0)) / DM;
323 else HH = 4 + (c.at(0) - c.at(1)) / DM;
324 if (HH < 0) HH += 6;
325 HH /= 6;
326 convert_color_component(HH, hls.at(0));
327 convert_color_component(LL, hls.at(1));
328 convert_color_component(SS, hls.at(2));
329 }
330}
332template <typename T1, typename T2>
333void convert_color_model(const color_base<T1, HLS>& hls, color_base<T2, RGB>& rgb) {
334 double HH, LL, SS;
335 convert_color_component(hls.at(0), HH); HH *= 6;
336 convert_color_component(hls.at(1), LL);
337 convert_color_component(hls.at(2), SS);
338 int I = (int)HH;
339 double F = HH - I;
340 while (I >= 6) I -= 6;
341 double mx = (LL <= 0.5) ? LL * (1 + SS) : LL + SS - LL * SS;
342 double mn = 2 * LL - mx;
343 double DM = mx - mn;
344 if (SS == 0) {
345 T2 tmp;
346 convert_color_component(LL, tmp);
347 rgb.at(0) = rgb.at(1) = rgb.at(2) = tmp;
348 }
349 else {
350 switch (I) {
351 case 0:
352 convert_color_component(mx, rgb.at(0));
353 convert_color_component(mn + F * DM, rgb.at(1));
354 convert_color_component(mn, rgb.at(2));
355 break;
356 case 1:
357 convert_color_component(mn + (1 - F) * DM, rgb.at(0));
358 convert_color_component(mx, rgb.at(1));
359 convert_color_component(mn, rgb.at(2));
360 break;
361 case 2:
362 convert_color_component(mn, rgb.at(0));
363 convert_color_component(mx, rgb.at(1));
364 convert_color_component(mn + F * DM, rgb.at(2));
365 break;
366 case 3:
367 convert_color_component(mn, rgb.at(0));
368 convert_color_component(mn + (1 - F) * DM, rgb.at(1));
369 convert_color_component(mx, rgb.at(2));
370 break;
371 case 4:
372 convert_color_component(mn + F * DM, rgb.at(0));
373 convert_color_component(mn, rgb.at(1));
374 convert_color_component(mx, rgb.at(2));
375 break;
376 case 5:
377 convert_color_component(mx, rgb.at(0));
378 convert_color_component(mn, rgb.at(1));
379 convert_color_component(mn + (1 - F) * DM, rgb.at(2));
380 break;
381 }
382 }
383}
385template <typename T1, typename T2>
386void convert_color_model(const color_base<T1, HLS>& c1, color_base<T2, XYZ>& c2) {
387 color_base<typename type::func::promote<T1, T2>::type, RGB> tmp;
388 convert_color_model(c1, tmp);
389 convert_color_model(tmp, c2);
390}
392template <typename T1, typename T2>
393void convert_color_model(const color_base<T1, XYZ>& c1, color_base<T2, HLS>& c2) {
394 color_base<typename type::func::promote<T1, T2>::type, RGB> tmp;
395 convert_color_model(c1, tmp);
396 convert_color_model(tmp, c2);
397}
398
400template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
401inline void convert_color(const color_base<T1,cm1,am1>& from, color_base<T2,cm2,am2>& to)
402{
403 convert_color_model(reinterpret_cast<const color_base<T1,cm1>&>(from),reinterpret_cast<color_base<T2,cm2>&>(to));
404 convert_alpha_model(const_alpha_reference<T1,am1>(from),alpha_reference<T2,am2>(to));
405}
406
408template <typename ta_derived> struct rgb_color_interface {};
410template <typename T, ColorModel cm, AlphaModel am>
411struct rgb_color_interface<color<T,cm,am> > : public color_base<T,cm,am>
412{
414 T R() const { return color_base<T,RGB>(*this).at(0); }
416 T G() const { return color_base<T, RGB>(*this).at(1); }
418 T B() const { return color_base<T, RGB>(*this).at(2); }
419};
421template <typename T, AlphaModel am>
422struct rgb_color_interface<color<T,RGB,am> > : public color_base<T, RGB,am>
423{
425 T& R() { return this->at(0); }
427 const T& R() const { return this->at(0); }
429 T& G() { return this->at(1); }
431 const T& G() const { return this->at(1); }
433 T& B() { return this->at(2); }
435 const T& B() const { return this->at(2); }
436};
437
439template <typename ta_derived> struct hls_color_interface {};
441template <typename T, ColorModel cm, AlphaModel am>
442struct hls_color_interface<color<T,cm,am> > : public rgb_color_interface<color<T, cm, am> >
443{
445 T H() const { return color_base<T, HLS>(*this).at(0); }
447 T L() const { return color_base<T, HLS>(*this).at(1); }
449 T S() const { return color_base<T, HLS>(*this).at(2); }
450};
452template <typename T, AlphaModel am>
453struct hls_color_interface<color<T,HLS,am> > : public rgb_color_interface<color<T, HLS, am> >
454{
456 T& H() { return this->at(0); }
458 const T& H() const { return this->at(0); }
460 T& L() { return this->at(1); }
462 const T& L() const { return this->at(1); }
464 T& S() { return this->at(2); }
466 const T& S() const { return this->at(2); }
467};
468
470template <typename ta_derived> struct xyz_color_interface {};
472template <typename T, ColorModel cm, AlphaModel am>
473struct xyz_color_interface<color<T,cm,am> > : public hls_color_interface<color<T, cm, am> >
474{
476 T X() const { return color_base<T,XYZ>(*this).at(0); }
478 T Y() const { return color_base<T, XYZ>(*this).at(1); }
480 T Z() const { return color_base<T, XYZ>(*this).at(2); }
481};
483template <typename T, AlphaModel am>
484struct xyz_color_interface<color<T,XYZ,am> > : public hls_color_interface<color<T, XYZ, am> >
485{
487 T& X() { return this->at(0); }
489 const T& X() const { return this->at(0); }
491 T& Y() { return this->at(1); }
493 const T& Y() const { return this->at(1); }
495 T& Z() { return this->at(2); }
497 const T& Z() const { return this->at(2); }
498};
499
501template <typename ta_derived> struct opacity_alpha_interface {};
503template <typename T, ColorModel cm, AlphaModel am>
504struct opacity_alpha_interface<color<T,cm,am> > : public xyz_color_interface<color<T, cm, am> >
505{
507 T opacity() const {
509 alpha_reference<T, OPACITY> opa_ref(opa);
510 convert_alpha_model(const_alpha_reference<T, am>(*this), opa_ref);
511 return opa_ref.alpha_ref;
512 }
513};
515template <typename T, ColorModel cm>
516struct opacity_alpha_interface<color<T,cm,OPACITY> > :public xyz_color_interface<color<T, cm, OPACITY> >
517{
519 T& opacity() { return this->alpha(); }
521 const T& opacity() const { return this->alpha(); }
522};
523
525template <typename ta_derived> struct transparency_alpha_interface{};
527template <typename T, ColorModel cm, AlphaModel am>
528struct transparency_alpha_interface<color<T,cm,am> > : public opacity_alpha_interface<color<T, cm, am> >
529{
531 T transparency() const {
534 convert_alpha_model(const_alpha_reference<T, am>(*this), tra_ref);
535 return tra_ref.alpha_ref;
536 }
537};
539template <typename T, ColorModel cm>
540struct transparency_alpha_interface<color<T,cm,TRANSPARENCY> > : public opacity_alpha_interface<color<T, cm, TRANSPARENCY> >
541{
543 T& transparency() { return this->alpha(); }
545 const T& transparency() const { return this->alpha(); }
546};
547
549template <typename ta_derived> struct extinction_alpha_interface {};
551template <typename T, ColorModel cm, AlphaModel am>
552struct extinction_alpha_interface<color<T,cm,am> > : public transparency_alpha_interface<color<T, cm, am> >
553{
555 T extinction() const {
558 convert_alpha_model(const_alpha_reference<T, am>(*this), ext_ref);
559 return ext_ref.alpha_ref;
560 }
561};
563template <typename T, ColorModel cm>
564struct extinction_alpha_interface<color<T,cm,EXTINCTION> > : public transparency_alpha_interface<color<T, cm, EXTINCTION> >
565{
567 T& extinction() { return this->alpha(); }
569 const T& extinction() const { return this->alpha(); }
570};
571
573template <typename T, ColorModel cm, AlphaModel am>
574class color : public extinction_alpha_interface<color<T,cm,am> >
575{
576public:
578 static const ColorModel clr_mod = cm;
580 static const AlphaModel alp_mod = am;
588 typedef T component_type;
590 color() { }
592 color(const T& c) { *this = c; }
594 color(const T& c0, const T& c1) {
595 this->components[0] = c0;
596 if (nr_components > 1)
597 this->components[1] = c1;
598 }
600 color(const T& c0, const T& c1, const T& c2) {
601 this->components[0] = c0;
602 if (nr_components > 1)
603 this->components[1] = c1;
604 if (nr_components > 2)
605 this->components[2] = c2;
606 }
608 color(const T& c0, const T& c1, const T& c2, const T& c3) {
609 this->components[0] = c0;
610 if (nr_components > 1)
611 this->components[1] = c1;
612 if (nr_components > 2)
613 this->components[2] = c2;
614 if (nr_components > 3)
615 this->components[3] = c3;
616 }
618 color(const color<T, cm>& c, T a) {
619 this->at(nr_components - 1) = a; // looks bit like a hack but avoids invalid access for NO_ALPHA
620 for (unsigned i = 0; i < nr_color_components; ++i)
621 this->at(i) = c[i];
622 }
624 template <typename T2, ColorModel cm2, AlphaModel am2>
626 convert_color(c2, *this);
627 }
629 template <typename T2, ColorModel cm2, AlphaModel am2>
631 convert_color(c2, *this);
632 return *this;
633 }
636 std::fill(this->components, this->components+nr_components, c);
637 return *this;
638 }
640 color<T,cm>& drop_alpha() { return *((color<T,cm>*)this); }
641 const color<T,cm>& drop_alpha() const { return *((const color<T,cm>*)this); }
643 template <typename T2, ColorModel cm2, AlphaModel am2>
645 color<T,cm,am> tmp(c2);
646 for (int i=0; i<nr_components; ++i)
647 this->at(i) *= tmp[i];
648 return *this;
649 }
651 template <typename T2, ColorModel cm2, AlphaModel am2>
653 color<T,cm,am> res(*this);
654 res *= c2;
655 return res;
656 }
659 for (unsigned i=0; i<nr_components; ++i)
660 this->at(i) *= c;
661 return *this;
662 }
664 template <typename T2>
667 for (unsigned i=0; i<nr_components; ++i)
668 res[i] = this->at(i)*c;
669 return res;
670 }
672 template <typename T2, ColorModel cm2, AlphaModel am2>
674 color<T,cm,am> tmp(c2);
675 for (unsigned i=0; i<nr_components; ++i)
676 this->at(i) += tmp[i];
677 return *this;
678 }
680 template <typename T2, ColorModel cm2, AlphaModel am2>
682 color<T,cm,am> res(*this);
683 res += c2;
684 return res;
685 }
688 for (unsigned i=0; i<nr_components; ++i)
689 this->at(i) += c;
690 return *this;
691 }
694 color<T,cm,am> res(*this);
695 res += c;
696 return res;
697 }
699 template <typename T2, ColorModel cm2, AlphaModel am2>
701 color<T, cm, am> tmp(c2);
702 for(unsigned i = 0; i < nr_components; ++i)
703 this->at(i) -= tmp[i];
704 return *this;
705 }
707 template <typename T2, ColorModel cm2, AlphaModel am2>
709 color<T, cm, am> res(*this);
710 res -= c2;
711 return res;
712 }
715 for(unsigned i = 0; i < nr_components; ++i)
716 this->at(i) -= c;
717 return *this;
718 }
721 color<T, cm, am> res(*this);
722 res -= c;
723 return res;
724 }
726 void clamp(const T& mn = 0, const T& mx = color_one<T>::value(), bool skip_alpha = false) {
727 unsigned nr = skip_alpha ? nr_color_components : nr_components;
728 for (unsigned i = 0; i < nr; ++i)
729 if (this->at(i) < mn)
730 this->at(i) = mn;
731 else if (this->at(i) > mx)
732 this->at(i) = mx;
733 }
735 T& operator [] (unsigned int i) { return this->at(i); }
737 const T& operator [] (unsigned int i) const { return this->at(i); }
738};
739
741#define CGV_MEDIA_COLOR_DECLARED
742
743/*********************************************************************
744**
745** operators
746**
747*********************************************************************/
748
750template <typename T, ColorModel cm, AlphaModel am>
751bool operator == (const color<T,cm,am>& c1, const color<T,cm,am>& c2) {
752 for (unsigned int i=0; i<color<T,cm,am>::nr_components; ++i)
753 if (c1[i] != c2[i])
754 return false;
755 return true;
756}
758template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
759color<typename type::func::promote<T1,T2>::type,cm1,am1> operator * (const color<T1,cm1,am1>& c1, const color<T2,cm2,am2>& c2) {
760 color<typename type::func::promote<T1,T2>::type,cm1,am1> res(c1);
761 res *= c2;
762 return res;
763}
765template <typename T1, typename T2, ColorModel cm2, AlphaModel am2>
766color<typename type::func::promote<T1,T2>::type,cm2,am2> operator * (const T1& c1, const color<T2,cm2,am2>& c2) {
767 color<typename type::func::promote<T1,T2>::type,cm2,am2> res(c2);
768 res *= c1;
769 return res;
770}
772template <typename T1, ColorModel cm1, AlphaModel am1, typename T2, ColorModel cm2, AlphaModel am2>
773color<typename type::func::promote<T1,T2>::type,cm1,am1> operator + (const color<T1,cm1,am1>& c1, const color<T2,cm2,am2>& c2) {
774 color<typename type::func::promote<T1,T2>::type,cm1,am1> res(c1);
775 res += c2;
776 return res;
777}
779template <typename T1, ColorModel cm1, AlphaModel am1>
780std::ostream& operator << (std::ostream& os, const color<T1,cm1,am1>& c) {
781 os << c[0];
782 for (unsigned int i=1; i<color<T1,cm1,am1>::nr_components; ++i)
783 os << " " << c[i];
784 return os;
785}
787template <typename T1, ColorModel cm1, AlphaModel am1>
788std::istream& operator >> (std::istream& is, color<T1,cm1,am1>& c) {
789 is >> c[0];
790 for (unsigned int i=1; i<color<T1,cm1,am1>::nr_components; ++i)
791 is >> c[i];
792 return is;
793}
795template <ColorModel cm, AlphaModel am>
796std::ostream& operator << (std::ostream& os, const color<unsigned char,cm,am>& c) {
797 os << (int)c[0];
798 for (unsigned int i=1; i<color<unsigned char,cm,am>::nr_components; ++i)
799 os << " " << (int)c[i];
800 return os;
801}
803template <ColorModel cm, AlphaModel am>
804std::istream& operator >> (std::istream& is, color<unsigned char,cm,am>& c) {
805 int tmp;
806 is >> tmp;
807 c[0] = (unsigned char)tmp;
808 for (unsigned int i=1; i<color<unsigned char,cm,am>::nr_components; ++i) {
809 is >> tmp;
810 c[i] = (unsigned char)tmp;
811 }
812 return is;
813}
814
815/*********************************************************************
816**
817** functions
818**
819*********************************************************************/
820
822template <typename T, ColorModel cm, AlphaModel am>
823const color<T,cm,am> lerp(const color<T,cm,am>& c1, const color<T,cm,am>& c2, T t) {
824 return ((T)1 - t) * c1 + t * c2;
825}
826
828template<typename T1, typename T2, AlphaModel am>
829const color<T1, RGB, am> pow(const color<T1, RGB, am>& c, T2 e) {
830 color<T1, RGB, am> x = c;
831 for(unsigned int i = 0; i < color<T1, RGB, am>::nr_color_components; ++i) {
832 T2 v = T2(0);
833 convert_color_component(x[i], v);
834 convert_color_component(std::pow(v, e), x[i]);
835 }
836 return x;
837}
838
840template<typename T, AlphaModel am>
841const color<T, RGB, am> inv(const color<T, RGB, am>& c) {
842 color<T, RGB, am> x;
843 for(unsigned int i = 0; i < color<T, RGB, am>::nr_components; ++i) {
844 x[i] = color_one<T>::value() - c[i];
845 }
846 return x;
847}
848
850template<typename T, AlphaModel am>
851std::string to_hex(const color<T, RGB, am>& c) {
852 std::string res = "0x";
853 res.resize(2 * static_cast<size_t>(color<T, RGB, am>::nr_components) + 2, '0');
854 std::string buf = "00";
855
856 for(size_t i = 0; i < static_cast<size_t>(color<T, RGB, am>::nr_components); ++i) {
857 uint8_t v = 0;
858 convert_color_component(c[i], v);
859 buf = cgv::utils::to_hex(v);
860 res[2 * i + 2] = buf[0];
861 res[2 * i + 3] = buf[1];
862 }
863 return res;
864}
865
867template<typename T, AlphaModel am>
868bool from_hex(const std::string& s, color<T, RGB, am>& c) {
869 size_t off = 0;
870 // skip the first parsed byte if the string has the typical hexadecimal prefix
871 if(s.length() > 1 && s[0] == '0' && s[1] == 'x')
872 off = 1;
873
874 std::vector<uint8_t> parsed = cgv::utils::parse_hex_bytes(s);
875 if(parsed.empty() || parsed.size() - off < static_cast<size_t>(color<T, RGB, am>::nr_components))
876 return false;
877
878 for(size_t i = 0; i < static_cast<size_t>(color<T, RGB, am>::nr_components); ++i) {
879 uint8_t v = parsed[i + off];
880 convert_color_component(v, c[i]);
881 }
882 return true;
883}
884
885} // namespace media
886
889
898
900
901} // namespace cgv
minimal data interface for color used to implement conversion.
Definition color.h:52
color_base()
standard constructor does not initialize components
Definition color.h:63
color_base(const color_base< T2, cm2, am2 > &c2)
copy constructor uses color conversion if necessary
Definition color.h:66
static const unsigned int nr_alpha_components
static and const access to number of alpha components
Definition color.h:57
const T & at(unsigned int i) const
const access to components
Definition color.h:72
T component_type
type of color components
Definition color.h:61
T & alpha()
return alpha component
Definition color.h:74
T & at(unsigned int i)
access to components
Definition color.h:70
static const unsigned int nr_color_components
static and const access to number of color components
Definition color.h:55
static const unsigned int nr_components
static and const access to total number of components
Definition color.h:59
const T & alpha() const
return alpha component
Definition color.h:76
represent a color with components of given type and color and alpha model as specified.
Definition color.h:575
color< T, cm, am > operator-(const color< T2, cm2, am2 > &c2)
subtract color
Definition color.h:708
static const unsigned int nr_alpha_components
static and const access to number of alpha components
Definition color.h:584
static const unsigned int nr_color_components
static and const access to number of color components
Definition color.h:582
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:726
color(const T &c0, const T &c1, const T &c2)
set first three components to given values
Definition color.h:600
static const unsigned int nr_components
static and const access to total number of components
Definition color.h:586
static const AlphaModel alp_mod
static and const access to alpha model
Definition color.h:580
color(const T &c0, const T &c1, const T &c2, const T &c3)
set all four components to given values
Definition color.h:608
color< T, cm, am > & operator=(const color< T2, cm2, am2 > &c2)
assign to color with potential color conversion
Definition color.h:630
color(const T &c)
set all components to given value
Definition color.h:592
static const ColorModel clr_mod
static and const access to color model
Definition color.h:578
color< T, cm, am > operator*(const color< T2, cm2, am2 > &c2)
post multiply with color
Definition color.h:652
color< T, cm > & drop_alpha()
drop the alpha component if any by a cast operator
Definition color.h:640
color()
standard constructor does not initialize components
Definition color.h:590
color< T, cm, am > & operator+=(const color< T2, cm2, am2 > &c2)
add color
Definition color.h:673
T component_type
type of color components
Definition color.h:588
color(const color< T, cm > &c, T a)
construct from non-alpha color plus alpha
Definition color.h:618
color(const color< T2, cm2, am2 > &c2)
copy constructor uses color conversion if necessary
Definition color.h:625
color< T, cm, am > & operator-=(const color< T2, cm2, am2 > &c2)
subtract color
Definition color.h:700
color< T, cm, am > operator+(const color< T2, cm2, am2 > &c2)
add color
Definition color.h:681
color(const T &c0, const T &c1)
set first two components to given values
Definition color.h:594
T & operator[](unsigned int i)
access to components
Definition color.h:735
color< T, cm, am > & operator*=(const color< T2, cm2, am2 > &c2)
multiply with color
Definition color.h:644
std::string to_hex(uint8_t v, bool use_upper_case)
convert to hex
Definition scan.cxx:52
uint8_t from_hex(char c)
convert from hex character
Definition scan.cxx:60
std::vector< uint8_t > parse_hex_bytes(const std::string &byte_str)
parse bytes hex coded bytes
Definition scan.cxx:91
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:897
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
Definition color.h:893
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:891
cgv::media::color< cgv::type::uint8_type, cgv::media::RGB > rgb8
declare rgb color type with 8 bit components
Definition color.h:895
Helper functions to process strings.
captures reference to alpha component of color
Definition color.h:88
captures reference to alpha component of color
Definition color.h:105
const T & extinction() const
read access to extinction component
Definition color.h:569
T & extinction()
write access to extinction component
Definition color.h:567
T extinction() const
convert alpha to extinction
Definition color.h:555
the extinction_alpha_interface adds access function to the opacity, where write access is only grante...
Definition color.h:549
const T & L() const
read access to L component of HLS color
Definition color.h:462
T & H()
write access to H component of HLS color
Definition color.h:456
const T & S() const
read access to S component of HLS color
Definition color.h:466
const T & H() const
read access to H component of HLS color
Definition color.h:458
T & S()
write access to S component of HLS color
Definition color.h:464
T & L()
write access to L component of HLS color
Definition color.h:460
T H() const
convert color to HLS and return H component
Definition color.h:445
T S() const
convert color to HLS and return S component
Definition color.h:449
T L() const
convert color to HLS and return L component
Definition color.h:447
the hls_color_interface adds access function to the H, L, and S-channels of the color,...
Definition color.h:439
const T & opacity() const
read access to opacity component
Definition color.h:521
T & opacity()
write access to opacity component
Definition color.h:519
T opacity() const
convert alpha to opacity
Definition color.h:507
the opacity_alpha_interface adds access function to the opacity, where write access is only granted f...
Definition color.h:501
const T & R() const
read access to R component of RGB color
Definition color.h:427
const T & G() const
read access to G component of RGB color
Definition color.h:431
T & R()
write access to R component of RGB color
Definition color.h:425
T & B()
write access to B component of RGB color
Definition color.h:433
const T & B() const
read access to B component of RGB color
Definition color.h:435
T & G()
write access to G component of RGB color
Definition color.h:429
T B() const
convert color to RGB and return B component
Definition color.h:418
T R() const
convert color to RGB and return R component
Definition color.h:414
T G() const
convert color to RGB and return G component
Definition color.h:416
the rgb_color_interface adds access function to the R, G, and B-channels of the color,...
Definition color.h:408
T & transparency()
write access to transparency component
Definition color.h:543
const T & transparency() const
read access to transparency component
Definition color.h:545
T transparency() const
convert alpha to transparency
Definition color.h:531
the transparency_alpha_interface adds access function to the opacity, where write access is only gran...
Definition color.h:525
const T & X() const
read access to X component of XYZ color
Definition color.h:489
T & Y()
write access to Y component of XYZ color
Definition color.h:491
T & X()
write access to X component of XYZ color
Definition color.h:487
const T & Y() const
read access to Y component of XYZ color
Definition color.h:493
const T & Z() const
read access to Z component of XYZ color
Definition color.h:497
T & Z()
write access to Z component of XYZ color
Definition color.h:495
T Y() const
convert color to XYZ and return Y component
Definition color.h:478
T X() const
convert color to XYZ and return X component
Definition color.h:476
T Z() const
convert color to XYZ and return Z component
Definition color.h:480
the xyz_color_interface adds access function to the X, Y, and Z-channels of the color,...
Definition color.h:470
the max traits defines for each type in the static const member value, what the maximum value is.
Definition max.h:37