1 /*****************************************************************************
2 * video_spu.h : DVD subpicture units functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
33 #include "video_spu.h"
49 static int NewLine ( spu_t *p_spu, int *i_id );
51 /* i = get_nibble(); */
52 #define GET_NIBBLE( i ) \
55 i_next = *p_from[i_id]; \
56 /*printf("%.1x", i_next >> 4);*/ \
64 /*printf("%.1x", i_next & 0xf);*/ \
68 /* i = j + get_nibble(); */
69 #define ADD_NIBBLE( i, j ) \
72 i_next = *p_from[i_id]; \
73 /*printf("%.1x", i_next >> 4);*/ \
76 i = (j) + (i_next >> 4); \
81 /*printf("%.1x", i_next & 0xf);*/ \
82 i = (j) + (i_next & 0xf); \
85 /*****************************************************************************
86 * vout_RenderSPU: draws an SPU on a picture
87 *****************************************************************************
89 *****************************************************************************/
90 void vout_RenderSPU( byte_t *p_data, int p_offset[2],
91 int i_x, int i_y, byte_t *p_pic,
92 int i_bytes_per_pixel, int i_bytes_per_line )
98 static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x0000 };
100 boolean_t b_aligned = 1;
104 p_from[1] = p_data + p_offset[1];
105 p_from[0] = p_data + p_offset[0];
111 spu.p_data = p_pic + i_x * i_bytes_per_pixel + i_y * i_bytes_per_line;
113 while( p_from[0] < p_data + p_offset[1] )
115 GET_NIBBLE( i_code );
121 if( ((i_code >> 2) + spu.x + spu.y * spu.width)
122 > spu.height * spu.width )
124 intf_DbgMsg ( "video_spu: invalid draw request ! %d %d\n",
125 i_code >> 2, spu.height * spu.width
126 - ( (i_code >> 2) + spu.x
127 + spu.y * spu.width ) );
132 if( (i_color = i_code & 0x3) )
134 u8 *p_target = &spu.p_data[ 2 *
135 ( spu.x + spu.y * spu.width ) ];
136 memset( p_target, p_palette[i_color], 2 * (i_code >> 2) );
138 spu.x += i_code >> 2;
141 if( spu.x >= spu.width )
143 /* byte-align the stream */
145 /* finish the line */
146 NewLine( &spu, &i_id );
151 ADD_NIBBLE( i_code, (i_code << 4) );
152 if( i_code >= 0x10 ) /* 1x .. 3x */
155 ADD_NIBBLE( i_code, (i_code << 4) );
156 if( i_code >= 0x40 ) /* 04x .. 0fx */
159 ADD_NIBBLE( i_code, (i_code << 4) );
160 if( i_code >= 0x100 ) /* 01xx .. 03xx */
163 /* 00xx - should only happen for 00 00 */
166 ADD_NIBBLE( i_code, (i_code << 4) );
171 intf_DbgMsg( "video_spu: unknown code 0x%x "
172 "(dest %x side %x, x=%d, y=%d)\n",
173 i_code, p_from[i_id], i_id, spu.x, spu.y );
174 if( NewLine( &spu, &i_id ) < 0 )
180 if( NewLine( &spu, &i_id ) < 0 )
185 static int NewLine( spu_t *p_spu, int *i_id )
192 return( p_spu->width - p_spu->y );