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

📄 arithmeticcoder.cpp

📁 有关几个数字编码的C++ 程序
💻 CPP
字号:
// ArithmeticCoder.cpp: implementation of the CArithmeticCoder class.
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ArithmeticCoder.h"
#include "bitio.h"

//--------------------------------------------------------------
//---------------Construction/Destruction-----------------------
CArithmeticCoder::CArithmeticCoder()
{
	name_filein = "g:\\mine.doc";
	name_fileout = "g:\\mine.out";

	m_pModel = new CModel;
	m_pBitIO = new CBitIO;

}

CArithmeticCoder::~CArithmeticCoder()
{
	delete m_pModel;
	delete m_pBitIO;
}
//===============================================================

//---------------------------------------------------------------
//------- output bits plus following opposite bits---------------
void CArithmeticCoder::bit_plus_follow(int bit)
{
	m_pBitIO->output_bit(bit);
	while(bits_to_follow>0)
	{
		m_pBitIO->output_bit(!bit);
		bits_to_follow -= 1;
	}
}
//================================================================

//----------------------------------------------------------------
//-------------start encoding a stream of symbols-----------------
void CArithmeticCoder::start_encoding()
{
	low = 0;
	high = top_value;
	bits_to_follow = 0;
}
//================================================================

//----------------------------------------------------------------
//----------------encode a symbol---------------------------------
void CArithmeticCoder::encode_symbol(int symbol, int cum_freq[])
{
	long range;
	range = (long)(high-low)+1;
	
	// narrow the code region to that allotted to this symbol
 	high = low + (range*cum_freq[symbol-1])/cum_freq[0]-1;
	low = low + (range*cum_freq[symbol])/cum_freq[0];
	for(;;)
	{
		if ( high < half )
		{
			bit_plus_follow(0);	// output 0 in low half
		}
		else if ( low >= half )		// output 1 in high half
		{
			bit_plus_follow(1);
			low -= half;
			high -= half;
		}
		else if ( low >= first_qtr && high < third_qtr )
		{
			bits_to_follow += 1;
			low -= first_qtr;
			high -= first_qtr;
		}
		else
			break;
		low = 2*low;
		high = 2*high + 1;
	}
}
//================================================================

//----------------------------------------------------------------
//---------------finish encoding the stream-----------------------
void CArithmeticCoder::done_encoding()
{
	bits_to_follow += 1;
	if ( low < first_qtr )
		bits_to_follow = 0;
	else
		bits_to_follow = 1;
}
//================================================================

//----------------------------------------------------------------
//--------------------start the coding----------------------------
void CArithmeticCoder::start_decoding()
{
	int i; 
	value = 0; 
	for(i=1; i<=Code_value_bits; i++)
	{ 
		value = 2*value+m_pBitIO->input_bit();
	}
	low = 0; 
	high = top_value; 
}
//================================================================

//----------------------------------------------------------------
//----------------decode the next symbol--------------------------
int CArithmeticCoder::decode_symbol(int cum_freq[])
{ 
	long range; 
	int cum;
	int symbol;
	range = (long) (high-low) + 1;
	cum = (((long)(value-low)+1)*cum_freq[0]-1)/range; 
	// boring linear search
	for(symbol=1; cum_freq[symbol]>cum; symbol++)
	{ ; } 
	high = low + (range*cum_freq[symbol-1])/cum_freq[0]-1; 
	low = low + (range*cum_freq[symbol])/cum_freq[0];
	for(;;) 
	{
		if ( high < half ) 
		{ }
		else if ( low >= half ) 
		{
			value -= half;
			low -= half; 
			high -= half; } 
		else if 
			( low >= first_qtr && high < third_qtr )
		{ 
			value -= first_qtr;
			low -= first_qtr;
			high -= first_qtr; 
		} 
		else break; 
		low = 2*low;
		high = 2*high + 1; 
		value = 2*value + m_pBitIO->input_bit(); 
	}
	return symbol;

} 
//================================================================

//----------------------------------------------------------------
//------------------------Encode----------------------------------
void CArithmeticCoder::Encode()
{
	int ch;
    int symbol;

	filein = fopen(name_filein, "rb");
	fileout = fopen(name_fileout, "wb");

	m_pBitIO->start_outputing_bits(fileout);

	start_encoding();
	
	for(;;)
	{
		ch = getc(filein);
		if ( ch == EOF ) break;
		symbol = m_pModel->char_to_index[ch];
		encode_symbol(symbol, m_pModel->cum_freq);
		m_pModel->update(symbol);
	}
	encode_symbol(EOF_symbol, m_pModel->cum_freq);
	done_encoding();
	m_pBitIO->done_outputing_bits();
}
//==================================================================

//------------------------------------------------------------------
//----------------------------Attach---------------------------------
bool CArithmeticCoder::Attach(CModel *pmodel)
{
	if(pmodel == 0)
		return false;
	else {
		m_pModel = pmodel;
		return true;
	}
}

bool CArithmeticCoder::Attach(CBitIO *pBitIO)
{
	if(pBitIO == 0)
		return false;
	else {
		m_pBitIO = pBitIO;
		return true;
	}
}
//===============================================================

void CArithmeticCoder::SetOutputFileName(char *outfilename)
{
	name_fileout = outfilename;
}

void CArithmeticCoder::Decode()
{
    int ch;
    int symbol;
	
	filein = fopen(name_filein, "rb");
	fileout = fopen(name_fileout, "wb");

    m_pBitIO->start_inputing_bits(filein);
    start_decoding();
	
	for(;;)
    {
	symbol = decode_symbol(m_pModel->cum_freq);
	if ( symbol == EOF_symbol )
	    break;
	ch = m_pModel->index_to_char[symbol];
	putc(ch,fileout);
        m_pModel->update(symbol);
    }
    //return;
}

void CArithmeticCoder::SetInputFileName(char *infilename)
{
	name_filein = infilename;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -