Visual Computing Library
Loading...
Searching...
No Matches
color.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_CORE_COLOR_H
24#define VCL_SPACE_CORE_COLOR_H
25
26#include "point.h"
27
28#include <vector>
29
30namespace vcl {
31
47class Color : public Point4<uint8_t>
48{
49public:
64 enum class Representation { INT_0_255, FLOAT_0_1 };
65
77 enum class Format { ABGR, ARGB, RGBA, BGRA };
78
85 Black = 0xff000000,
86 DarkGray = 0xff404040,
87 Gray = 0xff808080,
88 LightGray = 0xffc0c0c0,
89 White = 0xffffffff,
90
91 Red = 0xff0000ff,
92 Green = 0xff00ff00,
93 Blue = 0xffff0000,
94
95 Yellow = 0xff00ffff,
96 Cyan = 0xffffff00,
97 Magenta = 0xffff00ff,
98
99 LightRed = 0xff8080ff,
100 LightGreen = 0xff80ff80,
101 LightBlue = 0xffff8080,
102
103 LightCyan = 0xffffff80,
104 LightYellow = 0xff80ffff,
105 LightMagenta = 0xffff80ff,
106
107 DarkRed = 0xff000040,
108 DarkGreen = 0xff004000,
109 DarkBlue = 0xff400000,
110
111 DarkCyan = 0xff404000,
112 DarkYellow = 0xff004040,
113 DarkMagenta = 0xff400040,
114
115 LightBrown = 0xff4080b0,
116 DarkBrown = 0xff002040,
117 Brown = 0xff004080,
118 };
119
123 enum class ColorMap { RedBlue, Parula, GreyShade };
124
129 Color() : Point(0, 0, 0, 255) {}
130
131 Color(ColorABGR cc) { *reinterpret_cast<uint32_t*>(Point::data()) = cc; }
132
133 Color(uint32_t cc, Format format) { set(cc, format); }
134
146
147 Color(const Point4<uint8_t>& p) : Point4<uint8_t>(p) {}
148
153 uint8_t red() const { return x(); }
154
159 uint8_t green() const { return y(); }
160
165 uint8_t blue() const { return z(); }
166
171 uint8_t alpha() const { return w(); }
172
177 uint8_t& red() { return x(); }
178
183 uint8_t& green() { return y(); }
184
189 uint8_t& blue() { return z(); }
190
195 uint8_t& alpha() { return w(); }
196
201 float redF() const { return (float) x() / 255; }
202
207 float greenF() const { return (float) y() / 255; }
208
213 float blueF() const { return (float) z() / 255; }
214
219 float alphaF() const { return (float) w() / 255; }
220
226 {
228 uint8_t h;
229
230 rgbMin = x() < y() ? (x() < z() ? x() : z()) : (y() < z() ? y() : z());
231 rgbMax = x() > y() ? (x() > z() ? x() : z()) : (y() > z() ? y() : z());
232
233 if (rgbMax == 0) {
234 return 0;
235 }
236
237 if (255 * long(rgbMax - rgbMin) / rgbMax == 0) {
238 return 0;
239 }
240
241 if (rgbMax == x())
242 h = 0 + 43 * (y() - z()) / (rgbMax - rgbMin);
243 else if (rgbMax == y())
244 h = 85 + 43 * (z() - x()) / (rgbMax - rgbMin);
245 else
246 h = 171 + 43 * (x() - y()) / (rgbMax - rgbMin);
247
248 return h;
249 }
250
256 {
258
259 rgbMin = x() < y() ? (x() < z() ? x() : z()) : (y() < z() ? y() : z());
260 rgbMax = x() > y() ? (x() > z() ? x() : z()) : (y() > z() ? y() : z());
261
262 if (rgbMax == 0) {
263 return 0;
264 }
265
266 return 255 * long(rgbMax - rgbMin) / rgbMax;
267 }
268
273 float hsvHueF() const { return (float) hsvHue() / 255; }
274
279 float hsvSaturationF() const { return (float) hsvSaturation() / 255; }
280
281 uint32_t abgr() const
282 {
283 return *reinterpret_cast<const uint32_t*>(Point::data());
284 }
285
286 uint32_t argb() const
287 {
288 return (alpha() << 24) | (red() << 16) | (green() << 8) | blue();
289 }
290
291 uint32_t rgba() const
292 {
293 return (red() << 24) | (green() << 16) | (blue() << 8) | alpha();
294 }
295
296 uint32_t bgra() const
297 {
298 return (blue() << 24) | (green() << 16) | (red() << 8) | alpha();
299 }
300
309 unsigned short bgr5() const
310 {
311 unsigned short r = x() / 8;
312 unsigned short g = y() / 8;
313 unsigned short b = z() / 8;
314 unsigned short res = r + g * 32 + b * 1024;
315 return res;
316 }
317
326 unsigned short rgb5() const
327 {
328 unsigned short r = x() / 8;
329 unsigned short g = y() / 8;
330 unsigned short b = z() / 8;
331 unsigned short res = b + g * 32 + r * 1024;
332 return res;
333 }
334
339 void setAlpha(uint8_t alpha) { w() = alpha; }
340
345 void setRed(uint8_t red) { x() = red; }
346
351 void setGreen(uint8_t green) { y() = green; }
352
357 void setBlue(uint8_t blue) { z() = blue; }
358
370 {
371 x() = red;
372 y() = green;
373 z() = blue;
374 w() = alpha;
375 }
376
377 void set(uint32_t cc, Format fmt = Format::ABGR)
378 {
379 switch (fmt) {
380 case Format::ARGB: setArgb(cc); break;
381 case Format::ABGR: setAbgr(cc); break;
382 case Format::RGBA: setRgba(cc); break;
383 case Format::BGRA: setBgra(cc); break;
384 }
385 }
386
387 void setAbgr(uint32_t val)
388 {
389 *reinterpret_cast<uint32_t*>(Point::data()) = val;
390 }
391
392 void setArgb(uint32_t val)
393 {
394 x() = (val >> 16) % 256;
395 y() = (val >> 8) % 256;
396 z() = val % 256;
397 w() = (val >> 24) % 256;
398 }
399
400 void setRgba(uint32_t val)
401 {
402 x() = (val >> 24) % 256;
403 y() = (val >> 16) % 256;
404 z() = (val >> 8) % 256;
405 w() = val % 256;
406 }
407
408 void setBgra(uint32_t val)
409 {
410 x() = (val >> 8) % 256;
411 y() = (val >> 16) % 256;
412 z() = (val >> 24) % 256;
413 w() = val % 256;
414 }
415
429 void setBgr5(unsigned short val)
430 {
431 x() = val % 32 * 8;
432 y() = ((val / 32) % 32) * 8;
433 z() = ((val / 1024) % 32) * 8;
434 w() = 255;
435 }
436
450 void setRgb5(unsigned short val)
451 {
452 z() = val % 32 * 8;
453 y() = ((val / 32) % 32) * 8;
454 x() = ((val / 1024) % 32) * 8;
455 w() = 255;
456 }
457
469 {
470 w() = alpha;
471 if (s == 0) {
472 x() = v;
473 y() = v;
474 z() = v;
475 }
476 else {
477 h = (h / 360.0) * 255;
478 uint8_t region, remainder, p, q, t;
479 region = h / 43;
480 remainder = (h - (region * 43)) * 6;
481
482 p = (v * (255 - s)) >> 8;
483 q = (v * (255 - ((s * remainder) >> 8))) >> 8;
484 t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
485
486 switch (region) {
487 case 0:
488 x() = v;
489 y() = t;
490 z() = p;
491 break;
492 case 1:
493 x() = q;
494 y() = v;
495 z() = p;
496 break;
497 case 2:
498 x() = p;
499 y() = v;
500 z() = t;
501 break;
502 case 3:
503 x() = p;
504 y() = q;
505 z() = v;
506 break;
507 case 4:
508 x() = t;
509 y() = p;
510 z() = v;
511 break;
512 default:
513 x() = v;
514 y() = p;
515 z() = q;
516 break;
517 }
518 }
519 }
520
525 void setAlphaF(float alpha) { w() = (uint8_t) (alpha * 255); }
526
531 void setRedF(float red) { x() = (uint8_t) (red * 255); }
532
537 void setGreenF(float green) { y() = (uint8_t) (green * 255); }
538
543 void setBlueF(float blue) { z() = (uint8_t) (blue * 255); }
544
559 void setRgbF(float red, float green, float blue, float alpha = 1.0)
560 {
561 w() = (uint8_t) (alpha * 255);
562 x() = (uint8_t) (red * 255);
563 y() = (uint8_t) (green * 255);
564 z() = (uint8_t) (blue * 255);
565 }
566
578 void setHsvF(float hf, float sf, float vf, float alpha = 1.0)
579 {
580 setHsv(hf * 255, sf * 255, vf * 255, alpha * 255);
581 }
582
590 bool operator==(const Color& otherColor) const
591 {
592 return (
593 x() == otherColor.x() && y() == otherColor.y() &&
594 z() == otherColor.z() && w() == otherColor.w());
595 }
596
604 bool operator!=(const Color& otherColor) const
605 {
606 return !(*this == otherColor);
607 }
608
616 bool operator<(const Color& otherColor) const
617 {
618 if (x() < otherColor.x())
619 return true;
620 if (x() > otherColor.x())
621 return false;
622 if (y() < otherColor.y())
623 return true;
624 if (y() > otherColor.y())
625 return false;
626 if (z() < otherColor.z())
627 return true;
628 if (z() > otherColor.z())
629 return false;
630 if (w() < otherColor.w())
631 return true;
632 return false;
633 }
634
636 friend std::ostream& operator<<(std::ostream& out, const Color& c);
637};
638
642inline std::ostream& operator<<(std::ostream& out, const Color& c)
643{
644 out << c.cast<uint>();
645 return out;
646}
647
661inline Color colorLerp(const Color& c0, const Color& c1, float value)
662{
663 Color c;
664 if (value < 0) // out of range - left
665 value = 0;
666 else if (value > 1) // out of range - right
667 value = 1;
668 for (uint i = 0; i < 4; i++)
669 c(i) = c1(i) * value + c0(i) * (1 - value);
670 return c;
671}
672
684inline Color colorFromIntervalRedBlue(float value)
685{
686 Color c;
687
688 if (value < 0) // out of range - left
689 value = 0;
690 else if (value > 1) // out of range - right
691 value = 1;
692
693 c.setHsv(value * 240, 255, 255);
694 return c;
695}
696
714inline Color colorFromIntervalRedBlue(float min, float max, float value)
715{
716 Color c;
717 if (min == max) { // no range
718 return Color::Gray;
719 }
720
721 value = std::abs((value - min) / (max - min));
722 return colorFromIntervalRedBlue(value);
723}
724
737inline Color colorFromIntervalParula(float value)
738{
739 if (value < 0) // out of range - left
740 value = 0;
741 else if (value > 1) // out of range - right
742 value = 1;
743
744 static uint paruVal[9] = {
745 0x271680ff,
746 0x0363e1ff,
747 0x1485d4ff,
748 0x06a7c6ff,
749 0x38b99eff,
750 0x92bf73ff,
751 0xd9ba56ff,
752 0xfcce2eff,
753 0xfffa0aff};
754
755 int ind = int(floor(value * 8.0f));
756 float div = (value * 8.0f - ind);
757
758 if (div < 0)
759 div = 0;
760 else if (div > 1)
761 div = 1;
762
763 return colorLerp(
764 (Color::ColorABGR) paruVal[ind],
765 (Color::ColorABGR) paruVal[ind + 1],
766 div);
767}
768
786inline Color colorFromIntervalParula(float min, float max, float value)
787{
788 Color c;
789 if (min == max) { // no range
790 return Color::Gray;
791 }
792
793 value = std::abs((value - min) / (max - min));
794 return colorFromIntervalParula(value);
795}
796
809inline Color colorFromIntervalGreyShade(float value)
810{
811 if (value < 0) // out of range - left
812 value = 0;
813 else if (value > 1) // out of range - right
814 value = 1;
815 return Color(value * 255, value * 255, value * 255, 255);
816}
817
835inline Color colorFromIntervalGreyShade(float min, float max, float value)
836{
837 Color c;
838 if (min == max) { // no range
839 return Color::Gray;
840 }
841
842 value = std::abs((value - min) / (max - min));
843 return colorFromIntervalGreyShade(value);
844}
845
855inline Color colorFromInterval(float value, Color::ColorMap cm)
856{
857 switch (cm) {
858 using enum Color::ColorMap;
859 case RedBlue: return colorFromIntervalRedBlue(value);
860 case Parula: return colorFromIntervalParula(value);
861 case GreyShade: return colorFromIntervalGreyShade(value);
862 default: assert(0); return Color::Gray;
863 }
864}
865
885inline Color colorFromInterval(
886 float min,
887 float max,
888 float value,
890{
891 if (min == max) { // no range
892 return Color::Gray;
893 }
894
895 value = std::abs((value - min) / (max - min));
896 return colorFromInterval(value, cm);
897}
898
908inline std::vector<Color> colorScattering(
909 uint n,
910 float sat = 0.3,
911 float val = 0.9)
912{
913 std::vector<Color> scattering;
914 scattering.reserve(n);
915
916 for (uint v = 0; v < n; ++v) {
917 uint value = v, m = n;
918 uint b = 0;
919
920 for (uint k = 1; k < n; k <<= 1) {
921 if (value << 1 >= m) {
922 b += k;
923 value -= (m + 1) >> 1;
924 m >>= 1;
925 }
926 else {
927 m = (m + 1) >> 1;
928 }
929 }
930
931 Color rc;
932 rc.setHsvF(float(b) / float(n), sat, val);
933 scattering.push_back(rc);
934 }
935 return scattering;
936}
937
938} // namespace vcl
939
940#endif // VCL_SPACE_CORE_COLOR_H
The Color class represents a 32 bit color.
Definition color.h:48
ColorABGR
ABGR enum with some standard colors.
Definition color.h:84
uint8_t green() const
Returns the green component of this color [0-255].
Definition color.h:159
bool operator==(const Color &otherColor) const
Returns true if this color has the same RGB and alpha values as otherColor; otherwise returns false.
Definition color.h:590
float greenF() const
Returns the float green component of this color [0-1].
Definition color.h:207
uint8_t & blue()
Returns the blue component of this color [0-255].
Definition color.h:189
void setBlue(uint8_t blue)
Sets the blue of this color [0-255].
Definition color.h:357
unsigned short bgr5() const
Converts the color to an unsigned short in bgr5 format.
Definition color.h:309
uint8_t & green()
Returns the green component of this color [0-255].
Definition color.h:183
void setHsvF(float hf, float sf, float vf, float alpha=1.0)
Sets the HSV values of this color.
Definition color.h:578
ColorMap
List of Color Maps supported by the vcl::Color.
Definition color.h:123
Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha=255)
Color constructor.
Definition color.h:142
uint8_t hsvHue() const
Returns the hue color component of this color [0-359].
Definition color.h:225
void setRgbF(float red, float green, float blue, float alpha=1.0)
Sets the RGB values of this color.
Definition color.h:559
Format
Color format enumeration.
Definition color.h:77
void setBgr5(unsigned short val)
Definition color.h:429
uint8_t red() const
Returns the red component of this color [0-255].
Definition color.h:153
Representation
Color representation enumeration.
Definition color.h:64
void setHsv(uint8_t h, uint8_t s, uint8_t v, uint8_t alpha=255)
Sets the HSV values of this color.
Definition color.h:468
float blueF() const
Returns the float blue component of this color [0-1].
Definition color.h:213
float alphaF() const
Returns the float alpha component of this color [0-1].
Definition color.h:219
bool operator!=(const Color &otherColor) const
Returns false if this color has the same RGB and alpha values as otherColor; otherwise returns true.
Definition color.h:604
uint8_t & red()
Returns the red component of this color [0-255].
Definition color.h:177
bool operator<(const Color &otherColor) const
Returns true if this color is less than otherColor follwing the RGBA order; otherwise returns false.
Definition color.h:616
void setRedF(float red)
Sets the red of this color [0-1].
Definition color.h:531
uint8_t & alpha()
Returns the alpha component of this color [0-255].
Definition color.h:195
void setRed(uint8_t red)
Sets the red of this color [0-255].
Definition color.h:345
float hsvSaturationF() const
Returns the float saturation color component of this color [0-1].
Definition color.h:279
void setAlpha(uint8_t alpha)
Sets the alpha of this color [0-255].
Definition color.h:339
float redF() const
Returns the float red component of this color [0-1].
Definition color.h:201
void setAlphaF(float alpha)
Sets the alpha of this color [0-1].
Definition color.h:525
Color()
Default constructor. Initializes a black color (with alpha 255).
Definition color.h:129
uint8_t hsvSaturation() const
Returns the saturation color component of this color [0-255].
Definition color.h:255
unsigned short rgb5() const
Converts the color to an unsigned short in rgb5 format.
Definition color.h:326
void setBlueF(float blue)
Sets the blue of this color [0-1].
Definition color.h:543
void setRgb5(unsigned short val)
Definition color.h:450
void setGreen(uint8_t green)
Sets the green of this color [0-255].
Definition color.h:351
uint8_t alpha() const
Returns the alpha component of this color [0-255].
Definition color.h:171
float hsvHueF() const
Returns the float saturation color component of this color [0-1].
Definition color.h:273
void setRgb(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha=255)
Sets the RGB values of this color.
Definition color.h:369
friend std::ostream & operator<<(std::ostream &out, const Color &c)
Overload of stream operator to allow a pretty print of a vcl::Color.
Definition color.h:642
uint8_t blue() const
Returns the blue component of this color [0-255].
Definition color.h:165
void setGreenF(float green)
Sets the green of this color [0-1].
Definition color.h:537
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:58
auto cast() const
Casts the Point object to a different scalar type.
Definition point.h:226
ScalarType & z()
Returns a reference to the z-component of the Point object.
Definition point.h:175
ScalarType & x()
Returns a reference to the x-component of the Point object.
Definition point.h:131
ScalarType & w()
Returns a reference to the w-component of the Point object.
Definition point.h:197
ScalarType & y()
Returns a reference to the y-component of the Point object.
Definition point.h:153
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:83
constexpr auto min(const T &p1, const T &p2)
Returns the minimum between the two parameters.
Definition min_max.h:42