00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "BitVector.hh"
00022
00023 BitVector::BitVector(unsigned char* baseBytePtr,
00024 unsigned baseBitOffset,
00025 unsigned totNumBits) {
00026 setup(baseBytePtr, baseBitOffset, totNumBits);
00027 }
00028
00029 void BitVector::setup(unsigned char* baseBytePtr,
00030 unsigned baseBitOffset,
00031 unsigned totNumBits) {
00032 fBaseBytePtr = baseBytePtr;
00033 fBaseBitOffset = baseBitOffset;
00034 fTotNumBits = totNumBits;
00035 fCurBitIndex = 0;
00036 }
00037
00038 static unsigned char const singleBitMask[8]
00039 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
00040
00041 #define MAX_LENGTH 32
00042
00043 void BitVector::putBits(unsigned from, unsigned numBits) {
00044 if (numBits == 0) return;
00045
00046 unsigned char tmpBuf[4];
00047 unsigned overflowingBits = 0;
00048
00049 if (numBits > MAX_LENGTH) {
00050 numBits = MAX_LENGTH;
00051 }
00052
00053 if (numBits > fTotNumBits - fCurBitIndex) {
00054 overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
00055 }
00056
00057 tmpBuf[0] = (unsigned char)(from>>24);
00058 tmpBuf[1] = (unsigned char)(from>>16);
00059 tmpBuf[2] = (unsigned char)(from>>8);
00060 tmpBuf[3] = (unsigned char)from;
00061
00062 shiftBits(fBaseBytePtr, fBaseBitOffset + fCurBitIndex,
00063 tmpBuf, MAX_LENGTH - numBits,
00064 numBits - overflowingBits );
00065 fCurBitIndex += numBits - overflowingBits;
00066 }
00067
00068 void BitVector::put1Bit(unsigned bit) {
00069
00070 if (fCurBitIndex >= fTotNumBits) {
00071 return;
00072 } else {
00073 unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
00074 unsigned char mask = singleBitMask[totBitOffset%8];
00075 if (bit) {
00076 fBaseBytePtr[totBitOffset/8] |= mask;
00077 } else {
00078 fBaseBytePtr[totBitOffset/8] &=~ mask;
00079 }
00080 }
00081 }
00082
00083 unsigned BitVector::getBits(unsigned numBits) {
00084 if (numBits == 0) return 0;
00085
00086 unsigned char tmpBuf[4];
00087 unsigned overflowingBits = 0;
00088
00089 if (numBits > MAX_LENGTH) {
00090 numBits = MAX_LENGTH;
00091 }
00092
00093 if (numBits > fTotNumBits - fCurBitIndex) {
00094 overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
00095 }
00096
00097 shiftBits(tmpBuf, 0,
00098 fBaseBytePtr, fBaseBitOffset + fCurBitIndex,
00099 numBits - overflowingBits );
00100 fCurBitIndex += numBits - overflowingBits;
00101
00102 unsigned result
00103 = (tmpBuf[0]<<24) | (tmpBuf[1]<<16) | (tmpBuf[2]<<8) | tmpBuf[3];
00104 result >>= (MAX_LENGTH - numBits);
00105 result &= (0xFFFFFFFF << overflowingBits);
00106 return result;
00107 }
00108
00109 unsigned BitVector::get1Bit() {
00110
00111
00112 if (fCurBitIndex >= fTotNumBits) {
00113 return 0;
00114 } else {
00115 unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
00116 unsigned char curFromByte = fBaseBytePtr[totBitOffset/8];
00117 unsigned result = (curFromByte >> (7-(totBitOffset%8))) & 0x01;
00118 return result;
00119 }
00120 }
00121
00122 void BitVector::skipBits(unsigned numBits) {
00123 if (numBits > fTotNumBits - fCurBitIndex) {
00124 fCurBitIndex = fTotNumBits;
00125 } else {
00126 fCurBitIndex += numBits;
00127 }
00128 }
00129
00130 unsigned BitVector::get_expGolomb() {
00131 unsigned numLeadingZeroBits = 0;
00132 unsigned codeStart = 1;
00133
00134 while (get1Bit() == 0 && fCurBitIndex < fTotNumBits) {
00135 ++numLeadingZeroBits;
00136 codeStart *= 2;
00137 }
00138
00139 return codeStart -1 + getBits(numLeadingZeroBits);
00140 }
00141
00142
00143 void shiftBits(unsigned char* toBasePtr, unsigned toBitOffset,
00144 unsigned char const* fromBasePtr, unsigned fromBitOffset,
00145 unsigned numBits) {
00146 if (numBits == 0) return;
00147
00148
00149 unsigned char const* fromBytePtr = fromBasePtr + fromBitOffset/8;
00150 unsigned fromBitRem = fromBitOffset%8;
00151 unsigned char* toBytePtr = toBasePtr + toBitOffset/8;
00152 unsigned toBitRem = toBitOffset%8;
00153
00154 while (numBits-- > 0) {
00155 unsigned char fromBitMask = singleBitMask[fromBitRem];
00156 unsigned char fromBit = (*fromBytePtr)&fromBitMask;
00157 unsigned char toBitMask = singleBitMask[toBitRem];
00158
00159 if (fromBit != 0) {
00160 *toBytePtr |= toBitMask;
00161 } else {
00162 *toBytePtr &=~ toBitMask;
00163 }
00164
00165 if (++fromBitRem == 8) {
00166 ++fromBytePtr;
00167 fromBitRem = 0;
00168 }
00169 if (++toBitRem == 8) {
00170 ++toBytePtr;
00171 toBitRem = 0;
00172 }
00173 }
00174 }