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 */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* render.c : Philips OGT and CVD (VCD Subtitle) blending routines * render.c : Philips OGT and CVD (VCD Subtitle) blending routines
***************************************************************************** *****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN * Copyright (C) 2003, 2004 VideoLAN
* $Id: render.c,v 1.26 2004/01/29 11:50:22 rocky Exp $ * $Id: render.c,v 1.27 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:
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
/*#define TESTING_BLENDING 1*/ /*#define TESTING_TRANSPARENCY 1*/
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
...@@ -235,7 +235,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -235,7 +235,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
} }
} }
#ifdef TESTING_BLENDING #ifdef TESTING_TRANSPARENCY
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1; if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
#endif #endif
...@@ -434,7 +434,7 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -434,7 +434,7 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
else else
i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2; i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2;
#ifdef TESTING_BLENDING #ifdef TESTING_TRANSPARENCY
if (i_avg_tr == MAX_ALPHA) i_avg_tr >>= 1; if (i_avg_tr == MAX_ALPHA) i_avg_tr >>= 1;
#endif #endif
...@@ -801,7 +801,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -801,7 +801,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
return; return;
} }
#ifdef TESTING_BLENDING #ifdef TESTING_TRANSPARENCY
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1; if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
#endif #endif
...@@ -1110,7 +1110,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1110,7 +1110,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
return; return;
} }
#ifdef TESTING_BLENDING #ifdef TESTING_TRANSPARENCY
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 2; if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 2;
#endif #endif
...@@ -1574,6 +1574,62 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1574,6 +1574,62 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
} }
} }
/*
Return the colormap index for the average of p_pixel and a subtitle
pixel in RGB form.
*/
static inline cmap_t
avg_rgb2(const vout_thread_t *p_vout, uint8_t i_pixel, cmap_t i_cmap_sub,
const uint8_t rgb_sub[] )
{
uint8_t rgb_vout[RGB_SIZE];
static cmap_t avg_cache[CMAP_RGB2_SIZE][NUM_SUBTITLE_COLORS];
static vlc_bool_t b_first_time = VLC_TRUE;
int i;
/* FIXME: really we need to save subtitle number since in theory
the palette can change each on each distinct subtitle. In practice
this doesn't happen that much.
*/
if (b_first_time)
{
int i, j;
for (i=0; i<CMAP_RGB2_SIZE; i++)
for (j=0; j<NUM_SUBTITLE_COLORS; j++)
avg_cache[i][j] = INVALID_CMAP_ENTRY;
}
if ( avg_cache[i_pixel][i_cmap_sub] != INVALID_CMAP_ENTRY )
return avg_cache[i_pixel][i_cmap_sub];
if ( !query_color(p_vout, i_pixel, rgb_vout) ) return INVALID_CMAP_ENTRY;
for (i = 0; i < RGB_SIZE; i++)
{
rgb_vout[i] = (rgb_vout[i] + rgb_sub[i]) / 2;
}
#if 0
{
uint8_t rgb_approx[RGB_SIZE];
avg_cache[i_pixel][i_cmap_sub] =
find_cmap_rgb8_nearest(p_vout, rgb_vout, rgb_approx);
printf(
"cmap old %0x new 0%x sub=(%0x, %0x, %0x) "
"avg=(%0x, %0x, %0x) vout=(%0x, %0x, %0x)\n",
i_pixel, i_cmap,
rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL], rgb_sub[BLUE_PIXEL],
rgb_approx[RED_PIXEL], rgb_approx[GREEN_PIXEL], rgb_approx[BLUE_PIXEL],
rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL]);
}
#else
avg_cache[i_pixel][i_cmap_sub] =
find_cmap_rgb8_nearest(p_vout, rgb_vout, NULL);
#endif
return avg_cache[i_pixel][i_cmap_sub];
}
#undef BYTES_PER_PIXEL #undef BYTES_PER_PIXEL
#define BYTES_PER_PIXEL 1 #define BYTES_PER_PIXEL 1
...@@ -1601,9 +1657,12 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1601,9 +1657,12 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
/* Crop-specific */ /* Crop-specific */
int i_x_start, i_y_start, i_x_end, i_y_end; int i_x_start, i_y_start, i_x_end, i_y_end;
/* 4 entry colormap */ /* 4-entry array of colormap indices */
uint8_t cmap[NUM_SUBTITLE_COLORS]; uint8_t cmap[NUM_SUBTITLE_COLORS];
int i_cmap; int i;
/* Actual RGB values for above; this is used in blending.*/
uint8_t cmap_rgb[NUM_SUBTITLE_COLORS][RGB_SIZE];
struct subpicture_sys_t *p_sys = p_spu->p_sys; struct subpicture_sys_t *p_sys = p_spu->p_sys;
unsigned int i_aspect_x, i_aspect_y; unsigned int i_aspect_x, i_aspect_y;
...@@ -1611,24 +1670,6 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1611,24 +1670,6 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
vout_AspectRatio( p_vout->render.i_aspect, &i_aspect_y, vout_AspectRatio( p_vout->render.i_aspect, &i_aspect_y,
&i_aspect_x ); &i_aspect_x );
/* Find a corresponding colormap entries for our palette entries. */
for( i_cmap = 0; i_cmap < NUM_SUBTITLE_COLORS; i_cmap++ )
{
uint8_t Y = p_sys->p_palette[i_cmap].s.y;
/* FIXME: when we have a way to look at colormap entries we can
do better. For now we have to use 0xff for white 0x00 for
black and 0x44 for something in between. To do this we use
only the Y component.
*/
if (Y > 0x70)
cmap[i_cmap] = 0xff; /* Use white. */
else if (Y < 0x10)
cmap[i_cmap] = 0x00; /* Use black. */
else
cmap[i_cmap] = 0x44; /* Use something else. */
}
i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x) i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)
/ (i_aspect_y * p_vout->render.i_width); / (i_aspect_y * p_vout->render.i_width);
i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height; i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
...@@ -1644,6 +1685,25 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1644,6 +1685,25 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
i_width = p_spu->i_width * i_xscale; i_width = p_spu->i_width * i_xscale;
i_height = p_spu->i_height * i_yscale; i_height = p_spu->i_height * i_yscale;
/** FIXME: do once per subtitle in subtitle processing, not here
each time we render. */
/* Find a corresponding colormap entries for our palette entries. */
for( i = 0; i < NUM_SUBTITLE_COLORS; i++ )
{
if ( p_sys->p_palette[i].s.t != 0 ) {
uint8_t rgb[RGB_SIZE];
uint8_t approx_rgb[RGB_SIZE];
yuv2rgb(&(p_sys->p_palette[i]), rgb);
cmap[i] =
find_cmap_rgb8_nearest(p_vout, rgb, approx_rgb);
dbg_print( (DECODE_DBG_RENDER),
"palette %d RGB=(%0x, %0x, %0x)\n", i,
rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL]);
}
}
/* Set where we will start blending subtitle from using /* Set where we will start blending subtitle from using
the picture coordinates subtitle offsets the picture coordinates subtitle offsets
*/ */
...@@ -1706,25 +1766,57 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1706,25 +1766,57 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
} }
p_yuvt = p_sys->p_palette[*p_source & 0x3]; p_yuvt = p_sys->p_palette[*p_source & 0x3];
if ( (p_yuvt.s.t) < (MAX_ALPHA) / 2 ) {
/* Completely or relatively transparent. Don't change pixel. */ #ifdef TESTING_TRANSPARENCY
; if (p_yuvt.s.t == MAX_ALPHA) p_yuvt.s.t >>= 1;
#endif
switch ( p_yuvt.s.t )
{
case 0:
/* Completely transparent. Don't change pixel. */
#if 0 #if 0
printf(" "); /*++++*/ printf(" "); /*++++*/
#endif #endif
} else { break;
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) case MAX_ALPHA:
* BYTES_PER_PIXEL ); {
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE) uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL ); * BYTES_PER_PIXEL );
/* This is the pixel that's going to change;*/ uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
uint8_t *p_dest = p_pixel_base_y + i_xdest; * BYTES_PER_PIXEL );
memset( p_dest, cmap[*p_source & 0x3], i_xlast - i_xdest ); /* This is the pixel that's going to change;*/
uint8_t *p_dest = p_pixel_base_y + i_xdest;
memset( p_dest, cmap[*p_source & 0x3], i_xlast - i_xdest );
#if 0 #if 0
printf("%1d", *p_source); /*++++*/ printf("%1d", *p_source); /*++++*/
#endif #endif
} break;
}
default:
{
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
/* This is the pixel that's going to change;*/
uint8_t *p_pixel = p_pixel_base_y + i_xdest;
uint32_t len = i_xlast - i_xdest;
for ( len = i_xlast - i_xdest -1; len >= 0; len-- )
{
cmap_t i_cmap = avg_rgb2(p_vout, *p_pixel,
cmap[*p_source],
cmap_rgb[*p_source]);
if (i_cmap != INVALID_CMAP_ENTRY)
*p_pixel= (uint8_t) i_cmap;
p_pixel++;
}
#if 0
printf("%1d", *p_source); /*++++*/
#endif
}
}
} }
#if 0 #if 0
printf("\n"); /*++++*/ printf("\n"); /*++++*/
...@@ -1758,29 +1850,62 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1758,29 +1850,62 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
return; return;
} }
if ( (p_yuvt.s.t) < (MAX_ALPHA) / 2 ) { #ifdef TESTING_TRANSPARENCY
/* Completely or relatively transparent. Don't change pixel. */ if (p_yuvt.s.t == MAX_ALPHA) p_yuvt.s.t >>= 1;
; #endif
switch ( p_yuvt.s.t )
{
case 0:
/* Completely transparent. Don't change pixel. */
#if 0
printf(" "); /*++++*/
#endif
break;
case MAX_ALPHA:
{
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
#if 0 #if 0
printf(" "); /*++++*/ printf("%1d", *p_source); /*++++*/
#endif #endif
} else { for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) i_ytmp += p_pic->p->i_pitch ) {
* BYTES_PER_PIXEL ); uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE) memset( p_dest, cmap[*p_source & 0x3], len );
* BYTES_PER_PIXEL ); }
uint32_t len = i_xlast - i_xdest; break;
}
default:
{
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
int32_t len;
#if 0 #if 0
printf("%1d", *p_source); /*++++*/ printf("%1d", *p_source); /*++++*/
#endif #endif
for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
i_ytmp += p_pic->p->i_pitch ) {
uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
memset( p_dest, cmap[*p_source & 0x3], len );
}
}
}
for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
i_ytmp += p_pic->p->i_pitch ) {
/* This is the pixel that's going to change;*/
uint8_t *p_pixel = p_pixel_base + i_ytmp + i_xdest;
for ( len = i_xlast - i_xdest -1; len >= 0; len-- )
{
cmap_t i_cmap = avg_rgb2(p_vout, *p_pixel,
cmap[*p_source],
cmap_rgb[*p_source]);
if (i_cmap != INVALID_CMAP_ENTRY)
*p_pixel= (uint8_t) i_cmap;
p_pixel++;
}
}
}
}
}
} }
} }
} }
......
/***************************************************************************** /*****************************************************************************
* 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