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 */
38 static inline void bs_init( bs_t *s, void *p_data, int i_data )
42 s->p_end = s->p + i_data;
45 static inline int bs_pos( bs_t *s )
47 return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
49 static inline int bs_eof( bs_t *s )
51 return( s->p >= s->p_end ? 1: 0 );
53 static inline uint32_t bs_read( bs_t *s, int i_count )
55 static uint32_t i_mask[33] ={0x00,
56 0x01, 0x03, 0x07, 0x0f,
57 0x1f, 0x3f, 0x7f, 0xff,
58 0x1ff, 0x3ff, 0x7ff, 0xfff,
59 0x1fff, 0x3fff, 0x7fff, 0xffff,
60 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
61 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
62 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
63 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
65 uint32_t i_result = 0;
69 if( s->p >= s->p_end )
74 if( ( i_shr = s->i_left - i_count ) >= 0 )
76 /* more in the buffer than requested */
77 i_result |= ( *s->p >> i_shr )&i_mask[i_count];
88 /* less in the buffer than requested */
89 i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
101 static uint32_t bswap32( uint32_t x )
103 asm( "bswap %0": "=r" (x):"0" (x));
106 /* work only for i_count <= 32 - 7 */
107 static inline uint32_t bs_read( bs_t *s, int i_count )
109 if( s->p < s->p_end && i_count > 0 )
112 uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
114 uint32_t i_cache = bswap32( *((uint32_t*)s->p) ) << (8-s->i_left);
116 uint32_t i_ret = i_cache >> ( 32 - i_count);
118 s->i_left -= i_count;
122 int i_skip = (8-s->i_left) >> 3;
126 s->i_left += i_skip << 3;
129 while( s->i_left <= 0 )
141 static inline uint32_t bs_read1( bs_t *s )
144 if( s->p < s->p_end )
146 unsigned int i_result;
149 i_result = ( *s->p >> s->i_left )&0x01;
160 static inline uint32_t bs_show( bs_t *s, int i_count )
164 return bs_read( &s_tmp, i_count );
166 if( s->p < s->p_end && i_count > 0 )
168 uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
169 return( i_cache >> ( 32 - i_count) );
176 static inline void bs_skip( bs_t *s, int i_count )
178 s->i_left -= i_count;
180 while( s->i_left <= 0 )
188 static inline int bs_read_ue( bs_t *s )
192 while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 )
196 return( ( 1 << i) - 1 + bs_read( s, i ) );
198 static inline int bs_read_se( bs_t *s )
200 int val = bs_read_ue( s );
202 return val&0x01 ? (val+1)/2 : -(val/2);
205 static inline int bs_read_te( bs_t *s, int x )
209 return 1 - bs_read1( s );
213 return bs_read_ue( s );
218 /* TODO optimize (write x bits at once) */
219 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
223 if( s->p >= s->p_end )
230 if( ( i_bits >> i_count )&0x01 )
232 *s->p |= 1 << ( s->i_left - 1 );
236 *s->p &= ~( 1 << ( s->i_left - 1 ) );
247 static inline void bs_write1( bs_t *s, uint32_t i_bits )
249 if( s->p < s->p_end )
255 *s->p |= 1 << s->i_left;
259 *s->p &= ~( 1 << s->i_left );
269 static inline void bs_align( bs_t *s )
277 static inline void bs_align_0( bs_t *s )
281 bs_write( s, s->i_left, 0 );
284 static inline void bs_align_1( bs_t *s )
288 bs_write( s, s->i_left, ~0 );
294 /* golomb functions */
296 static inline void bs_write_ue( bs_t *s, unsigned int val )
299 static const int i_size0_255[256] =
301 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,
302 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,
303 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,
304 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,
305 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,
306 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,
307 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,
308 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
317 unsigned int tmp = ++val;
319 if( tmp >= 0x00010000 )
329 i_size += i_size0_255[tmp];
331 bs_write( s, 2 * i_size - 1, val );
335 static inline void bs_write_se( bs_t *s, int val )
337 bs_write_ue( s, val <= 0 ? -val * 2 : val * 2 - 1);
340 static inline void bs_write_te( bs_t *s, int x, int val )
344 bs_write( s, 1, ~val );
348 bs_write_ue( s, val );
352 static inline void bs_rbsp_trailing( bs_t *s )
357 bs_write( s, s->i_left, 0x00 );
361 static inline int bs_size_ue( unsigned int val )
363 static const int i_size0_254[255] =
365 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
366 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
367 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
368 11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
369 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
370 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
371 13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
372 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
373 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
374 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
375 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
376 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
381 return i_size0_254[val];
392 val = (val >> 16) - 1;
397 val = (val >> 8) - 1;
399 return i_size0_254[val] + i_size;
403 static inline int bs_size_se( int val )
405 return bs_size_ue( val <= 0 ? -val * 2 : val * 2 - 1);
408 static inline int bs_size_te( int x, int val )
416 return bs_size_ue( val );