00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef _BLT_BIT_STREAM_H_
00014 #define _BLT_BIT_STREAM_H_
00015
00016
00017
00018
00019 #include "BltConfig.h"
00020 #include "BltTypes.h"
00021 #include "BltErrors.h"
00022
00023
00024
00025
00026
00027 typedef BLT_UInt32 BLT_BitsWord;
00028 #define BLT_WORD_BITS 32
00029 #define BLT_WORD_BYTES 4
00030
00031
00032
00033
00034 typedef struct BLT_BitStream
00035 {
00036 unsigned char* buffer;
00037 BLT_Size buffer_size;
00038 BLT_Size data_size;
00039 unsigned int pos;
00040 BLT_BitsWord cache;
00041 unsigned int bits_cached;
00042 } BLT_BitStream;
00043
00044
00045
00046
00047 #ifdef __cplusplus
00048 extern "C" {
00049 #endif
00050
00051 BLT_Result BLT_BitStream_Construct(BLT_BitStream* bits, BLT_Size size);
00052 BLT_Result BLT_BitStream_Destruct(BLT_BitStream* bits);
00053 BLT_Result BLT_BitStream_SetData(BLT_BitStream* bits,
00054 const unsigned char* data,
00055 BLT_Size data_size);
00056 BLT_Result BLT_BitStream_ByteAlign(BLT_BitStream* bits);
00057 BLT_Result BLT_BitStream_Reset(BLT_BitStream* bits);
00058 BLT_Size BLT_BitStream_GetBitsLeft(BLT_BitStream* bits);
00059
00060 #ifdef __cplusplus
00061 }
00062 #endif
00063
00064
00065
00066
00067 #define BLT_BIT_MASK(_n) ((1<<(_n))-1)
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 static inline BLT_BitsWord
00082 BLT_BitStream_ReadCache (const BLT_BitStream* bits_ptr)
00083 {
00084 unsigned int pos = bits_ptr->pos;
00085
00086 #if BLT_WORD_BITS != 32
00087 #error unsupported word size
00088 #endif
00089
00090 if (pos > bits_ptr->buffer_size - BLT_WORD_BYTES) return 0;
00091
00092 {
00093 unsigned char *in = &bits_ptr->buffer[pos];
00094 return (((BLT_BitsWord) in[0]) << 24)
00095 | (((BLT_BitsWord) in[1]) << 16)
00096 | (((BLT_BitsWord) in[2]) << 8)
00097 | (((BLT_BitsWord) in[3]) );
00098 }
00099 }
00100
00101
00102
00103
00104 static inline unsigned int
00105 BLT_BitStream_ReadBits(BLT_BitStream* bits, unsigned int n)
00106 {
00107 BLT_BitsWord result;
00108 if (bits->bits_cached >= n) {
00109
00110 bits->bits_cached -= n;
00111 result = (bits->cache >> bits->bits_cached) & BLT_BIT_MASK(n);
00112 } else {
00113
00114 BLT_BitsWord word;
00115
00116
00117 word = BLT_BitStream_ReadCache (bits);
00118 bits->pos += BLT_WORD_BYTES;
00119
00120
00121 {
00122 BLT_BitsWord cache = bits->cache & BLT_BIT_MASK(bits->bits_cached);
00123 n -= bits->bits_cached;
00124 bits->bits_cached = BLT_WORD_BITS - n;
00125 result = (word >> bits->bits_cached) | (cache << n);
00126 bits->cache = word;
00127 }
00128 }
00129
00130 return result;
00131 }
00132
00133
00134
00135
00136 static inline unsigned int
00137 BLT_BitStream_ReadBit(BLT_BitStream* bits)
00138 {
00139 BLT_BitsWord result;
00140 if (bits->bits_cached == 0) {
00141
00142
00143
00144 bits->cache = BLT_BitStream_ReadCache (bits);
00145 bits->pos += BLT_WORD_BYTES;
00146 bits->bits_cached = BLT_WORD_BITS - 1;
00147
00148
00149 result = bits->cache >> (BLT_WORD_BITS - 1);
00150 } else {
00151
00152 result = (bits->cache >> (--bits->bits_cached)) & 1;
00153 }
00154 return result;
00155 }
00156
00157
00158
00159
00160 static inline unsigned int
00161 BLT_BitStream_PeekBits(const BLT_BitStream* bits, unsigned int n)
00162 {
00163
00164 if (bits->bits_cached >= n) {
00165 return (bits->cache >> (bits->bits_cached - n)) & BLT_BIT_MASK(n);
00166 } else {
00167
00168
00169 BLT_BitsWord word = BLT_BitStream_ReadCache (bits);
00170
00171
00172 BLT_BitsWord cache = bits->cache & BLT_BIT_MASK(bits->bits_cached);
00173 n -= bits->bits_cached;
00174 return (word >> (BLT_WORD_BITS - n)) | (cache << n);
00175 }
00176 }
00177
00178
00179
00180
00181 static inline unsigned int
00182 BLT_BitStream_PeekBit(const BLT_BitStream* bits)
00183 {
00184
00185 if (bits->bits_cached == 0) {
00186
00187 BLT_BitsWord cache = BLT_BitStream_ReadCache (bits);
00188
00189
00190 return cache >> (BLT_WORD_BITS - 1);
00191 } else {
00192
00193 return (bits->cache >> (bits->bits_cached-1)) & 1;
00194 }
00195 }
00196
00197
00198
00199
00200 static inline void
00201 BLT_BitStream_SkipBits(BLT_BitStream* bits, unsigned int n)
00202 {
00203 if (n <= bits->bits_cached) {
00204 bits->bits_cached -= n;
00205 } else {
00206 n -= bits->bits_cached;
00207 while (n >= BLT_WORD_BITS) {
00208 bits->pos += BLT_WORD_BYTES;
00209 n -= BLT_WORD_BITS;
00210 }
00211 if (n) {
00212 bits->cache = BLT_BitStream_ReadCache (bits);
00213 bits->bits_cached = BLT_WORD_BITS-n;
00214 bits->pos += BLT_WORD_BYTES;
00215 } else {
00216 bits->bits_cached = 0;
00217 bits->cache = 0;
00218 }
00219 }
00220 }
00221
00222
00223
00224
00225 static inline void
00226 BLT_BitStream_SkipBit(BLT_BitStream* bits)
00227 {
00228 if (bits->bits_cached == 0) {
00229 bits->cache = BLT_BitStream_ReadCache (bits);
00230 bits->pos += BLT_WORD_BYTES;
00231 bits->bits_cached = BLT_WORD_BITS - 1;
00232 } else {
00233 --bits->bits_cached;
00234 }
00235 }
00236
00237
00238 #endif