ed3b6fe1e6e0506598985f2e5b8db308b319b113
[goodguy/history.git] / cinelerra-5.1 / guicast / bccolors.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifndef __BCCOLORS_H__
23 #define __BCCOLORS_H__
24
25 // Duplicate filename in guicast
26
27 #include "clip.h"
28 #include "vframe.inc"
29
30 #include <stdint.h>
31
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
37
38 #define R_TO_U  -0.16874
39 #define G_TO_U  -0.33126
40 #define B_TO_U  0.50000
41
42 #define R_TO_V  0.50000
43 #define G_TO_V  -0.41869
44 #define B_TO_V  -0.08131
45
46 // Decompression coefficients straight out of jpeglib
47 #define V_TO_R  1.40200
48 #define V_TO_G  -0.71414
49
50 #define U_TO_G  -0.34414
51 #define U_TO_B  1.77200
52
53 /*
54 Digital YCbCr is derived from analog RGB as follows:
55 RGB are 0..1 (gamma corrected supposedly),
56 normalized equations:
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
60 inverse:
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)
64
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
69 inverse:
70    R  = Py + 1.402000*Pr
71    G  = Py - 0.714136*Pr - 0.344136*Pb
72    B  = Py               + 1.772000*Pb
73
74 equations zeroed at (0,128,128), range (255,255,255)
75 bt.601  0..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
79 inverse:
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)
83
84 equations zeroed at (16,128,128), range (219,224,224)
85 Y,Cb,Cr = (16,128,128) + (219*Py,224*Pb,224*Pr)
86
87 bt.601  16..235
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
91 inverse:
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)
95
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
100
101 equations zeroed at (0,128,128), range (255,255,255)
102 bt.709  0..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
106 inverse:
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)
110
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
116 inverse:
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)
120
121 */
122 // white vector normalized, so:
123 //  Kg = 1 - Kr - Kb
124
125 #define BT601_Kr 0.299
126 #define BT601_Kb 0.114
127
128 #define BT709_Kr 0.2126
129 #define BT709_Kb 0.0722
130
131 #define BT2020_Kr 0.2627
132 #define BT2020_Kb 0.0593
133
134 class YUV
135 {
136         int mpeg, yzero, uvzero;
137         int ymin8, ymax8, ymin16, ymax16;
138         int uvmin8, uvmax8, uvmin16, uvmax16;
139         double Kr, Kg, Kb;
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;
147         int *tab;
148         float *tabf;
149
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);
158
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)
175
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)
190
191 #define vtor16f (tabf+0x00000)
192 #define vtog16f (tabf+0x10000)
193 #define utog16f (tabf+0x20000)
194 #define utob16f (tabf+0x30000)
195
196 #define vtor8f (tabf+0x40000)
197 #define vtog8f (tabf+0x40100)
198 #define utog8f (tabf+0x40200)
199 #define utob8f (tabf+0x40300)
200
201 #define bc_always_inline __attribute__ ((__always_inline__)) inline
202
203 public:
204         YUV();
205         ~YUV();
206         void yuv_set_colors(int color_space, int color_range);
207         inline int is_mpeg() { return mpeg; }
208
209         static YUV yuv;
210
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
215
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);
218         }
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);
221         }
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);
224         }
225
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
230
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);
233         }
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);
236         }
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);
240         }
241
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;
246         }
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;
253         }
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;
261         }
262
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
267
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);
271         }
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);
274         }
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);
278         }
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;
282         }
283
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
288
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);
292         }
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);
295         }
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);
299         }
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;
303         }
304
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;
307                 r = y + v_to_r * v;
308                 g = y + u_to_g * u + v_to_g * v;
309                 b = y + u_to_b * u;
310         }
311
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) {}
324 };
325
326
327 class HSV
328 {
329 public:
330         HSV();
331         ~HSV();
332
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);
336
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; };
343 };
344
345
346 // standard colors
347 #define BLACK   0x000000
348 #define WHITE   0xFFFFFF
349
350 #define LTBLUE  0x9090FF
351 #define BLUE    0x0000FF
352 #define DKBLUE  0x000090
353
354 #define LTPINK  0xFFC0C0
355 #define PINK    0xFF8080
356 #define RED     0xFF0000
357
358 #define LTGREEN 0xC0FFC0
359 #define GREEN   0x00FF00
360 #define DKGREEN 0x009000
361
362 #define YELLOW  0xFFFF00
363 #define LTYELLOW 0xFFFFA0
364 #define MEYELLOW 0xFFFF00
365 #define MDYELLOW 0xFFFFD2
366 #define DKYELLOW 0xFFFFB4
367
368 #define LTCYAN  0x00CBCB
369 #define MECYAN  0x009696
370 #define MDCYAN  0x007E7E
371 #define DKCYAN  0x004949
372
373 #define LTPURPLE 0xFFC0FF
374 #define MEPURPLE 0xFF00FF
375 #define MDPURPLE 0xC000C0
376 #define DKPURPLE 0xA000A0
377
378 #define LTGREY  0xE0E0E0
379 #define MEGREY  0xAFAFAF
380 #define DMGREY  0x999999
381 #define MDGREY  0x7D7D7D
382 #define DKGREY  0x4B4B4B
383
384 #define BLOND   0xb4b487
385 #define SLBLUE  0x6040c0
386
387 #define MNGREY  0xe6e6e6
388 #define FGGREY  0xe3e3e3
389 #define MNBLUE  0x003cff
390 #define ORANGE  0xffdd76
391 #define FTGREY  0xbcbcbc
392
393 #endif