ZenLib
BitStream_Fast.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 ZenBitStream_FastH
16#define ZenBitStream_FastH
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_Fast () {Buffer=NULL;
34 Buffer_Size=Buffer_Size_Init=0;
35 BufferUnderRun=false;}
36 BitStream_Fast (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_;
37 Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
38 BufferUnderRun=false;}
40
41 void Attach(const int8u* Buffer_, size_t Size_)
42 {
43 Buffer=Buffer_;
44 Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
45 BufferUnderRun=false;
46 }
47
48 bool GetB ()
49 {
50 if (Buffer_Size%8)
51 {
52 Buffer_Size--;
53 return ((LastByte>>(Buffer_Size%8))&0x1)?true:false;
54 }
55
56 if (!Buffer_Size)
57 {
58 Buffer_Size=0;
59 BufferUnderRun=true;
60 return false;
61 }
62
63 LastByte=*Buffer;
64 Buffer++;
65 Buffer_Size--;
66 return (LastByte&0x80)?true:false;
67 }
68
69 int8u Get1 (int8u HowMany)
70 {
71 int8u ToReturn;
72 static const int8u Mask[9]=
73 {
74 0x00,
75 0x01, 0x03, 0x07, 0x0f,
76 0x1f, 0x3f, 0x7f, 0xff,
77 };
78
79 if (HowMany<=(Buffer_Size%8))
80 {
81 Buffer_Size-=HowMany;
82 return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
83 }
84
85 if (HowMany>Buffer_Size)
86 {
87 Buffer_Size=0;
88 BufferUnderRun=true;
89 return 0;
90 }
91
92 int8u NewBits=HowMany-(Buffer_Size%8);
93 if (NewBits==8)
94 ToReturn=0;
95 else
96 ToReturn=LastByte<<NewBits;
97 LastByte=*Buffer;
98 Buffer++;
99 Buffer_Size-=HowMany;
100 ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
101 return ToReturn&Mask[HowMany];
102 }
103
104 int16u Get2 (int8u HowMany)
105 {
106 int16u ToReturn;
107 static const int16u Mask[17]=
108 {
109 0x0000,
110 0x0001, 0x0003, 0x0007, 0x000f,
111 0x001f, 0x003f, 0x007f, 0x00ff,
112 0x01ff, 0x03ff, 0x07ff, 0x0fff,
113 0x1fff, 0x3fff, 0x7fff, 0xffff,
114 };
115
116 if (HowMany<=(Buffer_Size%8))
117 {
118 Buffer_Size-=HowMany;
119 return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
120 }
121
122 if (HowMany>Buffer_Size)
123 {
124 Buffer_Size=0;
125 BufferUnderRun=true;
126 return 0;
127 }
128
129 int8u NewBits=HowMany-(Buffer_Size%8);
130 if (NewBits==16)
131 ToReturn=0;
132 else
133 ToReturn=LastByte<<NewBits;
134 if ((NewBits-1)>>3)
135 {
136 NewBits-=8;
137 ToReturn|=*Buffer<<NewBits;
138 Buffer++;
139 }
140 LastByte=*Buffer;
141 Buffer++;
142 Buffer_Size-=HowMany;
143 ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
144 return ToReturn&Mask[HowMany];
145 }
146
147 int32u Get4 (int8u HowMany)
148 {
149 int32u ToReturn;
150 static const int32u Mask[33]=
151 {
152 0x00000000,
153 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
154 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
155 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
156 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
157 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
158 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
159 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
160 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
161 };
162
163 if (HowMany<=(Buffer_Size%8))
164 {
165 Buffer_Size-=HowMany;
166 return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
167 }
168
169 if (HowMany>Buffer_Size)
170 {
171 Buffer_Size=0;
172 BufferUnderRun=true;
173 return 0;
174 }
175
176 int8u NewBits=HowMany-(Buffer_Size%8);
177 if (NewBits==32)
178 ToReturn=0;
179 else
180 ToReturn=LastByte<<NewBits;
181 switch ((NewBits-1)>>3)
182 {
183 case 3 : NewBits-=8;
184 ToReturn|=*(Buffer++)<<NewBits;
185 case 2 : NewBits-=8;
186 ToReturn|=*(Buffer++)<<NewBits;
187 case 1 : NewBits-=8;
188 ToReturn|=*(Buffer++)<<NewBits;
189 default: ;
190 }
191 LastByte=*(Buffer++);
192 Buffer_Size-=HowMany;
193 ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
194 return ToReturn&Mask[HowMany];
195 }
196
197 int64u Get8 (int8u HowMany)
198 {
199 if (HowMany>64)
200 return 0; //Not supported
201 int8u HowMany1, HowMany2;
202 int64u Value1, Value2;
203 if (HowMany>32)
204 HowMany1=HowMany-32;
205 else
206 HowMany1=0;
207 HowMany2=HowMany-HowMany1;
208 Value1=Get4(HowMany1);
209 Value2=Get4(HowMany2);
210 if (BufferUnderRun)
211 return 0;
212 return Value1*0x100000000LL+Value2;
213 }
214
215 void Skip (size_t HowMany)
216 {
217 if (HowMany<=(Buffer_Size%8))
218 {
219 Buffer_Size-=HowMany;
220 return;
221 }
222
223 if (HowMany>Buffer_Size)
224 {
225 Buffer_Size=0;
226 BufferUnderRun=true;
227 return;
228 }
229
230 Buffer+=(HowMany-(Buffer_Size%8)-1)>>3;
231 LastByte=*Buffer;
232 Buffer++;
233 Buffer_Size-=HowMany;
234 }
235
236 bool PeekB()
237 {
238 if (Buffer_Size%8)
239 return ((LastByte>>((Buffer_Size-1)%8))&0x1)?true:false;
240
241 if (!Buffer_Size)
242 {
243 Buffer_Size=0;
244 BufferUnderRun=true;
245 return false;
246 }
247
248 return ((*Buffer)&0x80)?true:false;
249 }
250
251 int8u Peek1(int8u HowMany)
252 {
253 int8u ToReturn;
254 static const int8u Mask[9]=
255 {
256 0x00,
257 0x01, 0x03, 0x07, 0x0f,
258 0x1f, 0x3f, 0x7f, 0xff,
259 };
260
261 if (HowMany<=(Buffer_Size%8))
262 return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
263
264 if (HowMany>Buffer_Size)
265 {
266 Buffer_Size=0;
267 BufferUnderRun=true;
268 return 0;
269 }
270
271 int8u NewBits=HowMany-(Buffer_Size%8);
272 if (NewBits==8)
273 ToReturn=0;
274 else
275 ToReturn=LastByte<<NewBits;
276 ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
277
278 return ToReturn&Mask[HowMany];
279 }
280
281 int16u Peek2(int8u HowMany)
282 {
283 int16u ToReturn;
284 static const int16u Mask[17]=
285 {
286 0x0000,
287 0x0001, 0x0003, 0x0007, 0x000f,
288 0x001f, 0x003f, 0x007f, 0x00ff,
289 0x01ff, 0x03ff, 0x07ff, 0x0fff,
290 0x1fff, 0x3fff, 0x7fff, 0xffff,
291 };
292
293 if (HowMany<=(Buffer_Size%8))
294 return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
295
296 if (HowMany>Buffer_Size)
297 {
298 Buffer_Size=0;
299 BufferUnderRun=true;
300 return 0;
301 }
302
303 const int8u* Buffer_Save=Buffer;
304
305 int8u NewBits=HowMany-(Buffer_Size%8);
306 if (NewBits==16)
307 ToReturn=0;
308 else
309 ToReturn=LastByte<<NewBits;
310 if ((NewBits-1)>>3)
311 {
312 NewBits-=8;
313 ToReturn|=*Buffer<<NewBits;
314 Buffer++;
315 }
316 ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
317
318 Buffer=Buffer_Save;
319
320 return ToReturn&Mask[HowMany];
321 }
322
323 int32u Peek4(int8u HowMany)
324 {
325 int32u ToReturn;
326 static const int32u Mask[33]=
327 {
328 0x00000000,
329 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
330 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
331 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
332 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
333 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
334 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
335 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
336 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
337 };
338
339 if (HowMany<=(Buffer_Size%8))
340 return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
341
342 if (HowMany>Buffer_Size)
343 {
344 Buffer_Size=0;
345 BufferUnderRun=true;
346 return 0;
347 }
348
349 const int8u* Buffer_Save=Buffer;
350
351 int8u NewBits=HowMany-(Buffer_Size%8);
352 if (NewBits==32)
353 ToReturn=0;
354 else
355 ToReturn=LastByte<<NewBits;
356 switch ((NewBits-1)>>3)
357 {
358 case 3 : NewBits-=8;
359 ToReturn|=*Buffer<<NewBits;
360 Buffer++;
361 case 2 : NewBits-=8;
362 ToReturn|=*Buffer<<NewBits;
363 Buffer++;
364 case 1 : NewBits-=8;
365 ToReturn|=*Buffer<<NewBits;
366 Buffer++;
367 default: ;
368 }
369 ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
370
371 Buffer=Buffer_Save;
372
373 return ToReturn&Mask[HowMany];
374 }
375
376 int64u Peek8(int8u HowMany)
377 {
378 return (int64u)Peek4(HowMany); //Not yet implemented
379 }
380
381 inline size_t Remain () const //How many bits remain?
382 {
383 return Buffer_Size;
384 }
385
386 inline void Byte_Align()
387 {
388 Skip (Buffer_Size%8);
389 }
390
391 inline size_t Offset_Get() const
392 {
393 return (Buffer_Size_Init-Buffer_Size)/8;
394 }
395
396 inline size_t BitOffset_Get() const
397 {
398 return Buffer_Size%8;
399 }
400
401 inline size_t OffsetBeforeLastCall_Get() const //No more valid
402 {
403 return Buffer_Size%8;
404 }
405
406 inline void Resize(size_t Size_) //Size_ is the new count of remaining bits, must have the same alignment as Remain()
407 {
408 if (BufferUnderRun && Size_>Buffer_Size)
409 BufferUnderRun=false;
410 Buffer_Size=Size_;
411 }
412
413private :
414 const int8u* Buffer;
415 size_t Buffer_Size;
416 size_t Buffer_Size_Init;
417 int8u LastByte;
418public :
420};
421
422} //namespace ZenLib
423#endif
#define NULL
Definition HTTPClientWrapper.h:98
Definition BitStream_Fast.h:31
BitStream_Fast(const int8u *Buffer_, size_t Size_)
Definition BitStream_Fast.h:36
int64u Get8(int8u HowMany)
Definition BitStream_Fast.h:197
void Skip(size_t HowMany)
Definition BitStream_Fast.h:215
int32u Get4(int8u HowMany)
Definition BitStream_Fast.h:147
bool GetB()
Definition BitStream_Fast.h:48
size_t OffsetBeforeLastCall_Get() const
Definition BitStream_Fast.h:401
int16u Peek2(int8u HowMany)
Definition BitStream_Fast.h:281
bool BufferUnderRun
Definition BitStream_Fast.h:419
size_t BitOffset_Get() const
Definition BitStream_Fast.h:396
void Resize(size_t Size_)
Definition BitStream_Fast.h:406
int8u Peek1(int8u HowMany)
Definition BitStream_Fast.h:251
bool PeekB()
Definition BitStream_Fast.h:236
~BitStream_Fast()
Definition BitStream_Fast.h:39
size_t Offset_Get() const
Definition BitStream_Fast.h:391
int64u Peek8(int8u HowMany)
Definition BitStream_Fast.h:376
void Byte_Align()
Definition BitStream_Fast.h:386
void Attach(const int8u *Buffer_, size_t Size_)
Definition BitStream_Fast.h:41
int32u Peek4(int8u HowMany)
Definition BitStream_Fast.h:323
int16u Get2(int8u HowMany)
Definition BitStream_Fast.h:104
BitStream_Fast()
Definition BitStream_Fast.h:33
size_t Remain() const
Definition BitStream_Fast.h:381
int8u Get1(int8u HowMany)
Definition BitStream_Fast.h:69
Definition BitStream.h:24