ZenLib
BitStream_Fast.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 ZenBitStream_FastH
30 #define ZenBitStream_FastH
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 
45 {
46 public:
47  BitStream_Fast () {Buffer=NULL;
48  Buffer_Size=Buffer_Size_Init=0;
49  BufferUnderRun=false;}
50  BitStream_Fast (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_;
51  Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
52  BufferUnderRun=false;}
54 
55  void Attach(const int8u* Buffer_, size_t Size_)
56  {
57  Buffer=Buffer_;
58  Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
59  BufferUnderRun=false;
60  };
61 
62  bool GetB ()
63  {
64  if (Buffer_Size%8)
65  {
66  Buffer_Size--;
67  return ((LastByte>>(Buffer_Size%8))&0x1)?true:false;
68  }
69 
70  if (!Buffer_Size)
71  {
72  Buffer_Size=0;
73  BufferUnderRun=true;
74  return false;
75  }
76 
77  LastByte=*Buffer;
78  Buffer++;
79  Buffer_Size--;
80  return (LastByte&0x80)?true:false;
81  }
82 
83  int8u Get1 (int8u HowMany)
84  {
85  int8u ToReturn;
86  static const int8u Mask[9]=
87  {
88  0x00,
89  0x01, 0x03, 0x07, 0x0f,
90  0x1f, 0x3f, 0x7f, 0xff,
91  };
92 
93  if (HowMany<=(Buffer_Size%8))
94  {
95  Buffer_Size-=HowMany;
96  return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
97  }
98 
99  if (HowMany>Buffer_Size)
100  {
101  Buffer_Size=0;
102  BufferUnderRun=true;
103  return 0;
104  }
105 
106  int8u NewBits=HowMany-(Buffer_Size%8);
107  if (NewBits==8)
108  ToReturn=0;
109  else
110  ToReturn=LastByte<<NewBits;
111  LastByte=*Buffer;
112  Buffer++;
113  Buffer_Size-=HowMany;
114  ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
115  return ToReturn&Mask[HowMany];
116  }
117 
118  int16u Get2 (int8u HowMany)
119  {
120  int16u ToReturn;
121  static const int16u Mask[17]=
122  {
123  0x0000,
124  0x0001, 0x0003, 0x0007, 0x000f,
125  0x001f, 0x003f, 0x007f, 0x00ff,
126  0x01ff, 0x03ff, 0x07ff, 0x0fff,
127  0x1fff, 0x3fff, 0x7fff, 0xffff,
128  };
129 
130  if (HowMany<=(Buffer_Size%8))
131  {
132  Buffer_Size-=HowMany;
133  return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
134  }
135 
136  if (HowMany>Buffer_Size)
137  {
138  Buffer_Size=0;
139  BufferUnderRun=true;
140  return 0;
141  }
142 
143  int8u NewBits=HowMany-(Buffer_Size%8);
144  if (NewBits==16)
145  ToReturn=0;
146  else
147  ToReturn=LastByte<<NewBits;
148  if ((NewBits-1)>>3)
149  {
150  NewBits-=8;
151  ToReturn|=*Buffer<<NewBits;
152  Buffer++;
153  }
154  LastByte=*Buffer;
155  Buffer++;
156  Buffer_Size-=HowMany;
157  ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
158  return ToReturn&Mask[HowMany];
159  }
160 
161  int32u Get4 (int8u HowMany)
162  {
163  int32u ToReturn;
164  static const int32u Mask[33]=
165  {
166  0x00000000,
167  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
168  0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
169  0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
170  0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
171  0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
172  0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
173  0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
174  0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
175  };
176 
177  if (HowMany<=(Buffer_Size%8))
178  {
179  Buffer_Size-=HowMany;
180  return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
181  }
182 
183  if (HowMany>Buffer_Size)
184  {
185  Buffer_Size=0;
186  BufferUnderRun=true;
187  return 0;
188  }
189 
190  int8u NewBits=HowMany-(Buffer_Size%8);
191  if (NewBits==32)
192  ToReturn=0;
193  else
194  ToReturn=LastByte<<NewBits;
195  switch ((NewBits-1)>>3)
196  {
197  case 3 : NewBits-=8;
198  ToReturn|=*Buffer<<NewBits;
199  Buffer++;
200  case 2 : NewBits-=8;
201  ToReturn|=*Buffer<<NewBits;
202  Buffer++;
203  case 1 : NewBits-=8;
204  ToReturn|=*Buffer<<NewBits;
205  Buffer++;
206  default: ;
207  }
208  LastByte=*Buffer;
209  Buffer++;
210  Buffer_Size-=HowMany;
211  ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
212  return ToReturn&Mask[HowMany];
213  }
214 
215  int64u Get8 (int8u HowMany)
216  {
217  if (HowMany>64)
218  return 0; //Not supported
219  int8u HowMany1, HowMany2;
220  int64u Value1, Value2;
221  if (HowMany>32)
222  HowMany1=HowMany-32;
223  else
224  HowMany1=0;
225  HowMany2=HowMany-HowMany1;
226  Value1=Get4(HowMany1);
227  Value2=Get4(HowMany2);
228  if (BufferUnderRun)
229  return 0;
230  return Value1*0x100000000LL+Value2;
231  }
232 
233  void Skip (size_t HowMany)
234  {
235  if (HowMany<=(Buffer_Size%8))
236  {
237  Buffer_Size-=HowMany;
238  return;
239  }
240 
241  if (HowMany>Buffer_Size)
242  {
243  Buffer_Size=0;
244  BufferUnderRun=true;
245  return;
246  }
247 
248  Buffer+=(HowMany-(Buffer_Size%8)-1)>>3;
249  LastByte=*Buffer;
250  Buffer++;
251  Buffer_Size-=HowMany;
252  };
253 
254  bool PeekB()
255  {
256  if (Buffer_Size%8)
257  return ((LastByte>>((Buffer_Size-1)%8))&0x1)?true:false;
258 
259  if (!Buffer_Size)
260  {
261  Buffer_Size=0;
262  BufferUnderRun=true;
263  return false;
264  }
265 
266  return ((*Buffer)&0x80)?true:false;
267  }
268 
269  int8u Peek1(int8u HowMany)
270  {
271  int8u ToReturn;
272  static const int8u Mask[9]=
273  {
274  0x00,
275  0x01, 0x03, 0x07, 0x0f,
276  0x1f, 0x3f, 0x7f, 0xff,
277  };
278 
279  if (HowMany<=(Buffer_Size%8))
280  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
281 
282  if (HowMany>Buffer_Size)
283  {
284  Buffer_Size=0;
285  BufferUnderRun=true;
286  return 0;
287  }
288 
289  int8u NewBits=HowMany-(Buffer_Size%8);
290  if (NewBits==8)
291  ToReturn=0;
292  else
293  ToReturn=LastByte<<NewBits;
294  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
295 
296  return ToReturn&Mask[HowMany];
297  }
298 
299  int16u Peek2(int8u HowMany)
300  {
301  int16u ToReturn;
302  static const int16u Mask[17]=
303  {
304  0x0000,
305  0x0001, 0x0003, 0x0007, 0x000f,
306  0x001f, 0x003f, 0x007f, 0x00ff,
307  0x01ff, 0x03ff, 0x07ff, 0x0fff,
308  0x1fff, 0x3fff, 0x7fff, 0xffff,
309  };
310 
311  if (HowMany<=(Buffer_Size%8))
312  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
313 
314  if (HowMany>Buffer_Size)
315  {
316  Buffer_Size=0;
317  BufferUnderRun=true;
318  return 0;
319  }
320 
321  const int8u* Buffer_Save=Buffer;
322 
323  int8u NewBits=HowMany-(Buffer_Size%8);
324  if (NewBits==16)
325  ToReturn=0;
326  else
327  ToReturn=LastByte<<NewBits;
328  if ((NewBits-1)>>3)
329  {
330  NewBits-=8;
331  ToReturn|=*Buffer<<NewBits;
332  Buffer++;
333  }
334  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
335 
336  Buffer=Buffer_Save;
337 
338  return ToReturn&Mask[HowMany];
339  }
340 
341  int32u Peek4(int8u HowMany)
342  {
343  int32u ToReturn;
344  static const int32u Mask[33]=
345  {
346  0x00000000,
347  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
348  0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
349  0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
350  0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
351  0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
352  0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
353  0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
354  0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
355  };
356 
357  if (HowMany<=(Buffer_Size%8))
358  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
359 
360  if (HowMany>Buffer_Size)
361  {
362  Buffer_Size=0;
363  BufferUnderRun=true;
364  return 0;
365  }
366 
367  const int8u* Buffer_Save=Buffer;
368 
369  int8u NewBits=HowMany-(Buffer_Size%8);
370  if (NewBits==32)
371  ToReturn=0;
372  else
373  ToReturn=LastByte<<NewBits;
374  switch ((NewBits-1)>>3)
375  {
376  case 3 : NewBits-=8;
377  ToReturn|=*Buffer<<NewBits;
378  Buffer++;
379  case 2 : NewBits-=8;
380  ToReturn|=*Buffer<<NewBits;
381  Buffer++;
382  case 1 : NewBits-=8;
383  ToReturn|=*Buffer<<NewBits;
384  Buffer++;
385  default: ;
386  }
387  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
388 
389  Buffer=Buffer_Save;
390 
391  return ToReturn&Mask[HowMany];
392  }
393 
394  int64u Peek8(int8u HowMany)
395  {
396  return (int64u)Peek4(HowMany); //Not yet implemented
397  }
398 
399  inline size_t Remain () //How many bits remain?
400  {
401  return Buffer_Size;
402  };
403 
404  inline void Byte_Align()
405  {
406  Skip (Buffer_Size%8);
407  };
408 
409  inline size_t Offset_Get()
410  {
411  return (Buffer_Size_Init-Buffer_Size)/8;
412  };
413 
414  inline size_t BitOffset_Get()
415  {
416  return Buffer_Size%8;
417  };
418 
419  inline size_t OffsetBeforeLastCall_Get() //No more valid
420  {
421  return Buffer_Size%8;
422  };
423 
424 private :
425  const int8u* Buffer;
426  size_t Buffer_Size;
427  size_t Buffer_Size_Init;
428  int8u LastByte;
429 public :
431 };
432 
433 } //namespace ZenLib
434 #endif