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