ZenLib
BitStream.h
Go to the documentation of this file.
1/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a zlib-style license that can
4 * be found in the License.txt file in the root of the source tree.
5 */
6
7//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8//
9// Read a stream bit per bit
10// Can read up to 32 bits at once
11//
12//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
14//---------------------------------------------------------------------------
15#ifndef ZenBitStreamH
16#define ZenBitStreamH
17//---------------------------------------------------------------------------
18
19//---------------------------------------------------------------------------
20#include "ZenLib/Conf.h"
21//---------------------------------------------------------------------------
22
23namespace ZenLib
24{
25
26#ifndef MIN
27 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
28#endif
29
31{
32public:
33 BitStream () {Buffer=NULL;
34 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=0;
35 LastByte_Size=0;
36 BufferUnderRun=true;
37 BookMark=false;}
38 BitStream (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_;
39 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
40 LastByte_Size=0;
41 BufferUnderRun=Buffer_Size?false:true;
42 BookMark=false;}
43 virtual ~BitStream () {};
44
45 virtual void Attach(const int8u* Buffer_, size_t Size_)
46 {
47 if (Buffer_==Buffer)
48 return; //Nothing to do
49 Buffer=Buffer_;
50 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
51 LastByte_Size=0;
52 BufferUnderRun=Buffer_Size?false:true;
53 BookMark=false;
54 };
55
56 virtual int32u Get (size_t HowMany)
57 {
58 size_t ToReturn;
59 static const int32u Mask[33]={
60 0x00000000,
61 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
62 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
63 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
64 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
65 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
66 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
67 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
68 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
69 };
70
71 if (HowMany==0 || HowMany>32)
72 return 0;
73 if ((size_t)HowMany>Buffer_Size+LastByte_Size)
74 {
75 Buffer_Size=0;
76 LastByte_Size=0;
77 BufferUnderRun=true;
78 return 0;
79 }
80
81 Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
82
83 if (HowMany<=LastByte_Size)
84 {
85 LastByte_Size-=HowMany;
86 ToReturn=LastByte>>LastByte_Size;
87 }
88 else
89 {
90 size_t NewBits=HowMany-LastByte_Size;
91 if (NewBits==32)
92 ToReturn=0;
93 else
94 ToReturn=LastByte<<NewBits;
95 switch ((NewBits-1)/8)
96 {
97 case 3 : NewBits-=8;
98 ToReturn |= ((size_t)*Buffer) << NewBits;
99 Buffer++;
100 Buffer_Size-=8;
101 case 2 : NewBits-=8;
102 ToReturn |= ((size_t)*Buffer) << NewBits;
103 Buffer++;
104 Buffer_Size-=8;
105 case 1 : NewBits-=8;
106 ToReturn |= ((size_t)*Buffer) << NewBits;
107 Buffer++;
108 Buffer_Size-=8;
109 case 0 :
110 LastByte=*Buffer;
111 Buffer++;
112 }
113 LastByte_Size=MIN(8, Buffer_Size)-NewBits;
114 Buffer_Size -=MIN(8, Buffer_Size);
115 ToReturn|=(LastByte>>LastByte_Size)&Mask[NewBits];
116 }
117 return (int32u)(ToReturn&Mask[HowMany]);
118 };
119
120 bool GetB ()
121 {
122 return Get(1)?true:false;
123 }
124
125 int8u Get1 (size_t HowMany)
126 {
127 return (int8u )Get(HowMany);
128 }
129
130 int16u Get2 (size_t HowMany)
131 {
132 return (int16u)Get(HowMany);
133 }
134
135 int32u Get4 (size_t HowMany)
136 {
137 return (int32u)Get(HowMany);
138 }
139
140 int64u Get8 (size_t HowMany)
141 {
142 if (HowMany>64)
143 return 0; //Not supported
144 size_t HowMany1, HowMany2;
145 int64u Value1, Value2;
146 if (HowMany>32)
147 HowMany1=HowMany-32;
148 else
149 HowMany1=0;
150 HowMany2=HowMany-HowMany1;
151 Value1=Get(HowMany1);
152 Value2=Get(HowMany2);
153 if (BufferUnderRun)
154 return 0;
155 return Value1*0x100000000LL+Value2;
156 }
157
158 virtual void Skip (size_t HowMany)
159 {
160 if (HowMany==0)
161 return;
162 if (HowMany>32) //Algorithm is only for <=32 bits
163 {
164 do
165 {
166 Skip(32);
167 HowMany-=32;
168 }
169 while(HowMany>32);
170 if (HowMany)
171 Skip(HowMany);
172 return;
173 }
174 if ((size_t)HowMany>Buffer_Size+LastByte_Size)
175 {
176 Buffer_Size=0;
177 LastByte_Size=0;
178 BufferUnderRun=true;
179 return;
180 }
181
182 Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
183
184 if (HowMany<=LastByte_Size)
185 LastByte_Size-=HowMany;
186 else
187 {
188 size_t NewBits=HowMany-LastByte_Size;
189 switch ((NewBits-1)/8)
190 {
191 case 3 : NewBits-=8;
192 Buffer++;
193 Buffer_Size-=8;
194 case 2 : NewBits-=8;
195 Buffer++;
196 Buffer_Size-=8;
197 case 1 : NewBits-=8;
198 Buffer++;
199 Buffer_Size-=8;
200 case 0 :
201 LastByte=*Buffer;
202 Buffer++;
203 }
204 LastByte_Size=MIN(8, Buffer_Size)-NewBits;
205 Buffer_Size -=MIN(8, Buffer_Size);
206 }
207 };
208
209 void SkipB ()
210 {
211 Skip(1);
212 }
213
214 void Skip1 (size_t HowMany)
215 {
216 Skip(HowMany);
217 }
218
219 void Skip2 (size_t HowMany)
220 {
221 Skip(HowMany);
222 }
223
224 void Skip4 (size_t HowMany)
225 {
226 Skip(HowMany);
227 }
228
229 void Skip8 (size_t HowMany)
230 {
231 if (HowMany>64)
232 return; //Not supported
233 size_t HowMany1, HowMany2;
234 if (HowMany>32)
235 HowMany1=HowMany-32;
236 else
237 HowMany1=0;
238 HowMany2=HowMany-HowMany1;
239 Skip(HowMany1);
240 Skip(HowMany2);
241 }
242
243 int32u Peek(size_t HowMany)
244 {
245 BookMarkPos(true);
246 int32u ToReturn=Get(HowMany);
247 BookMarkPos(false);
248 return ToReturn;
249 }
250
251 bool PeekB()
252 {
253 return Peek(1)?true:false;
254 }
255
256 int8u Peek1(size_t HowMany)
257 {
258 return (int8u )Peek(HowMany);
259 }
260
261 int16u Peek2(size_t HowMany)
262 {
263 return (int16u)Peek(HowMany);
264 }
265
266 int32u Peek4(size_t HowMany)
267 {
268 return (int32u)Peek(HowMany);
269 }
270
271 int32u Peek3(size_t HowMany)
272 {
273 return (int32u)Peek(HowMany);
274 }
275
276 int64u Peek8(size_t HowMany)
277 {
278 return (int64u)Peek(HowMany);
279 }
280
281 void BookMarkPos(bool ToSet)
282 {
283 if (ToSet)
284 {
285 BookMark=1;
286 Buffer_BookMark=Buffer;
287 Buffer_Size_BookMark=Buffer_Size;
288 LastByte_BookMark=LastByte;
289 LastByte_Size_BookMark=LastByte_Size;
290 BufferUnderRun_BookMark=BufferUnderRun;
291 }
292 else
293 {
294 BookMark=0;
295 Buffer=Buffer_BookMark;
296 Buffer_Size=Buffer_Size_BookMark;
297 LastByte=LastByte_BookMark;
298 LastByte_Size=LastByte_Size_BookMark;
299 BufferUnderRun=BufferUnderRun_BookMark;
300 }
301 };
302
303 virtual int32u Remain () //How many bits remain?
304 {
305 return (int32u)(Buffer_Size+LastByte_Size);
306 };
307
308 virtual void Byte_Align()
309 {
310 Get(LastByte_Size);
311 };
312
313 virtual size_t Offset_Get()
314 {
315 if (BufferUnderRun)
316 return 0;
317 return (Buffer_Size_Init-Buffer_Size)/8;
318 };
319
320 virtual size_t BitOffset_Get()
321 {
322 if (BufferUnderRun)
323 return 0;
324 return LastByte_Size;
325 };
326
328 {
329 if (BufferUnderRun)
330 return 0;
331 return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8;
332 };
333
334private :
335 const int8u* Buffer;
336 size_t Buffer_Size;
337 size_t Buffer_Size_Init;
338 size_t Buffer_Size_BeforeLastCall;
339 size_t LastByte;
340 size_t LastByte_Size;
341 bool BufferUnderRun;
342
343 bool BookMark;
344 const int8u* Buffer_BookMark;
345 size_t Buffer_Size_BookMark;
346 size_t LastByte_BookMark;
347 size_t LastByte_Size_BookMark;
348 bool BufferUnderRun_BookMark;
349};
350
351} //namespace ZenLib
352#endif
#define MIN(a, b)
Definition BitStream.h:27
#define NULL
Definition HTTPClientWrapper.h:97
Definition BitStream.h:31
int32u Peek(size_t HowMany)
Definition BitStream.h:243
void Skip8(size_t HowMany)
Definition BitStream.h:229
int64u Peek8(size_t HowMany)
Definition BitStream.h:276
void Skip1(size_t HowMany)
Definition BitStream.h:214
int32u Get4(size_t HowMany)
Definition BitStream.h:135
virtual void Attach(const int8u *Buffer_, size_t Size_)
Definition BitStream.h:45
virtual size_t BitOffset_Get()
Definition BitStream.h:320
virtual void Byte_Align()
Definition BitStream.h:308
virtual int32u Remain()
Definition BitStream.h:303
int32u Peek3(size_t HowMany)
Definition BitStream.h:271
int8u Get1(size_t HowMany)
Definition BitStream.h:125
virtual size_t OffsetBeforeLastCall_Get()
Definition BitStream.h:327
void SkipB()
Definition BitStream.h:209
int16u Get2(size_t HowMany)
Definition BitStream.h:130
int32u Peek4(size_t HowMany)
Definition BitStream.h:266
bool GetB()
Definition BitStream.h:120
bool PeekB()
Definition BitStream.h:251
virtual int32u Get(size_t HowMany)
Definition BitStream.h:56
void Skip2(size_t HowMany)
Definition BitStream.h:219
int16u Peek2(size_t HowMany)
Definition BitStream.h:261
virtual size_t Offset_Get()
Definition BitStream.h:313
BitStream()
Definition BitStream.h:33
int8u Peek1(size_t HowMany)
Definition BitStream.h:256
int64u Get8(size_t HowMany)
Definition BitStream.h:140
virtual void Skip(size_t HowMany)
Definition BitStream.h:158
void BookMarkPos(bool ToSet)
Definition BitStream.h:281
BitStream(const int8u *Buffer_, size_t Size_)
Definition BitStream.h:38
void Skip4(size_t HowMany)
Definition BitStream.h:224
virtual ~BitStream()
Definition BitStream.h:43
Definition BitStream.h:24