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