Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vlc_bits.h

00001 /*****************************************************************************
00002  * bits.h :
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: vlc_bits.h 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Laurent Aimar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 #ifndef _VLC_BITS_H
00025 #define _VLC_BITS_H 1
00026 
00027 typedef struct bs_s
00028 {
00029     uint8_t *p_start;
00030     uint8_t *p;
00031     uint8_t *p_end;
00032 
00033     int     i_left;    /* i_count number of available bits */
00034 } bs_t;
00035 
00036 static inline void bs_init( bs_t *s, void *p_data, int i_data )
00037 {
00038     s->p_start = p_data;
00039     s->p       = p_data;
00040     s->p_end   = s->p + i_data;
00041     s->i_left  = 8;
00042 }
00043 static inline int bs_pos( bs_t *s )
00044 {
00045     return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
00046 }
00047 static inline int bs_eof( bs_t *s )
00048 {
00049     return( s->p >= s->p_end ? 1: 0 );
00050 }
00051 static inline uint32_t bs_read( bs_t *s, int i_count )
00052 {
00053      static uint32_t i_mask[33] =
00054      {  0x00,
00055         0x01,      0x03,      0x07,      0x0f,
00056         0x1f,      0x3f,      0x7f,      0xff,
00057         0x1ff,     0x3ff,     0x7ff,     0xfff,
00058         0x1fff,    0x3fff,    0x7fff,    0xffff,
00059         0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
00060         0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
00061         0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
00062         0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
00063     int      i_shr;
00064     uint32_t i_result = 0;
00065 
00066     while( i_count > 0 )
00067     {
00068         if( s->p >= s->p_end )
00069         {
00070             break;
00071         }
00072 
00073         if( ( i_shr = s->i_left - i_count ) >= 0 )
00074         {
00075             /* more in the buffer than requested */
00076             i_result |= ( *s->p >> i_shr )&i_mask[i_count];
00077             s->i_left -= i_count;
00078             if( s->i_left == 0 )
00079             {
00080                 s->p++;
00081                 s->i_left = 8;
00082             }
00083             return( i_result );
00084         }
00085         else
00086         {
00087             /* less in the buffer than requested */
00088            i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
00089            i_count  -= s->i_left;
00090            s->p++;
00091            s->i_left = 8;
00092         }
00093     }
00094 
00095     return( i_result );
00096 }
00097 
00098 static inline uint32_t bs_read1( bs_t *s )
00099 {
00100     if( s->p < s->p_end )
00101     {
00102         unsigned int i_result;
00103 
00104         s->i_left--;
00105         i_result = ( *s->p >> s->i_left )&0x01;
00106         if( s->i_left == 0 )
00107         {
00108             s->p++;
00109             s->i_left = 8;
00110         }
00111         return i_result;
00112     }
00113 
00114     return 0;
00115 }
00116 
00117 static inline uint32_t bs_show( bs_t *s, int i_count )
00118 {
00119     bs_t     s_tmp = *s;
00120     return bs_read( &s_tmp, i_count );
00121 }
00122 
00123 static inline void bs_skip( bs_t *s, int i_count )
00124 {
00125     s->i_left -= i_count;
00126 
00127     while( s->i_left <= 0 )
00128     {
00129         s->p++;
00130         s->i_left += 8;
00131     }
00132 }
00133 
00134 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
00135 {
00136     while( i_count > 0 )
00137     {
00138         if( s->p >= s->p_end )
00139         {
00140             break;
00141         }
00142 
00143         i_count--;
00144 
00145         if( ( i_bits >> i_count )&0x01 )
00146         {
00147             *s->p |= 1 << ( s->i_left - 1 );
00148         }
00149         else
00150         {
00151             *s->p &= ~( 1 << ( s->i_left - 1 ) );
00152         }
00153         s->i_left--;
00154         if( s->i_left == 0 )
00155         {
00156             s->p++;
00157             s->i_left = 8;
00158         }
00159     }
00160 }
00161 
00162 static inline void bs_align( bs_t *s )
00163 {
00164     if( s->i_left != 8 )
00165     {
00166         s->i_left = 8;
00167         s->p++;
00168     }
00169 }
00170 static inline void bs_align_0( bs_t *s )
00171 {
00172     if( s->i_left != 8 )
00173     {
00174         bs_write( s, s->i_left, 0 );
00175     }
00176 }
00177 static inline void bs_align_1( bs_t *s )
00178 {
00179     while( s->i_left != 8 )
00180     {
00181         bs_write( s, 1, 1 );
00182     }
00183 }
00184 
00185 #endif

Generated on Tue Dec 20 10:14:19 2005 for vlc-0.8.4a by  doxygen 1.4.2