ZenLib
|
00001 // ZenLib::bitStream - Read bit per bit 00002 // Copyright (C) 2006-2011 MediaArea.net SARL, Info@MediaArea.net 00003 // 00004 // This software is provided 'as-is', without any express or implied 00005 // warranty. In no event will the authors be held liable for any damages 00006 // arising from the use of this software. 00007 // 00008 // Permission is granted to anyone to use this software for any purpose, 00009 // including commercial applications, and to alter it and redistribute it 00010 // freely, subject to the following restrictions: 00011 // 00012 // 1. The origin of this software must not be misrepresented; you must not 00013 // claim that you wrote the original software. If you use this software 00014 // in a product, an acknowledgment in the product documentation would be 00015 // appreciated but is not required. 00016 // 2. Altered source versions must be plainly marked as such, and must not be 00017 // misrepresented as being the original software. 00018 // 3. This notice may not be removed or altered from any source distribution. 00019 // 00020 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00021 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00022 // 00023 // Read a stream bit per bit 00024 // Can read up to 32 bits at once 00025 // 00026 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00027 00028 //--------------------------------------------------------------------------- 00029 #ifndef ZenBitStreamH 00030 #define ZenBitStreamH 00031 //--------------------------------------------------------------------------- 00032 00033 //--------------------------------------------------------------------------- 00034 #include "ZenLib/Conf.h" 00035 //--------------------------------------------------------------------------- 00036 00037 namespace ZenLib 00038 { 00039 00040 #ifndef MIN 00041 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 00042 #endif 00043 00044 class BitStream 00045 { 00046 public: 00047 BitStream () {Buffer=NULL; 00048 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=0; 00049 LastByte_Size=0; 00050 BufferUnderRun=true; 00051 BookMark=false;} 00052 BitStream (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_; 00053 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits 00054 LastByte_Size=0; 00055 BufferUnderRun=Buffer_Size?false:true; 00056 BookMark=false;} 00057 virtual ~BitStream () {}; 00058 00059 virtual void Attach(const int8u* Buffer_, size_t Size_) 00060 { 00061 if (Buffer_==Buffer) 00062 return; //Nothing to do 00063 Buffer=Buffer_; 00064 Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits 00065 LastByte_Size=0; 00066 BufferUnderRun=Buffer_Size?false:true; 00067 BookMark=false; 00068 }; 00069 00070 virtual int32u Get (size_t HowMany) 00071 { 00072 size_t ToReturn; 00073 static const int32u Mask[33]={ 00074 0x00000000, 00075 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 00076 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 00077 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 00078 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 00079 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 00080 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 00081 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 00082 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, 00083 }; 00084 00085 if (HowMany==0 || HowMany>32) 00086 return 0; 00087 if ((size_t)HowMany>Buffer_Size+LastByte_Size) 00088 { 00089 Buffer_Size=0; 00090 LastByte_Size=0; 00091 BufferUnderRun=true; 00092 return 0; 00093 } 00094 00095 Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size; 00096 00097 if (HowMany<=LastByte_Size) 00098 { 00099 LastByte_Size-=HowMany; 00100 ToReturn=LastByte>>LastByte_Size; 00101 } 00102 else 00103 { 00104 size_t NewBits=HowMany-LastByte_Size; 00105 if (NewBits==32) 00106 ToReturn=0; 00107 else 00108 ToReturn=LastByte<<NewBits; 00109 switch ((NewBits-1)/8) 00110 { 00111 case 3 : NewBits-=8; 00112 ToReturn|=*Buffer<<NewBits; 00113 Buffer++; 00114 Buffer_Size-=8; 00115 case 2 : NewBits-=8; 00116 ToReturn|=*Buffer<<NewBits; 00117 Buffer++; 00118 Buffer_Size-=8; 00119 case 1 : NewBits-=8; 00120 ToReturn|=*Buffer<<NewBits; 00121 Buffer++; 00122 Buffer_Size-=8; 00123 case 0 : 00124 LastByte=*Buffer; 00125 Buffer++; 00126 } 00127 LastByte_Size=MIN(8, Buffer_Size)-NewBits; 00128 Buffer_Size -=MIN(8, Buffer_Size); 00129 ToReturn|=(LastByte>>LastByte_Size)&Mask[NewBits]; 00130 } 00131 return (int32u)(ToReturn&Mask[HowMany]); 00132 }; 00133 00134 bool GetB () 00135 { 00136 return Get(1)?true:false; 00137 } 00138 00139 int8u Get1 (size_t HowMany) 00140 { 00141 return (int8u )Get(HowMany); 00142 } 00143 00144 int16u Get2 (size_t HowMany) 00145 { 00146 return (int16u)Get(HowMany); 00147 } 00148 00149 int32u Get4 (size_t HowMany) 00150 { 00151 return (int32u)Get(HowMany); 00152 } 00153 00154 int64u Get8 (size_t HowMany) 00155 { 00156 if (HowMany>64) 00157 return 0; //Not supported 00158 size_t HowMany1, HowMany2; 00159 int64u Value1, Value2; 00160 if (HowMany>32) 00161 HowMany1=HowMany-32; 00162 else 00163 HowMany1=0; 00164 HowMany2=HowMany-HowMany1; 00165 Value1=Get(HowMany1); 00166 Value2=Get(HowMany2); 00167 if (BufferUnderRun) 00168 return 0; 00169 return Value1*0x100000000LL+Value2; 00170 } 00171 00172 virtual void Skip (size_t HowMany) 00173 { 00174 if (HowMany==0) 00175 return; 00176 if (HowMany>32) //Algorithm is only for <=32 bits 00177 { 00178 do 00179 { 00180 Skip(32); 00181 HowMany-=32; 00182 } 00183 while(HowMany>32); 00184 if (HowMany) 00185 Skip(HowMany); 00186 return; 00187 } 00188 if ((size_t)HowMany>Buffer_Size+LastByte_Size) 00189 { 00190 Buffer_Size=0; 00191 LastByte_Size=0; 00192 BufferUnderRun=true; 00193 return; 00194 } 00195 00196 Buffer_Size_BeforeLastCall=Buffer_Size+LastByte_Size; 00197 00198 if (HowMany<=LastByte_Size) 00199 LastByte_Size-=HowMany; 00200 else 00201 { 00202 size_t NewBits=HowMany-LastByte_Size; 00203 switch ((NewBits-1)/8) 00204 { 00205 case 3 : NewBits-=8; 00206 Buffer++; 00207 Buffer_Size-=8; 00208 case 2 : NewBits-=8; 00209 Buffer++; 00210 Buffer_Size-=8; 00211 case 1 : NewBits-=8; 00212 Buffer++; 00213 Buffer_Size-=8; 00214 case 0 : 00215 LastByte=*Buffer; 00216 Buffer++; 00217 } 00218 LastByte_Size=MIN(8, Buffer_Size)-NewBits; 00219 Buffer_Size -=MIN(8, Buffer_Size); 00220 } 00221 }; 00222 00223 void SkipB () 00224 { 00225 Skip(1); 00226 } 00227 00228 void Skip1 (size_t HowMany) 00229 { 00230 Skip(HowMany); 00231 } 00232 00233 void Skip2 (size_t HowMany) 00234 { 00235 Skip(HowMany); 00236 } 00237 00238 void Skip4 (size_t HowMany) 00239 { 00240 Skip(HowMany); 00241 } 00242 00243 void Skip8 (size_t HowMany) 00244 { 00245 if (HowMany>64) 00246 return; //Not supported 00247 size_t HowMany1, HowMany2; 00248 if (HowMany>32) 00249 HowMany1=HowMany-32; 00250 else 00251 HowMany1=0; 00252 HowMany2=HowMany-HowMany1; 00253 Skip(HowMany1); 00254 Skip(HowMany2); 00255 } 00256 00257 int32u Peek(size_t HowMany) 00258 { 00259 BookMarkPos(true); 00260 int32u ToReturn=Get(HowMany); 00261 BookMarkPos(false); 00262 return ToReturn; 00263 } 00264 00265 bool PeekB() 00266 { 00267 return Peek(1)?true:false; 00268 } 00269 00270 int8u Peek1(size_t HowMany) 00271 { 00272 return (int8u )Peek(HowMany); 00273 } 00274 00275 int16u Peek2(size_t HowMany) 00276 { 00277 return (int16u)Peek(HowMany); 00278 } 00279 00280 int32u Peek4(size_t HowMany) 00281 { 00282 return (int32u)Peek(HowMany); 00283 } 00284 00285 int32u Peek3(size_t HowMany) 00286 { 00287 return (int32u)Peek(HowMany); 00288 } 00289 00290 int64u Peek8(size_t HowMany) 00291 { 00292 return (int64u)Peek(HowMany); 00293 } 00294 00295 void BookMarkPos(bool ToSet) 00296 { 00297 if (ToSet) 00298 { 00299 BookMark=1; 00300 Buffer_BookMark=Buffer; 00301 Buffer_Size_BookMark=Buffer_Size; 00302 LastByte_BookMark=LastByte; 00303 LastByte_Size_BookMark=LastByte_Size; 00304 BufferUnderRun_BookMark=BufferUnderRun; 00305 } 00306 else 00307 { 00308 BookMark=0; 00309 Buffer=Buffer_BookMark; 00310 Buffer_Size=Buffer_Size_BookMark; 00311 LastByte=LastByte_BookMark; 00312 LastByte_Size=LastByte_Size_BookMark; 00313 BufferUnderRun=BufferUnderRun_BookMark; 00314 } 00315 }; 00316 00317 virtual int32u Remain () //How many bits remain? 00318 { 00319 return (int32u)(Buffer_Size+LastByte_Size); 00320 }; 00321 00322 virtual void Byte_Align() 00323 { 00324 Get(LastByte_Size); 00325 }; 00326 00327 virtual size_t Offset_Get() 00328 { 00329 if (BufferUnderRun) 00330 return 0; 00331 return (Buffer_Size_Init-Buffer_Size)/8; 00332 }; 00333 00334 virtual size_t BitOffset_Get() 00335 { 00336 if (BufferUnderRun) 00337 return 0; 00338 return LastByte_Size; 00339 }; 00340 00341 virtual size_t OffsetBeforeLastCall_Get() 00342 { 00343 if (BufferUnderRun) 00344 return 0; 00345 return (Buffer_Size_Init-Buffer_Size_BeforeLastCall)/8; 00346 }; 00347 00348 private : 00349 const int8u* Buffer; 00350 size_t Buffer_Size; 00351 size_t Buffer_Size_Init; 00352 size_t Buffer_Size_BeforeLastCall; 00353 size_t LastByte; 00354 size_t LastByte_Size; 00355 bool BufferUnderRun; 00356 00357 bool BookMark; 00358 const int8u* Buffer_BookMark; 00359 size_t Buffer_Size_BookMark; 00360 size_t LastByte_BookMark; 00361 size_t LastByte_Size_BookMark; 00362 bool BufferUnderRun_BookMark; 00363 }; 00364 00365 } //namespace ZenLib 00366 #endif