102
106
} video_ycbcr_color_t;
108
typedef struct video_ycbcr_palette_s {
109
unsigned int num_entries;
110
video_ycbcr_color_t *entries;
111
} video_ycbcr_palette_t;
113
static video_ycbcr_palette_t *video_ycbcr_palette_create(unsigned int num_entries)
115
video_ycbcr_palette_t *p;
117
p = (video_ycbcr_palette_t *)lib_malloc(sizeof(video_ycbcr_palette_t));
119
p->num_entries = num_entries;
120
p->entries = lib_calloc(num_entries, sizeof(video_ycbcr_color_t));
125
static void video_ycbcr_palette_free(video_ycbcr_palette_t *p)
130
lib_free(p->entries);
104
135
/* variables needed for generating and activating a palette */
106
137
struct video_canvas_s *video_current_canvas = NULL;
207
238
dst->name = NULL;
241
/* conversion of RGB to YCbCr */
243
static void video_convert_rgb_to_ycbcr(const palette_entry_t *src,
244
video_ycbcr_color_t *dst)
249
/* convert RGB to YCbCr */
251
yf = 0.2989f*src->red + 0.5866f*src->green + 0.1145f*src->blue;
252
cbf = src->blue - yf;
255
/* convert to int and clip to 8 bit boundaries */
262
if (y > 255) y = 255;
264
if (cb > 255) cb = 255;
266
if (cr > 255) cr = 255;
210
273
/* gammatable calculation */
212
275
static void video_calc_gammatable(void)
243
306
/* ycbcr table calculation */
245
/* YUV table for hardware rendering: (Y << 16) | (U << 8) | V */
246
DWORD yuv_table[128];
248
static void video_calc_ycbcrtable(const video_cbm_palette_t *p)
308
static void video_calc_ycbcrtable(const video_ycbcr_palette_t *p)
250
video_ycbcr_color_t primary;
310
video_ycbcr_color_t *primary;
251
311
unsigned int i, lf, hf;
254
lf = 64*video_resources.pal_blur/1000;
255
hf = 256 - (lf << 1);
314
lf = 64*video_resources.pal_blur/1000;
315
hf = 256 - (lf << 1);
256
316
sat = ((float)(video_resources.color_saturation)) * (256.0f / 1000.0f);
257
317
for (i = 0;i < p->num_entries; i++) {
258
video_convert_cbm_to_ycbcr(&p->entries[i], p->saturation,
260
ytable[i] = (SDWORD)(primary.y * 256.0f);
318
primary = &p->entries[i];
319
ytable[i] = (SDWORD)(primary->y * 256.0f);
261
320
ytablel[i] = ytable[i]*lf;
262
321
ytableh[i] = ytable[i]*hf;
263
cbtable[i] = (SDWORD)(primary.cb * sat);
264
crtable[i] = (SDWORD)(primary.cr * sat);
322
cbtable[i] = (SDWORD)(primary->cb * sat);
323
crtable[i] = (SDWORD)(primary->cr * sat);
266
325
/* YCbCr to YUV, scale [0, 256] to [0, 255] */
267
yuv_table[i] = ((BYTE)(primary.y * 255 / 256 + 0.5) << 16)
268
| ((BYTE)(0.493111 * primary.cb * 255 / 256 + 128.5) << 8)
269
| (BYTE)(0.877283 * primary.cr * 255 / 256 + 128.5);
326
yuv_table[i] = ((BYTE)(primary->y * 255 / 256 + 0.5) << 16)
327
| ((BYTE)(0.493111 * primary->cb * 255 / 256 + 128.5) << 8)
328
| (BYTE)(0.877283 * primary->cr * 255 / 256 + 128.5);
332
/* Convert an RGB palette to YCbCr. */
333
static void video_palette_to_ycbcr(const palette_t *p,
334
video_ycbcr_palette_t* ycbcr)
338
for (i = 0;i < p->num_entries; i++) {
339
video_convert_rgb_to_ycbcr(&p->entries[i], &ycbcr->entries[i]);
343
/* Convert a CBM palette to YCbCr. */
344
static void video_cbm_palette_to_ycbcr(const video_cbm_palette_t *p,
345
video_ycbcr_palette_t* ycbcr)
349
for (i = 0;i < p->num_entries; i++) {
350
video_convert_cbm_to_ycbcr(&p->entries[i], p->saturation,
351
p->phase, &ycbcr->entries[i]);
273
355
/* Calculate a RGB palette out of VIC/VIC-II/TED colors. */
274
static palette_t *video_calc_palette(const video_cbm_palette_t *p)
356
static palette_t *video_calc_palette(const video_ycbcr_palette_t *p)
277
359
video_ycbcr_color_t primary;
292
374
for (i = 0; i <p->num_entries; i++) {
293
video_convert_cbm_to_ycbcr(&p->entries[i], p->saturation,
295
video_convert_ycbcr_to_rgb(&primary, sat, bri, con, gam,
375
video_convert_ycbcr_to_rgb(&p->entries[i], sat, bri, con, gam,
296
376
&prgb->entries[i]);
307
387
for (j = 0; j < p->num_entries; j++) {
308
video_convert_cbm_to_ycbcr(&p->entries[j], p->saturation,
388
primary = p->entries[j];
312
391
for (i = 0; i < p->num_entries; i++) {
313
video_convert_cbm_to_ycbcr(&p->entries[i], p->saturation,
392
primary = p->entries[i];
315
393
primary.cb = (primary.cb + cb) * 0.5f;
316
394
primary.cr = (primary.cr + cr) * 0.5f;
317
395
video_convert_ycbcr_to_rgb(&primary, sat, bri, con, gam,
355
434
if (canvas->videoconfig->external_palette) {
356
435
palette = video_load_palette(canvas->videoconfig->cbm_palette,
357
436
canvas->videoconfig->external_palette_name);
437
video_calc_gammatable();
438
ycbcr = video_ycbcr_palette_create(palette->num_entries);
439
video_palette_to_ycbcr(palette, ycbcr);
440
video_calc_ycbcrtable(ycbcr);
441
if (video_resources.delayloop_emulation) {
442
palette_free(palette);
443
palette = video_calc_palette(ycbcr);
359
446
video_calc_gammatable();
360
video_calc_ycbcrtable(canvas->videoconfig->cbm_palette);
361
palette = video_calc_palette(canvas->videoconfig->cbm_palette);
447
ycbcr = video_ycbcr_palette_create(canvas->videoconfig->cbm_palette->num_entries);
448
video_cbm_palette_to_ycbcr(canvas->videoconfig->cbm_palette, ycbcr);
449
video_calc_ycbcrtable(ycbcr);
450
palette = video_calc_palette(ycbcr);
453
video_ycbcr_palette_free(ycbcr);
364
455
if (palette != NULL)
365
456
return video_canvas_palette_set(canvas, palette);