Ticket #4576: vicepalette.c

File vicepalette.c, 7.1 KB (added by SF/tobigun, 15 years ago)

VICE default palette YUV to RGB

Line 
1/*
2 * VICE default palette color extraction tool
3 *
4 * Based on the VICE 2.1 source files:
5 * video/video-color.c - Video implementation of YUV, YCbCr and RGB colors
6 * vicii/vicii-color.c - Colors for the MOS 6569 (VIC-II) emulation.
7 *
8 * Both files are part of VICE, the Versatile Commodore Emulator.
9 * See README for copyright notice.
10 *
11 * Both originally written by
12 * John Selck <graham@cruise.de>
13 *
14 * Research about the YUV values by
15 * Philip Timmermann <pepto@pepto.de>
16 * John Selck <graham@cruise.de>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
31 * 02111-1307 USA.
32 *
33 */
34
35#include <stdio.h>
36#include <math.h>
37
38/* VIC/VIC-II/TED related color/palette types */
39typedef struct video_cbm_color_s {
40 float luminance; /* luminance */
41 float angle; /* angle on color wheel */
42 int direction; /* +1 (pos), -1 (neg) or 0 (grey) */
43 char *name; /* name of this color */
44} video_cbm_color_t;
45
46typedef struct video_cbm_palette_s {
47 unsigned int num_entries; /* number of colors in palette */
48 video_cbm_color_t *entries; /* array of colors */
49 float saturation; /* base saturation of all colors except the grey tones */
50 float phase; /* color phase (will be added to all color angles) */
51} video_cbm_palette_t;
52
53#define VICII_NUM_COLORS 16
54
55/* base saturation of all colors except the grey tones */
56
57#define VICII_SATURATION 48.0f
58
59/* phase shift of all colors */
60
61#define VICII_PHASE -4.5f
62
63/* chroma angles in UV space */
64
65#define ANGLE_RED 112.5f
66#define ANGLE_GRN -135.0f
67#define ANGLE_BLU 0.0f
68#define ANGLE_ORN -45.0f /* negative orange (orange is at +135.0 degree)
69*/
70#define ANGLE_BRN 157.5f
71
72/* new luminances */
73
74#define LUMN0 0.0f
75#define LUMN1 56.0f
76#define LUMN2 74.0f
77#define LUMN3 92.0f
78#define LUMN4 117.0f
79#define LUMN5 128.0f
80#define LUMN6 163.0f
81#define LUMN7 199.0f
82#define LUMN8 256.0f
83
84/* old luminances */
85
86#define LUMO0 0.0f
87#define LUMO1 56.0f
88#define LUMO2 128.0f
89#define LUMO3 191.0f
90#define LUMO4 256.0f
91
92/* the wellknown vic-ii palette used for 99% of all vic-ii chips */
93
94static video_cbm_color_t vicii_colors[VICII_NUM_COLORS] =
95{
96 { LUMN0, ANGLE_ORN, -0, "Black" },
97 { LUMN8, ANGLE_BRN, 0, "White" },
98 { LUMN2, ANGLE_RED, 1, "Red" },
99 { LUMN6, ANGLE_RED, -1, "Cyan" },
100 { LUMN3, ANGLE_GRN, -1, "Purple" },
101 { LUMN5, ANGLE_GRN, 1, "Green" },
102 { LUMN1, ANGLE_BLU, 1, "Blue" },
103 { LUMN7, ANGLE_BLU, -1, "Yellow" },
104 { LUMN3, ANGLE_ORN, -1, "Orange" },
105 { LUMN1, ANGLE_BRN, 1, "Brown" },
106 { LUMN5, ANGLE_RED, 1, "Light Red" },
107 { LUMN2, ANGLE_RED, -0, "Dark Grey" },
108 { LUMN4, ANGLE_GRN, -0, "Medium Grey" },
109 { LUMN7, ANGLE_GRN, 1, "Light Green" },
110 { LUMN4, ANGLE_BLU, 1, "Light Blue" },
111 { LUMN6, ANGLE_BLU, -0, "Light Grey" }
112};
113
114static video_cbm_palette_t vicii_palette =
115{
116 VICII_NUM_COLORS,
117 vicii_colors,
118 VICII_SATURATION,
119 VICII_PHASE
120};
121
122typedef struct video_ycbcr_color_s {
123 float y;
124 float cb;
125 float cr;
126} video_ycbcr_color_t;
127
128#define MATH_PI 3.141592653589793238462643383279
129
130/* conversion of VIC/VIC-II/TED colors to YCbCr */
131
132static void video_convert_cbm_to_ycbcr(const video_cbm_color_t *src,
133 float basesat, float phase,
134 video_ycbcr_color_t *dst)
135{
136 dst->y = src->luminance;
137
138 /* chrominance (U and V) of color */
139
140 dst->cb = (float)(basesat * cos((src->angle + phase) * (MATH_PI / 180.0)));
141 dst->cr = (float)(basesat * sin((src->angle + phase) * (MATH_PI / 180.0)));
142
143 /* convert UV to CbCr */
144
145 dst->cb /= 0.493111f;
146 dst->cr /= 0.877283f;
147
148 /* direction of color vector (-1 = inverted vector, 0 = grey vector) */
149
150 if (src->direction == 0) {
151 dst->cb = 0.0f;
152 dst->cr = 0.0f;
153 }
154 if (src->direction < 0) {
155 dst->cb = -dst->cb;
156 dst->cr = -dst->cr;
157 }
158
159}
160
161typedef unsigned char BYTE;
162
163typedef struct video_rgb_color_s {
164 BYTE red;
165 BYTE green;
166 BYTE blue;
167} video_rgb_color_t;
168
169/* gamma correction */
170
171static float video_gamma(float value, float gamma, float bri, float con)
172{
173 double factor;
174 float ret;
175
176 value += bri;
177 value *= con;
178
179 if (value <= 0.0f)
180 return 0.0f;
181
182 factor = pow(255.0f, 1.0f - gamma);
183 ret = (float)(factor * pow(value, gamma));
184
185 if (ret < 0.0f)
186 ret = 0.0f;
187
188 return ret;
189}
190
191/* conversion of YCbCr to RGB */
192
193static void video_convert_ycbcr_to_rgb(video_ycbcr_color_t *src, float sat,
194 float bri, float con, float gam, float tin,
195 video_rgb_color_t *dst)
196{
197 float rf, bf, gf;
198 float cb,cr,y;
199 int r, g, b;
200
201 cb=src->cb;
202 cr=src->cr;
203 y=src->y;
204
205 cr += tin; /* apply tint */
206
207 /* apply saturation */
208 cb *= sat;
209 cr *= sat;
210
211 /* convert YCbCr to RGB */
212 bf = cb + y;
213 rf = cr + y;
214 gf = y - (0.1145f / 0.5866f) * cb - (0.2989f / 0.5866f) * cr;
215
216 rf = video_gamma(rf, gam, bri, con);
217 gf = video_gamma(gf, gam, bri, con);
218 bf = video_gamma(bf, gam, bri, con);
219
220 /* convert to int and clip to 8 bit boundaries */
221
222 r = (int)rf;
223 g = (int)gf;
224 b = (int)bf;
225
226 if (r < 0) r = 0;
227 else if (r > 255) r = 255;
228 if (g < 0) g = 0;
229 else if (g > 255) g = 255;
230 if (b < 0) b = 0;
231 else if (b > 255) b = 255;
232 dst->red = (BYTE)r;
233 dst->green = (BYTE)g;
234 dst->blue = (BYTE)b;
235}
236
237/*
238 * Note: VICE uses a default gamma value of 0.88.
239 * As gamma correction should be done by ScummVM's
240 * display settings do not perform any color correction.
241 */
242const float GAMMA = 1.0f; /* 0.88f */
243
244int main() {
245 int i;
246 FILE *f;
247 video_ycbcr_color_t ycbcrColor;
248 video_rgb_color_t rgbColors[VICII_NUM_COLORS];
249
250 for (i = 0; i < VICII_NUM_COLORS; ++i) {
251 video_convert_cbm_to_ycbcr(
252 &vicii_palette.entries[i],
253 vicii_palette.saturation,
254 vicii_palette.phase,
255 &ycbcrColor);
256 video_convert_ycbcr_to_rgb(
257 &ycbcrColor,
258 1, 0, 1, GAMMA, 0,
259 &rgbColors[i]);
260 }
261
262 f = fopen("c64_palette.txt", "w");
263 for (i = 0; i < VICII_NUM_COLORS; ++i) {
264 fprintf(f, "0x%02X, 0x%02X, 0x%02X,", rgbColors[i].red, rgbColors[i].green, rgbColors[i].blue);
265 if ((i+1) % 4 == 0)
266 fprintf(f, "\n");
267 else
268 fprintf(f, " ");
269 }
270 fclose(f);
271
272 return 0;
273}