• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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                         Buffer++;
00186             case 2 :    NewBits-=8;
00187                         ToReturn|=*Buffer<<NewBits;
00188                         Buffer++;
00189             case 1 :    NewBits-=8;
00190                         ToReturn|=*Buffer<<NewBits;
00191                         Buffer++;
00192             default:    ;
00193         }
00194         LastByte=*Buffer;
00195         Buffer++;
00196         Buffer_Size-=HowMany;
00197         ToReturn|=(LastByte>>(Buffer_Size%8))&Mask[NewBits];
00198         return ToReturn&Mask[HowMany];
00199     }
00200 
00201     int64u Get8 (int8u HowMany)
00202     {
00203         if (HowMany>64)
00204             return 0; //Not supported
00205         int8u HowMany1, HowMany2;
00206         int64u Value1, Value2;
00207         if (HowMany>32)
00208             HowMany1=HowMany-32;
00209         else
00210             HowMany1=0;
00211         HowMany2=HowMany-HowMany1;
00212         Value1=Get4(HowMany1);
00213         Value2=Get4(HowMany2);
00214         if (BufferUnderRun)
00215             return 0;
00216         return Value1*0x100000000LL+Value2;
00217     }
00218 
00219     void Skip (size_t HowMany)
00220     {
00221         if (HowMany<=(Buffer_Size%8))
00222         {
00223             Buffer_Size-=HowMany;
00224             return;
00225         }
00226 
00227         if (HowMany>Buffer_Size)
00228         {
00229             Buffer_Size=0;
00230             BufferUnderRun=true;
00231             return;
00232         }
00233 
00234         Buffer+=(HowMany-(Buffer_Size%8)-1)>>3;
00235         LastByte=*Buffer;
00236         Buffer++;
00237         Buffer_Size-=HowMany;
00238     }
00239 
00240     bool   PeekB()
00241     {
00242         if (Buffer_Size%8)
00243             return ((LastByte>>((Buffer_Size-1)%8))&0x1)?true:false;
00244 
00245         if (!Buffer_Size)
00246         {
00247             Buffer_Size=0;
00248             BufferUnderRun=true;
00249             return false;
00250         }
00251 
00252         return ((*Buffer)&0x80)?true:false;
00253     }
00254 
00255     int8u  Peek1(int8u HowMany)
00256     {
00257         int8u ToReturn;
00258         static const int8u Mask[9]=
00259         {
00260             0x00,
00261             0x01, 0x03, 0x07, 0x0f,
00262             0x1f, 0x3f, 0x7f, 0xff,
00263         };
00264 
00265         if (HowMany<=(Buffer_Size%8))
00266             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00267 
00268         if (HowMany>Buffer_Size)
00269         {
00270             Buffer_Size=0;
00271             BufferUnderRun=true;
00272             return 0;
00273         }
00274 
00275         int8u NewBits=HowMany-(Buffer_Size%8);
00276         if (NewBits==8)
00277             ToReturn=0;
00278         else
00279             ToReturn=LastByte<<NewBits;
00280         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00281 
00282         return ToReturn&Mask[HowMany];
00283     }
00284 
00285     int16u Peek2(int8u HowMany)
00286     {
00287         int16u ToReturn;
00288         static const int16u Mask[17]=
00289         {
00290             0x0000,
00291             0x0001, 0x0003, 0x0007, 0x000f,
00292             0x001f, 0x003f, 0x007f, 0x00ff,
00293             0x01ff, 0x03ff, 0x07ff, 0x0fff,
00294             0x1fff, 0x3fff, 0x7fff, 0xffff,
00295         };
00296 
00297         if (HowMany<=(Buffer_Size%8))
00298             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00299 
00300         if (HowMany>Buffer_Size)
00301         {
00302             Buffer_Size=0;
00303             BufferUnderRun=true;
00304             return 0;
00305         }
00306 
00307         const int8u* Buffer_Save=Buffer;
00308 
00309         int8u NewBits=HowMany-(Buffer_Size%8);
00310         if (NewBits==16)
00311             ToReturn=0;
00312         else
00313             ToReturn=LastByte<<NewBits;
00314         if ((NewBits-1)>>3)
00315         {
00316             NewBits-=8;
00317             ToReturn|=*Buffer<<NewBits;
00318             Buffer++;
00319         }
00320         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00321 
00322         Buffer=Buffer_Save;
00323 
00324         return ToReturn&Mask[HowMany];
00325     }
00326 
00327     int32u Peek4(int8u HowMany)
00328     {
00329         int32u ToReturn;
00330         static const int32u Mask[33]=
00331         {
00332             0x00000000,
00333             0x00000001, 0x00000003, 0x00000007, 0x0000000f,
00334             0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
00335             0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
00336             0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
00337             0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
00338             0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
00339             0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
00340             0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
00341         };
00342 
00343         if (HowMany<=(Buffer_Size%8))
00344             return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany];
00345 
00346         if (HowMany>Buffer_Size)
00347         {
00348             Buffer_Size=0;
00349             BufferUnderRun=true;
00350             return 0;
00351         }
00352 
00353         const int8u* Buffer_Save=Buffer;
00354 
00355         int8u NewBits=HowMany-(Buffer_Size%8);
00356         if (NewBits==32)
00357             ToReturn=0;
00358         else
00359             ToReturn=LastByte<<NewBits;
00360         switch ((NewBits-1)>>3)
00361         {
00362             case 3 :    NewBits-=8;
00363                         ToReturn|=*Buffer<<NewBits;
00364                         Buffer++;
00365             case 2 :    NewBits-=8;
00366                         ToReturn|=*Buffer<<NewBits;
00367                         Buffer++;
00368             case 1 :    NewBits-=8;
00369                         ToReturn|=*Buffer<<NewBits;
00370                         Buffer++;
00371             default:    ;
00372         }
00373         ToReturn|=((*Buffer)>>((Buffer_Size-HowMany)%8))&Mask[NewBits];
00374 
00375         Buffer=Buffer_Save;
00376 
00377         return ToReturn&Mask[HowMany];
00378     }
00379 
00380     int64u Peek8(int8u HowMany)
00381     {
00382         return (int64u)Peek4(HowMany); //Not yet implemented
00383     }
00384 
00385     inline size_t Remain () const //How many bits remain?
00386     {
00387         return Buffer_Size;
00388     }
00389 
00390     inline void Byte_Align()
00391     {
00392         Skip (Buffer_Size%8);
00393     }
00394 
00395     inline size_t Offset_Get() const
00396     {
00397         return (Buffer_Size_Init-Buffer_Size)/8;
00398     }
00399 
00400     inline size_t BitOffset_Get() const
00401     {
00402         return Buffer_Size%8;
00403     }
00404 
00405     inline size_t OffsetBeforeLastCall_Get()  const //No more valid
00406     {
00407         return Buffer_Size%8;
00408     }
00409 
00410 private :
00411     const int8u*    Buffer;
00412     size_t          Buffer_Size;
00413     size_t          Buffer_Size_Init;
00414     int8u           LastByte;
00415 public :
00416     bool            BufferUnderRun;
00417 };
00418 
00419 } //namespace ZenLib
00420 #endif

Generated on Fri Mar 31 2017 00:17:47 for ZenLib by  doxygen 1.7.1