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