1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 Laurent Aimar
5 * $Id: bs.h,v 1.1 2004/06/03 19:27:06 fenrir Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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 *****************************************************************************/
25 #warning FIXME Multiple inclusion of bs.h
35 int i_left; /* i_count number of available bits */
36 int i_bits_encoded; /* RD only */
39 static inline void bs_init( bs_t *s, void *p_data, int i_data )
43 s->p_end = s->p + i_data;
46 static inline int bs_pos( bs_t *s )
48 return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
50 static inline int bs_eof( bs_t *s )
52 return( s->p >= s->p_end ? 1: 0 );
54 static inline uint32_t bs_read( bs_t *s, int i_count )
56 static uint32_t i_mask[33] ={0x00,
57 0x01, 0x03, 0x07, 0x0f,
58 0x1f, 0x3f, 0x7f, 0xff,
59 0x1ff, 0x3ff, 0x7ff, 0xfff,
60 0x1fff, 0x3fff, 0x7fff, 0xffff,
61 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
62 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
63 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
64 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
66 uint32_t i_result = 0;
70 if( s->p >= s->p_end )
75 if( ( i_shr = s->i_left - i_count ) >= 0 )
77 /* more in the buffer than requested */
78 i_result |= ( *s->p >> i_shr )&i_mask[i_count];
89 /* less in the buffer than requested */
90 i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
100 static inline uint32_t bs_read1( bs_t *s )
103 if( s->p < s->p_end )
105 unsigned int i_result;
108 i_result = ( *s->p >> s->i_left )&0x01;
119 static inline uint32_t bs_show( bs_t *s, int i_count )
121 if( s->p < s->p_end && i_count > 0 )
123 uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
124 return( i_cache >> ( 32 - i_count) );
130 static inline void bs_skip( bs_t *s, int i_count )
132 s->i_left -= i_count;
134 while( s->i_left <= 0 )
142 static inline int bs_read_ue( bs_t *s )
146 while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 )
150 return( ( 1 << i) - 1 + bs_read( s, i ) );
152 static inline int bs_read_se( bs_t *s )
154 int val = bs_read_ue( s );
156 return val&0x01 ? (val+1)/2 : -(val/2);
159 static inline int bs_read_te( bs_t *s, int x )
163 return 1 - bs_read1( s );
167 return bs_read_ue( s );
172 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
174 if( s->p >= s->p_end - 4 )
179 i_bits &= (1<<i_count)-1;
180 if( i_count < s->i_left )
182 *s->p = (*s->p << i_count) | i_bits;
183 s->i_left -= i_count;
188 *s->p = (*s->p << s->i_left) | (i_bits >> (i_count - s->i_left));
189 i_count -= s->i_left;
196 static inline void bs_write1( bs_t *s, uint32_t i_bit )
198 if( s->p < s->p_end )
211 static inline void bs_align_0( bs_t *s )
220 static inline void bs_align_1( bs_t *s )
225 *s->p |= (1 << s->i_left) - 1;
230 static inline void bs_align( bs_t *s )
237 /* golomb functions */
239 static inline void bs_write_ue( bs_t *s, unsigned int val )
242 static const int i_size0_255[256] =
244 1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
245 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
246 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
247 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
248 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
249 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
250 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
251 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
260 unsigned int tmp = ++val;
262 if( tmp >= 0x00010000 )
272 i_size += i_size0_255[tmp];
274 bs_write( s, 2 * i_size - 1, val );
278 static inline void bs_write_se( bs_t *s, int val )
280 bs_write_ue( s, val <= 0 ? -val * 2 : val * 2 - 1);
283 static inline void bs_write_te( bs_t *s, int x, int val )
287 bs_write1( s, 1&~val );
291 bs_write_ue( s, val );
295 static inline void bs_rbsp_trailing( bs_t *s )
300 bs_write( s, s->i_left, 0x00 );
304 static inline int bs_size_ue( unsigned int val )
306 static const int i_size0_254[255] =
308 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
309 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
310 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
311 11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
312 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
313 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
314 13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
315 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
316 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
317 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
318 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
319 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
324 return i_size0_254[val];
335 val = (val >> 16) - 1;
340 val = (val >> 8) - 1;
342 return i_size0_254[val] + i_size;
346 static inline int bs_size_se( int val )
348 return bs_size_ue( val <= 0 ? -val * 2 : val * 2 - 1);
351 static inline int bs_size_te( int x, int val )
359 return bs_size_ue( val );