00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00031 #ifndef _MLO_BIT_STREAM_H_
00032 #define _MLO_BIT_STREAM_H_
00033
00034
00035
00036
00037 #include "MloConfig.h"
00038 #include "MloTypes.h"
00039 #include "MloResults.h"
00040
00041
00042
00043
00044
00045
00046 #define MLO_ERROR_NOT_ENOUGH_DATA (MLO_ERROR_BASE_BITSTREAM - 0)
00047 #define MLO_ERROR_CORRUPTED_BITSTREAM (MLO_ERROR_BASE_BITSTREAM - 1)
00048 #define MLO_ERROR_NOT_ENOUGH_FREE_BUFFER (MLO_ERROR_BASE_BITSTREAM - 2)
00049
00050
00051
00052
00053
00054 typedef unsigned int MLO_BitsWord;
00055 #define MLO_WORD_BITS 32
00056 #define MLO_WORD_BYTES 4
00057
00058
00059
00060
00061 typedef struct MLO_BitStream
00062 {
00063 unsigned char* buffer;
00064 MLO_Size buffer_size;
00065 MLO_Size data_size;
00066 unsigned int pos;
00067 MLO_BitsWord cache;
00068 unsigned int bits_cached;
00069 } MLO_BitStream;
00070
00071
00072
00073
00074 #ifdef __cplusplus
00075 extern "C" {
00076 #endif
00077
00078 MLO_Result MLO_BitStream_Construct(MLO_BitStream* bits, MLO_Size size);
00079 MLO_Result MLO_BitStream_Destruct(MLO_BitStream* bits);
00080 MLO_Result MLO_BitStream_SetData(MLO_BitStream* bits,
00081 const MLO_Byte* data,
00082 MLO_Size data_size);
00083 MLO_Result MLO_BitStream_ByteAlign(MLO_BitStream* bits);
00084 MLO_Result MLO_BitStream_Reset(MLO_BitStream* bits);
00085 MLO_Size MLO_BitStream_GetBitsLeft(MLO_BitStream* bits);
00086
00087 #ifdef __cplusplus
00088 }
00089 #endif
00090
00091
00092
00093
00094 #define MLO_BIT_MASK(_n) ((1<<(_n))-1)
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static inline MLO_BitsWord
00109 MLO_BitStream_ReadCache (const MLO_BitStream* bits_ptr)
00110 {
00111 unsigned int pos = bits_ptr->pos;
00112
00113 #if MLO_WORD_BITS != 32
00114 #error unsupported word size
00115 #endif
00116
00117 if (pos > bits_ptr->buffer_size - MLO_WORD_BYTES) return 0;
00118
00119 {
00120 unsigned char * out_ptr = &bits_ptr->buffer [pos];
00121 return (((MLO_BitsWord) out_ptr [0]) << 24)
00122 | (((MLO_BitsWord) out_ptr [1]) << 16)
00123 | (((MLO_BitsWord) out_ptr [2]) << 8)
00124 | (((MLO_BitsWord) out_ptr [3]) );
00125 }
00126 }
00127
00128
00129
00130
00131 static inline unsigned int
00132 MLO_BitStream_ReadBits(MLO_BitStream* bits, unsigned int n)
00133 {
00134 MLO_BitsWord result;
00135 if (bits->bits_cached >= n) {
00136
00137 bits->bits_cached -= n;
00138 result = (bits->cache >> bits->bits_cached) & MLO_BIT_MASK(n);
00139 } else {
00140
00141 MLO_BitsWord word;
00142
00143
00144 word = MLO_BitStream_ReadCache (bits);
00145 bits->pos += MLO_WORD_BYTES;
00146
00147
00148 {
00149 MLO_BitsWord cache = bits->cache & MLO_BIT_MASK(bits->bits_cached);
00150 n -= bits->bits_cached;
00151 bits->bits_cached = MLO_WORD_BITS - n;
00152 result = (word >> bits->bits_cached) | (cache << n);
00153 bits->cache = word;
00154 }
00155 }
00156
00157 return result;
00158 }
00159
00160
00161
00162
00163 static inline unsigned int
00164 MLO_BitStream_ReadBit(MLO_BitStream* bits)
00165 {
00166 MLO_BitsWord result;
00167 if (bits->bits_cached == 0) {
00168
00169
00170
00171 bits->cache = MLO_BitStream_ReadCache (bits);
00172 bits->pos += MLO_WORD_BYTES;
00173 bits->bits_cached = MLO_WORD_BITS - 1;
00174
00175
00176 result = bits->cache >> (MLO_WORD_BITS - 1);
00177 } else {
00178
00179 result = (bits->cache >> (--bits->bits_cached)) & 1;
00180 }
00181 return result;
00182 }
00183
00184
00185
00186
00187 static inline unsigned int
00188 MLO_BitStream_PeekBits(const MLO_BitStream* bits, unsigned int n)
00189 {
00190
00191 if (bits->bits_cached >= n) {
00192 return (bits->cache >> (bits->bits_cached - n)) & MLO_BIT_MASK(n);
00193 } else {
00194
00195
00196 MLO_BitsWord word = MLO_BitStream_ReadCache (bits);
00197
00198
00199 MLO_BitsWord cache = bits->cache & MLO_BIT_MASK(bits->bits_cached);
00200 n -= bits->bits_cached;
00201 return (word >> (MLO_WORD_BITS - n)) | (cache << n);
00202 }
00203 }
00204
00205
00206
00207
00208 static inline unsigned int
00209 MLO_BitStream_PeekBit(const MLO_BitStream* bits)
00210 {
00211
00212 if (bits->bits_cached == 0) {
00213
00214 MLO_BitsWord cache = MLO_BitStream_ReadCache (bits);
00215
00216
00217 return cache >> (MLO_WORD_BITS - 1);
00218 } else {
00219
00220 return (bits->cache >> (bits->bits_cached-1)) & 1;
00221 }
00222 }
00223
00224
00225
00226
00227 static inline void
00228 MLO_BitStream_SkipBits(MLO_BitStream* bits, unsigned int n)
00229 {
00230 if (n <= bits->bits_cached) {
00231 bits->bits_cached -= n;
00232 } else {
00233 n -= bits->bits_cached;
00234 while (n >= MLO_WORD_BITS) {
00235 bits->pos += MLO_WORD_BYTES;
00236 n -= MLO_WORD_BITS;
00237 }
00238 if (n) {
00239 bits->cache = MLO_BitStream_ReadCache (bits);
00240 bits->bits_cached = MLO_WORD_BITS-n;
00241 bits->pos += MLO_WORD_BYTES;
00242 } else {
00243 bits->bits_cached = 0;
00244 bits->cache = 0;
00245 }
00246 }
00247 }
00248
00249
00250
00251
00252 static inline void
00253 MLO_BitStream_SkipBit(MLO_BitStream* bits)
00254 {
00255 if (bits->bits_cached == 0) {
00256 bits->cache = MLO_BitStream_ReadCache (bits);
00257 bits->pos += MLO_WORD_BYTES;
00258 bits->bits_cached = MLO_WORD_BITS - 1;
00259 } else {
00260 --bits->bits_cached;
00261 }
00262 }
00263
00264
00265 #endif