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 = \
cvd.h \
subtitle.h \
cvd_parse.c \
pixmap.c \
pixmap.h \
render.c \
render.h \
......
/*****************************************************************************
* Common SVCD and VCD subtitle routines.
* Common SVCD and CVD subtitle routines.
*****************************************************************************
* 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>
* based on code from:
......
......@@ -2,7 +2,7 @@
* Common pixel/chroma manipulation routines.
*****************************************************************************
* 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
*
......@@ -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],
p_rgb_b[i])
*/
uint8_t *p_rgb_r; /* Red values of palette */
uint8_t *p_rgb_g; /* Green values of palette */
uint8_t *p_rgb_b; /* Blue values of palette */
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 */
};
/* Number of entries in RGB palette/colormap*/
#define CMAP_SIZE 256
/*
From
http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC11
......@@ -110,9 +107,9 @@ struct chroma_sys_t
/**
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
RGB to the color found and return the colormap index. -1 is returned
if there is some error.
chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
out_rgb to the color found and return the colormap index.
INVALID_CMAP_ENTRY is returned if there is some error.
The closest match is determined by the the Euclidean distance
using integer-scaled 601-2 coefficients described above.
......@@ -121,31 +118,28 @@ struct chroma_sys_t
comparisons it amounts to the same thing.
*/
int
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
cmap_t
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *rgb,
uint8_t *out_rgb)
{
uint8_t *p_cmap_r;
uint8_t *p_cmap_g;
uint8_t *p_cmap_b;
uint8_t rgb[RGB_SIZE];
uint16_t *p_cmap_r;
uint16_t *p_cmap_g;
uint16_t *p_cmap_b;
int i;
int i_bestmatch=0;
cmap_t i_bestmatch = INVALID_CMAP_ENTRY;
uint32_t i_mindist = 0xFFFFFFFF; /* The largest number here. */
/* Check that we really have RGB2. */
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_g=p_vout->chroma.p_sys->p_rgb_g;
p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
yuv2rgb(p_yuv, rgb);
for (i = 0; i < CMAP_SIZE; i++) {
for (i = 0; i < CMAP_RGB2_SIZE; i++) {
/* Interval range calculations to show that we don't overflow the
word sizes below. pixels component values start out 8
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,
#define SCALEBITS 6
#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);
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);
uint32_t db = ( BLUE_COEF * ( int32_sqr(rgb[BLUE_PIXEL] - p_cmap_b[i])
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t i_dist = dr + dg + db;
if (i_dist < i_mindist) {
i_bestmatch = i;
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];
out_rgb[GREEN_PIXEL] = p_cmap_g[i_bestmatch];
out_rgb[BLUE_PIXEL] = p_cmap_b[i_bestmatch];
if (out_rgb)
{
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;
}
/**
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:
......
......@@ -2,7 +2,7 @@
* Common pixel/chroma manipulation routines.
*****************************************************************************
* 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
*
......@@ -36,6 +36,15 @@ typedef union {
} s;
} 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
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 )
to do.)
*/
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
*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
chroma, i.e. 256 RGB entries) that is closest in color to p_yuv. Set
rgb to the color found and return the colormap index. -1 is returned
if there is some error.
Find the nearest colormap entry in p_vout (assumed to have RGB2
chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
out_rgb to the color found and return the colormap index.
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
find_cmap_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
uint8_t *rgb);
vlc_bool_t
query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
/*out*/ uint8_t *rgb);
#endif /* PIXMAP_H */
......
This diff is collapsed.
/*****************************************************************************
* i420_rgb.c : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_rgb.c,v 1.6 2003/12/22 14:32:56 sam Exp $
* Copyright (C) 2000, 2001, 2004 VideoLAN
* $Id: i420_rgb.c,v 1.7 2004/01/31 05:53:35 rocky Exp $
*
* Author: Sam Hocevar <sam@zoy.org>
*
......@@ -344,7 +344,10 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
int y,u,v;
int r,g,b;
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];
/* 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 )
}
/* Clip the colors */
red[ j ] = CLIP( r );
green[ j ] = CLIP( g );
blue[ j ] = CLIP( b );
p_cmap_r[ j ] = CLIP( r );
p_cmap_g[ j ] = CLIP( g );
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 */
p_lookup[ i ] = 1;
......@@ -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 */
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
/* There will eventually be a way to know which colors
......
/*****************************************************************************
* i420_rgb.h : YUV to bitmap RGB conversion module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: i420_rgb.h,v 1.4 2003/08/29 18:58:05 fenrir Exp $
* Copyright (C) 2000, 2004 VideoLAN
* $Id: i420_rgb.h,v 1.5 2004/01/31 05:53:35 rocky Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -21,23 +21,34 @@
* 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
*****************************************************************************
* This structure is part of the chroma transformation descriptor, it
* describes the yuv2rgb specific properties.
*****************************************************************************/
*/
struct chroma_sys_t
{
uint8_t *p_buffer;
int *p_offset;
#ifdef MODULE_NAME_IS_i420_rgb
/* Pre-calculated conversion tables */
void *p_base; /* base for all conversion tables */
uint8_t *p_rgb8; /* RGB 8 bits table */
uint16_t *p_rgb16; /* RGB 16 bits table */
uint32_t *p_rgb32; /* RGB 32 bits table */
/**< Pre-calculated conversion tables */
void *p_base; /**< base for all conversion tables */
uint8_t *p_rgb8; /**< RGB 8 bits table */
uint16_t *p_rgb16; /**< RGB 16 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
};
......
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