Commit 636df0d7 authored by Rocky Bernstein's avatar Rocky Bernstein

render.c: RGB2 now gets the right color from the RGB color map.

  And a first cut at handling transparancy values properly. However
  to do this we merely needed to

pixmap.[ch]: write our own routines for retrieving a close colormap index
  given a pixel value. Well, and also had to

video_chroma/i420_rgb.[ch]: save the RGB colormap that is allocated.

Modules.am: forgot new pixmap.c

others: more misc abstraction/cleanup
parent acdfa352
...@@ -20,6 +20,7 @@ SOURCES_cvdsub = \ ...@@ -20,6 +20,7 @@ SOURCES_cvdsub = \
cvd.h \ cvd.h \
subtitle.h \ subtitle.h \
cvd_parse.c \ cvd_parse.c \
pixmap.c \
pixmap.h \ pixmap.h \
render.c \ render.c \
render.h \ render.h \
......
/***************************************************************************** /*****************************************************************************
* Common SVCD and VCD subtitle routines. * Common SVCD and CVD subtitle routines.
***************************************************************************** *****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN * Copyright (C) 2003, 2004 VideoLAN
* $Id: common.c,v 1.11 2004/01/30 13:17:12 rocky Exp $ * $Id: common.c,v 1.12 2004/01/31 05:53:35 rocky Exp $
* *
* Author: Rocky Bernstein <rocky@panix.com> * Author: Rocky Bernstein <rocky@panix.com>
* based on code from: * based on code from:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Common pixel/chroma manipulation routines. * Common pixel/chroma manipulation routines.
***************************************************************************** *****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN * Copyright (C) 2003, 2004 VideoLAN
* $Id: pixmap.c,v 1.2 2004/01/30 13:23:08 rocky Exp $ * $Id: pixmap.c,v 1.3 2004/01/31 05:53:35 rocky Exp $
* *
* Author: Rocky Bernstein * Author: Rocky Bernstein
* *
...@@ -50,15 +50,12 @@ struct chroma_sys_t ...@@ -50,15 +50,12 @@ struct chroma_sys_t
/* To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i], /* To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
p_rgb_b[i]) p_rgb_b[i])
*/ */
uint8_t *p_rgb_r; /* Red values of palette */ uint16_t p_rgb_r[CMAP_RGB2_SIZE]; /* Red values of palette */
uint8_t *p_rgb_g; /* Green values of palette */ uint16_t p_rgb_g[CMAP_RGB2_SIZE]; /* Green values of palette */
uint8_t *p_rgb_b; /* Blue values of palette */ uint16_t p_rgb_b[CMAP_RGB2_SIZE]; /* Blue values of palette */
}; };
/* Number of entries in RGB palette/colormap*/
#define CMAP_SIZE 256
/* /*
From From
http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC11 http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC11
...@@ -110,9 +107,9 @@ struct chroma_sys_t ...@@ -110,9 +107,9 @@ struct chroma_sys_t
/** /**
Find the nearest colormap entry in p_vout (assumed to have RGB2 Find the nearest colormap entry in p_vout (assumed to have RGB2
chroma, i.e. 256 RGB entries) that is closest in color to p_yuv. Set chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
RGB to the color found and return the colormap index. -1 is returned out_rgb to the color found and return the colormap index.
if there is some error. INVALID_CMAP_ENTRY is returned if there is some error.
The closest match is determined by the the Euclidean distance The closest match is determined by the the Euclidean distance
using integer-scaled 601-2 coefficients described above. using integer-scaled 601-2 coefficients described above.
...@@ -121,31 +118,28 @@ struct chroma_sys_t ...@@ -121,31 +118,28 @@ struct chroma_sys_t
comparisons it amounts to the same thing. comparisons it amounts to the same thing.
*/ */
int cmap_t
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv, find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *rgb,
uint8_t *out_rgb) uint8_t *out_rgb)
{ {
uint8_t *p_cmap_r; uint16_t *p_cmap_r;
uint8_t *p_cmap_g; uint16_t *p_cmap_g;
uint8_t *p_cmap_b; uint16_t *p_cmap_b;
uint8_t rgb[RGB_SIZE];
int i; int i;
int i_bestmatch=0; cmap_t i_bestmatch = INVALID_CMAP_ENTRY;
uint32_t i_mindist = 0xFFFFFFFF; /* The largest number here. */ uint32_t i_mindist = 0xFFFFFFFF; /* The largest number here. */
/* Check that we really have RGB2. */ /* Check that we really have RGB2. */
if ( !p_vout && p_vout->output.i_chroma != VLC_FOURCC('R','G','B','2') ) if ( !p_vout && p_vout->output.i_chroma != VLC_FOURCC('R','G','B','2') )
return -1; return INVALID_CMAP_ENTRY;
p_cmap_r=p_vout->chroma.p_sys->p_rgb_r; p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
p_cmap_g=p_vout->chroma.p_sys->p_rgb_g; p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
p_cmap_b=p_vout->chroma.p_sys->p_rgb_b; p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
yuv2rgb(p_yuv, rgb); for (i = 0; i < CMAP_RGB2_SIZE; i++) {
for (i = 0; i < CMAP_SIZE; i++) {
/* Interval range calculations to show that we don't overflow the /* Interval range calculations to show that we don't overflow the
word sizes below. pixels component values start out 8 word sizes below. pixels component values start out 8
bits. When we subtract two components we get 9 bits, then bits. When we subtract two components we get 9 bits, then
...@@ -170,27 +164,73 @@ find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv, ...@@ -170,27 +164,73 @@ find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
#define SCALEBITS 6 #define SCALEBITS 6
#define int32_sqr(x) ( ((int32_t) (x)) * ((int32_t) x) ) #define int32_sqr(x) ( ((int32_t) (x)) * ((int32_t) x) )
uint32_t dr = ( RED_COEF * ( int32_sqr(rgb[RED_PIXEL] - p_cmap_r[i]) /* colormap entires are scaled to 16 bits, so we need to shift
them back down to 8. */
#define CMAP8_RED(i) (p_cmap_r[i]>>8)
#define CMAP8_GREEN(i) (p_cmap_g[i]>>8)
#define CMAP8_BLUE(i) (p_cmap_b[i]>>8)
uint32_t dr = ( RED_COEF * ( int32_sqr(rgb[RED_PIXEL] - CMAP8_RED(i))
<< SCALEBITS ) ) >> (SCALEBITS*2); << SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t dg = ( GREEN_COEF * ( int32_sqr(rgb[GREEN_PIXEL] - p_cmap_g[i]) uint32_t dg = ( GREEN_COEF * ( int32_sqr(rgb[GREEN_PIXEL] - CMAP8_GREEN(i))
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t db = ( BLUE_COEF * ( int32_sqr(rgb[BLUE_PIXEL] - CMAP8_BLUE(i))
<< SCALEBITS ) ) >> (SCALEBITS*2); << SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t db = ( BLUE_COEF * ( int32_sqr(rgb[BLUE_PIXEL] - p_cmap_b[i])
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t i_dist = dr + dg + db; uint32_t i_dist = dr + dg + db;
if (i_dist < i_mindist) { if (i_dist < i_mindist) {
i_bestmatch = i; i_bestmatch = i;
i_mindist = i_dist; i_mindist = i_dist;
#if 0
printf("+++Change dist to %d RGB cmap %d (%0x, %0x, %0x)\n",
i_dist, i, p_cmap_r[ i ], p_cmap_g[ i ], p_cmap_b[ i ]);
#endif
} }
} }
out_rgb[RED_PIXEL] = p_cmap_r[i_bestmatch]; if (out_rgb)
out_rgb[GREEN_PIXEL] = p_cmap_g[i_bestmatch]; {
out_rgb[BLUE_PIXEL] = p_cmap_b[i_bestmatch]; out_rgb[RED_PIXEL] = CMAP8_RED(i_bestmatch);
out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_bestmatch);
out_rgb[BLUE_PIXEL] = CMAP8_BLUE(i_bestmatch);
}
return i_bestmatch; return i_bestmatch;
} }
/**
Get the the rgb value for a given colormap entry for p_vout (which is'
assumed to have RGB2 chroma).
VLC_FALSE is returned if there was some error.
*/
vlc_bool_t
query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
/*out*/ uint8_t *out_rgb)
{
uint16_t *p_cmap_r;
uint16_t *p_cmap_g;
uint16_t *p_cmap_b;
/* Check that we really have RGB2. */
if ( !p_vout && p_vout->output.i_chroma != VLC_FOURCC('R','G','B','2') )
return VLC_FALSE;
if ( !out_rgb )
return VLC_FALSE;
p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
out_rgb[RED_PIXEL] = CMAP8_RED(i_cmap);
out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_cmap);
out_rgb[BLUE_PIXEL] = CMAP8_BLUE(i_cmap);
return VLC_TRUE;
}
/* /*
* Local variables: * Local variables:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Common pixel/chroma manipulation routines. * Common pixel/chroma manipulation routines.
***************************************************************************** *****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN * Copyright (C) 2003, 2004 VideoLAN
* $Id: pixmap.h,v 1.4 2004/01/30 13:17:12 rocky Exp $ * $Id: pixmap.h,v 1.5 2004/01/31 05:53:35 rocky Exp $
* *
* Author: Rocky Bernstein * Author: Rocky Bernstein
* *
...@@ -36,6 +36,15 @@ typedef union { ...@@ -36,6 +36,15 @@ typedef union {
} s; } s;
} ogt_yuvt_t; } ogt_yuvt_t;
/** An undefined or invalid colormap index. */
#define INVALID_CMAP_ENTRY -1
/** Type of a palette/colormap index*/
typedef int16_t cmap_t;
/** Number of entries in RGB palette/colormap*/
#define CMAP_RGB2_SIZE 256
/** /**
Force v in the range 0..255. In video_chroma/i420_rgb.c, this Force v in the range 0..255. In video_chroma/i420_rgb.c, this
is macro is called CLIP. FIXME: Combine with that. is macro is called CLIP. FIXME: Combine with that.
...@@ -113,7 +122,7 @@ yuv2rgb(const ogt_yuvt_t *p_yuv, uint8_t *p_rgb_out ) ...@@ -113,7 +122,7 @@ yuv2rgb(const ogt_yuvt_t *p_yuv, uint8_t *p_rgb_out )
to do.) to do.)
*/ */
static inline void static inline void
put_rgb24_pixel(const uint8_t *rgb, uint8_t *p_pixel) put_rgb24_pixel(const uint8_t *rgb, /*out*/ uint8_t *p_pixel)
{ {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
*p_pixel++; *p_pixel++;
...@@ -124,14 +133,24 @@ put_rgb24_pixel(const uint8_t *rgb, uint8_t *p_pixel) ...@@ -124,14 +133,24 @@ put_rgb24_pixel(const uint8_t *rgb, uint8_t *p_pixel)
} }
/** /**
Find the nearest colormap entry in p_vout (assumed to have RGB2 Find the nearest colormap entry in p_vout (assumed to have RGB2
chroma, i.e. 256 RGB entries) that is closest in color to p_yuv. Set chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
rgb to the color found and return the colormap index. -1 is returned out_rgb to the color found and return the colormap index.
if there is some error. INVALID_CMAP_ENTRY is returned if there is some error.
*/
cmap_t
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *p_rgb,
/*out*/ uint8_t *out_rgb);
/**
Get the the rgb value for a given colormap entry for p_vout (which is'
assumed to have RGB2 chroma).
VLC_FALSE is returned if there was some error.
*/ */
int vlc_bool_t
find_cmap_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv, query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
uint8_t *rgb); /*out*/ uint8_t *rgb);
#endif /* PIXMAP_H */ #endif /* PIXMAP_H */
......
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
* i420_rgb.c : YUV to bitmap RGB conversion module for vlc * i420_rgb.c : YUV to bitmap RGB conversion module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001, 2004 VideoLAN
* $Id: i420_rgb.c,v 1.6 2003/12/22 14:32:56 sam Exp $ * $Id: i420_rgb.c,v 1.7 2004/01/31 05:53:35 rocky Exp $
* *
* Author: Sam Hocevar <sam@zoy.org> * Author: Sam Hocevar <sam@zoy.org>
* *
...@@ -344,7 +344,10 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) ...@@ -344,7 +344,10 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
int y,u,v; int y,u,v;
int r,g,b; int r,g,b;
int i = 0, j = 0; int i = 0, j = 0;
uint16_t red[ 256 ], green[ 256 ], blue[ 256 ]; uint16_t *p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
uint16_t *p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
uint16_t *p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
unsigned char p_lookup[PALETTE_TABLE_SIZE]; unsigned char p_lookup[PALETTE_TABLE_SIZE];
/* This loop calculates the intersection of an YUV box and the RGB cube. */ /* This loop calculates the intersection of an YUV box and the RGB cube. */
...@@ -371,9 +374,15 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) ...@@ -371,9 +374,15 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
} }
/* Clip the colors */ /* Clip the colors */
red[ j ] = CLIP( r ); p_cmap_r[ j ] = CLIP( r );
green[ j ] = CLIP( g ); p_cmap_g[ j ] = CLIP( g );
blue[ j ] = CLIP( b ); p_cmap_b[ j ] = CLIP( b );
#if 0
printf("+++Alloc RGB cmap %d (%d, %d, %d)\n", j,
p_cmap_r[ j ] >>8, p_cmap_g[ j ] >>8,
p_cmap_b[ j ] >>8);
#endif
/* Allocate color */ /* Allocate color */
p_lookup[ i ] = 1; p_lookup[ i ] = 1;
...@@ -390,7 +399,7 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 ) ...@@ -390,7 +399,7 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
} }
/* The colors have been allocated, we can set the palette */ /* The colors have been allocated, we can set the palette */
p_vout->output.pf_setpalette( p_vout, red, green, blue ); p_vout->output.pf_setpalette( p_vout, p_cmap_r, p_cmap_g, p_cmap_b );
#if 0 #if 0
/* There will eventually be a way to know which colors /* There will eventually be a way to know which colors
......
/***************************************************************************** /*****************************************************************************
* i420_rgb.h : YUV to bitmap RGB conversion module for vlc * i420_rgb.h : YUV to bitmap RGB conversion module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000, 2004 VideoLAN
* $Id: i420_rgb.h,v 1.4 2003/08/29 18:58:05 fenrir Exp $ * $Id: i420_rgb.h,v 1.5 2004/01/31 05:53:35 rocky Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -21,23 +21,34 @@ ...@@ -21,23 +21,34 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
/***************************************************************************** /** Number of entries in RGB palette/colormap */
#define CMAP_RGB2_SIZE 256
/**
* chroma_sys_t: chroma method descriptor * chroma_sys_t: chroma method descriptor
*****************************************************************************
* This structure is part of the chroma transformation descriptor, it * This structure is part of the chroma transformation descriptor, it
* describes the yuv2rgb specific properties. * describes the yuv2rgb specific properties.
*****************************************************************************/ */
struct chroma_sys_t struct chroma_sys_t
{ {
uint8_t *p_buffer; uint8_t *p_buffer;
int *p_offset; int *p_offset;
#ifdef MODULE_NAME_IS_i420_rgb #ifdef MODULE_NAME_IS_i420_rgb
/* Pre-calculated conversion tables */ /**< Pre-calculated conversion tables */
void *p_base; /* base for all conversion tables */ void *p_base; /**< base for all conversion tables */
uint8_t *p_rgb8; /* RGB 8 bits table */ uint8_t *p_rgb8; /**< RGB 8 bits table */
uint16_t *p_rgb16; /* RGB 16 bits table */ uint16_t *p_rgb16; /**< RGB 16 bits table */
uint32_t *p_rgb32; /* RGB 32 bits table */ uint32_t *p_rgb32; /**< RGB 32 bits table */
/**< To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
p_rgb_b[i]). Note these are 16 bits per pixel. For 8bpp entries,
shift right 8 bits.
*/
uint16_t p_rgb_r[CMAP_RGB2_SIZE]; /**< Red values of palette */
uint16_t p_rgb_g[CMAP_RGB2_SIZE]; /**< Green values of palette */
uint16_t p_rgb_b[CMAP_RGB2_SIZE]; /**< Blue values of palette */
#endif #endif
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment