#pragma once #ifndef UTILITY_BITSTREAM_V1_H #define UTILITY_BITSTREAM_V1_H #define USING_BITSTREAM_VERSION (2) #if (USING_BITSTREAM_VERSION == 2) #include "./BitStream_v2.hpp" #elif (USING_BITSTREAM_VERSION == 1) #include "assert.h" #include #define BITS_TO_BYTES(x) (((x)+7)>>3) #define BYTES_TO_BITS(x) ((x)<<3) #define DEBUG_BIT_STREAM //#define DEBUG_BIT_STREAM_TEST class BitStream { public: BitStream( BYTE * p, WORD wNumberOfByte, BOOL TF) :m_pBuffer(p), m_BufferMaxSizeByte(wNumberOfByte), m_Offset(0) { if(TF) { memset(m_pBuffer,0, wNumberOfByte); #ifdef DEBUG_BIT_STREAM_TEST FileStream.open( "Temp\\WriteBit.txt", ios::out ); #endif } else { #ifdef DEBUG_BIT_STREAM_TEST FileStream.open( "Temp\\ReadBit.txt", ios::out ); #endif } } ~BitStream() { #ifdef DEBUG_BIT_STREAM_TEST FileStream.close(); #endif } public: void SetBuf( BYTE * p, WORD wNumberOfByte, BOOL TF) { m_Offset=0; m_pBuffer=p; m_BufferMaxSizeByte=wNumberOfByte; if(TF) memset(m_pBuffer,0, wNumberOfByte); } template __inline void Write( TYPE type, int NumberOfBits ) { if( NumberOfBits <= 0) return; Write(&type, NumberOfBits); } template __inline void Read( TYPE & type, int NumberOfBits ) { if( NumberOfBits <= 0) return; memset(&type, 0, sizeof(TYPE)); Read(&type, NumberOfBits); } template __inline void Write( TYPE * pvBuf, int NumberOfBits) { if( NumberOfBits <= 0 ) return; assert( m_Offset + NumberOfBits <= BYTES_TO_BITS(m_BufferMaxSizeByte) ); if(m_Offset + NumberOfBits > BYTES_TO_BITS(m_BufferMaxSizeByte) ) return; #ifdef DEBUG_BIT_STREAM_TEST FileStream << endl; FileStream << NumberOfBits << endl; #endif const BYTE* pBuffer = reinterpret_cast(pvBuf); //unit byte int i = 0; for(; i < (NumberOfBits >> 3); ++i) { WriteByte(*(pBuffer+i), 8); #ifdef DEBUG_BIT_STREAM_TEST FileStream << (DWORD)(*(pBuffer+i)) << ' '; #endif } //unit bit DWORD WriteBit = NumberOfBits % 8; if( WriteBit > 0) { #ifdef DEBUG_BIT_STREAM unsigned __int64 i64_Test = 1; ASSERT(*(pBuffer+i) < (i64_Test << WriteBit)); #endif WriteByte( (*(pBuffer+i)) << (8-WriteBit), WriteBit); #ifdef DEBUG_BIT_STREAM_TEST FileStream << (DWORD)(*(pBuffer+i)) << ' '; #endif } } template __inline void Read( TYPE * pvBuf, int NumberOfBits ) { if( NumberOfBits <= 0) return; // assert( m_Offset + NumberOfBits <= BYTES_TO_BITS(m_BufferMaxSizeByte) ); if(m_Offset + NumberOfBits > BYTES_TO_BITS(m_BufferMaxSizeByte) ) return; #ifdef DEBUG_BIT_STREAM_TEST FileStream << endl; FileStream << NumberOfBits << endl; #endif BYTE* pBuffer = reinterpret_cast(pvBuf); //unit byte int i = 0; for(; i < (NumberOfBits >> 3); ++i) { memset(pBuffer+i, 0, 1); ReadByte( pBuffer+i, 8, 0); #ifdef DEBUG_BIT_STREAM_TEST FileStream << (DWORD)(*(pBuffer+i)) << ' '; #endif } //unit bit DWORD ReadBit = NumberOfBits % 8; if( 0 != ReadBit ) { memset(pBuffer+i, 0, 1); ReadByte( pBuffer+i, ReadBit, 0); *(pBuffer+i) = (*(pBuffer+i)) >> (8 - ReadBit); #ifdef DEBUG_BIT_STREAM_TEST FileStream << (DWORD)(*(pBuffer+i)) << ' '; #endif } } __inline int GetMaxBufferBytes() const { return m_BufferMaxSizeByte; } __inline int GetReadOffset() const { return m_Offset; } __inline int GetNumberOfBitsUsed() const { return m_Offset; } __inline int GetNumberOfBytesUsed() const { return BITS_TO_BYTES(m_Offset); } __inline void SetReadOffSet( const int offset ) { m_Offset = offset; } __inline void SetWriteOffSet( const int offset ) { m_Offset = offset; } private: //WriteByte´Â ¿ÞÂʺñÆ®ºÎÅÍ º¹»çÇϹǷΠ¿À¸¥ÂÊ ±âÁØÀ¸·Î º¹»ç½Ã¿¡´Â ¿ÞÂÊÀ¸·Î ½¬ÇÁÆ® ÇØ¼­ È£Ãâ. void WriteByte( BYTE Buffer, int NumberOfBits) { if(NumberOfBits <= 0) return; DWORD dwPortion = m_Offset >> 3; DWORD dwRemain = m_Offset % 8; m_pBuffer[dwPortion] |= (Buffer) >> dwRemain; int EmptySpace = (8-dwRemain); if(NumberOfBits > EmptySpace) { m_Offset += EmptySpace; WriteByte((Buffer) << EmptySpace, NumberOfBits - EmptySpace); } else { m_Offset += NumberOfBits; } } //ReadByte´Â ¿ÞÂʺñÆ®ºÎÅÍ ÀÐÀ¸¹Ç·Î ¿À¸¥ÂÊ ±âÁØÀ¸·Î º¹»ç¸¦ ¿øÇҽà ȣÃâÈÄ ¿À¸¥ÂÊÀ¸·Î ½¬ÇÁÆ® void ReadByte( BYTE* pBuffer, int NumberOfBits, DWORD ReadPos ) { if( NumberOfBits <= 0 ) return; DWORD dwPortion = m_Offset >> 3; DWORD dwRemain = m_Offset % 8; //memset(pBuffer, 0 , 1); int ReadSpace = (8-dwRemain); if( NumberOfBits > ReadSpace ) { *pBuffer |= m_pBuffer[dwPortion] << dwRemain; m_Offset += ReadSpace; ReadByte(pBuffer, NumberOfBits - ReadSpace, ReadPos+ReadSpace); } else { //¾²·¹±â°ª »èÁ¦ BYTE Temp = m_pBuffer[dwPortion] >> (ReadSpace - NumberOfBits); Temp = Temp << (ReadSpace - NumberOfBits); Temp = Temp << dwRemain; *pBuffer |= Temp >> ReadPos; m_Offset += NumberOfBits; } } private: #ifdef DEBUG_BIT_STREAM_TEST std::ofstream FileStream; #endif BYTE * m_pBuffer; int m_BufferMaxSizeByte; int m_Offset; }; #endif //(USING_BITSTREAM_VERSION == 1) #endif //UTILITY_BITSTREAM_V1_H