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

Generated on Sun Apr 8 21:22:59 2012 for ZenLib by  doxygen 1.4.7