• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <kms++util/color.h>
2 
3 namespace kms
4 {
RGB()5 RGB::RGB()
6 {
7 	r = g = b = 0;
8 	a = 255;
9 }
10 
RGB(uint8_t r,uint8_t g,uint8_t b)11 RGB::RGB(uint8_t r, uint8_t g, uint8_t b)
12 	: RGB(255, r, g, b)
13 {
14 }
15 
RGB(uint8_t a,uint8_t r,uint8_t g,uint8_t b)16 RGB::RGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
17 {
18 	this->r = r;
19 	this->g = g;
20 	this->b = b;
21 	this->a = a;
22 }
23 
RGB(uint32_t argb)24 RGB::RGB(uint32_t argb)
25 {
26 	this->b = (argb >> 0) & 0xff;
27 	this->g = (argb >> 8) & 0xff;
28 	this->r = (argb >> 16) & 0xff;
29 	this->a = (argb >> 24) & 0xff;
30 }
31 
rgb888() const32 uint32_t RGB::rgb888() const
33 {
34 	return (r << 16) | (g << 8) | (b << 0);
35 }
36 
bgr888() const37 uint32_t RGB::bgr888() const
38 {
39 	return (b << 16) | (g << 8) | (r << 0);
40 }
41 
argb8888() const42 uint32_t RGB::argb8888() const
43 {
44 	return (a << 24) | (r << 16) | (g << 8) | (b << 0);
45 }
46 
abgr8888() const47 uint32_t RGB::abgr8888() const
48 {
49 	return (a << 24) | (b << 16) | (g << 8) | (r << 0);
50 }
51 
rgba8888() const52 uint32_t RGB::rgba8888() const
53 {
54 	return (r << 24) | (g << 16) | (b << 8) | (a << 0);
55 }
56 
bgra8888() const57 uint32_t RGB::bgra8888() const
58 {
59 	return (b << 24) | (g << 16) | (r << 8) | (a << 0);
60 }
61 
argb2101010() const62 uint32_t RGB::argb2101010() const
63 {
64 	return ((a >> 6) << 30) | (r << 22) | (g << 12) | (b << 2);
65 }
66 
abgr2101010() const67 uint32_t RGB::abgr2101010() const
68 {
69 	return ((a >> 6) << 30) | (b << 22) | (g << 12) | (r << 2);
70 }
71 
rgba1010102() const72 uint32_t RGB::rgba1010102() const
73 {
74 	return (r << 24) | (g << 14) | (b << 4) | (a >> 6);
75 }
76 
bgra1010102() const77 uint32_t RGB::bgra1010102() const
78 {
79 	return (b << 24) | (g << 14) | (r << 4) | (a >> 6);
80 }
81 
rgb332() const82 uint8_t RGB::rgb332() const
83 {
84 	return ((r >> 5) << 5) | ((g >> 5) << 2) | ((b >> 6) << 0);
85 }
86 
rgb565() const87 uint16_t RGB::rgb565() const
88 {
89 	return ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
90 }
91 
bgr565() const92 uint16_t RGB::bgr565() const
93 {
94 	return ((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0);
95 }
96 
argb4444() const97 uint16_t RGB::argb4444() const
98 {
99 	return ((a >> 4) << 12) | ((r >> 4) << 8) | ((g >> 4) << 4) | ((b >> 4) << 0);
100 }
101 
argb1555() const102 uint16_t RGB::argb1555() const
103 {
104 	return ((!!a) << 15) | ((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3) << 0);
105 }
106 
yuv(YUVType type) const107 YUV RGB::yuv(YUVType type) const
108 {
109 	return YUV(*this, type);
110 }
111 
112 #define CF_ONE (256)
113 #define CF(a, b, c)                                                           \
114 	{                                                                     \
115 		((int)((a)*CF_ONE)), ((int)((b)*CF_ONE)), ((int)((c)*CF_ONE)) \
116 	}
117 #define CLAMP(a) ((a) > (CF_ONE - 1) ? (CF_ONE - 1) : (a) < 0 ? 0 : (a))
118 
119 const int YUVcoef[static_cast<unsigned>(YUVType::MAX)][3][3] = {
120 	[static_cast<unsigned>(YUVType::BT601_Lim)] = {
121 		CF(0.257, 0.504, 0.098),
122 		CF(-0.148, -0.291, 0.439),
123 		CF(0.439, -0.368, -0.071) },
124 	[static_cast<unsigned>(YUVType::BT601_Full)] = { CF(0.299, 0.587, 0.114), CF(-0.169, -0.331, 0.500), CF(0.500, -0.419, -0.081) },
125 	[static_cast<unsigned>(YUVType::BT709_Lim)] = { CF(0.1826, 0.6142, 0.0620), CF(-0.1006, -0.3386, 0.4392), CF(0.4392, -0.3989, -0.0403) },
126 	[static_cast<unsigned>(YUVType::BT709_Full)] = { CF(0.2126, 0.7152, 0.0722), CF(-0.1146, -0.3854, 0.5000), CF(0.5000, -0.4542, -0.0468) },
127 };
128 
129 const int YUVoffset[static_cast<unsigned>(YUVType::MAX)][3] = {
130 	[static_cast<unsigned>(YUVType::BT601_Lim)] = CF(0.0625, 0.5, 0.5),
131 	[static_cast<unsigned>(YUVType::BT601_Full)] = CF(0, 0.5, 0.5),
132 	[static_cast<unsigned>(YUVType::BT709_Lim)] = CF(0.0625, 0.5, 0.5),
133 	[static_cast<unsigned>(YUVType::BT709_Full)] = CF(0, 0.5, 0.5),
134 };
135 
YUV()136 YUV::YUV()
137 {
138 	y = u = v = a = 0;
139 }
140 
YUV(uint8_t y,uint8_t u,uint8_t v)141 YUV::YUV(uint8_t y, uint8_t u, uint8_t v)
142 {
143 	this->y = y;
144 	this->u = u;
145 	this->v = v;
146 	this->a = 0;
147 }
148 
MAKE_YUV_Y(uint8_t r,uint8_t g,uint8_t b,YUVType type)149 static inline uint8_t MAKE_YUV_Y(uint8_t r, uint8_t g, uint8_t b, YUVType type)
150 {
151 	unsigned tidx = static_cast<unsigned>(type);
152 
153 	return CLAMP(((YUVcoef[tidx][0][0] * r + YUVcoef[tidx][0][1] * g +
154 		       YUVcoef[tidx][0][2] * b + CF_ONE / 2) /
155 		      CF_ONE) +
156 		     YUVoffset[tidx][0]);
157 }
158 
MAKE_YUV_U(uint8_t r,uint8_t g,uint8_t b,YUVType type)159 static inline uint8_t MAKE_YUV_U(uint8_t r, uint8_t g, uint8_t b, YUVType type)
160 {
161 	unsigned tidx = static_cast<unsigned>(type);
162 
163 	return CLAMP(((YUVcoef[tidx][1][0] * r + YUVcoef[tidx][1][1] * g +
164 		       YUVcoef[tidx][1][2] * b + CF_ONE / 2) /
165 		      CF_ONE) +
166 		     YUVoffset[tidx][1]);
167 }
168 
MAKE_YUV_V(uint8_t r,uint8_t g,uint8_t b,YUVType type)169 static inline uint8_t MAKE_YUV_V(uint8_t r, uint8_t g, uint8_t b, YUVType type)
170 {
171 	unsigned tidx = static_cast<unsigned>(type);
172 
173 	return CLAMP(((YUVcoef[tidx][2][0] * r + YUVcoef[tidx][2][1] * g +
174 		       YUVcoef[tidx][2][2] * b + CF_ONE / 2) /
175 		      CF_ONE) +
176 		     YUVoffset[tidx][2]);
177 }
178 
YUV(const RGB & rgb,YUVType type)179 YUV::YUV(const RGB& rgb, YUVType type)
180 {
181 	this->y = MAKE_YUV_Y(rgb.r, rgb.g, rgb.b, type);
182 	this->u = MAKE_YUV_U(rgb.r, rgb.g, rgb.b, type);
183 	this->v = MAKE_YUV_V(rgb.r, rgb.g, rgb.b, type);
184 	this->a = rgb.a;
185 }
186 } // namespace kms
187