4 * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef __BCCOLORS_H__
23 #define __BCCOLORS_H__
25 // Duplicate filename in guicast
32 // bt601 coefs originaly used
33 // Compression coefficients straight out of jpeglib
34 #define R_TO_Y 0.29900
35 #define G_TO_Y 0.58700
36 #define B_TO_Y 0.11400
38 #define R_TO_U -0.16874
39 #define G_TO_U -0.33126
40 #define B_TO_U 0.50000
42 #define R_TO_V 0.50000
43 #define G_TO_V -0.41869
44 #define B_TO_V -0.08131
46 // Decompression coefficients straight out of jpeglib
47 #define V_TO_R 1.40200
48 #define V_TO_G -0.71414
50 #define U_TO_G -0.34414
51 #define U_TO_B 1.77200
54 Digital YCbCr is derived from analog RGB as follows:
55 RGB are 0..1 (gamma corrected supposedly),
57 Y Py = Kr * R + Kg * G + Kb * B
58 U Pb = - 0.5*Kr/(1-Kb)*R - 0.5*Kg/(1-Kb)*G + 0.5*B
59 V Pr = 0.5*R - 0.5*Kg/(1-Kr)*G - 0.5*Kb/(1-Kr)*B
61 R = Py + Pr * 2*(1-Kr)
62 G = Py - Pr * 2*Kr*(1-Kr)/Kg - Pb * 2*Kb*(1-Kb)/Kg
63 B = Py + Pb * 2*(1-Kb)
65 bt601, white vector= Kr=0.299,Kg=0.587,Kb=0.114
66 Py = + 0.299000*R + 0.587000*G + 0.114000*B
67 Pb = - 0.168736*R - 0.331264*G + 0.500000*B
68 Pr = + 0.500000*R - 0.418698*G - 0.081312*B
71 G = Py - 0.714136*Pr - 0.344136*Pb
74 equations zeroed at (0,128,128), range (255,255,255)
76 Y = 0 + 0.299000*R + 0.587000*G + 0.114000*B
77 Cb = 128 - 0.168736*R - 0.331264*G + 0.500000*B
78 Cr = 128 + 0.500000*R - 0.418698*G - 0.081312*B
80 R = Y + 1.402000*(Cr-128)
81 G = Y - 0.714136*(Cr-128) - 0.344136*(Cb-128)
82 B = Y + 1.772000*(Cb-128)
84 equations zeroed at (16,128,128), range (219,224,224)
85 Y,Cb,Cr = (16,128,128) + (219*Py,224*Pb,224*Pr)
88 Y = 16 + 0.256788*R + 0.504129*G + 0.097906*B
89 Cb = 128 - 0.148227*R - 0.290992*G + 0.439216*B
90 Cr = 128 + 0.439216*R - 0.367789*G - 0.071426*B
92 R = (Y-16)*1.164384 + 1.596027*(Cr-128)
93 G = (Y-16)*1.164384 - 0.812968*(Cr-128) - 0.391762*(Cb-128)
94 B = (Y-16)*1.164384 + 2.017232*(Cb-128)
96 bt.709, white vector= Kr=0.2126,Kg=0.7152,Kb=0.0722
97 Py = + 0.212600*R + 0.715200*G + 0.072200*B
98 Pb = - 0.114572*R - 0.385428*G + 0.500000*B
99 Pr = + 0.500000*R - 0.454153*G - 0.045847*B
101 equations zeroed at (0,128,128), range (255,255,255)
103 Y = 0 + 0.212600*R + 0.715200*G + 0.072200*B
104 Cb = 128 - 0.114572*R - 0.385428*G + 0.500000*B
105 Cr = 128 + 0.500000*R - 0.454153*G - 0.045847*B
107 R = Y + 1.574800*(Cr-128)
108 G = Y - 0.468124*(Cr-128) - 0.187324*(Cb-128)
109 B = Y + 1.855600*(Cb-128)
111 equations zeroed at (16,128,128), range (219,224,224)
112 Y,Cb,Cr = (16,128,128) + (219*Py,224*Pb,224*Pr)
113 Y = 16 + 0.182586*R + 0.614231*G + 0.062007*B
114 Cb = 128 - 0.100644*R - 0.338572*G + 0.439216*B
115 Cr = 128 + 0.439216*R - 0.398942*G - 0.040276*B
117 R = (Y-16)*1.164384 + 1.792741*(Cr-128)
118 G = (Y-16)*1.164384 - 0.532909*(Cr-128) - 0.213249*(Cb-128)
119 B = (Y-16)*1.164384 + 2.112402*(Cb-128)
122 // white vector normalized, so:
125 #define BT601_Kr 0.299
126 #define BT601_Kb 0.114
128 #define BT709_Kr 0.2126
129 #define BT709_Kb 0.0722
131 #define BT2020_Kr 0.2627
132 #define BT2020_Kb 0.0593
136 int mpeg, yzero, uvzero;
137 int ymin8, ymax8, ymin16, ymax16;
138 int uvmin8, uvmax8, uvmin16, uvmax16;
140 float yminf, ymaxf, yrangef;
141 float uvminf, uvmaxf, uvrangef;
142 float r_to_y, g_to_y, b_to_y;
143 float r_to_u, g_to_u, b_to_u;
144 float r_to_v, g_to_v, b_to_v;
145 float v_to_r, v_to_g;
146 float u_to_g, u_to_b;
150 void init(double Kr, double Kb, int mpeg);
151 void init_tables(int len,
152 int *rtoy, int *rtou, int *rtov,
153 int *gtoy, int *gtou, int *gtov,
154 int *btoy, int *btou, int *btov,
155 int *ytab, int *vtor, int *vtog, int *utog, int *utob);
156 void init_tables(int len,
157 float *vtorf, float *vtogf, float *utogf, float *utobf);
159 // dont use pointers,
160 // offsets do not require indirect access
161 #define rtoy16 (tab+0x00000)
162 #define gtoy16 (tab+0x10000)
163 #define btoy16 (tab+0x20000)
164 #define rtou16 (tab+0x30000)
165 #define gtou16 (tab+0x40000)
166 #define btou16 (tab+0x50000)
167 #define rtov16 (tab+0x60000)
168 #define gtov16 (tab+0x70000)
169 #define btov16 (tab+0x80000)
170 #define ytab16 (tab+0x90000)
171 #define vtor16 (tab+0xa0000)
172 #define vtog16 (tab+0xb0000)
173 #define utog16 (tab+0xc0000)
174 #define utob16 (tab+0xd0000)
176 #define rtoy8 (tab+0xe0000)
177 #define gtoy8 (tab+0xe0100)
178 #define btoy8 (tab+0xe0200)
179 #define rtou8 (tab+0xe0300)
180 #define gtou8 (tab+0xe0400)
181 #define btou8 (tab+0xe0500)
182 #define rtov8 (tab+0xe0600)
183 #define gtov8 (tab+0xe0700)
184 #define btov8 (tab+0xe0800)
185 #define ytab8 (tab+0xe0900)
186 #define vtor8 (tab+0xe0a00)
187 #define vtog8 (tab+0xe0b00)
188 #define utog8 (tab+0xe0c00)
189 #define utob8 (tab+0xe0d00)
191 #define vtor16f (tabf+0x00000)
192 #define vtog16f (tabf+0x10000)
193 #define utog16f (tabf+0x20000)
194 #define utob16f (tabf+0x30000)
196 #define vtor8f (tabf+0x40000)
197 #define vtog8f (tabf+0x40100)
198 #define utog8f (tabf+0x40200)
199 #define utob8f (tabf+0x40300)
201 #define bc_always_inline __attribute__ ((__always_inline__)) inline
206 void yuv_set_colors(int color_space, int color_range);
207 inline int is_mpeg() { return mpeg; }
211 #define YUV_rgb_to_yuv_8(r,g,b, y,u,v) \
212 y = (rtoy8[r] + gtoy8[g] + btoy8[b] + yzero) >> 16; \
213 u = (rtou8[r] + gtou8[g] + btou8[b] + uvzero) >> 16; \
214 v = (rtov8[r] + gtov8[g] + btov8[b] + uvzero) >> 16
216 bc_always_inline void rgb_to_yuv_8(int r, int g, int b, int &y, int &u, int &v) {
217 YUV_rgb_to_yuv_8(r,g,b, y,u,v);
219 bc_always_inline void rgb_to_yuv_8(int r, int g, int b, uint8_t &y, uint8_t &u, uint8_t &v) {
220 YUV_rgb_to_yuv_8(r,g,b, y,u,v);
222 bc_always_inline void rgb_to_yuv_8(int &y, int &u, int &v) {
223 int r = y, g = u, b = v; YUV_rgb_to_yuv_8(r, g, b, y, u, v);
226 #define YUV_rgb_to_yuv_16(r,g,b, y,u,v) \
227 y = (rtoy16[r] + gtoy16[g] + btoy16[b] + yzero) >> 8; \
228 u = (rtou16[r] + gtou16[g] + btou16[b] + uvzero) >> 8; \
229 v = (rtov16[r] + gtov16[g] + btov16[b] + uvzero) >> 8
231 bc_always_inline void rgb_to_yuv_16(int r, int g, int b, int &y, int &u, int &v) {
232 YUV_rgb_to_yuv_16(r,g,b, y,u,v);
234 bc_always_inline void rgb_to_yuv_16(int r, int g, int b, uint16_t &y, uint16_t &u, uint16_t &v) {
235 YUV_rgb_to_yuv_16(r,g,b, y,u,v);
237 bc_always_inline void rgb_to_yuv_16(int &y, int &u, int &v) {
238 int r = y, g = u, b = v;
239 YUV_rgb_to_yuv_16(r, g, b, y, u, v);
242 bc_always_inline void rgb_to_yuv_f(float r, float g, float b, float &y, float &u, float &v) {
243 y = r * r_to_y + g * g_to_y + b * b_to_y + yminf;
244 u = r * r_to_u + g * g_to_u + b * b_to_u;
245 v = r * r_to_v + g * g_to_v + b * b_to_v;
247 bc_always_inline void rgb_to_yuv_8(float r, float g, float b, int &y, int &u, int &v) {
248 float fy, fu, fv; rgb_to_yuv_f(r, g, b, fy, fu, fv);
249 int iy = fy * 0x100, iu = fu * 0x100, iv = fv * 0x100;
250 CLAMP(iy, ymin8, ymax8);
251 CLAMP(iu, uvmin8, uvmax8); CLAMP(iv, uvmin8, uvmax8);
252 y = iy; u = iu; v = iv;
254 bc_always_inline void rgb_to_yuv_16(float r, float g, float b,
255 int &y, int &u, int &v) {
256 float fy, fu, fv; rgb_to_yuv_f(r, g, b, fy, fu, fv);
257 int iy = fy * 0x10000, iu = fu * 0x10000, iv = fv * 0x10000;
258 CLAMP(iy, ymin16, ymax16);
259 CLAMP(iu, uvmin16, uvmax16); CLAMP(iv, uvmin16, uvmax16);
260 y = iy; u = iu; v = iv;
263 #define YUV_yuv_to_rgb_8(r,g,b, y,u,v) \
264 r = (ytab8[y] + vtor8[v]) >> 16; \
265 g = (ytab8[y] + utog8[u] + vtog8[v]) >> 16; \
266 b = (ytab8[y] + utob8[u]) >> 16
268 bc_always_inline void yuv_to_rgb_8(int &r, int &g, int &b, int y, int u, int v) {
269 YUV_yuv_to_rgb_8(r,g,b, y,u,v);
270 CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff);
272 bc_always_inline void yuv_to_rgb_8(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) {
273 YUV_yuv_to_rgb_8(r,g,b, y,u,v);
275 bc_always_inline void yuv_to_rgb_8(int &r, int &g, int &b) {
276 int y = r, u = g, v = b; YUV_yuv_to_rgb_8(r,g,b, y,u,v);
277 CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff);
279 bc_always_inline void yuv_to_rgb_8(float &r, float &g, float &b, int y, int u, int v) {
280 int ir, ig, ib; YUV_yuv_to_rgb_8(ir,ig,ib, y,u,v);
281 float s = 1/255.f; r = s*ir; g = s*ig; b = s*ib;
284 #define YUV_yuv_to_rgb_16(r,g,b, y,u,v) \
285 r = (ytab16[y] + vtor16[v]) >> 8; \
286 g = (ytab16[y] + utog16[u] + vtog16[v]) >> 8; \
287 b = (ytab16[y] + utob16[u]) >> 8
289 bc_always_inline void yuv_to_rgb_16(int &r, int &g, int &b, int y, int u, int v) {
290 YUV_yuv_to_rgb_16(r,g,b, y,u,v);
291 CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff);
293 bc_always_inline void yuv_to_rgb_16(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) {
294 YUV_yuv_to_rgb_16(r,g,b, y,u,v);
296 bc_always_inline void yuv_to_rgb_16(int &r, int &g, int &b) {
297 int y = r, u = g, v = b; YUV_yuv_to_rgb_16(r,g,b, y,u,v);
298 CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff);
300 bc_always_inline void yuv_to_rgb_16(float &r, float &g, float &b, int y, int u, int v) {
301 int ir, ig, ib; YUV_yuv_to_rgb_16(ir,ig,ib, y,u,v);
302 float s = 1/65535.f; r = s*ir; g = s*ig; b = s*ib;
305 bc_always_inline void yuv_to_rgb_f(float &r, float &g, float &b, float y, float u, float v) {
306 y = (y-yminf) / yrangef;
308 g = y + u_to_g * u + v_to_g * v;
312 // For easier programming. Doesn't do anything.
313 // unused cases in macro expansions, mismatched argument types
314 inline void yuv_to_rgb_8(float &r, float &g, float &b, float y, float u, float v) {}
315 inline void yuv_to_rgb_16(float &r, float &g, float &b, float y, float u, float v) {}
316 inline void yuv_to_rgb_f(int &r, int &g, int &b, int y, int u, int v) {}
317 inline void yuv_to_rgb_f(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) {}
318 inline void yuv_to_rgb_f(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) {}
319 inline void rgb_to_yuv_8(float r, float g, float b, float &y, float &u, float &v) {}
320 inline void rgb_to_yuv_16(float r, float g, float b, float &y, float &u, float &v) {}
321 inline void rgb_to_yuv_f(int &r, int &g, int &b, int y, int u, int v) {}
322 inline void rgb_to_yuv_f(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) {}
323 inline void rgb_to_yuv_f(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) {}
333 // All units are 0 - 1
334 static int rgb_to_hsv(float r, float g, float b, float &h, float &s, float &v);
335 static int hsv_to_rgb(float &r, float &g, float &b, float h, float s, float v);
337 // YUV units are 0 - max. HSV units are 0 - 1
338 static int yuv_to_hsv(int y, int u, int v, float &h, float &s, float &va, int max);
339 static int hsv_to_yuv(int &y, int &u, int &v, float h, float s, float va, int max);
340 // Dummies for macros
341 static int yuv_to_hsv(float y, float u, float v, float &h, float &s, float &va, float max) { return 0; };
342 static int hsv_to_yuv(float &y, float &u, float &v, float h, float s, float va, float max) { return 0; };
347 #define BLACK 0x000000
348 #define WHITE 0xFFFFFF
350 #define LTBLUE 0x9090FF
351 #define BLUE 0x0000FF
352 #define DKBLUE 0x000090
354 #define LTPINK 0xFFC0C0
355 #define PINK 0xFF8080
358 #define LTGREEN 0xC0FFC0
359 #define GREEN 0x00FF00
360 #define DKGREEN 0x009000
362 #define YELLOW 0xFFFF00
363 #define LTYELLOW 0xFFFFA0
364 #define MEYELLOW 0xFFFF00
365 #define MDYELLOW 0xFFFFD2
366 #define DKYELLOW 0xFFFFB4
368 #define LTCYAN 0x00CBCB
369 #define MECYAN 0x009696
370 #define MDCYAN 0x007E7E
371 #define DKCYAN 0x004949
373 #define LTPURPLE 0xFFC0FF
374 #define MEPURPLE 0xFF00FF
375 #define MDPURPLE 0xC000C0
376 #define DKPURPLE 0xA000A0
378 #define LTGREY 0xE0E0E0
379 #define MEGREY 0xAFAFAF
380 #define DMGREY 0x999999
381 #define MDGREY 0x7D7D7D
382 #define DKGREY 0x4B4B4B
384 #define BLOND 0xb4b487
385 #define SLBLUE 0x6040c0
387 #define MNGREY 0xe6e6e6
388 #define FGGREY 0xe3e3e3
389 #define MNBLUE 0x003cff
390 #define ORANGE 0xffdd76
391 #define FTGREY 0xbcbcbc