home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Priss / h / bitreader.h next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  4.0 KB  |  175 lines

  1. //    Priss (NekoAmp 2.0) - MPEG-1/2 audio decoding library
  2. //    Copyright (C) 2003 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #ifndef f_VD2_PRISS_BITREADER_H
  19. #define f_VD2_PRISS_BITREADER_H
  20.  
  21. #pragma warning(push)
  22. #pragma warning(disable: 4035)        // warning C4035: 'bswap': no return value
  23.  
  24. #if _MSC_VER >= 1300
  25.     extern unsigned long _byteswap_ulong(unsigned long v);
  26.     #pragma intrinsic(_byteswap_ulong)
  27. #endif
  28.  
  29. // our favorite bitreader
  30. class VDMPEGAudioBitReader {
  31. public:
  32.     VDMPEGAudioBitReader(const uint8 *src, uint32 len) : mpSrc(src), mpSrcLimit(src+len), mBitOffset(0) {}
  33.  
  34. #if _MSC_VER >= 1300
  35.     static inline uint32 bswap(uint32 v) {
  36.         return _byteswap_ulong(v);
  37.     }
  38. #else
  39.     static inline uint32 __fastcall bswap(uint32 v) {
  40.         __asm {
  41.             mov eax, v
  42.             bswap eax
  43.         }
  44.     }
  45. #endif
  46.  
  47.     unsigned get(unsigned bits) {
  48.         static const uint32 masks[17]={
  49.             (1<<0)-1,
  50.             (1<<1)-1,
  51.             (1<<2)-1,
  52.             (1<<3)-1,
  53.             (1<<4)-1,
  54.             (1<<5)-1,
  55.             (1<<6)-1,
  56.             (1<<7)-1,
  57.             (1<<8)-1,
  58.             (1<<9)-1,
  59.             (1<<10)-1,
  60.             (1<<11)-1,
  61.             (1<<12)-1,
  62.             (1<<13)-1,
  63.             (1<<14)-1,
  64.             (1<<15)-1,
  65.             (1<<16)-1,
  66.         };
  67. #if 0
  68.         unsigned v = (((mpSrc[0]<<16)+(mpSrc[1]<<8)+mpSrc[2]) >> (24-mBitOffset-bits)) & masks[bits];
  69. #elif defined(__INTEL_COMPILER)
  70.         unsigned v = (_bswap(*(const uint32 *)mpSrc) >> (32-mBitOffset-bits)) & masks[bits];
  71. #else
  72.         unsigned v = (bswap(*(const uint32 *)mpSrc) >> (32-mBitOffset-bits)) & masks[bits];
  73. #endif
  74.  
  75.         mBitOffset += bits;
  76.         mpSrc += mBitOffset>>3;
  77.         mBitOffset &= 7;
  78.  
  79.         return v;
  80.     }
  81.  
  82.     bool getbool() {
  83.         bool b = 0 != (mpSrc[0] & (0x80 >> mBitOffset));
  84.  
  85.         ++mBitOffset;
  86.         mpSrc += mBitOffset>>3;
  87.         mBitOffset &= 7;
  88.  
  89.         return b;
  90.     }
  91.  
  92.     int avail() const {
  93.         return (int)(((mpSrcLimit - mpSrc)<<3) - mBitOffset);
  94.     }
  95.  
  96.     bool chkavail(int needed) const {
  97.         return avail() >= needed;
  98.     }
  99.  
  100. protected:
  101.     const uint8 *mpSrc;
  102.     const uint8 *const mpSrcLimit;
  103.     unsigned    mBitOffset;
  104. };
  105.  
  106.  
  107. class VDMPEGAudioHuffBitReader {
  108. public:
  109.     enum {
  110.         kAddressMask = 2047
  111.     };
  112.  
  113.     VDMPEGAudioHuffBitReader(const uint8 *src, uint32 offset) : mpSrc(src), mInitialByteOffset(offset & kAddressMask), mByteOffset(offset & kAddressMask), mBitHeap(0), mBitShift(24), mBitOffset(-24) {
  114.         refill();
  115.     }
  116.  
  117.     unsigned peek(unsigned bits) const {
  118.         return mBitHeap >> (32-bits);
  119.     }
  120.  
  121.     void consume(unsigned bits) {
  122.         mBitHeap <<= bits;
  123.         mBitShift += bits;
  124.         refill();
  125.     }
  126.  
  127.     unsigned get(unsigned bits) {
  128.         const unsigned v = peek(bits);
  129.         consume(bits);
  130.         return v;
  131.     }
  132.  
  133.     bool getbit() {
  134.         const bool v = (sint32)mBitHeap < 0;
  135.         consume(1);
  136.         return v;
  137.     }
  138.  
  139.     void refill_one() {
  140.         mBitHeap += mpSrc[mByteOffset] << mBitShift;
  141.         mBitShift -= 8;
  142.         mByteOffset = (mByteOffset+1) & kAddressMask;
  143.         mBitOffset += 8;
  144.     }
  145.  
  146.     void refill() {
  147.         while(mBitShift >= 0)
  148.             refill_one();
  149.     }
  150.  
  151.     unsigned pos() const { return mBitOffset + mBitShift; }
  152.  
  153.     void seek(unsigned offset) {
  154.         mByteOffset = (mInitialByteOffset + (offset>>3)) & kAddressMask;
  155.         mBitOffset = (offset & ~7) - 24;
  156.         mBitShift = 24;
  157.         mBitHeap = 0;
  158.         refill();
  159.         get(offset & 7);
  160.     }
  161.  
  162. protected:
  163.     uint32        mBitHeap;
  164.     sint8        mBitShift;        // left shift for next byte (24-bits_in_heap)
  165.     const uint8 *mpSrc;
  166.     unsigned    mByteOffset;
  167.     unsigned    mBitOffset;        // bitoffset - bitshift = bit position
  168.     unsigned    mInitialByteOffset;
  169. };
  170.  
  171.  
  172. #pragma warning(pop)
  173.  
  174. #endif
  175.