bitstrm.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:5k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: bitstrm.h 292 2005-10-14 20:30:00Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #ifndef __BITSTRM_H
  24. #define __BITSTRM_H
  25. typedef struct bitstream
  26. {
  27. int bits;
  28. int bitpos;
  29. const uint8_t *bitptr;
  30. const uint8_t *bitend;
  31. } bitstream;
  32. // n=1..24 (or ..32 after bytealign)
  33. #define bitshow(p,n) ((uint32_t)((p)->bits << (p)->bitpos) >> (32-(n)))
  34. // n=9..32
  35. static INLINE int bitshowlarge(bitstream* p, int n) 
  36. {
  37. int i = bitshow(p,n);
  38. i |= *p->bitptr >> (40-n-p->bitpos);
  39. return i;
  40. }
  41. static INLINE void bitrewind(bitstream* p,int n)
  42. {
  43. p->bitpos += 32 - (n & 7);
  44. p->bitptr -= 4 + (n >> 3);
  45. }
  46. #define bitflush(p,n) (p)->bitpos += n;
  47. // use this only in boolean expression. to get a 1 bit value use getbits(p,1)
  48. #define bitget1(p) (((p)->bits << (p)->bitpos++) < 0)
  49. static INLINE int bitget(bitstream* p,int n)
  50. {
  51. int i = bitshow(p,n);
  52. bitflush(p,n);
  53. return i;
  54. }
  55. static INLINE const uint8_t* bitendptr(bitstream* p) { return p->bitend-4; }
  56. static INLINE uintptr_t bitendbookmark(bitstream* p)
  57. {
  58. return (uintptr_t)p->bitend*8;
  59. }
  60. static INLINE uintptr_t bitbookmark(bitstream* p)
  61. {
  62. return (uintptr_t)p->bitptr*8 + p->bitpos;
  63. }
  64. // non-exact eof, just for error checking
  65. static INLINE int biteof(bitstream* p)
  66. {
  67. return p->bitptr >= p->bitend;
  68. }
  69. static INLINE void bitbytealign(bitstream* p)
  70. {
  71. p->bitpos = ALIGN8(p->bitpos);
  72. }
  73. static INLINE int bittonextbyte(bitstream* p)
  74. {
  75. return 8-(p->bitpos & 7);
  76. }
  77. static INLINE const uint8_t *bitbytepos(bitstream* p)
  78. {
  79. return p->bitptr - 4 + ((p->bitpos+7) >> 3);
  80. }
  81. //************************************************************************
  82. // optimized reader using one local variable
  83. #define bitload_pos(p, bitpos)
  84. bitpos -= 8;
  85. if (bitpos >= 0) {
  86. int bits = (p)->bits;
  87. const uint8_t* bitptr = (p)->bitptr;
  88. do {
  89. bits = (bits << 8) | *bitptr++;
  90. bitpos -= 8;
  91. } while (bitpos>=0);
  92. (p)->bits = bits;
  93. (p)->bitptr = bitptr;
  94. }
  95. bitpos += 8;
  96. #define bitbookmark_pos(p,bitpos) ((int)(p)->bitptr*8 + bitpos)
  97. #define bitshow_pos(p,bitpos,n) ((uint32_t)((p)->bits << bitpos) >> (32-(n)))
  98. #define bitflush_pos(p,bitpos,n) bitpos += n;
  99. #define bitget1_pos(p,bitpos) (((p)->bits << bitpos++) < 0)
  100. #define bitbytealign_pos(p,bitpos) bitpos = ALIGN8(bitpos);
  101. #define bitrewind_pos(p,bitpos,n) bitpos += 32 - ((n) & 7); (p)->bitptr -= 4 + ((n) >> 3);
  102. #define bitgetx_pos(p,bitpos,n,tmp)
  103. {
  104. tmp = (p)->bits << bitpos;
  105. bitflush_pos(p,bitpos,n);
  106. tmp >>= 1;
  107. tmp ^= 0x80000000;
  108. tmp >>= 31-n;
  109. n = tmp - (tmp >> 31);
  110. }
  111. //************************************************************************
  112. // optimized reader using two prenamed local variables
  113. #define bitbegin_pos2(p)
  114. int bitpos = (p)->bitpos;
  115. int bits = (p)->bits;
  116. #define bitend_pos2(p)
  117. (p)->bitpos = bitpos;
  118. #define bitload_pos2(p)
  119. if (bitpos >= 8) {
  120. const uint8_t* bitptr = (p)->bitptr;
  121. do {
  122. bits = (bits << 8) | *bitptr++;
  123. bitpos -= 8;
  124. } while (bitpos >= 8);
  125. (p)->bits = bits;
  126. (p)->bitptr = bitptr;
  127. }
  128. #define bitshow_pos2(p,n) ((uint32_t)(bits << bitpos) >> (32-(n)))
  129. #define bitflush_pos2(p,n) bitpos += n
  130. #define bitget1_pos2(p) ((bits << bitpos++) < 0)
  131. #define bitsign_pos2(p) (((bits << bitpos++) >> 31)|1)
  132. //************************************************************************
  133. #define bitloadcond(p) if ((p)->bitpos >= 8) bitload(p);
  134. #define DECLARE_BITLOAD
  135. static NOINLINE void bitload(bitstream* p)
  136. {
  137. bitbegin_pos2(p);
  138. bitload_pos2(p);
  139. bitend_pos2(p);
  140. }
  141. #define DECLARE_BITINIT
  142. static void bitinit(bitstream* p,const uint8_t *stream, int len)
  143. {
  144. p->bits = 0;
  145. p->bitpos = 32;
  146. p->bitptr = stream;
  147. p->bitend = stream+len+4;
  148. }
  149. static INLINE void bitsetpos(bitstream* p,const uint8_t *stream)
  150. {
  151. p->bitpos = 32;
  152. p->bitptr = stream;
  153. }
  154. #ifdef MIPS
  155. static INLINE void bitloadinline(bitstream* p)
  156. {
  157. int n = p->bitpos-8;
  158. if (n>=0)
  159. {
  160. const uint8_t* bitptr = p->bitptr;
  161. int bits = p->bits;
  162. do
  163. {
  164. bits = (bits << 8) | *bitptr++;
  165. n -= 8;
  166. }
  167. while (n>=0);
  168. p->bits = bits;
  169. p->bitptr = bitptr;
  170. p->bitpos = n+8;
  171. }
  172. }
  173. #else
  174. #define bitloadinline(p) if ((p)->bitpos >= 8) bitload(p)
  175. #endif
  176. #endif