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

BitStream.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 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 |= ((size_t)*Buffer) << NewBits;
00099                             Buffer++;
00100                             Buffer_Size-=8;
00101                 case 2 :    NewBits-=8;
00102                             ToReturn |= ((size_t)*Buffer) << NewBits;
00103                             Buffer++;
00104                             Buffer_Size-=8;
00105                 case 1 :    NewBits-=8;
00106                             ToReturn |= ((size_t)*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

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