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 
30 class BitStream_Fast
31 {
32 public:
BitStream_Fast()33     BitStream_Fast ()                                                           {Buffer=NULL;
34                                                                                  Buffer_Size=Buffer_Size_Init=0;
35                                                                                  BufferUnderRun=false;}
BitStream_Fast(const int8u * Buffer_,size_t Size_)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;}
~BitStream_Fast()39     ~BitStream_Fast ()                                                          {}
40 
Attach(const int8u * Buffer_,size_t Size_)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 
GetB()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 
Get1(int8u HowMany)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 
Get2(int8u HowMany)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 
Get4(int8u HowMany)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 
Get8(int8u HowMany)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 
Skip(size_t HowMany)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 
PeekB()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 
Peek1(int8u HowMany)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 
Peek2(int8u HowMany)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 
Peek4(int8u HowMany)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 
Peek8(int8u HowMany)376     int64u Peek8(int8u HowMany)
377     {
378         return (int64u)Peek4(HowMany); //Not yet implemented
379     }
380 
Remain()381     inline size_t Remain () const //How many bits remain?
382     {
383         return Buffer_Size;
384     }
385 
Byte_Align()386     inline void Byte_Align()
387     {
388         Skip (Buffer_Size%8);
389     }
390 
Offset_Get()391     inline size_t Offset_Get() const
392     {
393         return (Buffer_Size_Init-Buffer_Size)/8;
394     }
395 
BitOffset_Get()396     inline size_t BitOffset_Get() const
397     {
398         return Buffer_Size%8;
399     }
400 
OffsetBeforeLastCall_Get()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 :
412     bool            BufferUnderRun;
413 };
414 
415 } //namespace ZenLib
416 #endif
417