BitStream_Fast.h

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

Generated on Mon May 28 17:35:42 2012 for ZenLib by  doxygen 1.4.7