📄 bitstrm.cpp
字号:
/*************************************************************************
This software module was originally developed by
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
Bruce Lin (blin@microsoft.com), Microsoft Corporation
Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
(date: March, 1996)
and edited by
Yoshihiro Kikuchi (TOSHIBA CORPORATION)
Takeshi Nagai (TOSHIBA CORPORATION)
Toshiaki Watanabe (TOSHIBA CORPORATION)
Noboru Yamaguchi (TOSHIBA CORPORATION)
in the course of development of the MPEG-4 Video (ISO/IEC 14496-2).
This software module is an implementation of a part of one or more MPEG-4 Video tools
as specified by the MPEG-4 Video.
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video.
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents.
The original developer of this software module and his/her company,
the subsequent editors and their companies,
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation.
Copyright is not released for non MPEG-4 Video conforming products.
Microsoft retains full right to use the code for his/her own purpose,
assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video conforming products.
This copyright notice must be included in all copies or derivative works.
Copyright (c) 1996, 1997.
Module Name:
bitstrm.cpp
Abstract:
Classes for bitstream I/O.
Revision History:
*************************************************************************/
#include "typeapi.h"
#include "bitstrm.hpp"
#include <istream.h>
#include <ostream.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#endif // __MFC_
UInt getbit (UInt data, UInt position, UInt num) // get the num-bit field of x starting from position p
{
return ((data >> (position + 1 - num)) & ~(~0 << num));
}
Void print_bit (UInt x, UInt num, UInt startPos) // print num bits starting from startPos
{
for (Int k = 0; k <= (Int) (num - startPos); k++) {
UInt y = getbit (x, num, 1);
printf ("%u ", y);
x = x << 1;
}
printf ("\n");
}
Char CInBitStream::getBitsC (Int iNOfBits)
{
assert (iNOfBits <= 8);
assert (iNOfBits >= 0);
return (Char) getBits ((UInt) iNOfBits);
}
UInt CInBitStream::getBits (UInt numBits)
{
assert (numBits <= 32);
if (numBits == 0) return 0;
UInt retData;
if (m_uNumOfBitsInBuffer >= numBits) { // don't need to read from FILE
retData = getbit (m_chDecBuffer, 7, numBits);
m_chDecBuffer = m_chDecBuffer << numBits;
m_uNumOfBitsInBuffer -= numBits;
m_lCounter += numBits;
}
else { // ready, but need to handle the leftover part
numBits -= m_uNumOfBitsInBuffer; // left-over unhandled bits
retData = getbit (m_chDecBuffer, 7, m_uNumOfBitsInBuffer) << numBits;
m_lCounter += m_uNumOfBitsInBuffer;
assert(!m_pInStream->eof()); // dont allow repeated gets off end of file
m_chDecBuffer = m_pInStream -> get ();
m_uNumOfBitsInBuffer = 8;
retData += getBits (numBits);
}
return retData;
}
Void CInBitStream::getBits (Char *pBits, Int lNOfBits)
{
assert (lNOfBits <= 8);
assert (lNOfBits >= 0);
while(lNOfBits>0)
{
if(lNOfBits>8)
{
*pBits=(Char) getBitsC(8);
lNOfBits-=8;
pBits++;
}
else
{
*pBits=(Char) getBitsC ((UInt) lNOfBits);
break;
}
}
}
Void CInBitStream::attach (istream &inStream, Int iBitPosition)
{
assert(iBitPosition<8);
assert(iBitPosition>=0);
m_iBitPosition=iBitPosition;
m_pInStream=&inStream;
m_iBuffer=0x00ff&m_pInStream->peek();
}
Void CInBitStream::flush (Int nExtraBits)
{
// Modified for error resilient mode by Toshiba(1997-11-14)
if(m_uNumOfBitsInBuffer==0) getBits (nExtraBits); //first get some bits then flush
//getBits (nExtraBits); //first get some bits then flush
// End Toshiba(1997-11-14)
assert (m_uNumOfBitsInBuffer != 8);
m_lCounter += m_uNumOfBitsInBuffer;
m_uNumOfBitsInBuffer = 0;
}
Void CInBitStream::setBookmark ()
{
bookmark (1);
}
Void CInBitStream::gotoBookmark ()
{
bookmark (0);
}
Void CInBitStream::bookmark (Bool bSet)
{
static Bool bBookmarkOn = FALSE;
static streampos strmpos;
static UInt uNumOfBitsInBuffer;
static Char chDecBuffer;
static Int lCounter;
if(bSet) {
strmpos = m_pInStream -> tellg();
uNumOfBitsInBuffer = m_uNumOfBitsInBuffer;
chDecBuffer = m_chDecBuffer;
lCounter = m_lCounter;
bBookmarkOn = TRUE;
}
else {
m_pInStream -> seekg (strmpos);
m_uNumOfBitsInBuffer = uNumOfBitsInBuffer;
m_chDecBuffer = chDecBuffer;
m_lCounter = lCounter;
bBookmarkOn = FALSE;
}
}
COutBitStream::COutBitStream (Char* pchBuffer, Int iBitPosition, ostream* pstrmTrace) :
m_pstrmTrace (pstrmTrace),
m_chEncBuffer (0),
m_uEncNumEmptyBits (8)
{
assert (iBitPosition < 8);
assert (iBitPosition >= 0);
m_iBitPosition = iBitPosition;
m_pchBuffer = pchBuffer;
m_lCounter = 0;
m_pchBufferRun = m_pchBuffer;
m_iBuffer = 0;
// Added for Data Partitioning mode by Toshiba(1998-1-16)
m_bDontSendBits = FALSE;
// End Toshiba(1998-1-16)
}
Void COutBitStream::reset () //but keep the byte buffer
{
// m_uEncNumEmptyBits = 8;
// m_chEncBuffer = 0;
m_pchBufferRun = m_pchBuffer;
m_iBuffer = 0;
}
Void COutBitStream::resetAll ()
{
m_iBitPosition = 0;
m_lCounter = 0;
m_uEncNumEmptyBits = 8;
m_chEncBuffer = 0;
m_pchBufferRun = m_pchBuffer;
m_iBuffer = 0;
}
Void COutBitStream::setBookmark ()
{
bookmark (1);
}
Void COutBitStream::gotoBookmark ()
{
bookmark (0);
}
Void COutBitStream::bookmark (Bool bSet)
{
static Bool bBookmarkOn = FALSE;
static Int iBitPosition;
static Int lCounter;
static UInt uEncNumEmptyBits;
static U8 chEncBuffer;
static Char* pchBufferRun;
static Int iBuffer;
if (bSet) {
iBitPosition = m_iBitPosition;
lCounter = m_lCounter;
uEncNumEmptyBits = m_uEncNumEmptyBits;
chEncBuffer = m_chEncBuffer;
pchBufferRun = m_pchBufferRun;
iBuffer = m_iBuffer;
bBookmarkOn = TRUE;
}
else {
m_iBitPosition = iBitPosition;
m_lCounter = lCounter;
m_uEncNumEmptyBits = uEncNumEmptyBits;
m_chEncBuffer = chEncBuffer;
m_pchBufferRun = pchBufferRun;
m_iBuffer = iBuffer;
bBookmarkOn = FALSE;
}
}
Void COutBitStream::putBitsC (Char cBits,Int iNOfBits)
{
putBits ((Int) cBits, (UInt) iNOfBits);
}
Void COutBitStream::putBits (Int data, UInt numBits, const Char* rgchSymbolName)
{
assert (numBits < 100); //usually not that large
if (numBits == 0) return;
// Added for Data Partitioning mode by Toshiba(1998-1-16)
if(m_bDontSendBits) return;
// End Toshiba(1998-1-16)
#ifdef __TRACE_AND_STATS_
if (m_pstrmTrace != NULL && rgchSymbolName != NULL) {
Char* rgchBinaryForm = new Char [numBits + 1];
assert (rgchBinaryForm != NULL);
m_pstrmTrace->width (20);
(*m_pstrmTrace) << rgchSymbolName << ": ";
Int iMask = 0xFFFFFFFF;
iMask = iMask << numBits;
iMask = ~iMask;
Int iCleanData = data & iMask;
//_itoa (iCleanData, rgchBinaryForm, 2); // win32 only
Int iBit;
iMask = 0x00000001;
for (iBit = (Int) numBits - 1; iBit >= 0; iBit--) {
rgchBinaryForm [iBit] = ((iCleanData & iMask) == 0) ? '0' : '1';
iMask = iMask << 1;
}
rgchBinaryForm [numBits] = '\0';
m_pstrmTrace->width (numBits);
m_pstrmTrace->fill ('0');
(*m_pstrmTrace) << rgchBinaryForm;
m_pstrmTrace->fill (' ');
(*m_pstrmTrace) << " @" << m_lCounter << '\n';
m_pstrmTrace->flush ();
delete rgchBinaryForm;
}
#endif // __TRACE_AND_STATS_
if (m_uEncNumEmptyBits > numBits) { // not ready to put the data to buffer since it's not full
m_uEncNumEmptyBits -= numBits;
Char mskData = (0xFF >> (8 - numBits)) & data;
mskData = mskData << m_uEncNumEmptyBits;
m_chEncBuffer = m_chEncBuffer ^ mskData;
m_lCounter += numBits;
}
else if (m_uEncNumEmptyBits == numBits) { // ready
Char mskData = (0xFF >> (8 - numBits)) & data;
m_chEncBuffer = m_chEncBuffer ^ mskData;
*m_pchBufferRun++ = m_chEncBuffer;
m_iBuffer++;
m_chEncBuffer = 0;
m_uEncNumEmptyBits = 8;
m_lCounter += numBits;
}
else { // ready, but need to handle the leftover part
UInt temp = getbit (data, numBits - 1, m_uEncNumEmptyBits);
numBits -= m_uEncNumEmptyBits; // length of unhandled part
m_chEncBuffer = m_chEncBuffer ^ temp;
m_lCounter += m_uEncNumEmptyBits;
*m_pchBufferRun++ = m_chEncBuffer;
m_iBuffer++;
m_chEncBuffer = 0;
m_uEncNumEmptyBits = 8;
data = data ^ (temp << numBits);
putBits (data, numBits);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -