ZenLib

BitStream_LE.h

Go to the documentation of this file.
00001 // ZenLib::BitStream_LE - Read bit per bit, Little Endian version
00002 // Copyright (C) 2007-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, Little Endian version (rarely used!!!)
00024 // Can read up to 32 bits at once
00025 //
00026 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00027 
00028 //---------------------------------------------------------------------------
00029 #ifndef ZenBitStream_LEH
00030 #define ZenBitStream_LEH
00031 //---------------------------------------------------------------------------
00032 
00033 //---------------------------------------------------------------------------
00034 #include "ZenLib/BitStream.h"
00035 //---------------------------------------------------------------------------
00036 
00037 namespace ZenLib
00038 {
00039 
00040 class BitStream_LE : public BitStream
00041 {
00042 public:
00043     BitStream_LE ()                                                             :BitStream() {};
00044     BitStream_LE (const int8u* Buffer_, size_t Size_)                           :BitStream(Buffer_, Size_) {};
00045 
00046     void Attach(const int8u* Buffer_, size_t Size_)
00047     {
00048         endbyte=0;
00049         endbit=0;
00050         buffer=Buffer_;
00051         ptr=Buffer_;
00052         storage=(long)Size_;
00053     };
00054 
00055     int32u Get (size_t HowMany)
00056     {
00057         ptr_BeforeLastCall=ptr;
00058 
00059         long ret;
00060         static const int32u Mask[33]={
00061           0x00000000,
00062           0x00000001, 0x00000003, 0x00000007, 0x0000000f,
00063           0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
00064           0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
00065           0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
00066           0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
00067           0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
00068           0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
00069           0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
00070         };
00071         unsigned long m=Mask[HowMany];
00072 
00073         HowMany+=endbit;
00074 
00075         if(endbyte+4>=storage){
00076             ret=-1L;
00077             if(endbyte*8+(long)HowMany>storage*8){
00078                 Attach(NULL, 0);
00079                 goto overflow;
00080             }
00081         }
00082 
00083         ret=ptr[0]>>endbit;
00084         if(HowMany>8){
00085         ret|=ptr[1]<<(8-endbit);
00086         if(HowMany>16){
00087           ret|=ptr[2]<<(16-endbit);
00088           if(HowMany>24){
00089         ret|=ptr[3]<<(24-endbit);
00090         if(HowMany>32 && endbit){
00091           ret|=ptr[4]<<(32-endbit);
00092         }
00093           }
00094         }
00095         }
00096         ret&=m;
00097 
00098         ptr+=HowMany/8;
00099         endbyte+=(long)HowMany/8;
00100         endbit=(long)HowMany&7;
00101 
00102         overflow:
00103 
00104         return(ret);
00105     };
00106 
00107     void Skip(size_t bits)
00108     {
00109         Get(bits);
00110     }
00111 
00112     int32u Remain () //How many bits remain?
00113     {
00114         return storage*8-(endbyte*8+endbit);
00115     };
00116 
00117     void Byte_Align()
00118     {
00119     };
00120 
00121     size_t Offset_Get()
00122     {
00123         return ptr-buffer;
00124     };
00125 
00126     size_t BitOffset_Get()
00127     {
00128         return endbit;
00129     };
00130 
00131     size_t OffsetBeforeLastCall_Get()
00132     {
00133         return ptr_BeforeLastCall-buffer;
00134     };
00135 
00136 private :
00137     long endbyte;
00138     int  endbit;
00139 
00140     const unsigned char *buffer;
00141     const unsigned char *ptr;
00142     const unsigned char *ptr_BeforeLastCall;
00143     long storage;
00144 };
00145 
00146 } //namespace ZenLib
00147 #endif