1 /*****************************************************************************
2 * video_spu.c : DVD subpicture units functions
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: video_spu.c,v 1.22 2001/11/28 15:08:06 massiot Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
30 #include <string.h> /* memcpy(), memset() */
39 #include "video_output.h"
40 #include "video_spu.h"
42 /* FIXME: fake palette - the real one has to be sought in the .IFO */
43 static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
45 /*****************************************************************************
46 * vout_RenderRGBSPU: draw an SPU on a picture
47 *****************************************************************************
48 * This is a fast implementation of the subpicture drawing code. The data
49 * has been preprocessed once in spu_decoder.c, so we don't need to parse the
50 * RLE buffer again and again. Most sanity checks are done in spu_decoder.c
51 * so that this routine can be as fast as possible.
52 *****************************************************************************/
53 void vout_RenderRGBSPU( picture_t *p_pic, const subpicture_t *p_spu,
54 vout_buffer_t *p_buffer,
55 int i_bytes_per_pixel, int i_bytes_per_line )
58 u16 *p_source = (u16 *)p_spu->p_data;
60 int i_xscale = ( p_buffer->i_pic_width << 6 ) / p_pic->i_width;
61 int i_yscale = ( p_buffer->i_pic_height << 6 ) / p_pic->i_height;
63 int i_width = p_spu->i_width * i_xscale;
64 int i_height = p_spu->i_height * i_yscale;
66 int i_x, i_y, i_ytmp, i_yreal, i_ynext;
68 u8 *p_dest = p_buffer->p_data + ( i_width >> 6 ) * i_bytes_per_pixel
69 /* Add the picture coordinates and the SPU coordinates */
70 + ( p_buffer->i_pic_x + ((p_spu->i_x * i_xscale) >> 6))
72 + ( p_buffer->i_pic_y + ((p_spu->i_y * i_yscale) >> 6))
75 /* Draw until we reach the bottom of the subtitle */
78 while( i_y < i_height )
83 /* Check whether we need to draw one line or more than one */
84 if( i_ytmp + 1 >= ( i_y >> 6 ) )
86 /* Just one line : we precalculate i_y >> 6 */
87 i_yreal = i_bytes_per_line * i_ytmp;
89 /* Draw until we reach the end of the line */
94 /* Get the RLE part */
95 i_color = *p_source & 0x3;
100 i_len = i_xscale * ( *p_source++ >> 2 );
102 memset( p_dest - i_bytes_per_pixel * ( i_x >> 6 )
104 p_palette[ i_color ],
105 i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
111 i_x -= i_xscale * ( *p_source++ >> 2 );
116 i_yreal = i_bytes_per_line * i_ytmp;
117 i_ynext = i_bytes_per_line * i_y >> 6;
119 /* Draw until we reach the end of the line */
124 /* Get the RLE part */
125 i_color = *p_source & 0x3;
127 /* Draw as many lines as needed */
130 i_len = i_xscale * ( *p_source++ >> 2 );
132 for( i_ytmp = i_yreal ;
134 i_ytmp += i_bytes_per_line )
136 memset( p_dest - i_bytes_per_pixel * ( i_x >> 6 )
138 p_palette[ i_color ],
139 i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
146 i_x -= i_xscale * ( *p_source++ >> 2 );
152 /*****************************************************************************
153 * vout_RenderYUVSPU: draw an SPU on an YUV overlay
154 *****************************************************************************
155 * This is a fast implementation of the subpicture drawing code. The data
156 * has been preprocessed once in spu_decoder.c, so we don't need to parse the
157 * RLE buffer again and again. Most sanity checks are done in spu_decoder.c
158 * so that this routine can be as fast as possible.
159 *****************************************************************************/
160 void vout_RenderYUVSPU( picture_t *p_pic, const subpicture_t *p_spu )
163 u16 *p_source = (u16 *)p_spu->p_data;
167 u8 *p_dest = p_pic->p_y + p_spu->i_x + p_spu->i_width
168 + p_pic->i_width * ( p_spu->i_y + p_spu->i_height );
170 /* Draw until we reach the bottom of the subtitle */
171 i_y = p_spu->i_height * p_pic->i_width;
175 /* Draw until we reach the end of the line */
176 i_x = p_spu->i_width;
180 /* Draw the line if needed */
181 i_color = *p_source & 0x3;
185 i_len = *p_source++ >> 2;
186 memset( p_dest - i_x - i_y, p_palette[ i_color ], i_len );
191 i_x -= *p_source++ >> 2;
194 i_y -= p_pic->i_width;