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  case 2 : NewBits-=8;
186  ToReturn|=*(Buffer++)<<NewBits;
187  case 1 : NewBits-=8;
188  ToReturn|=*(Buffer++)<<NewBits;
189  default: ;
190  }
191  LastByte=*(Buffer++);
192  Buffer_Size-=HowMany;
193  ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
194  return ToReturn&Mask[HowMany];
195  }
196 
197  int64u Get8 (int8u HowMany)
198  {
199  if (HowMany>64)
200  return 0; //Not supported
201  int8u HowMany1, HowMany2;
202  int64u Value1, Value2;
203  if (HowMany>32)
204  HowMany1=HowMany-32;
205  else
206  HowMany1=0;
207  HowMany2=HowMany-HowMany1;
208  Value1=Get4(HowMany1);
209  Value2=Get4(HowMany2);
210  if (BufferUnderRun)
211  return 0;
212  return Value1*0x100000000LL+Value2;
213  }
214 
215  void Skip (size_t HowMany)
216  {
217  if (HowMany<=(Buffer_Size%8))
218  {
219  Buffer_Size-=HowMany;
220  return;
221  }
222 
223  if (HowMany>Buffer_Size)
224  {
225  Buffer_Size=0;
226  BufferUnderRun=true;
227  return;
228  }
229 
230  Buffer+=(HowMany-(Buffer_Size%8)-1)>>3;
231  LastByte=*Buffer;
232  Buffer++;
233  Buffer_Size-=HowMany;
234  }
235 
236  bool PeekB()
237  {
238  if (Buffer_Size%8)
239  return ((LastByte>>((Buffer_Size-1)%8))&0x1)?true:false;
240 
241  if (!Buffer_Size)
242  {
243  Buffer_Size=0;
244  BufferUnderRun=true;
245  return false;
246  }
247 
248  return ((*Buffer)&0x80)?true:false;
249  }
250 
251  int8u Peek1(int8u HowMany)
252  {
253  int8u ToReturn;
254  static const int8u Mask[9]=
255  {
256  0x00,
257  0x01, 0x03, 0x07, 0x0f,
258  0x1f, 0x3f, 0x7f, 0xff,
259  };
260 
261  if (HowMany<=(Buffer_Size%8))
262  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
263 
264  if (HowMany>Buffer_Size)
265  {
266  Buffer_Size=0;
267  BufferUnderRun=true;
268  return 0;
269  }
270 
271  int8u NewBits=HowMany-(Buffer_Size%8);
272  if (NewBits==8)
273  ToReturn=0;
274  else
275  ToReturn=LastByte<<NewBits;
276  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
277 
278  return ToReturn&Mask[HowMany];
279  }
280 
281  int16u Peek2(int8u HowMany)
282  {
283  int16u ToReturn;
284  static const int16u Mask[17]=
285  {
286  0x0000,
287  0x0001, 0x0003, 0x0007, 0x000f,
288  0x001f, 0x003f, 0x007f, 0x00ff,
289  0x01ff, 0x03ff, 0x07ff, 0x0fff,
290  0x1fff, 0x3fff, 0x7fff, 0xffff,
291  };
292 
293  if (HowMany<=(Buffer_Size%8))
294  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
295 
296  if (HowMany>Buffer_Size)
297  {
298  Buffer_Size=0;
299  BufferUnderRun=true;
300  return 0;
301  }
302 
303  const int8u* Buffer_Save=Buffer;
304 
305  int8u NewBits=HowMany-(Buffer_Size%8);
306  if (NewBits==16)
307  ToReturn=0;
308  else
309  ToReturn=LastByte<<NewBits;
310  if ((NewBits-1)>>3)
311  {
312  NewBits-=8;
313  ToReturn|=*Buffer<<NewBits;
314  Buffer++;
315  }
316  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
317 
318  Buffer=Buffer_Save;
319 
320  return ToReturn&Mask[HowMany];
321  }
322 
323  int32u Peek4(int8u HowMany)
324  {
325  int32u ToReturn;
326  static const int32u Mask[33]=
327  {
328  0x00000000,
329  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
330  0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
331  0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
332  0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
333  0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
334  0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
335  0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
336  0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
337  };
338 
339  if (HowMany<=(Buffer_Size%8))
340  return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
341 
342  if (HowMany>Buffer_Size)
343  {
344  Buffer_Size=0;
345  BufferUnderRun=true;
346  return 0;
347  }
348 
349  const int8u* Buffer_Save=Buffer;
350 
351  int8u NewBits=HowMany-(Buffer_Size%8);
352  if (NewBits==32)
353  ToReturn=0;
354  else
355  ToReturn=LastByte<<NewBits;
356  switch ((NewBits-1)>>3)
357  {
358  case 3 : NewBits-=8;
359  ToReturn|=*Buffer<<NewBits;
360  Buffer++;
361  case 2 : NewBits-=8;
362  ToReturn|=*Buffer<<NewBits;
363  Buffer++;
364  case 1 : NewBits-=8;
365  ToReturn|=*Buffer<<NewBits;
366  Buffer++;
367  default: ;
368  }
369  ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
370 
371  Buffer=Buffer_Save;
372 
373  return ToReturn&Mask[HowMany];
374  }
375 
376  int64u Peek8(int8u HowMany)
377  {
378  return (int64u)Peek4(HowMany); //Not yet implemented
379  }
380 
381  inline size_t Remain () const //How many bits remain?
382  {
383  return Buffer_Size;
384  }
385 
386  inline void Byte_Align()
387  {
388  Skip (Buffer_Size%8);
389  }
390 
391  inline size_t Offset_Get() const
392  {
393  return (Buffer_Size_Init-Buffer_Size)/8;
394  }
395 
396  inline size_t BitOffset_Get() const
397  {
398  return Buffer_Size%8;
399  }
400 
401  inline size_t OffsetBeforeLastCall_Get() const //No more valid
402  {
403  return Buffer_Size%8;
404  }
405 
406 private :
407  const int8u* Buffer;
408  size_t Buffer_Size;
409  size_t Buffer_Size_Init;
410  int8u LastByte;
411 public :
413 };
414 
415 } //namespace ZenLib
416 #endif
ZenLib::BitStream_Fast::Attach
void Attach(const int8u *Buffer_, size_t Size_)
Definition: BitStream_Fast.h:41
ZenLib::BitStream_Fast::Peek4
int32u Peek4(int8u HowMany)
Definition: BitStream_Fast.h:323
ZenLib::BitStream_Fast::BitStream_Fast
BitStream_Fast()
Definition: BitStream_Fast.h:33
ZenLib::BitStream_Fast::OffsetBeforeLastCall_Get
size_t OffsetBeforeLastCall_Get() const
Definition: BitStream_Fast.h:401
ZenLib::BitStream_Fast::Offset_Get
size_t Offset_Get() const
Definition: BitStream_Fast.h:391
ZenLib::BitStream_Fast::Peek2
int16u Peek2(int8u HowMany)
Definition: BitStream_Fast.h:281
ZenLib::BitStream_Fast::Skip
void Skip(size_t HowMany)
Definition: BitStream_Fast.h:215
ZenLib::BitStream_Fast::Get8
int64u Get8(int8u HowMany)
Definition: BitStream_Fast.h:197
ZenLib::BitStream_Fast::Peek1
int8u Peek1(int8u HowMany)
Definition: BitStream_Fast.h:251
ZenLib::BitStream_Fast::PeekB
bool PeekB()
Definition: BitStream_Fast.h:236
ZenLib::BitStream_Fast::GetB
bool GetB()
Definition: BitStream_Fast.h:48
ZenLib::BitStream_Fast::BufferUnderRun
bool BufferUnderRun
Definition: BitStream_Fast.h:412
ZenLib::BitStream_Fast::Get4
int32u Get4(int8u HowMany)
Definition: BitStream_Fast.h:147
ZenLib::BitStream_Fast::~BitStream_Fast
~BitStream_Fast()
Definition: BitStream_Fast.h:39
ZenLib::BitStream_Fast::Peek8
int64u Peek8(int8u HowMany)
Definition: BitStream_Fast.h:376
ZenLib::BitStream_Fast::Remain
size_t Remain() const
Definition: BitStream_Fast.h:381
ZenLib::BitStream_Fast::BitStream_Fast
BitStream_Fast(const int8u *Buffer_, size_t Size_)
Definition: BitStream_Fast.h:36
ZenLib::BitStream_Fast::Byte_Align
void Byte_Align()
Definition: BitStream_Fast.h:386
ZenLib::BitStream_Fast::Get2
int16u Get2(int8u HowMany)
Definition: BitStream_Fast.h:104
ZenLib::BitStream_Fast::Get1
int8u Get1(int8u HowMany)
Definition: BitStream_Fast.h:69
Conf.h
ZenLib
Definition: BitStream.h:24
ZenLib::BitStream_Fast::BitOffset_Get
size_t BitOffset_Get() const
Definition: BitStream_Fast.h:396
NULL
#define NULL
Definition: HTTPClientWrapper.h:97
ZenLib::BitStream_Fast
Definition: BitStream_Fast.h:31