#ifdef _BS_H
#warning FIXME Multiple inclusion of bs.h #else
#define _BS_H
typedef struct bs_s bs_t; struct bs_s {
uint8_t *p_start; uint8_t *p;
uint8_t *p_end;
int i_left; /* i_count number of available bits */ int i_bits_encoded; /* RD only */ };
static void bs_init( bs_t *s, void *p_data, int i_data ) {
s->p_start = p_data; s->p = p_data;
s->p_end = s->p + i_data; s->i_left = 8; }
static int bs_pos( bs_t *s ) {
return( 8 * ( s->p - s->p_start ) + 8 - s->i_left ); }
static int bs_eof( bs_t *s ) {
return( s->p >= s->p_end ? 1: 0 ); }
static uint32_t bs_read( bs_t *s, int i_count ) {
static uint32_t i_mask[33] ={0x00,
0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
int i_shr;
uint32_t i_result = 0;
while( i_count > 0 ) {
if( s->p >= s->p_end ) {
break; }
if( ( i_shr = s->i_left - i_count ) >= 0 ) {
/* more in the buffer than requested */
i_result |= ( *s->p >> i_shr )&i_mask[i_count]; s->i_left -= i_count; if( s->i_left == 0 ) {
s->p++; s->i_left = 8; }
return( i_result ); } else {
/* less in the buffer than requested */
i_result |= (*s->p&i_mask[s->i_left]) << -i_shr; i_count -= s->i_left; s->p++;
s->i_left = 8; } }
return( i_result ); }
static uint32_t bs_read1( bs_t *s ) {
if( s->p < s->p_end ) {
unsigned int i_result;
s->i_left--;
i_result = ( *s->p >> s->i_left )&0x01;
if( s->i_left == 0 ) {
s->p++; s->i_left = 8; }
return i_result; }
return 0; }
static uint32_t bs_show( bs_t *s, int i_count ) {
if( s->p < s->p_end && i_count > 0 ) {
uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
return( i_cache >> ( 32 - i_count) ); }
return 0; }
/* TODO optimize */
static void bs_skip( bs_t *s, int i_count ) {
s->i_left -= i_count;
while( s->i_left <= 0 ) {
s->p++;
s->i_left += 8; } }
static int bs_read_ue( bs_t *s ) {
int i = 0;
while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 ) {
i++; }
return( ( 1 << i) - 1 + bs_read( s, i ) ); }
static int bs_read_se( bs_t *s ) {
int val = bs_read_ue( s );
return val&0x01 ? (val+1)/2 : -(val/2); }
static int bs_read_te( bs_t *s, int x ) {
if( x == 1 ) {
return 1 - bs_read1( s ); }
else if( x > 1 ) {
return bs_read_ue( s ); }
return 0; }
static void bs_write( bs_t *s, int i_count, uint32_t i_bits ) {
if( s->p >= s->p_end - 4 ) return;
while( i_count > 0 ) {
if( i_count < 32 )
i_bits &= (1<
*s->p = (*s->p << i_count) | i_bits; s->i_left -= i_count; break; } else {
*s->p = (*s->p << s->i_left) | (i_bits >> (i_count - s->i_left)); i_count -= s->i_left; s->p++; s->i_left = 8; } } }