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

📄 arithmcode.cpp

📁 A high quality VC++ source code implementing the very important context-based adaptive arithmetic co
💻 CPP
字号:
#include "StdAfx.h"
#include ".\arithmcode.h"

CArithmCode::CArithmCode(void)
: memFile(NULL)
, numSymbol(0)
, numContext(0)
, low(0)
, high(0)
, range(0)
, underflowBits(0)
, code(0)
, count(0)
, mask(0)
, rack(0)
{
}

CArithmCode::~CArithmCode(void)
{
}

void CArithmCode::OutputBit(short bit)
{
	if(bit != 0)
		rack |= mask;
	
	mask >>= 1;

	if(mask == 0)
	{	
		memFile->MemWrite((unsigned char *)&rack, sizeof(char)); 
		rack = 0;
		mask = 0x80;
	}
}

void CArithmCode::OutputBits(unsigned long code1, short count1)
{
	long mask1;

	mask1 = 1L << (count1 - 1);
	while(mask1 != 0)
	{
		if((mask1 & code1) != 0) 
			rack |= mask;

		mask >>= 1;
		if(mask == 0)
		{
			memFile->MemWrite((unsigned char *)&rack, sizeof(char));
			rack = 0;
			mask = 0x80;
		}
		
		mask1 >>= 1;
	}
}

void CArithmCode::InitializeEncode(void)
{
	int i, cxt;

	for(cxt=0; cxt<numContext; cxt++)
	{
		hTable[cxt] = ::GlobalAlloc(GHND, sizeof(int)*(numSymbol+1));
		Table[cxt] = (unsigned int *)::GlobalLock(hTable[cxt]); 
	}

	for(cxt=0; cxt<numContext; cxt++)
	{		
		for(Table[cxt][numSymbol]=0, i=numSymbol-1; i>=0; i--)
			Table[cxt][i] = Table[cxt][i+1]+1;
	}
	
	rack = 0;
	mask = 0x80;
	low = 0;
	high = 0xffff;
	underflowBits = 0;
}

void CArithmCode::convert_int_to_symbol(short cxt, short i)
{
	symbol.scale = Table[cxt][0];
	symbol.highRange = Table[cxt][i-1];
	symbol.lowRange = Table[cxt][i];
}

void CArithmCode::EncodeSymbol(void)
{
	range = high - low + 1;
	high = low + (unsigned short)(range * symbol.highRange / symbol.scale - 1);
	low += (unsigned short)(range * symbol.lowRange / symbol.scale);

	for(; ;)
	{
		if((high & 0x8000) == (low & 0x8000))
		{
			OutputBit(high & 0x8000);

			while(underflowBits > 0)
			{
				OutputBit(~high & 0x8000);
				underflowBits--;
			}
		}
		else if((low & 0x4000) && (!(high & 0x4000)))
		{
			underflowBits++;
			low &= 0x3fff;
			high |= 0x4000;
		}
		else break;

		low <<= 1;
		high <<= 1;
		high |= 1;
	}
}

void CArithmCode::UpdateModel(short cxt, short i)
{
	for(short j=i-1; j>=0; j--)
		Table[cxt][j]++;
}

void CArithmCode::AdaptiveEncode(short cxt, short i)
{
	convert_int_to_symbol(cxt, i);
	EncodeSymbol();
    UpdateModel(cxt, i);
}

short CArithmCode::InputBit(void)
{
	if(mask == 0x80)
		memFile->MemRead((unsigned char *)&rack, sizeof(char));
	
	short value;
	value = rack & mask;
    mask >>= 1;
	if(mask == 0)	mask = 0x80;

	return (value?1:0);
}

void CArithmCode::GetScale(short cxt)
{
	symbol.scale = Table[cxt][0];
}

void CArithmCode::InitializeDecode(void)
{
	int i, cxt;	

	for(cxt=0; cxt<numContext; cxt++)
	{
		hTable[cxt] = ::GlobalAlloc(GHND, sizeof(int)*(numSymbol+1));
		Table[cxt] = (unsigned int *)::GlobalLock(hTable[cxt]); 
	}

	for(cxt=0; cxt<numContext; cxt++)
	{		
		for(Table[cxt][numSymbol]=0, i=numSymbol-1; i>=0; i--)
			Table[cxt][i] = Table[cxt][i+1]+1;
	}
	
	rack = 0;
	mask = 0x80;
	low = 0;
	high = 0xffff;

	code = 0;
	for(i=0; i<16; i++)
	{
		code <<= 1;
		code += InputBit();
	}

	rack = 0;
	mask = 0x80;
}

void CArithmCode::GetCount(void)
{
	range = high - low +1;
	count = (((code -low) + 1) * symbol.scale - 1) / range;
}

short CArithmCode::convert_symbol_to_int(short cxt)
{
	short i;
	for(i=numSymbol; i>0; i--)
	{
		if((count >= Table[cxt][i]) && (count < Table[cxt][i-1]))
			break;
	}

	symbol.lowRange = Table[cxt][i];
	symbol.highRange = Table[cxt][i-1];

	return i;
}

void CArithmCode::RemoveSymbol(void)
{
	range = high - low + 1;

	high = low + (unsigned short)((range * symbol.highRange) / symbol.scale - 1);
	low += (unsigned short)((range * symbol.lowRange) / symbol.scale);

	for(; ;)
	{
		if((high & 0x8000) == (low & 0x8000))
		{
		}
		else if(((low & 0x4000) == 0x4000) && ((high & 0x4000) == 0))
		{
			code ^= 0x4000;
			low &= 0x3fff;
			high |= 0x4000;
		}
		else break;

		low <<= 1;
		high <<= 1;
		high |= 1;
		code <<= 1;
		code += InputBit();
	}
}

short CArithmCode::AdaptiveDecode(short cxt)
{
	short i;
    
	GetScale(cxt);
	GetCount( );
	i = convert_symbol_to_int(cxt);
	RemoveSymbol( );
	UpdateModel(cxt, i);
	
	return i;
}

void CArithmCode::Flush(void)
{
	OutputBit(low&0x4000);
	underflowBits ++;
	while(underflowBits > 0)
	{
		OutputBit(~low & 0x4000);
		underflowBits --;
	}
	OutputBits(0L, 16);	
}

void CArithmCode::Clear(void)
{
	short cxt;
	for(cxt=0; cxt<numContext; cxt++)
	{
		::GlobalUnlock(hTable[cxt]);
		::GlobalFree(hTable[cxt]);
	}
}

⌨️ 快捷键说明

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