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  HowMany-=32;
187  }
188  while(HowMany>32);
189  if (HowMany)
190  Skip(HowMany);
191  return;
192  }
193  if ((size_t)HowMany>Buffer_Size+LastByte_Size)
194  {
195  Buffer_Size=0;
196  LastByte_Size=0;
197  BufferUnderRun=true;
198  return;
199  }
200 
201  Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
202 
203  if (HowMany<=LastByte_Size)
204  LastByte_Size-=HowMany;
205  else
206  {
207  size_t NewBits=HowMany-LastByte_Size;
208  switch ((NewBits-1)/8)
209  {
210  case 3 : NewBits-=8;
211  Buffer++;
212  Buffer_Size-=8;
213  [[fallthrough]];
214  case 2 : NewBits-=8;
215  Buffer++;
216  Buffer_Size-=8;
217  [[fallthrough]];
218  case 1 : NewBits-=8;
219  Buffer++;
220  Buffer_Size-=8;
221  [[fallthrough]];
222  case 0 :
223  LastByte=*Buffer;
224  Buffer++;
225  }
226  LastByte_Size=MIN(8, Buffer_Size)-NewBits;
227  Buffer_Size -=MIN(8, Buffer_Size);
228  }
229  };
230 
231  void SkipB ()
232  {
233  Skip(1);
234  }
235 
236  void Skip1 (size_t HowMany)
237  {
238  Skip(HowMany);
239  }
240 
241  void Skip2 (size_t HowMany)
242  {
243  Skip(HowMany);
244  }
245 
246  void Skip4 (size_t HowMany)
247  {
248  Skip(HowMany);
249  }
250 
251  void Skip8 (size_t HowMany)
252  {
253  if (HowMany>64)
254  return; //Not supported
255  size_t HowMany1, HowMany2;
256  if (HowMany>32)
257  HowMany1=HowMany-32;
258  else
259  HowMany1=0;
260  HowMany2=HowMany-HowMany1;
261  Skip(HowMany1);
262  Skip(HowMany2);
263  }
264 
265  int32u Peek(size_t HowMany)
266  {
267  BookMarkPos(true);
268  int32u ToReturn=Get(HowMany);
269  BookMarkPos(false);
270  return ToReturn;
271  }
272 
273  bool PeekB()
274  {
275  return Peek(1)?true:false;
276  }
277 
278  int8u Peek1(size_t HowMany)
279  {
280  return (int8u )Peek(HowMany);
281  }
282 
283  int16u Peek2(size_t HowMany)
284  {
285  return (int16u)Peek(HowMany);
286  }
287 
288  int32u Peek4(size_t HowMany)
289  {
290  return (int32u)Peek(HowMany);
291  }
292 
293  int32u Peek3(size_t HowMany)
294  {
295  return (int32u)Peek(HowMany);
296  }
297 
298  int64u Peek8(size_t HowMany)
299  {
300  return (int64u)Peek(HowMany);
301  }
302 
303  void BookMarkPos(bool ToSet)
304  {
305  if (ToSet)
306  {
307  BookMark=1;
308  Buffer_BookMark=Buffer;
309  Buffer_Size_BookMark=Buffer_Size;
310  LastByte_BookMark=LastByte;
311  LastByte_Size_BookMark=LastByte_Size;
312  BufferUnderRun_BookMark=BufferUnderRun;
313  }
314  else
315  {
316  BookMark=0;
317  Buffer=Buffer_BookMark;
318  Buffer_Size=Buffer_Size_BookMark;
319  LastByte=LastByte_BookMark;
320  LastByte_Size=LastByte_Size_BookMark;
321  BufferUnderRun=BufferUnderRun_BookMark;
322  }
323  };
324 
325  virtual int32u Remain () //How many bits remain?
326  {
327  return (int32u)(Buffer_Size+LastByte_Size);
328  };
329 
330  virtual void Byte_Align()
331  {
332  Get(LastByte_Size);
333  };
334 
335  virtual size_t Offset_Get()
336  {
337  if (BufferUnderRun)
338  return 0;
339  return (Buffer_Size_Init-Buffer_Size)/8;
340  };
341 
342  virtual size_t BitOffset_Get()
343  {
344  if (BufferUnderRun)
345  return 0;
346  return LastByte_Size;
347  };
348 
349  virtual size_t OffsetBeforeLastCall_Get()
350  {
351  if (BufferUnderRun)
352  return 0;
353  return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8;
354  };
355 
356 private :
357  const int8u* Buffer;
358  size_t Buffer_Size;
359  size_t Buffer_Size_Init;
360  size_t Buffer_Size_BeforeLastCall;
361  size_t LastByte;
362  size_t LastByte_Size;
363  bool BufferUnderRun;
364 
365  bool BookMark;
366  const int8u* Buffer_BookMark;
367  size_t Buffer_Size_BookMark;
368  size_t LastByte_BookMark;
369  size_t LastByte_Size_BookMark;
370  bool BufferUnderRun_BookMark;
371 };
372 
373 } //namespace ZenLib
374 #endif
#define MIN(a, b)
Definition: BitStream.h:27
virtual void Attach(const int8u *Buffer_, size_t Size_)
Definition: BitStream.h:61
int64u Get8(size_t HowMany)
Definition: BitStream.h:159
virtual int32u Remain()
Definition: BitStream.h:325
int32u Peek4(size_t HowMany)
Definition: BitStream.h:288
int16u Peek2(size_t HowMany)
Definition: BitStream.h:283
Definition: BitStream.h:30
void Skip2(size_t HowMany)
Definition: BitStream.h:241
int8u Get1(size_t HowMany)
Definition: BitStream.h:144
#define NULL
Definition: HTTPClientWrapper.h:98
void Skip1(size_t HowMany)
Definition: BitStream.h:236
virtual void Byte_Align()
Definition: BitStream.h:330
Definition: BitStream.h:23
void BookMarkPos(bool ToSet)
Definition: BitStream.h:303
virtual ~BitStream()
Definition: BitStream.h:59
virtual int32u Get(size_t HowMany)
Definition: BitStream.h:72
bool PeekB()
Definition: BitStream.h:273
int32u Get4(size_t HowMany)
Definition: BitStream.h:154
BitStream(const int8u *Buffer_, size_t Size_)
Definition: BitStream.h:46
void Skip4(size_t HowMany)
Definition: BitStream.h:246
void Skip8(size_t HowMany)
Definition: BitStream.h:251
bool GetB()
Definition: BitStream.h:139
int32u Peek3(size_t HowMany)
Definition: BitStream.h:293
virtual size_t OffsetBeforeLastCall_Get()
Definition: BitStream.h:349
int32u Peek(size_t HowMany)
Definition: BitStream.h:265
BitStream()
Definition: BitStream.h:33
int16u Get2(size_t HowMany)
Definition: BitStream.h:149
void SkipB()
Definition: BitStream.h:231
int64u Peek8(size_t HowMany)
Definition: BitStream.h:298
virtual size_t BitOffset_Get()
Definition: BitStream.h:342
int8u Peek1(size_t HowMany)
Definition: BitStream.h:278
virtual size_t Offset_Get()
Definition: BitStream.h:335
virtual void Skip(size_t HowMany)
Definition: BitStream.h:177