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