📄 bitstreams.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <more/util/bitstreams.hpp>using namespace more;using namespace more::util;////////////////////////////////////////////////////////////////////////////////static BitInputStream::Bits nBitsMasks[33] ={ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF};////////////////////////////////////////////////////////////////////////////////inline BitInputStream::Bits getBitMaskFor( size_t nNoOfBits ){ return nBitsMasks[nNoOfBits]; // ( 1 << nNoOfBits ) - 1;}////////////////////////////////////////////////////////////////////////////////BitInputStream::BitInputStream( const Array<Byte>& bitBuffer, size_t nNoOfBits): m_bitBuffer( bitBuffer ), m_nNoOfBitsLeft( nNoOfBits ), m_nBitAccumulator( 0 ), m_nNoOfLoadedBits( 0 ){ loadAccumulator( );}////////////////////////////////////////////////////////////////////////////////size_t BitInputStream::getNoOfBits( ) const{ return m_nNoOfLoadedBits + m_nNoOfBitsLeft;}////////////////////////////////////////////////////////////////////////////////BitInputStream::Bits BitInputStream::getBits( size_t nNoOfBits) const{ if( nNoOfBits > m_nNoOfBitsLeft + m_nNoOfLoadedBits ) { nNoOfBits = m_nNoOfBitsLeft + m_nNoOfLoadedBits; } if( nNoOfBits > 8 * sizeof( m_nBitAccumulator ) ) { nNoOfBits = 8 * sizeof( m_nBitAccumulator ); } return m_nBitAccumulator & getBitMaskFor( nNoOfBits );}////////////////////////////////////////////////////////////////////////////////void BitInputStream::forgetBits( size_t nNoOfBits){ if( nNoOfBits > m_nNoOfLoadedBits ) { nNoOfBits = m_nNoOfLoadedBits; } if( nNoOfBits > 8 * sizeof( m_nBitAccumulator ) ) { nNoOfBits = 8 * sizeof( m_nBitAccumulator ); } m_nBitAccumulator >>= nNoOfBits; m_nNoOfLoadedBits -= nNoOfBits; loadAccumulator( );}////////////////////////////////////////////////////////////////////////////////void BitInputStream::loadAccumulator( ){ static const size_t nSizeOfAkku = 8 * sizeof( BitInputStream::Bits ); while( m_nNoOfBitsLeft > 0 && m_nNoOfLoadedBits <= nSizeOfAkku - 8 ) { size_t nIndex = ( 8 * m_bitBuffer.getLength( ) - m_nNoOfBitsLeft ) / 8; Bits nBits = m_bitBuffer[nIndex]; m_nBitAccumulator |= nBits << m_nNoOfLoadedBits; if( m_nNoOfBitsLeft > 8 ) { m_nNoOfLoadedBits += 8; m_nNoOfBitsLeft -= 8; } else { m_nNoOfLoadedBits += m_nNoOfBitsLeft; m_nNoOfBitsLeft = 0; } }}////////////////////////////////////////////////////////////////////////////////BitOutputStream::BitOutputStream( const Array<Byte>& bitBuffer, size_t nNoOfMaxBits): m_bitBuffer( bitBuffer ), m_nMaxNoOfBits( nNoOfMaxBits ), m_nNoOfBitsSet( 0 ){ if( nNoOfMaxBits > 8 * bitBuffer.getLength( ) ) { nNoOfMaxBits = 8 * bitBuffer.getLength( ); }}////////////////////////////////////////////////////////////////////////////////size_t BitOutputStream::getNoOfBits( ) const{ return m_nNoOfBitsSet;}////////////////////////////////////////////////////////////////////////////////void BitOutputStream::setBits( BitOutputStream::Bits nBits, size_t nNoOfBits, bool bBigEndianOrder){ if( bBigEndianOrder ) { setBitsInBigEndianOrder( nBits, nNoOfBits ); } else { setBitsInLittleEndianOrder( nBits, nNoOfBits ); }}////////////////////////////////////////////////////////////////////////////////void BitOutputStream::setBitsInBigEndianOrder( BitOutputStream::Bits nBits, size_t nNoOfBits){ if( m_nNoOfBitsSet < m_nMaxNoOfBits && nNoOfBits > 0 ) { size_t nIndex, nOverflow; if( nNoOfBits > 8 * sizeof( nBits ) ) { nNoOfBits = 8 * sizeof( nBits ); } if( nNoOfBits > m_nMaxNoOfBits - m_nNoOfBitsSet ) { nBits >>= ( nNoOfBits - ( m_nMaxNoOfBits - m_nNoOfBitsSet ) ); nNoOfBits = m_nMaxNoOfBits - m_nNoOfBitsSet; } nIndex = ( m_nNoOfBitsSet + nNoOfBits - 1 ) / 8; nOverflow = ( m_nNoOfBitsSet + nNoOfBits ) % 8; m_nNoOfBitsSet += nNoOfBits; if( nOverflow > 0 ) { Byte nAccumulator = ( Byte ) ( nBits << ( 8 - nOverflow ) ); if( nNoOfBits < nOverflow ) { Byte nMask = getBitMaskFor( nNoOfBits ) << ( 8 - nOverflow ); m_bitBuffer[nIndex] |= nAccumulator & nMask; nNoOfBits = 0; } else { m_bitBuffer[nIndex--] = nAccumulator; nNoOfBits -= nOverflow; nBits >>= nOverflow; } } while( nNoOfBits >= 8 ) { m_bitBuffer[nIndex--] = ( Byte ) nBits; nNoOfBits -= 8; nBits >>= 8; } if( nNoOfBits > 0 ) { m_bitBuffer[nIndex] |= ( Byte ) ( nBits & getBitMaskFor( nNoOfBits ) ); } }}////////////////////////////////////////////////////////////////////////////////void BitOutputStream::setBitsInLittleEndianOrder( BitOutputStream::Bits nBits, size_t nNoOfBits){ if( m_nNoOfBitsSet < m_nMaxNoOfBits && nNoOfBits > 0 ) { size_t nIndex, nOverflow; if( nNoOfBits > 8 * sizeof( nBits ) ) { nNoOfBits = 8 * sizeof( nBits ); } if( nNoOfBits > m_nMaxNoOfBits - m_nNoOfBitsSet ) { nBits >>= ( nNoOfBits - ( m_nMaxNoOfBits - m_nNoOfBitsSet ) ); nNoOfBits = m_nMaxNoOfBits - m_nNoOfBitsSet; } nIndex = m_nNoOfBitsSet / 8; nOverflow = m_nNoOfBitsSet % 8; m_nNoOfBitsSet += nNoOfBits; if( nOverflow > 0 ) { Byte nAccumulator = ( Byte ) nBits << nOverflow; if( nNoOfBits < 8 - nOverflow ) { Byte nMask = getBitMaskFor( nNoOfBits ) << nOverflow; m_bitBuffer[nIndex] |= nAccumulator & nMask; nNoOfBits = 0; } else { m_bitBuffer[nIndex++] |= nAccumulator; nNoOfBits -= 8 - nOverflow; nBits >>= 8 - nOverflow; } } while( nNoOfBits >= 8 ) { m_bitBuffer[nIndex++] = ( Byte ) nBits; nNoOfBits -= 8; nBits >>= 8; } if( nNoOfBits > 0 ) { m_bitBuffer[nIndex] = ( Byte ) nBits; } }}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -