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