BitVector.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**********
  2. This library is free software; you can redistribute it and/or modify it under
  3. the terms of the GNU Lesser General Public License as published by the
  4. Free Software Foundation; either version 2.1 of the License, or (at your
  5. option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
  6. This library is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
  9. more details.
  10. You should have received a copy of the GNU Lesser General Public License
  11. along with this library; if not, write to the Free Software Foundation, Inc.,
  12. 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  13. **********/
  14. // "liveMedia"
  15. // Copyright (c) 1996-2001 Live Networks, Inc.  All rights reserved.
  16. // Bit Vector data structure
  17. // Implementation
  18. #include "BitVector.hh"
  19. BitVector::BitVector(unsigned char* baseBytePtr,
  20.      unsigned baseBitOffset,
  21.      unsigned totNumBits) {
  22.   setup(baseBytePtr, baseBitOffset, totNumBits);
  23. }
  24. void BitVector::setup(unsigned char* baseBytePtr,
  25.       unsigned baseBitOffset,
  26.       unsigned totNumBits) {
  27.   fBaseBytePtr = baseBytePtr;
  28.   fBaseBitOffset = baseBitOffset;
  29.   fTotNumBits = totNumBits;
  30.   fCurBitIndex = 0;
  31. }
  32. static unsigned char singleBitMask[8]
  33.     = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  34. #define MAX_LENGTH 32
  35. void BitVector::putBits(unsigned from, unsigned numBits) {
  36.   unsigned char tmpBuf[4];
  37.   unsigned overflowingBits = 0;
  38.   if (numBits > MAX_LENGTH) {
  39.     numBits = MAX_LENGTH;
  40.   }
  41.   if (numBits > fTotNumBits - fCurBitIndex) {
  42.     overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
  43.   }
  44.   tmpBuf[0] = (unsigned char)(from>>24);
  45.   tmpBuf[1] = (unsigned char)(from>>16);
  46.   tmpBuf[2] = (unsigned char)(from>>8);
  47.   tmpBuf[3] = (unsigned char)from;
  48.   shiftBits(fBaseBytePtr, fBaseBitOffset + fCurBitIndex, /* to */
  49.     tmpBuf, MAX_LENGTH - numBits, /* from */
  50.     numBits - overflowingBits /* num bits */);
  51.   fCurBitIndex += numBits - overflowingBits;
  52. }
  53. void BitVector::put1Bit(unsigned bit) {
  54.   // The following is equivalent to "putBits(..., 1)", except faster:
  55.   if (fCurBitIndex >= fTotNumBits) { /* overflow */
  56.     return;
  57.   } else {
  58.     unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
  59.     unsigned char mask = singleBitMask[totBitOffset%8];
  60.     if (bit) {
  61.       fBaseBytePtr[totBitOffset/8] |= mask;
  62.     } else {
  63.       fBaseBytePtr[totBitOffset/8] &=~ mask;
  64.     }
  65.   }
  66. }
  67. unsigned BitVector::getBits(unsigned numBits) {
  68.   unsigned char tmpBuf[4];
  69.   unsigned overflowingBits = 0;
  70.   if (numBits > MAX_LENGTH) {
  71.     numBits = MAX_LENGTH;
  72.   }
  73.   if (numBits > fTotNumBits - fCurBitIndex) {
  74.     overflowingBits = numBits - (fTotNumBits - fCurBitIndex);
  75.   }
  76.   shiftBits(tmpBuf, 0, /* to */
  77.     fBaseBytePtr, fBaseBitOffset + fCurBitIndex, /* from */
  78.     numBits - overflowingBits /* num bits */);
  79.   fCurBitIndex += numBits - overflowingBits;
  80.   unsigned result
  81.     = (tmpBuf[0]<<24) | (tmpBuf[1]<<16) | (tmpBuf[2]<<8) | tmpBuf[3];
  82.   result >>= (MAX_LENGTH - numBits); // move into low-order part of word
  83.   result &= (0xFFFFFFFF << overflowingBits); // so any overflow bits are 0
  84.   return result;
  85. }
  86. unsigned BitVector::get1Bit() {
  87.   // The following is equivalent to "hgetbits(1)", except faster:
  88.   if (fCurBitIndex >= fTotNumBits) { /* overflow */
  89.     return 0;
  90.   } else {
  91.     unsigned totBitOffset = fBaseBitOffset + fCurBitIndex++;
  92.     unsigned char curFromByte = fBaseBytePtr[totBitOffset/8];
  93.     unsigned result = (curFromByte >> (7-(totBitOffset%8))) & 0x01;
  94.     return result;
  95.   }
  96. }
  97. void BitVector::skipBits(unsigned numBits) {
  98.   if (numBits > fTotNumBits - fCurBitIndex) { /* overflow */
  99.     fCurBitIndex = fTotNumBits;
  100.   } else {
  101.     fCurBitIndex += numBits;
  102.   }
  103. }
  104. void shiftBits(unsigned char* toBasePtr, unsigned toBitOffset,
  105.        unsigned char const* fromBasePtr, unsigned fromBitOffset,
  106.        unsigned numBits) {
  107.   /* Note that from and to may overlap, if from>to */
  108.   unsigned char const* fromBytePtr = fromBasePtr + fromBitOffset/8;
  109.   unsigned fromBitRem = fromBitOffset%8;
  110.   unsigned char* toBytePtr = toBasePtr + toBitOffset/8;
  111.   unsigned toBitRem = toBitOffset%8;
  112.   while (numBits-- > 0) {
  113.     unsigned char fromBitMask = singleBitMask[fromBitRem];
  114.     unsigned char fromBit = (*fromBytePtr)&fromBitMask;
  115.     unsigned char toBitMask = singleBitMask[toBitRem];
  116.     if (fromBit != 0) {
  117.       *toBytePtr |= toBitMask;
  118.     } else {
  119.       *toBytePtr &=~ toBitMask;
  120.     }
  121.     if (++fromBitRem == 8) {
  122.       ++fromBytePtr;
  123.       fromBitRem = 0;
  124.     }
  125.     if (++toBitRem == 8) {
  126.       ++toBytePtr;
  127.       toBitRem = 0;
  128.     }
  129.   }
  130. }