// Sign bit comes first void bf_write::WriteSBitLong( int data, int numbits ) { // Do we have a valid # of bits to encode with? Assert( numbits >= 1 ); // Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer. // (Some old code writes direct integers right into the buffer). if(data < 0) { #ifdef _DEBUG if( numbits < 32 ) { // Make sure it doesn't overflow. if( data < 0 ) { Assert( data >= -(1 << (numbits-1)) ); } else { Assert( data < (1 << (numbits-1)) ); } } #endif WriteUBitLong( (unsigned int)(0x80000000 + data), numbits - 1, false ); WriteOneBit( 1 ); } else { WriteUBitLong((unsigned int)data, numbits - 1); WriteOneBit( 0 ); } }
void bf_write::WriteVarInt32( uint32 data ) { while ( data > 0x7F ) { WriteUBitLong( (data & 0x7F) | 0x80, 8 ); data >>= 7; } WriteUBitLong( data & 0x7F, 8 ); }
// writes an unsigned integer with variable bit length void old_bf_write::WriteUBitVar( unsigned int data ) { if ( ( data &0xf ) == data ) { WriteUBitLong( 0, 2 ); WriteUBitLong( data, 4 ); } else { if ( ( data & 0xff ) == data ) { WriteUBitLong( 1, 2 ); WriteUBitLong( data, 8 ); } else { if ( ( data & 0xfff ) == data ) { WriteUBitLong( 2, 2 ); WriteUBitLong( data, 12 ); } else { WriteUBitLong( 0x3, 2 ); WriteUBitLong( data, 32 ); } } } #if 0 #if !FAST_BIT_SCAN unsigned int bits = 0; unsigned int base = 0; while (data > (base<<1)) { bits++; base = BitForBitnum(bits)-1; } #else unsigned int bits = BitCountNeededToEncode(data); unsigned int base = GetBitForBitnum(bits)-1; #endif // how many bits do we use WriteUBitLong( 0, bits ); // end marker WriteOneBit( 1 ); // write the value if ( bits > 0) WriteUBitLong( data - base , bits ); #endif }
void bf_write::WriteBitLong(unsigned int data, int numbits, bool bSigned) { if(bSigned) WriteSBitLong((int)data, numbits); else WriteUBitLong(data, numbits); }
// writes an unsigned integer with variable bit length void bf_write::WriteUBitVar( unsigned int data ) { unsigned int bits = 0; unsigned int base = 0; while (data > (base<<1)) { bits++; base = (1<<bits)-1; } // how many bits do we use if ( bits > 0) WriteUBitLong( 0, bits ); // end marker WriteOneBit( 1 ); // write the value if ( bits > 0) WriteUBitLong( data - base , bits ); }
bool bf_write::WriteBits(const void *pInData, int nBits) { #if defined( BB_PROFILING ) VPROF( "bf_write::WriteBits" ); #endif unsigned char *pOut = (unsigned char*)pInData; int nBitsLeft = nBits; if((m_iCurBit+nBits) > m_nDataBits) { SetOverflowFlag(); CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); return false; } // Get output dword-aligned. while(((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8) { WriteUBitLong( *pOut, 8, false ); ++pOut; nBitsLeft -= 8; } // check if we can use fast memcpy if m_iCurBit is byte aligned if ( (nBitsLeft >= 32) && (m_iCurBit & 7) == 0 ) { int numbytes = (nBitsLeft >> 3); int numbits = numbytes << 3; // Bounds checking.. // TODO: May not need this check anymore if((m_iCurBit+numbits) > m_nDataBits) { m_iCurBit = m_nDataBits; SetOverflowFlag(); CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); return false; } Q_memcpy( m_pData+(m_iCurBit>>3), pOut, numbytes ); pOut += numbytes; nBitsLeft -= numbits; m_iCurBit += numbits; }
bool old_bf_write::WriteBits(const void *pInData, int nBits) { #if defined( BB_PROFILING ) VPROF( "old_bf_write::WriteBits" ); #endif unsigned char *pOut = (unsigned char*)pInData; int nBitsLeft = nBits; // Bounds checking.. if ( (m_iCurBit+nBits) > m_nDataBits ) { SetOverflowFlag(); CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() ); return false; } // Align output to dword boundary while (((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8) { WriteUBitLong( *pOut, 8, false ); ++pOut; nBitsLeft -= 8; } if ( IsPC() && (nBitsLeft >= 32) && (m_iCurBit & 7) == 0 ) { // current bit is byte aligned, do block copy int numbytes = nBitsLeft >> 3; int numbits = numbytes << 3; Q_memcpy( m_pData+(m_iCurBit>>3), pOut, numbytes ); pOut += numbytes; nBitsLeft -= numbits; m_iCurBit += numbits; }