00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef VLC_BITS_H
00025 #define VLC_BITS_H 1
00026
00027
00028
00029
00030
00031
00032 typedef struct bs_s
00033 {
00034 uint8_t *p_start;
00035 uint8_t *p;
00036 uint8_t *p_end;
00037
00038 ssize_t i_left;
00039 } bs_t;
00040
00041 static inline void bs_init( bs_t *s, const void *p_data, size_t i_data )
00042 {
00043 s->p_start = (void *)p_data;
00044 s->p = s->p_start;
00045 s->p_end = s->p_start + i_data;
00046 s->i_left = 8;
00047 }
00048
00049 static inline int bs_pos( const bs_t *s )
00050 {
00051 return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
00052 }
00053
00054 static inline int bs_eof( const bs_t *s )
00055 {
00056 return( s->p >= s->p_end ? 1: 0 );
00057 }
00058
00059 static inline uint32_t bs_read( bs_t *s, int i_count )
00060 {
00061 static const uint32_t i_mask[33] =
00062 { 0x00,
00063 0x01, 0x03, 0x07, 0x0f,
00064 0x1f, 0x3f, 0x7f, 0xff,
00065 0x1ff, 0x3ff, 0x7ff, 0xfff,
00066 0x1fff, 0x3fff, 0x7fff, 0xffff,
00067 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
00068 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
00069 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
00070 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
00071 int i_shr;
00072 uint32_t i_result = 0;
00073
00074 while( i_count > 0 )
00075 {
00076 if( s->p >= s->p_end )
00077 {
00078 break;
00079 }
00080
00081 if( ( i_shr = s->i_left - i_count ) >= 0 )
00082 {
00083
00084 i_result |= ( *s->p >> i_shr )&i_mask[i_count];
00085 s->i_left -= i_count;
00086 if( s->i_left == 0 )
00087 {
00088 s->p++;
00089 s->i_left = 8;
00090 }
00091 return( i_result );
00092 }
00093 else
00094 {
00095
00096 i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
00097 i_count -= s->i_left;
00098 s->p++;
00099 s->i_left = 8;
00100 }
00101 }
00102
00103 return( i_result );
00104 }
00105
00106 static inline uint32_t bs_read1( bs_t *s )
00107 {
00108 if( s->p < s->p_end )
00109 {
00110 unsigned int i_result;
00111
00112 s->i_left--;
00113 i_result = ( *s->p >> s->i_left )&0x01;
00114 if( s->i_left == 0 )
00115 {
00116 s->p++;
00117 s->i_left = 8;
00118 }
00119 return i_result;
00120 }
00121
00122 return 0;
00123 }
00124
00125 static inline uint32_t bs_show( bs_t *s, int i_count )
00126 {
00127 bs_t s_tmp = *s;
00128 return bs_read( &s_tmp, i_count );
00129 }
00130
00131 static inline void bs_skip( bs_t *s, ssize_t i_count )
00132 {
00133 s->i_left -= i_count;
00134
00135 if( s->i_left <= 0 )
00136 {
00137 const int i_bytes = ( -s->i_left + 8 ) / 8;
00138
00139 s->p += i_bytes;
00140 s->i_left += 8 * i_bytes;
00141 }
00142 }
00143
00144 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
00145 {
00146 while( i_count > 0 )
00147 {
00148 if( s->p >= s->p_end )
00149 {
00150 break;
00151 }
00152
00153 i_count--;
00154
00155 if( ( i_bits >> i_count )&0x01 )
00156 {
00157 *s->p |= 1 << ( s->i_left - 1 );
00158 }
00159 else
00160 {
00161 *s->p &= ~( 1 << ( s->i_left - 1 ) );
00162 }
00163 s->i_left--;
00164 if( s->i_left == 0 )
00165 {
00166 s->p++;
00167 s->i_left = 8;
00168 }
00169 }
00170 }
00171
00172 static inline void bs_align( bs_t *s )
00173 {
00174 if( s->i_left != 8 )
00175 {
00176 s->i_left = 8;
00177 s->p++;
00178 }
00179 }
00180
00181 static inline void bs_align_0( bs_t *s )
00182 {
00183 if( s->i_left != 8 )
00184 {
00185 bs_write( s, s->i_left, 0 );
00186 }
00187 }
00188
00189 static inline void bs_align_1( bs_t *s )
00190 {
00191 while( s->i_left != 8 )
00192 {
00193 bs_write( s, 1, 1 );
00194 }
00195 }
00196
00197 #endif