📄 arithmcode.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 + -