BitStream.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:3k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "StdAfx.h"
  22. #include "BitStream.h"
  23. //
  24. // CBitStream
  25. //
  26. CBitStream::CBitStream(IStream* pStream, bool fThrowError)
  27. : CUnknown(_T("CBitStream"), NULL)
  28. , m_pStream(pStream)
  29. , m_fThrowError(fThrowError)
  30. , m_bitlen(0)
  31. {
  32. ASSERT(m_pStream);
  33. LARGE_INTEGER li = {0};
  34. m_pStream->Seek(li, STREAM_SEEK_SET, NULL);
  35. ULARGE_INTEGER uli = {0};
  36. m_pStream->SetSize(uli); // not that it worked...
  37. m_pStream->Commit(S_OK); // also seems to have no effect, but maybe in the future...
  38. }
  39. CBitStream::~CBitStream()
  40. {
  41. BitFlush();
  42. }
  43. STDMETHODIMP CBitStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  44. {
  45. CheckPointer(ppv, E_POINTER);
  46. *ppv = NULL;
  47. return 
  48. QI(IBitStream)
  49. __super::NonDelegatingQueryInterface(riid, ppv);
  50. }
  51. // IBitStream
  52. STDMETHODIMP_(UINT64) CBitStream::GetPos()
  53. {
  54. ULARGE_INTEGER pos = {0, 0};
  55. m_pStream->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_CUR, &pos);
  56. return pos.QuadPart;
  57. }
  58. STDMETHODIMP_(UINT64) CBitStream::Seek(UINT64 pos)
  59. {
  60. BitFlush();
  61. LARGE_INTEGER li;
  62. li.QuadPart = pos;
  63. ULARGE_INTEGER linew;
  64. linew.QuadPart = -1;
  65. m_pStream->Seek(li, STREAM_SEEK_SET, &linew);
  66. ASSERT(li.QuadPart == linew.QuadPart);
  67. return linew.QuadPart;
  68. }
  69. STDMETHODIMP CBitStream::ByteWrite(const void* pData, int len)
  70. {
  71. HRESULT hr = S_OK;
  72. BitFlush();
  73. if(len > 0)
  74. {
  75. ULONG cbWritten = 0;
  76. hr = m_pStream->Write(pData, len, &cbWritten);
  77. ASSERT(SUCCEEDED(hr));
  78. if(m_fThrowError && FAILED(hr)) throw hr;
  79. }
  80. return hr;
  81. }
  82. STDMETHODIMP CBitStream::BitWrite(UINT64 data, int len)
  83. {
  84. HRESULT hr = S_OK;
  85. ASSERT(len >= 0 && len <= 64);
  86. if(len > 56) {BitWrite(data >> 56, len - 56); len = 56;}
  87. m_bitbuff <<= len;
  88. m_bitbuff |= data & ((1ui64 << len) - 1);
  89. m_bitlen += len;
  90. while(m_bitlen >= 8)
  91. {
  92. BYTE b = (BYTE)(m_bitbuff >> (m_bitlen - 8));
  93. hr = m_pStream->Write(&b, 1, NULL);
  94. m_bitlen -= 8;
  95. ASSERT(SUCCEEDED(hr));
  96. if(m_fThrowError && FAILED(hr)) throw E_FAIL;
  97. }
  98. return hr;
  99. }
  100. STDMETHODIMP CBitStream::BitFlush()
  101. {
  102. HRESULT hr = S_OK;
  103. if(m_bitlen > 0)
  104. {
  105. ASSERT(m_bitlen < 8);
  106. BYTE b = (BYTE)(m_bitbuff << (8 - m_bitlen));
  107. hr = m_pStream->Write(&b, 1, NULL);
  108. m_bitlen = 0;
  109. ASSERT(SUCCEEDED(hr));
  110. if(m_fThrowError && FAILED(hr)) throw E_FAIL;
  111. }
  112. return hr;
  113. }