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 ZenBitStreamH
16 #define ZenBitStreamH
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
31 {
32 public:
BitStream()33     BitStream ()                                                                {Buffer=NULL;
34                                                                                  Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=0;
35                                                                                  LastByte_Size=0;
36                                                                                  BufferUnderRun=true;
37                                                                                  BookMark=false;}
BitStream(const int8u * Buffer_,size_t Size_)38     BitStream (const int8u* Buffer_, size_t Size_)                              {Buffer=Buffer_;
39                                                                                  Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
40                                                                                  LastByte_Size=0;
41                                                                                  BufferUnderRun=Buffer_Size?false:true;
42                                                                                  BookMark=false;}
~BitStream()43     virtual ~BitStream ()                                                       {};
44 
Attach(const int8u * Buffer_,size_t Size_)45     virtual void Attach(const int8u* Buffer_, size_t Size_)
46     {
47         if (Buffer_==Buffer)
48             return; //Nothing to do
49         Buffer=Buffer_;
50         Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits
51         LastByte_Size=0;
52         BufferUnderRun=Buffer_Size?false:true;
53         BookMark=false;
54     };
55 
Get(size_t HowMany)56     virtual int32u Get (size_t HowMany)
57     {
58         size_t ToReturn;
59         static const int32u Mask[33]={
60           0x00000000,
61           0x00000001, 0x00000003, 0x00000007, 0x0000000f,
62           0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
63           0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
64           0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
65           0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
66           0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
67           0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
68           0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
69         };
70 
71         if (HowMany==0 || HowMany>32)
72             return 0;
73         if ((size_t)HowMany>Buffer_Size+LastByte_Size)
74         {
75             Buffer_Size=0;
76             LastByte_Size=0;
77             BufferUnderRun=true;
78             return 0;
79         }
80 
81         Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
82 
83         if (HowMany<=LastByte_Size)
84         {
85             LastByte_Size-=HowMany;
86             ToReturn=LastByte>>LastByte_Size;
87         }
88         else
89         {
90             size_t NewBits=HowMany-LastByte_Size;
91             if (NewBits==32)
92                 ToReturn=0;
93             else
94                 ToReturn=LastByte<<NewBits;
95             switch ((NewBits-1)/8)
96             {
97                 case 3 :    NewBits-=8;
98                             ToReturn |= ((size_t)*Buffer) << NewBits;
99                             Buffer++;
100                             Buffer_Size-=8;
101                 case 2 :    NewBits-=8;
102                             ToReturn |= ((size_t)*Buffer) << NewBits;
103                             Buffer++;
104                             Buffer_Size-=8;
105                 case 1 :    NewBits-=8;
106                             ToReturn |= ((size_t)*Buffer) << NewBits;
107                             Buffer++;
108                             Buffer_Size-=8;
109                 case 0 :
110                             LastByte=*Buffer;
111                             Buffer++;
112             }
113             LastByte_Size=MIN(8, Buffer_Size)-NewBits;
114             Buffer_Size -=MIN(8, Buffer_Size);
115             ToReturn|=(LastByte>>LastByte_Size)&Mask[NewBits];
116         }
117         return (int32u)(ToReturn&Mask[HowMany]);
118     };
119 
GetB()120     bool  GetB ()
121     {
122         return Get(1)?true:false;
123     }
124 
Get1(size_t HowMany)125     int8u  Get1 (size_t HowMany)
126     {
127         return (int8u )Get(HowMany);
128     }
129 
Get2(size_t HowMany)130     int16u Get2 (size_t HowMany)
131     {
132         return (int16u)Get(HowMany);
133     }
134 
Get4(size_t HowMany)135     int32u Get4 (size_t HowMany)
136     {
137         return (int32u)Get(HowMany);
138     }
139 
Get8(size_t HowMany)140     int64u Get8 (size_t HowMany)
141     {
142         if (HowMany>64)
143             return 0; //Not supported
144         size_t HowMany1, HowMany2;
145         int64u Value1, Value2;
146         if (HowMany>32)
147             HowMany1=HowMany-32;
148         else
149             HowMany1=0;
150         HowMany2=HowMany-HowMany1;
151         Value1=Get(HowMany1);
152         Value2=Get(HowMany2);
153         if (BufferUnderRun)
154             return 0;
155         return Value1*0x100000000LL+Value2;
156     }
157 
Skip(size_t HowMany)158     virtual void Skip (size_t HowMany)
159     {
160         if (HowMany==0)
161             return;
162         if (HowMany>32) //Algorithm is only for <=32 bits
163         {
164             do
165             {
166                 Skip(32);
167                 HowMany-=32;
168             }
169             while(HowMany>32);
170             if (HowMany)
171                 Skip(HowMany);
172             return;
173         }
174         if ((size_t)HowMany>Buffer_Size+LastByte_Size)
175         {
176             Buffer_Size=0;
177             LastByte_Size=0;
178             BufferUnderRun=true;
179             return;
180         }
181 
182         Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
183 
184         if (HowMany<=LastByte_Size)
185             LastByte_Size-=HowMany;
186         else
187         {
188             size_t NewBits=HowMany-LastByte_Size;
189             switch ((NewBits-1)/8)
190             {
191                 case 3 :    NewBits-=8;
192                             Buffer++;
193                             Buffer_Size-=8;
194                 case 2 :    NewBits-=8;
195                             Buffer++;
196                             Buffer_Size-=8;
197                 case 1 :    NewBits-=8;
198                             Buffer++;
199                             Buffer_Size-=8;
200                 case 0 :
201                             LastByte=*Buffer;
202                             Buffer++;
203             }
204             LastByte_Size=MIN(8, Buffer_Size)-NewBits;
205             Buffer_Size -=MIN(8, Buffer_Size);
206         }
207     };
208 
SkipB()209     void SkipB ()
210     {
211         Skip(1);
212     }
213 
Skip1(size_t HowMany)214     void Skip1 (size_t HowMany)
215     {
216         Skip(HowMany);
217     }
218 
Skip2(size_t HowMany)219     void Skip2 (size_t HowMany)
220     {
221         Skip(HowMany);
222     }
223 
Skip4(size_t HowMany)224     void Skip4 (size_t HowMany)
225     {
226         Skip(HowMany);
227     }
228 
Skip8(size_t HowMany)229     void Skip8 (size_t HowMany)
230     {
231         if (HowMany>64)
232             return; //Not supported
233         size_t HowMany1, HowMany2;
234         if (HowMany>32)
235             HowMany1=HowMany-32;
236         else
237             HowMany1=0;
238         HowMany2=HowMany-HowMany1;
239         Skip(HowMany1);
240         Skip(HowMany2);
241     }
242 
Peek(size_t HowMany)243     int32u Peek(size_t HowMany)
244     {
245         BookMarkPos(true);
246         int32u ToReturn=Get(HowMany);
247         BookMarkPos(false);
248         return ToReturn;
249     }
250 
PeekB()251     bool   PeekB()
252     {
253         return Peek(1)?true:false;
254     }
255 
Peek1(size_t HowMany)256     int8u  Peek1(size_t HowMany)
257     {
258         return (int8u )Peek(HowMany);
259     }
260 
Peek2(size_t HowMany)261     int16u Peek2(size_t HowMany)
262     {
263         return (int16u)Peek(HowMany);
264     }
265 
Peek4(size_t HowMany)266     int32u Peek4(size_t HowMany)
267     {
268         return (int32u)Peek(HowMany);
269     }
270 
Peek3(size_t HowMany)271     int32u Peek3(size_t HowMany)
272     {
273         return (int32u)Peek(HowMany);
274     }
275 
Peek8(size_t HowMany)276     int64u Peek8(size_t HowMany)
277     {
278         return (int64u)Peek(HowMany);
279     }
280 
BookMarkPos(bool ToSet)281     void BookMarkPos(bool ToSet)
282     {
283         if (ToSet)
284         {
285             BookMark=1;
286             Buffer_BookMark=Buffer;
287             Buffer_Size_BookMark=Buffer_Size;
288             LastByte_BookMark=LastByte;
289             LastByte_Size_BookMark=LastByte_Size;
290             BufferUnderRun_BookMark=BufferUnderRun;
291         }
292         else
293         {
294             BookMark=0;
295             Buffer=Buffer_BookMark;
296             Buffer_Size=Buffer_Size_BookMark;
297             LastByte=LastByte_BookMark;
298             LastByte_Size=LastByte_Size_BookMark;
299             BufferUnderRun=BufferUnderRun_BookMark;
300         }
301     };
302 
Remain()303     virtual int32u Remain () //How many bits remain?
304     {
305         return (int32u)(Buffer_Size+LastByte_Size);
306     };
307 
Byte_Align()308     virtual void Byte_Align()
309     {
310         Get(LastByte_Size);
311     };
312 
Offset_Get()313     virtual size_t Offset_Get()
314     {
315         if (BufferUnderRun)
316             return 0;
317         return (Buffer_Size_Init-Buffer_Size)/8;
318     };
319 
BitOffset_Get()320     virtual size_t BitOffset_Get()
321     {
322         if (BufferUnderRun)
323             return 0;
324         return LastByte_Size;
325     };
326 
OffsetBeforeLastCall_Get()327     virtual size_t OffsetBeforeLastCall_Get()
328     {
329         if (BufferUnderRun)
330             return 0;
331         return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8;
332     };
333 
334 private :
335     const int8u*    Buffer;
336     size_t          Buffer_Size;
337     size_t          Buffer_Size_Init;
338     size_t          Buffer_Size_BeforeLastCall;
339     size_t          LastByte;
340     size_t          LastByte_Size;
341     bool            BufferUnderRun;
342 
343     bool            BookMark;
344     const int8u*    Buffer_BookMark;
345     size_t          Buffer_Size_BookMark;
346     size_t          LastByte_BookMark;
347     size_t          LastByte_Size_BookMark;
348     bool            BufferUnderRun_BookMark;
349 };
350 
351 } //namespace ZenLib
352 #endif
353