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