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