Commit afd56ce5 authored by Rocky Bernstein's avatar Rocky Bernstein

render.c: RV24 blending

all: more code cleanup and perhaps slightly better bigendian handling though
     more common routines/includes.
parent 55645776
......@@ -2,7 +2,7 @@
* Common SVCD and VCD subtitle routines.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: common.c,v 1.9 2004/01/23 10:19:37 rocky Exp $
* $Id: common.c,v 1.10 2004/01/29 11:50:21 rocky Exp $
*
* Author: Rocky Bernstein <rocky@panix.com>
* based on code from:
......@@ -510,7 +510,6 @@ void VCDSubDumpImage( uint8_t *p_image, uint32_t i_height, uint32_t i_width )
#ifdef HAVE_LIBPNG
#define BYTES_PER_RGB 3
#define PALETTE_SIZE 4
/* Note the below assumes the above is a power of 2 */
#define PALETTE_SIZE_MASK (PALETTE_SIZE-1)
......@@ -529,11 +528,11 @@ VCDSubDumpPNG( uint8_t *p_image, decoder_t *p_dec,
{
decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t *p = p_image;
uint8_t *image_data = malloc(BYTES_PER_RGB * i_height * i_width );
uint8_t *image_data = malloc(RGB_SIZE * i_height * i_width );
uint8_t *q = image_data;
unsigned int i_row; /* scanline row number */
unsigned int i_column; /* scanline column number */
uint8_t rgb_palette[PALETTE_SIZE * BYTES_PER_RGB];
uint8_t rgb_palette[PALETTE_SIZE * RGB_SIZE];
int i;
dbg_print( (DECODE_DBG_CALL), "%s", filename);
......@@ -543,14 +542,14 @@ VCDSubDumpPNG( uint8_t *p_image, decoder_t *p_dec,
/* Convert palette YUV into RGB. */
for (i=0; i<PALETTE_SIZE; i++) {
ogt_yuvt_t *p_yuv = &(p_sys->p_palette[i]);
uint8_t *p_rgb_out = &(rgb_palette[i*BYTES_PER_RGB]);
uint8_t *p_rgb_out = &(rgb_palette[i*RGB_SIZE]);
yuv2rgb( p_yuv, p_rgb_out );
}
/* Convert palette entries into linear RGB array. */
for ( i_row=0; i_row < i_height; i_row ++ ) {
for ( i_column=0; i_column<i_width; i_column++ ) {
uint8_t *p_rgb = &rgb_palette[ ((*p)&PALETTE_SIZE_MASK)*BYTES_PER_RGB ];
uint8_t *p_rgb = &rgb_palette[ ((*p)&PALETTE_SIZE_MASK)*RGB_SIZE ];
*q++ = p_rgb[0];
*q++ = p_rgb[1];
*q++ = p_rgb[2];
......
......@@ -2,7 +2,7 @@
* Common pixel/chroma manipulation routines.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: pixmap.h,v 1.2 2004/01/16 13:32:37 rocky Exp $
* $Id: pixmap.h,v 1.3 2004/01/29 11:50:22 rocky Exp $
*
* Author: Rocky Bernstein
*
......@@ -57,10 +57,37 @@ yuv2rgb(ogt_yuvt_t *p_yuv, uint8_t *p_rgb_out )
i_green = clip_8_bit( i_green );
i_blue = clip_8_bit( i_blue );
#ifdef WORDS_BIGENDIAN
*p_rgb_out++ = i_red;
*p_rgb_out++ = i_green;
*p_rgb_out++ = i_blue;
#else
*p_rgb_out++ = i_blue;
*p_rgb_out++ = i_green;
*p_rgb_out++ = i_red;
#endif
}
#define GREEN_PIXEL 1
#ifdef WORDS_BIGENDIAN
#define RED_PIXEL 0
#define BLUE_PIXEL 2
#else
#define BLUE_PIXEL 2
#define RED_PIXEL 0
#endif
static inline void
put_rgb24_pixel(uint8_t *rgb, uint8_t *p_pixel)
{
#ifdef WORDS_BIGENDIAN
*p_pixel++;
#endif
*p_pixel++ = rgb[RED_PIXEL];
*p_pixel++ = rgb[GREEN_PIXEL];
*p_pixel++ = rgb[BLUE_PIXEL];
}
#endif /* PIXMAP_H */
......@@ -2,7 +2,7 @@
* render.c : Philips OGT and CVD (VCD Subtitle) blending routines
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: render.c,v 1.25 2004/01/29 04:04:21 rocky Exp $
* $Id: render.c,v 1.26 2004/01/29 11:50:22 rocky Exp $
*
* Author: Rocky Bernstein <rocky@panix.com>
* based on code from:
......@@ -25,6 +25,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*#define TESTING_BLENDING 1*/
/*****************************************************************************
* Preamble
*****************************************************************************/
......@@ -254,10 +256,8 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
*p_pixel_Y = p_source->plane[Y_PLANE];
if ( even_scanline && i_x % 2 == 0 ) {
uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2
- p_pic->p[U_PLANE].i_pitch / 2;
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2
- p_pic->p[V_PLANE].i_pitch / 2;
uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2;
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2;
*p_pixel_U = p_source->plane[U_PLANE];
*p_pixel_V = p_source->plane[V_PLANE];
}
......@@ -434,7 +434,7 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
else
i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2;
#ifdef TESTING_BLENDING /**/
#ifdef TESTING_BLENDING
if (i_avg_tr == MAX_ALPHA) i_avg_tr >>= 1;
#endif
......@@ -514,10 +514,10 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
uint16_t i_pixel_color_Y1 =
(uint16_t) ( *(p_pixel) *
(uint16_t) (MAX_ALPHA - p_source->s.t) ) ;
(uint16_t) (MAX_ALPHA - i_avg_tr) ) ;
uint16_t i_pixel_color_Y2 =
(uint16_t) ( *(p_pixel) *
(uint16_t) (MAX_ALPHA - (p_source+1)->s.t) ) ;
(uint16_t) ( *(p_pixel+2) *
(uint16_t) (MAX_ALPHA - i_avg_tr) ) ;
uint16_t i_pixel_color_U =
(uint16_t) ( *(p_pixel+1) *
(uint16_t) (MAX_ALPHA - i_avg_tr) ) ;
......@@ -563,11 +563,7 @@ static inline void
yuv2rgb555(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
{
uint8_t rgb[3];
#define RED_PIXEL 0
#define GREEN_PIXEL 1
#define BLUE_PIXEL 2
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_yuv, rgb);
......@@ -603,7 +599,7 @@ static inline void
yuv2rgb565(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
{
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_yuv, rgb);
......@@ -631,21 +627,25 @@ rv16_pack_blend(uint8_t *p_pixel, ogt_yuvt_t *p_source, uint8_t *p_rgb1,
int a_scale_down )
{
uint8_t rgb_source[3];
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
int i;
#ifdef FIXED_RV16_TRANSPARENCY
uint8_t i_dest_alpha = MAX_ALPHA - i_alpha;
#endif
yuv2rgb(p_source, rgb_source);
/* Scale RGB from 8 bits down to 6 or 5. */
rgb_source[RED_PIXEL] >>= b_15bpp ? (8-5) : (8-6);
rgb_source[GREEN_PIXEL] >>= (8-5);
rgb_source[BLUE_PIXEL] >>= (8-5);
rgb[GREEN_PIXEL] = *(p_pixel+1) & 0x1f;
if (b_15bpp) {
rgb_source[RED_PIXEL] >>= (8-5);
rgb[BLUE_PIXEL] = ((*p_pixel)>>2) & 0x1f;
rgb[RED_PIXEL] = ((*p_pixel & 0x03) << 3) | ((*(p_pixel+1)&0xe0)>>5);
} else {
rgb_source[RED_PIXEL] >>= (8-6);
rgb[BLUE_PIXEL] = ((*p_pixel)>>3) & 0x1f;
rgb[RED_PIXEL] = ((*p_pixel & 0x07) << 3) | ((*(p_pixel+1)&0xe0)>>5);
}
......@@ -658,11 +658,10 @@ rv16_pack_blend(uint8_t *p_pixel, ogt_yuvt_t *p_source, uint8_t *p_rgb1,
rgb_source[BLUE_PIXEL], i_alpha, i_dest_alpha);
#endif
for (i=0; i<3; i++) {
for (i=0; i < RGB_SIZE; i++) {
/* Average the two pixels. */
#ifdef FIXED_RV16_TRANSPARENCY
uint8_t i_dest_alpha = MAX_ALPHA - i_alpha;
rgb[i] = ( (uint16_t) rgb_source[i]*i_alpha + rgb[i]*i_dest_alpha) >>
ALPHA_BITS;
#else
......@@ -679,12 +678,18 @@ rv16_pack_blend(uint8_t *p_pixel, ogt_yuvt_t *p_source, uint8_t *p_rgb1,
rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL] );
#endif
#if 0
if (b_15bpp) {
*p_rgb1 = ( (rgb[BLUE_PIXEL] << 2)&0x7c )|( (rgb[RED_PIXEL]>>3)&0x03 );
} else {
*p_rgb1 = ( (rgb[BLUE_PIXEL] << 3)&0xF8 )|( (rgb[RED_PIXEL]>>3)&0x07 );
}
*p_rgb2 = ( (rgb[RED_PIXEL] << 5)&0xe0 ) | ( rgb[GREEN_PIXEL]&0x1f );
#else
*p_rgb1 = (*p_rgb1)+1;
*p_rgb2 = (*p_rgb2)+1;
#endif
}
#undef BYTES_PER_PIXEL
......@@ -956,20 +961,36 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
#define BYTES_PER_PIXEL 4
static inline void
put_rgb24_pixel(uint8_t *rgb, uint8_t *p_pixel)
rv24_pack_blend(uint8_t *p_pixel, uint8_t *rgb_source, uint8_t i_alpha,
int a_scale_down )
{
int i;
uint8_t i_dest_alpha = MAX_ALPHA - i_alpha;
#if 0
printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d), alpha %d, dest_alpha %d\n",
p_pixel[RED_PIXEL], p_pixel[GREEN_PIXEL], p_pixel[BLUE_PIXEL],
rgb_source[RED_PIXEL], rgb_source[GREEN_PIXEL],
rgb_source[BLUE_PIXEL], i_alpha, i_dest_alpha);
#endif
#ifdef WORDS_BIGENDIAN
*p_pixel++;
*p_pixel++ = rgb[RED_PIXEL];
*p_pixel++ = rgb[GREEN_PIXEL];
*p_pixel++ = rgb[BLUE_PIXEL];
#else
*p_pixel++ = rgb[BLUE_PIXEL];
*p_pixel++ = rgb[GREEN_PIXEL];
*p_pixel++ = rgb[RED_PIXEL];
#endif
}
for (i=0; i < RGB_SIZE; i++) {
/* Average the two pixels. */
p_pixel[i] = ( (uint16_t) rgb_source[i]*i_alpha + p_pixel[i]*i_dest_alpha)
>> ALPHA_BITS;
}
#if 0
printf("avg r,g,b=(%d,%d,%d)\n",
rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL] );
#endif
}
/*
RV24 format??? Is this just for X11? Or just not for Win32? Is this
......@@ -1089,13 +1110,16 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
return;
}
#ifdef TESTING_BLENDING
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 2;
#endif
switch( p_source->s.t )
{
case 0:
/* Completely transparent. Don't change pixel. */
break;
default:
case MAX_ALPHA:
{
/* Completely opaque. Completely overwrite underlying
......@@ -1107,7 +1131,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
/* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_y + i_xdest;
......@@ -1119,7 +1143,6 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
p_dest += BYTES_PER_PIXEL;
}
#ifdef TRANSPARENCY_FINISHED
default:
{
/* Blend in underlying pixel subtitle pixel. */
......@@ -1128,30 +1151,26 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint32_t len = i_xlast - i_xdest * BYTES_PER_PIXEL;
/* To be able to scale correctly for full opaqueness, we
add 1 to the alpha. This means alpha value 0 won't
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
uint8_t i_destalpha = MAX_ALPHA - p_source->s.t;
uint8_t rgb[3];
/* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_y + i_xdest;
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_source, rgb);
rv32_pack_blend(p_dest, rgb, dest_alpha,
ALPHA_SCALEDOWN);
for ( len = i_xlast - i_xdest; len ; len--) {
put_rgb24_pixel(rgb, p_dest);
rv24_pack_blend(p_dest, rgb, p_source->s.t,
ALPHA_SCALEDOWN);
p_dest += BYTES_PER_PIXEL;
}
break;
}
#endif /*TRANSPARENCY_FINISHED*/
}
}
}
......@@ -1190,7 +1209,6 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break;
default:
case MAX_ALPHA:
{
/* Completely opaque. Completely overwrite underlying
......@@ -1203,7 +1221,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_source, rgb);
......@@ -1222,7 +1240,6 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
}
break;
}
#ifdef TRANSPARENCY_FINISHED
default:
{
......@@ -1232,11 +1249,11 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_source, rgb);
for( ; i_ytmp < i_ynext ; y_ytmp += p_pic->p->i_pitch )
for( ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
{
/* Blend in underlying pixel subtitle pixel. */
......@@ -1248,13 +1265,14 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
uint8_t i_destalpha = MAX_ALPHA - p_source->s.t;
rv32_pack_blend(p_dest, rgb, dest_alpha,
for ( len = i_xlast - i_xdest; len ; len--) {
rv24_pack_blend(p_dest, rgb, p_source->s.t,
ALPHA_SCALEDOWN);
p_dest += BYTES_PER_PIXEL;
}
}
break;
#endif /*TRANSPARENCY_FINISHED*/
}
}
}
}
......@@ -1400,7 +1418,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
/* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_y + i_xdest;
......@@ -1431,7 +1449,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
that's handled in a special case above anyway. */
uint8_t i_destalpha = MAX_ALPHA - p_source->s.t;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
/* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_y + i_xdest;
......@@ -1500,7 +1518,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_source, rgb);
......@@ -1513,10 +1531,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
for ( len = i_xlast - i_xdest; len ; len--) {
*p_dest++ = rgb[BLUE_PIXEL];
*p_dest++ = rgb[GREEN_PIXEL];
*p_dest++ = rgb[RED_PIXEL];
*p_dest++;
put_rgb24_pixel(rgb, p_dest);
}
}
break;
......@@ -1531,7 +1546,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t rgb[3];
uint8_t rgb[RGB_SIZE];
yuv2rgb(p_source, rgb);
......
......@@ -2,7 +2,7 @@
* subtitle.h : Common SVCD and CVD subtitles header
*****************************************************************************
* Copyright (C) 2003,2004 VideoLAN
* $Id: subtitle.h,v 1.13 2004/01/25 19:27:09 rocky Exp $
* $Id: subtitle.h,v 1.14 2004/01/29 11:50:22 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -115,12 +115,17 @@ typedef enum {
SUBTITLE_BLOCK_COMPLETE
} packet_state_t;
/* The storage used by one pixel */
/* The byte storage of an RGB pixel. */
#define RGB_SIZE 3
/* The byte storage used by one pixel */
#define PIXEL_SIZE 4
/* Size in bytes of YUV portion above. */
#define YUV_SIZE 3
/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
#define T_PLANE V_PLANE+1
......
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