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 
23 namespace ZenLib
24 {
25 
26 #ifndef MIN
27  #define MIN(a, b) (((a) < (b)) ? (a) : (b))
28 #endif
29 
31 {
32 public:
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 
419 private :
420  const int8u* Buffer;
421  size_t Buffer_Size;
422  size_t Buffer_Size_Init;
423  int8u LastByte;
424 public :
426 };
427 
428 } //namespace ZenLib
429 #endif
size_t Remain() const
Definition: BitStream_Fast.h:387
~BitStream_Fast()
Definition: BitStream_Fast.h:43
BitStream_Fast(const int8u *Buffer_, size_t Size_)
Definition: BitStream_Fast.h:38
bool GetB()
Definition: BitStream_Fast.h:52
void Byte_Align()
Definition: BitStream_Fast.h:392
#define NULL
Definition: HTTPClientWrapper.h:98
int32u Get4(int8u HowMany)
Definition: BitStream_Fast.h:151
int16u Get2(int8u HowMany)
Definition: BitStream_Fast.h:108
Definition: BitStream.h:23
int8u Peek1(int8u HowMany)
Definition: BitStream_Fast.h:256
int32u Peek4(int8u HowMany)
Definition: BitStream_Fast.h:328
BitStream_Fast()
Definition: BitStream_Fast.h:33
size_t OffsetBeforeLastCall_Get() const
Definition: BitStream_Fast.h:407
Definition: BitStream_Fast.h:30
size_t Offset_Get() const
Definition: BitStream_Fast.h:397
bool PeekB()
Definition: BitStream_Fast.h:241
size_t BitOffset_Get() const
Definition: BitStream_Fast.h:402
void Attach(const int8u *Buffer_, size_t Size_)
Definition: BitStream_Fast.h:45
int8u Get1(int8u HowMany)
Definition: BitStream_Fast.h:73
void Resize(size_t Size_)
Definition: BitStream_Fast.h:412
bool BufferUnderRun
Definition: BitStream_Fast.h:425
int16u Peek2(int8u HowMany)
Definition: BitStream_Fast.h:286
int64u Get8(int8u HowMany)
Definition: BitStream_Fast.h:202
int64u Peek8(int8u HowMany)
Definition: BitStream_Fast.h:382
void Skip(size_t HowMany)
Definition: BitStream_Fast.h:220