]> git.sesse.net Git - vlc/blob - src/video_output/video_spu.c
-Fixed a bug in area management added in my last commit
[vlc] / src / video_output / video_spu.c
1 /*****************************************************************************
2  * video_spu.c : DVD subpicture units functions
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: video_spu.c,v 1.20 2001/04/06 09:15:48 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  * 
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "defs.h"
28
29 #include <stdio.h>
30 #include <string.h>                                    /* memcpy(), memset() */
31
32 #include "config.h"
33 #include "common.h"
34 #include "threads.h"
35 #include "mtime.h"
36
37 #include "video.h"
38 #include "video_output.h"
39 #include "video_spu.h"
40
41 /* FIXME: fake palette - the real one has to be sought in the .IFO */
42 static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
43
44 /*****************************************************************************
45  * vout_RenderSPU: draw an SPU on a picture
46  *****************************************************************************
47  * This is a fast implementation of the subpicture drawing code. The data
48  * has been preprocessed once in spu_decoder.c, so we don't need to parse the
49  * RLE buffer again and again. Most sanity checks are done in spu_decoder.c
50  * so that this routine can be as fast as possible.
51  *****************************************************************************/
52 void vout_RenderSPU( vout_buffer_t *p_buffer, subpicture_t *p_spu,
53                      int i_bytes_per_pixel, int i_bytes_per_line )
54 {
55     int  i_len, i_color;
56     u16 *p_source = (u16 *)p_spu->p_data;
57
58     /* FIXME: we need a way to get 720 and 576 from the stream */
59     int i_xscale = ( p_buffer->i_pic_width << 6 ) / 720;
60     int i_yscale = ( p_buffer->i_pic_height << 6 ) / 576;
61
62     int i_width  = p_spu->i_width  * i_xscale;
63     int i_height = p_spu->i_height * i_yscale;
64
65     int i_x = 0, i_y = 0, i_ytmp, i_yreal, i_ynext;
66
67     u8 *p_dest = p_buffer->p_data
68                   /* Add the picture coordinates and the SPU coordinates */
69                   + ( p_buffer->i_pic_x + ((p_spu->i_x * i_xscale) >> 6))
70                        * i_bytes_per_pixel
71                   + ( p_buffer->i_pic_y + ((p_spu->i_y * i_yscale) >> 6))
72                        * i_bytes_per_line;
73
74     /* Draw until we reach the bottom of the subtitle */
75     for( i_y = 0 ; i_y < i_height ; /* i_y incremented below */ )
76     {
77         i_ytmp = i_y >> 6;
78         i_y += i_yscale;
79
80         /* Check whether we need to draw one line or more than one */
81         if( i_ytmp + 1 >= ( i_y >> 6 ) )
82         {
83             /* Just one line : we precalculate i_y >> 6 */
84             i_yreal = i_bytes_per_line * i_ytmp;
85
86             /* Draw until we reach the end of the line */
87             for( i_x = 0 ; i_x < i_width ; i_x += i_len )
88             {
89                 /* Get RLE information */
90                 i_len = i_xscale * ( *p_source >> 2 );
91                 i_color = *p_source++ & 0x3;
92
93                 /* Draw the line */
94                 if( i_color )
95                 {
96                     memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
97                                    + i_yreal,
98                             p_palette[ i_color ],
99                             i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
100                 }
101             }
102         }
103         else
104         {
105             i_yreal = i_bytes_per_line * i_ytmp;
106             i_ynext = i_bytes_per_line * i_y >> 6;
107
108             /* Draw until we reach the end of the line */
109             for( i_x = 0 ; i_x < i_width ; i_x += i_len )
110             {
111                 /* Get RLE information */
112                 i_len = i_xscale * ( *p_source >> 2 );
113                 i_color = *p_source++ & 0x3;
114
115                 /* Draw as many lines as needed */
116                 if( i_color )
117                 {
118                     for( i_ytmp = i_yreal ;
119                          i_ytmp < i_ynext ;
120                          i_ytmp += i_bytes_per_line )
121                     {
122                         memset( p_dest + i_bytes_per_pixel * ( i_x >> 6 )
123                                        + i_ytmp,
124                                 p_palette[ i_color ],
125                                 i_bytes_per_pixel * ( ( i_len >> 6 ) + 1 ) );
126                     }
127                 }
128             }
129         }
130     }
131 }
132