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 if (BufferUnderRun)
187 return;
188 HowMany-=32;
189 }
190 while(HowMany>32);
191 if (HowMany)
192 Skip(HowMany);
193 return;
194 }
195 if ((size_t)HowMany>Buffer_Size+LastByte_Size)
196 {
197 Buffer_Size=0;
198 LastByte_Size=0;
199 BufferUnderRun=true;
200 return;
201 }
202
203 Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size;
204
205 if (HowMany<=LastByte_Size)
206 LastByte_Size-=HowMany;
207 else
208 {
209 size_t NewBits=HowMany-LastByte_Size;
210 switch ((NewBits-1)/8)
211 {
212 case 3 : NewBits-=8;
213 Buffer++;
214 Buffer_Size-=8;
215 [[fallthrough]];
216 case 2 : NewBits-=8;
217 Buffer++;
218 Buffer_Size-=8;
219 [[fallthrough]];
220 case 1 : NewBits-=8;
221 Buffer++;
222 Buffer_Size-=8;
223 [[fallthrough]];
224 case 0 :
225 LastByte=*Buffer;
226 Buffer++;
227 }
228 LastByte_Size=MIN(8, Buffer_Size)-NewBits;
229 Buffer_Size -=MIN(8, Buffer_Size);
230 }
231 };
232
233 void SkipB ()
234 {
235 Skip(1);
236 }
237
238 void Skip1 (size_t HowMany)
239 {
240 Skip(HowMany);
241 }
242
243 void Skip2 (size_t HowMany)
244 {
245 Skip(HowMany);
246 }
247
248 void Skip4 (size_t HowMany)
249 {
250 Skip(HowMany);
251 }
252
253 void Skip8 (size_t HowMany)
254 {
255 if (HowMany>64)
256 return; //Not supported
257 size_t HowMany1, HowMany2;
258 if (HowMany>32)
259 HowMany1=HowMany-32;
260 else
261 HowMany1=0;
262 HowMany2=HowMany-HowMany1;
263 Skip(HowMany1);
264 Skip(HowMany2);
265 }
266
267 int32u Peek(size_t HowMany)
268 {
269 BookMarkPos(true);
270 int32u ToReturn=Get(HowMany);
271 BookMarkPos(false);
272 return ToReturn;
273 }
274
275 bool PeekB()
276 {
277 return Peek(1)?true:false;
278 }
279
280 int8u Peek1(size_t HowMany)
281 {
282 return (int8u )Peek(HowMany);
283 }
284
285 int16u Peek2(size_t HowMany)
286 {
287 return (int16u)Peek(HowMany);
288 }
289
290 int32u Peek4(size_t HowMany)
291 {
292 return (int32u)Peek(HowMany);
293 }
294
295 int32u Peek3(size_t HowMany)
296 {
297 return (int32u)Peek(HowMany);
298 }
299
300 int64u Peek8(size_t HowMany)
301 {
302 return (int64u)Peek(HowMany);
303 }
304
305 void BookMarkPos(bool ToSet)
306 {
307 if (ToSet)
308 {
309 BookMark=1;
310 Buffer_BookMark=Buffer;
311 Buffer_Size_BookMark=Buffer_Size;
312 LastByte_BookMark=LastByte;
313 LastByte_Size_BookMark=LastByte_Size;
314 BufferUnderRun_BookMark=BufferUnderRun;
315 }
316 else
317 {
318 BookMark=0;
319 Buffer=Buffer_BookMark;
320 Buffer_Size=Buffer_Size_BookMark;
321 LastByte=LastByte_BookMark;
322 LastByte_Size=LastByte_Size_BookMark;
323 BufferUnderRun=BufferUnderRun_BookMark;
324 }
325 };
326
327 virtual int32u Remain () //How many bits remain?
328 {
329 return (int32u)(Buffer_Size+LastByte_Size);
330 };
331
332 virtual void Byte_Align()
333 {
334 Get(LastByte_Size);
335 };
336
337 virtual size_t Offset_Get()
338 {
339 if (BufferUnderRun)
340 return 0;
341 return (Buffer_Size_Init-Buffer_Size)/8;
342 };
343
344 virtual size_t BitOffset_Get()
345 {
346 if (BufferUnderRun)
347 return 0;
348 return LastByte_Size;
349 };
350
352 {
353 if (BufferUnderRun)
354 return 0;
355 return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8;
356 };
357
358private :
359 const int8u* Buffer;
360 size_t Buffer_Size;
361 size_t Buffer_Size_Init;
362 size_t Buffer_Size_BeforeLastCall;
363 size_t LastByte;
364 size_t LastByte_Size;
365 bool BufferUnderRun;
366
367 bool BookMark;
368 const int8u* Buffer_BookMark;
369 size_t Buffer_Size_BookMark;
370 size_t LastByte_BookMark;
371 size_t LastByte_Size_BookMark;
372 bool BufferUnderRun_BookMark;
373};
374
375} //namespace ZenLib
376#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:267
void Skip8(size_t HowMany)
Definition BitStream.h:253
int64u Peek8(size_t HowMany)
Definition BitStream.h:300
void Skip1(size_t HowMany)
Definition BitStream.h:238
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:344
virtual void Byte_Align()
Definition BitStream.h:332
virtual int32u Remain()
Definition BitStream.h:327
int32u Peek3(size_t HowMany)
Definition BitStream.h:295
int8u Get1(size_t HowMany)
Definition BitStream.h:144
virtual size_t OffsetBeforeLastCall_Get()
Definition BitStream.h:351
void SkipB()
Definition BitStream.h:233
int16u Get2(size_t HowMany)
Definition BitStream.h:149
int32u Peek4(size_t HowMany)
Definition BitStream.h:290
bool GetB()
Definition BitStream.h:139
bool PeekB()
Definition BitStream.h:275
virtual int32u Get(size_t HowMany)
Definition BitStream.h:72
void Skip2(size_t HowMany)
Definition BitStream.h:243
int16u Peek2(size_t HowMany)
Definition BitStream.h:285
virtual size_t Offset_Get()
Definition BitStream.h:337
BitStream()
Definition BitStream.h:33
int8u Peek1(size_t HowMany)
Definition BitStream.h:280
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:305
BitStream(const int8u *Buffer_, size_t Size_)
Definition BitStream.h:46
void Skip4(size_t HowMany)
Definition BitStream.h:248
virtual ~BitStream()
Definition BitStream.h:59
Definition BitStream.h:24