⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitstrm.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************

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 + -