0d46ff06b91d502c29039d414b28280583efc69f
[goodguy/history.git] / cinelerra-5.1 / cinelerra / cicolors.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 #include "cicolors.h"
23
24 #include <stdio.h>
25
26 HSV::HSV()
27 {
28 }
29
30
31 HSV::~HSV()
32 {
33 }
34
35 YUV HSV::yuv_static;
36
37 int HSV::rgb_to_hsv(float r, float g, float b, float &h, float &s, float &v)
38 {
39         float min, max, delta;
40         min = ((r < g) ? r : g) < b ? ((r < g) ? r : g) : b;
41         max = ((r > g) ? r : g) > b ? ((r > g) ? r : g) : b;
42         v = max;
43
44         delta = max - min;
45
46         if(max != 0 && delta != 0)
47     {
48             s = delta / max;               // s
49
50                 if(r == max)
51                 h = (g - b) / delta;         // between yellow & magenta
52                 else
53                 if(g == max)
54                 h = 2 + (b - r) / delta;     // between cyan & yellow
55                 else
56                 h = 4 + (r - g) / delta;     // between magenta & cyan
57
58                 h *= 60;                               // degrees
59                 if(h < 0)
60                 h += 360;
61         }
62         else
63         {
64         // r = g = b = 0                // s = 0, v is undefined
65         s = 0;
66         h = -1;
67         }
68
69         return 0;
70 }
71
72 int HSV::hsv_to_rgb(float &r, float &g, float &b, float h, float s, float v)
73 {
74     int i;
75         float f, p, q, t;
76     if(s == 0)
77         {
78         // achromatic (grey)
79         r = g = b = v;
80         return 0;
81     }
82
83     h /= 60;                        // sector 0 to 5
84     i = (int)h;
85     f = h - i;                      // factorial part of h
86     p = v * (1 - s);
87     q = v * (1 - s * f);
88     t = v * (1 - s * (1 - f));
89
90     switch(i)
91         {
92         case 0:
93             r = v;
94             g = t;
95             b = p;
96             break;
97         case 1:
98             r = q;
99             g = v;
100             b = p;
101             break;
102         case 2:
103             r = p;
104             g = v;
105             b = t;
106             break;
107         case 3:
108             r = p;
109             g = q;
110             b = v;
111             break;
112         case 4:
113             r = t;
114             g = p;
115             b = v;
116             break;
117         default:                // case 5:
118             r = v;
119             g = p;
120             b = q;
121             break;
122     }
123         return 0;
124 }
125
126 int HSV::yuv_to_hsv(int y, int u, int v, float &h, float &s, float &va, int max)
127 {
128         float r, g, b;
129         int r_i, g_i, b_i;
130
131 //      if(max == 0xffff)
132 //      {
133 //              yuv_static.yuv_to_rgb_16(r_i, g_i, b_i, y, u, v);
134 //      }
135 //      else
136         {
137                 yuv_static.yuv_to_rgb_8(r_i, g_i, b_i, y, u, v);
138         }
139         r = (float)r_i / max;
140         g = (float)g_i / max;
141         b = (float)b_i / max;
142
143         float h2, s2, v2;
144         HSV::rgb_to_hsv(r, g, b, h2, s2, v2);
145         h = h2;
146         s = s2;
147         va = v2;
148
149         return 0;
150 }
151
152 int HSV::hsv_to_yuv(int &y, int &u, int &v, float h, float s, float va, int max)
153 {
154         float r, g, b;
155         int r_i, g_i, b_i;
156         HSV::hsv_to_rgb(r, g, b, h, s, va);
157         r = r * max + 0.5;
158         g = g * max + 0.5;
159         b = b * max + 0.5;
160         r_i = (int)CLIP(r, 0, max);
161         g_i = (int)CLIP(g, 0, max);
162         b_i = (int)CLIP(b, 0, max);
163
164         int y2, u2, v2;
165 //      if(max == 0xffff)
166 //              yuv_static.rgb_to_yuv_16(r_i, g_i, b_i, y2, u2, v2);
167 //      else
168                 yuv_static.rgb_to_yuv_8(r_i, g_i, b_i, y2, u2, v2);
169         y = y2;
170         u = u2;
171         v = v2;
172
173         return 0;
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 YUV::YUV()
200 {
201         for(int i = 0; i < 0x100; i++)
202         {
203 // compression
204                 rtoy_tab_8[i] = (int)(R_TO_Y * 0x100 * i);
205                 rtou_tab_8[i] = (int)(R_TO_U * 0x100 * i);
206                 rtov_tab_8[i] = (int)(R_TO_V * 0x100 * i);
207
208                 gtoy_tab_8[i] = (int)(G_TO_Y * 0x100 * i);
209                 gtou_tab_8[i] = (int)(G_TO_U * 0x100 * i);
210                 gtov_tab_8[i] = (int)(G_TO_V * 0x100 * i);
211
212                 btoy_tab_8[i] = (int)(B_TO_Y * 0x100 * i);
213                 btou_tab_8[i] = (int)(B_TO_U * 0x100 * i) + 0x8000;
214                 btov_tab_8[i] = (int)(B_TO_V * 0x100 * i) + 0x8000;
215         }
216
217         vtor_8 = &(vtor_tab_8[(0x100) / 2]);
218         vtog_8 = &(vtog_tab_8[(0x100) / 2]);
219         utog_8 = &(utog_tab_8[(0x100) / 2]);
220         utob_8 = &(utob_tab_8[(0x100) / 2]);
221
222         for(int i = (-0x100) / 2; i < (0x100) / 2; i++)
223         {
224 // decompression
225                 vtor_8[i] = (int)(V_TO_R * 0x100 * i);
226                 vtog_8[i] = (int)(V_TO_G * 0x100 * i);
227
228                 utog_8[i] = (int)(U_TO_G * 0x100 * i);
229                 utob_8[i] = (int)(U_TO_B * 0x100 * i);
230         }
231
232         for(int i = 0; i < 0x10000; i++)
233         {
234 // compression
235                 rtoy_tab_16[i] = (int)(R_TO_Y * 0x100 * i);
236                 rtou_tab_16[i] = (int)(R_TO_U * 0x100 * i);
237                 rtov_tab_16[i] = (int)(R_TO_V * 0x100 * i);
238
239                 gtoy_tab_16[i] = (int)(G_TO_Y * 0x100 * i);
240                 gtou_tab_16[i] = (int)(G_TO_U * 0x100 * i);
241                 gtov_tab_16[i] = (int)(G_TO_V * 0x100 * i);
242
243                 btoy_tab_16[i] = (int)(B_TO_Y * 0x100 * i);
244                 btou_tab_16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000;
245                 btov_tab_16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000;
246         }
247
248         vtor_16 = &(vtor_tab_16[(0x10000) / 2]);
249         vtog_16 = &(vtog_tab_16[(0x10000) / 2]);
250         utog_16 = &(utog_tab_16[(0x10000) / 2]);
251         utob_16 = &(utob_tab_16[(0x10000) / 2]);
252
253         for(int i = (-0x10000) / 2; i < (0x10000) / 2; i++)
254         {
255 // decompression
256                 vtor_16[i] = (int)(V_TO_R * 0x100 * i);
257                 vtog_16[i] = (int)(V_TO_G * 0x100 * i);
258
259                 utog_16[i] = (int)(U_TO_G * 0x100 * i);
260                 utob_16[i] = (int)(U_TO_B * 0x100 * i);
261         }
262 }
263
264 YUV::~YUV()
265 {
266 }