?? arithmeticcoder.cpp
字號(hào):
// 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;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -