ZenLib

BitStream_Fast.h

Go to the documentation of this file.
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 ZenBitStream_FastH
00016 #define ZenBitStream_FastH
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_Fast
00031 {
00032 public:
00033     BitStream_Fast ()                                                           {Buffer=NULL;
00034                                                                                  Buffer_Size=Buffer_Size_Init=0;
00035                                                                                  BufferUnderRun=false;}
00036     BitStream_Fast (const int8u* Buffer_, size_t Size_)                         {Buffer=Buffer_;
00037                                                                                  Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
00038                                                                                  BufferUnderRun=false;}
00039     ~BitStream_Fast ()                                                          {}
00040 
00041     void Attach(const int8u* Buffer_, size_t Size_)
00042     {
00043         Buffer=Buffer_;
00044         Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits
00045         BufferUnderRun=false;
00046     }
00047 
00048     bool  GetB ()
00049     {
00050         if (Buffer_Size%8)
00051         {
00052             Buffer_Size--;
00053             return ((LastByte>>(Buffer_Size%8))&0x1)?true:false;
00054         }
00055 
00056         if (!Buffer_Size)
00057         {
00058             Buffer_Size=0;
00059             BufferUnderRun=true;
00060             return false;
00061         }
00062 
00063         LastByte=*Buffer;
00064         Buffer++;
00065         Buffer_Size--;
00066         return (LastByte&0x80)?true:false;
00067     }
00068 
00069     int8u  Get1 (int8u HowMany)
00070     {
00071         int8u ToReturn;
00072         static const int8u Mask[9]=
00073         {
00074             0x00,
00075             0x01, 0x03, 0x07, 0x0f,
00076             0x1f, 0x3f, 0x7f, 0xff,
00077         };
00078 
00079         if (HowMany<=(Buffer_Size%8))
00080         {
00081             Buffer_Size-=HowMany;
00082             return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
00083         }
00084 
00085         if (HowMany>Buffer_Size)
00086         {
00087             Buffer_Size=0;
00088             BufferUnderRun=true;
00089             return 0;
00090         }
00091 
00092         int8u NewBits=HowMany-(Buffer_Size%8);
00093         if (NewBits==8)
00094             ToReturn=0;
00095         else
00096             ToReturn=LastByte<<NewBits;
00097         LastByte=*Buffer;
00098         Buffer++;
00099         Buffer_Size-=HowMany;
00100         ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
00101         return ToReturn&Mask[HowMany];
00102     }
00103 
00104     int16u Get2 (int8u HowMany)
00105     {
00106         int16u ToReturn;
00107         static const int16u Mask[17]=
00108         {
00109             0x0000,
00110             0x0001, 0x0003, 0x0007, 0x000f,
00111             0x001f, 0x003f, 0x007f, 0x00ff,
00112             0x01ff, 0x03ff, 0x07ff, 0x0fff,
00113             0x1fff, 0x3fff, 0x7fff, 0xffff,
00114         };
00115 
00116         if (HowMany<=(Buffer_Size%8))
00117         {
00118             Buffer_Size-=HowMany;
00119             return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
00120         }
00121 
00122         if (HowMany>Buffer_Size)
00123         {
00124             Buffer_Size=0;
00125             BufferUnderRun=true;
00126             return 0;
00127         }
00128 
00129         int8u NewBits=HowMany-(Buffer_Size%8);
00130         if (NewBits==16)
00131             ToReturn=0;
00132         else
00133             ToReturn=LastByte<<NewBits;
00134         if ((NewBits-1)>>3)
00135         {
00136             NewBits-=8;
00137             ToReturn|=*Buffer<<NewBits;
00138             Buffer++;
00139         }
00140         LastByte=*Buffer;
00141         Buffer++;
00142         Buffer_Size-=HowMany;
00143         ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
00144         return ToReturn&Mask[HowMany];
00145     }
00146 
00147     int32u Get4 (int8u HowMany)
00148     {
00149         int32u ToReturn;
00150         static const int32u Mask[33]=
00151         {
00152             0x00000000,
00153             0x00000001, 0x00000003, 0x00000007, 0x0000000f,
00154             0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
00155             0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
00156             0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
00157             0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
00158             0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
00159             0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
00160             0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
00161         };
00162 
00163         if (HowMany<=(Buffer_Size%8))
00164         {
00165             Buffer_Size-=HowMany;
00166             return (LastByte>>(Buffer_Size%8))&Mask[HowMany];
00167         }
00168 
00169         if (HowMany>Buffer_Size)
00170         {
00171             Buffer_Size=0;
00172             BufferUnderRun=true;
00173             return 0;
00174         }
00175 
00176         int8u NewBits=HowMany-(Buffer_Size%8);
00177         if (NewBits==32)
00178             ToReturn=0;
00179         else
00180             ToReturn=LastByte<<NewBits;
00181         switch ((NewBits-1)>>3)
00182         {
00183             case 3 :    NewBits-=8;
00184                         ToReturn|=*(Buffer++)<<NewBits;
00185             case 2 :    NewBits-=8;
00186                         ToReturn|=*(Buffer++)<<NewBits;
00187             case 1 :    NewBits-=8;
00188                         ToReturn|=*(Buffer++)<<NewBits;
00189             default:    ;
00190         }
00191         LastByte=*(Buffer++);
00192         Buffer_Size-=HowMany;
00193         ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
00194         return ToReturn&Mask[HowMany];
00195     }
00196 
00197     int64u Get8 (int8u HowMany)
00198     {
00199         if (HowMany>64)
00200             return 0; //Not supported
00201         int8u HowMany1, HowMany2;
00202         int64u Value1, Value2;
00203         if (HowMany>32)
00204             HowMany1=HowMany-32;
00205         else
00206             HowMany1=0;
00207         HowMany2=HowMany-HowMany1;
00208         Value1=Get4(HowMany1);
00209         Value2=Get4(HowMany2);
00210         if (BufferUnderRun)
00211             return 0;
00212         return Value1*0x100000000LL+Value2;
00213     }
00214 
00215     void Skip (size_t HowMany)
00216     {
00217         if (HowMany<=(Buffer_Size%8))
00218         {
00219             Buffer_Size-=HowMany;
00220             return;
00221         }
00222 
00223         if (HowMany>Buffer_Size)
00224         {
00225             Buffer_Size=0;
00226             BufferUnderRun=true;
00227             return;
00228         }
00229 
00230         Buffer+=(HowMany-(Buffer_Size%8)-1)>>3;
00231         LastByte=*Buffer;
00232         Buffer++;
00233         Buffer_Size-=HowMany;
00234     }
00235 
00236     bool   PeekB()
00237     {
00238         if (Buffer_Size%8)
00239             return ((LastByte>>((Buffer_Size-1)%8))&0x1)?true:false;
00240 
00241         if (!Buffer_Size)
00242         {
00243             Buffer_Size=0;
00244             BufferUnderRun=true;
00245             return false;
00246         }
00247 
00248         return ((*Buffer)&0x80)?true:false;
00249     }
00250 
00251     int8u  Peek1(int8u HowMany)
00252     {
00253         int8u ToReturn;
00254         static const int8u Mask[9]=
00255         {
00256             0x00,
00257             0x01, 0x03, 0x07, 0x0f,
00258             0x1f, 0x3f, 0x7f, 0xff,
00259         };
00260 
00261         if (HowMany<=(Buffer_Size%8))
00262             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00263 
00264         if (HowMany>Buffer_Size)
00265         {
00266             Buffer_Size=0;
00267             BufferUnderRun=true;
00268             return 0;
00269         }
00270 
00271         int8u NewBits=HowMany-(Buffer_Size%8);
00272         if (NewBits==8)
00273             ToReturn=0;
00274         else
00275             ToReturn=LastByte<<NewBits;
00276         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00277 
00278         return ToReturn&Mask[HowMany];
00279     }
00280 
00281     int16u Peek2(int8u HowMany)
00282     {
00283         int16u ToReturn;
00284         static const int16u Mask[17]=
00285         {
00286             0x0000,
00287             0x0001, 0x0003, 0x0007, 0x000f,
00288             0x001f, 0x003f, 0x007f, 0x00ff,
00289             0x01ff, 0x03ff, 0x07ff, 0x0fff,
00290             0x1fff, 0x3fff, 0x7fff, 0xffff,
00291         };
00292 
00293         if (HowMany<=(Buffer_Size%8))
00294             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00295 
00296         if (HowMany>Buffer_Size)
00297         {
00298             Buffer_Size=0;
00299             BufferUnderRun=true;
00300             return 0;
00301         }
00302 
00303         const int8u* Buffer_Save=Buffer;
00304 
00305         int8u NewBits=HowMany-(Buffer_Size%8);
00306         if (NewBits==16)
00307             ToReturn=0;
00308         else
00309             ToReturn=LastByte<<NewBits;
00310         if ((NewBits-1)>>3)
00311         {
00312             NewBits-=8;
00313             ToReturn|=*Buffer<<NewBits;
00314             Buffer++;
00315         }
00316         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00317 
00318         Buffer=Buffer_Save;
00319 
00320         return ToReturn&Mask[HowMany];
00321     }
00322 
00323     int32u Peek4(int8u HowMany)
00324     {
00325         int32u ToReturn;
00326         static const int32u Mask[33]=
00327         {
00328             0x00000000,
00329             0x00000001, 0x00000003, 0x00000007, 0x0000000f,
00330             0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
00331             0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
00332             0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
00333             0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
00334             0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
00335             0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
00336             0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
00337         };
00338 
00339         if (HowMany<=(Buffer_Size%8))
00340             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00341 
00342         if (HowMany>Buffer_Size)
00343         {
00344             Buffer_Size=0;
00345             BufferUnderRun=true;
00346             return 0;
00347         }
00348 
00349         const int8u* Buffer_Save=Buffer;
00350 
00351         int8u NewBits=HowMany-(Buffer_Size%8);
00352         if (NewBits==32)
00353             ToReturn=0;
00354         else
00355             ToReturn=LastByte<<NewBits;
00356         switch ((NewBits-1)>>3)
00357         {
00358             case 3 :    NewBits-=8;
00359                         ToReturn|=*Buffer<<NewBits;
00360                         Buffer++;
00361             case 2 :    NewBits-=8;
00362                         ToReturn|=*Buffer<<NewBits;
00363                         Buffer++;
00364             case 1 :    NewBits-=8;
00365                         ToReturn|=*Buffer<<NewBits;
00366                         Buffer++;
00367             default:    ;
00368         }
00369         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00370 
00371         Buffer=Buffer_Save;
00372 
00373         return ToReturn&Mask[HowMany];
00374     }
00375 
00376     int64u Peek8(int8u HowMany)
00377     {
00378         return (int64u)Peek4(HowMany); //Not yet implemented
00379     }
00380 
00381     inline size_t Remain () const //How many bits remain?
00382     {
00383         return Buffer_Size;
00384     }
00385 
00386     inline void Byte_Align()
00387     {
00388         Skip (Buffer_Size%8);
00389     }
00390 
00391     inline size_t Offset_Get() const
00392     {
00393         return (Buffer_Size_Init-Buffer_Size)/8;
00394     }
00395 
00396     inline size_t BitOffset_Get() const
00397     {
00398         return Buffer_Size%8;
00399     }
00400 
00401     inline size_t OffsetBeforeLastCall_Get()  const //No more valid
00402     {
00403         return Buffer_Size%8;
00404     }
00405 
00406 private :
00407     const int8u*    Buffer;
00408     size_t          Buffer_Size;
00409     size_t          Buffer_Size_Init;
00410     int8u           LastByte;
00411 public :
00412     bool            BufferUnderRun;
00413 };
00414 
00415 } //namespace ZenLib
00416 #endif