ZenLib
BitStream.h
Go to the documentation of this file.
1 // ZenLib::bitStream - Read bit per bit
2 // Copyright (C) 2006-2011 MediaArea.net SARL, Info@MediaArea.net
3 //
4 // This software is provided 'as-is', without any express or implied
5 // warranty. In no event will the authors be held liable for any damages
6 // arising from the use of this software.
7 //
8 // Permission is granted to anyone to use this software for any purpose,
9 // including commercial applications, and to alter it and redistribute it
10 // freely, subject to the following restrictions:
11 //
12 // 1. The origin of this software must not be misrepresented; you must not
13 // claim that you wrote the original software. If you use this software
14 // in a product, an acknowledgment in the product documentation would be
15 // appreciated but is not required.
16 // 2. Altered source versions must be plainly marked as such, and must not be
17 // misrepresented as being the original software.
18 // 3. This notice may not be removed or altered from any source distribution.
19 //
20 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 //
23 // Read a stream bit per bit
24 // Can read up to 32 bits at once
25 //
26 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 
28 //---------------------------------------------------------------------------
29 #ifndef ZenBitStreamH
30 #define ZenBitStreamH
31 //---------------------------------------------------------------------------
32 
33 //---------------------------------------------------------------------------
34 #include "ZenLib/Conf.h"
35 //---------------------------------------------------------------------------
36 
37 namespace ZenLib
38 {
39 
40 #ifndef MIN
41  #define MIN(a, b) (((a) < (b)) ? (a) : (b))
42 #endif
43 
44 class BitStream
45 {
46 public:
47  BitStream () {Buffer=NULL;
48  Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=0;
49  LastByte_Size=0;
50  BufferUnderRun=true;
51  BookMark=false;}
52  BitStream (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_;
53  Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
54  LastByte_Size=0;
55  BufferUnderRun=Buffer_Size?false:true;
56  BookMark=false;}
57  virtual ~BitStream () {};
58 
59  virtual void Attach(const int8u* Buffer_, size_t Size_)
60  {
61  if (Buffer_==Buffer)
62  return; //Nothing to do
63  Buffer=Buffer_;
64  Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
65  LastByte_Size=0;
66  BufferUnderRun=Buffer_Size?false:true;
67  BookMark=false;
68  };
69 
70  virtual int32u Get (size_t HowMany)
71  {
72  size_t ToReturn;
73  static const int32u Mask[33]={
74  0x00000000,
75  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
76  0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
77  0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
78  0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
79  0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
80  0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
81  0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
82  0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
83  };
84 
85  if (HowMany==0 || HowMany>32)
86  return 0;
87  if ((size_t)HowMany>Buffer_Size+LastByte_Size)
88  {
89  Buffer_Size=0;
90  LastByte_Size=0;
91  BufferUnderRun=true;
92  return 0;
93  }
94 
95  Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
96 
97  if (HowMany<=LastByte_Size)
98  {
99  LastByte_Size-=HowMany;
100  ToReturn=LastByte>>LastByte_Size;
101  }
102  else
103  {
104  size_t NewBits=HowMany-LastByte_Size;
105  if (NewBits==32)
106  ToReturn=0;
107  else
108  ToReturn=LastByte<<NewBits;
109  switch ((NewBits-1)/8)
110  {
111  case 3 : NewBits-=8;
112  ToReturn|=*Buffer<<NewBits;
113  Buffer++;
114  Buffer_Size-=8;
115  case 2 : NewBits-=8;
116  ToReturn|=*Buffer<<NewBits;
117  Buffer++;
118  Buffer_Size-=8;
119  case 1 : NewBits-=8;
120  ToReturn|=*Buffer<<NewBits;
121  Buffer++;
122  Buffer_Size-=8;
123  case 0 :
124  LastByte=*Buffer;
125  Buffer++;
126  }
127  LastByte_Size=MIN(8, Buffer_Size)-NewBits;
128  Buffer_Size -=MIN(8, Buffer_Size);
129  ToReturn|=(LastByte>>LastByte_Size)&Mask[NewBits];
130  }
131  return (int32u)(ToReturn&Mask[HowMany]);
132  };
133 
134  bool GetB ()
135  {
136  return Get(1)?true:false;
137  }
138 
139  int8u Get1 (size_t HowMany)
140  {
141  return (int8u )Get(HowMany);
142  }
143 
144  int16u Get2 (size_t HowMany)
145  {
146  return (int16u)Get(HowMany);
147  }
148 
149  int32u Get4 (size_t HowMany)
150  {
151  return (int32u)Get(HowMany);
152  }
153 
154  int64u Get8 (size_t HowMany)
155  {
156  if (HowMany>64)
157  return 0; //Not supported
158  size_t HowMany1, HowMany2;
159  int64u Value1, Value2;
160  if (HowMany>32)
161  HowMany1=HowMany-32;
162  else
163  HowMany1=0;
164  HowMany2=HowMany-HowMany1;
165  Value1=Get(HowMany1);
166  Value2=Get(HowMany2);
167  if (BufferUnderRun)
168  return 0;
169  return Value1*0x100000000LL+Value2;
170  }
171 
172  virtual void Skip (size_t HowMany)
173  {
174  if (HowMany==0)
175  return;
176  if (HowMany>32) //Algorithm is only for <=32 bits
177  {
178  do
179  {
180  Skip(32);
181  HowMany-=32;
182  }
183  while(HowMany>32);
184  if (HowMany)
185  Skip(HowMany);
186  return;
187  }
188  if ((size_t)HowMany>Buffer_Size+LastByte_Size)
189  {
190  Buffer_Size=0;
191  LastByte_Size=0;
192  BufferUnderRun=true;
193  return;
194  }
195 
196  Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
197 
198  if (HowMany<=LastByte_Size)
199  LastByte_Size-=HowMany;
200  else
201  {
202  size_t NewBits=HowMany-LastByte_Size;
203  switch ((NewBits-1)/8)
204  {
205  case 3 : NewBits-=8;
206  Buffer++;
207  Buffer_Size-=8;
208  case 2 : NewBits-=8;
209  Buffer++;
210  Buffer_Size-=8;
211  case 1 : NewBits-=8;
212  Buffer++;
213  Buffer_Size-=8;
214  case 0 :
215  LastByte=*Buffer;
216  Buffer++;
217  }
218  LastByte_Size=MIN(8, Buffer_Size)-NewBits;
219  Buffer_Size -=MIN(8, Buffer_Size);
220  }
221  };
222 
223  void SkipB ()
224  {
225  Skip(1);
226  }
227 
228  void Skip1 (size_t HowMany)
229  {
230  Skip(HowMany);
231  }
232 
233  void Skip2 (size_t HowMany)
234  {
235  Skip(HowMany);
236  }
237 
238  void Skip4 (size_t HowMany)
239  {
240  Skip(HowMany);
241  }
242 
243  void Skip8 (size_t HowMany)
244  {
245  if (HowMany>64)
246  return; //Not supported
247  size_t HowMany1, HowMany2;
248  if (HowMany>32)
249  HowMany1=HowMany-32;
250  else
251  HowMany1=0;
252  HowMany2=HowMany-HowMany1;
253  Skip(HowMany1);
254  Skip(HowMany2);
255  }
256 
257  int32u Peek(size_t HowMany)
258  {
259  BookMarkPos(true);
260  int32u ToReturn=Get(HowMany);
261  BookMarkPos(false);
262  return ToReturn;
263  }
264 
265  bool PeekB()
266  {
267  return Peek(1)?true:false;
268  }
269 
270  int8u Peek1(size_t HowMany)
271  {
272  return (int8u )Peek(HowMany);
273  }
274 
275  int16u Peek2(size_t HowMany)
276  {
277  return (int16u)Peek(HowMany);
278  }
279 
280  int32u Peek4(size_t HowMany)
281  {
282  return (int32u)Peek(HowMany);
283  }
284 
285  int32u Peek3(size_t HowMany)
286  {
287  return (int32u)Peek(HowMany);
288  }
289 
290  int64u Peek8(size_t HowMany)
291  {
292  return (int64u)Peek(HowMany);
293  }
294 
295  void BookMarkPos(bool ToSet)
296  {
297  if (ToSet)
298  {
299  BookMark=1;
300  Buffer_BookMark=Buffer;
301  Buffer_Size_BookMark=Buffer_Size;
302  LastByte_BookMark=LastByte;
303  LastByte_Size_BookMark=LastByte_Size;
304  BufferUnderRun_BookMark=BufferUnderRun;
305  }
306  else
307  {
308  BookMark=0;
309  Buffer=Buffer_BookMark;
310  Buffer_Size=Buffer_Size_BookMark;
311  LastByte=LastByte_BookMark;
312  LastByte_Size=LastByte_Size_BookMark;
313  BufferUnderRun=BufferUnderRun_BookMark;
314  }
315  };
316 
317  virtual int32u Remain () //How many bits remain?
318  {
319  return (int32u)(Buffer_Size+LastByte_Size);
320  };
321 
322  virtual void Byte_Align()
323  {
324  Get(LastByte_Size);
325  };
326 
327  virtual size_t Offset_Get()
328  {
329  if (BufferUnderRun)
330  return 0;
331  return (Buffer_Size_Init-Buffer_Size)/8;
332  };
333 
334  virtual size_t BitOffset_Get()
335  {
336  if (BufferUnderRun)
337  return 0;
338  return LastByte_Size;
339  };
340 
341  virtual size_t OffsetBeforeLastCall_Get()
342  {
343  if (BufferUnderRun)
344  return 0;
345  return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8;
346  };
347 
348 private :
349  const int8u* Buffer;
350  size_t Buffer_Size;
351  size_t Buffer_Size_Init;
352  size_t Buffer_Size_BeforeLastCall;
353  size_t LastByte;
354  size_t LastByte_Size;
355  bool BufferUnderRun;
356 
357  bool BookMark;
358  const int8u* Buffer_BookMark;
359  size_t Buffer_Size_BookMark;
360  size_t LastByte_BookMark;
361  size_t LastByte_Size_BookMark;
362  bool BufferUnderRun_BookMark;
363 };
364 
365 } //namespace ZenLib
366 #endif