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