vlc_bits.h
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:4k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * bits.h : Bit handling helpers
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: 778493cb3f7f7e46a8ae967b500300b52b77f846 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifndef VLC_BITS_H
  24. #define VLC_BITS_H 1
  25. /**
  26.  * file
  27.  * This file defines functions, structures for handling streams of bits in vlc
  28.  */
  29. typedef struct bs_s
  30. {
  31.     uint8_t *p_start;
  32.     uint8_t *p;
  33.     uint8_t *p_end;
  34.     int     i_left;    /* i_count number of available bits */
  35. } bs_t;
  36. static inline void bs_init( bs_t *s, void *p_data, int i_data )
  37. {
  38.     s->p_start = p_data;
  39.     s->p       = p_data;
  40.     s->p_end   = s->p + i_data;
  41.     s->i_left  = 8;
  42. }
  43. static inline int bs_pos( bs_t *s )
  44. {
  45.     return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
  46. }
  47. static inline int bs_eof( bs_t *s )
  48. {
  49.     return( s->p >= s->p_end ? 1: 0 );
  50. }
  51. static inline uint32_t bs_read( bs_t *s, int i_count )
  52. {
  53.      static const uint32_t i_mask[33] =
  54.      {  0x00,
  55.         0x01,      0x03,      0x07,      0x0f,
  56.         0x1f,      0x3f,      0x7f,      0xff,
  57.         0x1ff,     0x3ff,     0x7ff,     0xfff,
  58.         0x1fff,    0x3fff,    0x7fff,    0xffff,
  59.         0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
  60.         0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
  61.         0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
  62.         0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
  63.     int      i_shr;
  64.     uint32_t i_result = 0;
  65.     while( i_count > 0 )
  66.     {
  67.         if( s->p >= s->p_end )
  68.         {
  69.             break;
  70.         }
  71.         if( ( i_shr = s->i_left - i_count ) >= 0 )
  72.         {
  73.             /* more in the buffer than requested */
  74.             i_result |= ( *s->p >> i_shr )&i_mask[i_count];
  75.             s->i_left -= i_count;
  76.             if( s->i_left == 0 )
  77.             {
  78.                 s->p++;
  79.                 s->i_left = 8;
  80.             }
  81.             return( i_result );
  82.         }
  83.         else
  84.         {
  85.             /* less in the buffer than requested */
  86.            i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
  87.            i_count  -= s->i_left;
  88.            s->p++;
  89.            s->i_left = 8;
  90.         }
  91.     }
  92.     return( i_result );
  93. }
  94. static inline uint32_t bs_read1( bs_t *s )
  95. {
  96.     if( s->p < s->p_end )
  97.     {
  98.         unsigned int i_result;
  99.         s->i_left--;
  100.         i_result = ( *s->p >> s->i_left )&0x01;
  101.         if( s->i_left == 0 )
  102.         {
  103.             s->p++;
  104.             s->i_left = 8;
  105.         }
  106.         return i_result;
  107.     }
  108.     return 0;
  109. }
  110. static inline uint32_t bs_show( bs_t *s, int i_count )
  111. {
  112.     bs_t     s_tmp = *s;
  113.     return bs_read( &s_tmp, i_count );
  114. }
  115. static inline void bs_skip( bs_t *s, int i_count )
  116. {
  117.     s->i_left -= i_count;
  118.     if( s->i_left <= 0 )
  119.     {
  120.         const int i_bytes = ( -s->i_left + 8 ) / 8;
  121.         s->p += i_bytes;
  122.         s->i_left += 8 * i_bytes;
  123.     }
  124. }
  125. static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
  126. {
  127.     while( i_count > 0 )
  128.     {
  129.         if( s->p >= s->p_end )
  130.         {
  131.             break;
  132.         }
  133.         i_count--;
  134.         if( ( i_bits >> i_count )&0x01 )
  135.         {
  136.             *s->p |= 1 << ( s->i_left - 1 );
  137.         }
  138.         else
  139.         {
  140.             *s->p &= ~( 1 << ( s->i_left - 1 ) );
  141.         }
  142.         s->i_left--;
  143.         if( s->i_left == 0 )
  144.         {
  145.             s->p++;
  146.             s->i_left = 8;
  147.         }
  148.     }
  149. }
  150. static inline void bs_align( bs_t *s )
  151. {
  152.     if( s->i_left != 8 )
  153.     {
  154.         s->i_left = 8;
  155.         s->p++;
  156.     }
  157. }
  158. static inline void bs_align_0( bs_t *s )
  159. {
  160.     if( s->i_left != 8 )
  161.     {
  162.         bs_write( s, s->i_left, 0 );
  163.     }
  164. }
  165. static inline void bs_align_1( bs_t *s )
  166. {
  167.     while( s->i_left != 8 )
  168.     {
  169.         bs_write( s, 1, 1 );
  170.     }
  171. }
  172. #endif