📄 huffmancoder.cpp
字号:
// HuffmanCoder.cpp: implementation of the HuffmanCoder class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HuffmanTest.h"
#include "HuffmanCoder.h"
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define BYTESWAP(In_Int) ( ((In_Int & 0xFF000000) >> 24) | ((In_Int & 0x00FF0000) >> 8) | ((In_Int & 0x0000FF00) << 8) | ((In_Int & 0x000000FF) << 24) )
#pragma warning (disable: 4786)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HuffmanCoder::HuffmanCoder()
{
EncDict=DecDict=NULL;
MyListener=NULL;
}
HuffmanCoder::~HuffmanCoder()
{
}
//////////////////////////////////
// Interface helpers
void HuffmanCoder::SetProgressHelper(ProgressListener *NewListener)
{
MyListener=NewListener;
}
void HuffmanCoder::SetEncDict(HuffmanDict *NewEncDict)
{
EncDict=NewEncDict;
}
void HuffmanCoder::SetDecDict(HuffmanDict *NewDecDict)
{
DecDict=NewDecDict;
}
//////////////////////////////////
// Main interface
unsigned int HuffmanCoder::Encode(FILE *SourceStream, FILE *TargetStream)
{
if ((!EncDict) || (!MyListener))
return 0;
HuffmanDict::EncEntry *CodeTable=EncDict->GetEncodeDict();
unsigned int OutSize=0, InPos=0;
unsigned int OutBuff=0;
unsigned char CurrSymbol,OutBuffLen=0;
HuffmanDict::EncEntry *CurrCode;
while (!feof(SourceStream))
{
fread(&CurrSymbol,1,1,SourceStream);
CurrCode=&(CodeTable[CurrSymbol]);
InPos++;
if ((CurrCode->CodeLen+OutBuffLen)<33)
{
OutBuff|=(CurrCode->Code) >> OutBuffLen;
OutBuffLen+=CurrCode->CodeLen;
//A special case to speed up writing.
if (OutBuffLen==32)
{
#if HUFFY_LITTLEENDIAN
OutBuff=BYTESWAP(OutBuff);
#endif
fwrite(&OutBuff,4,1,TargetStream);
OutSize+=4;
OutBuff=0;
OutBuffLen=0;
}
}
else
{
OutBuff|=(CurrCode->Code) >> (OutBuffLen);
#if HUFFY_LITTLEENDIAN
OutBuff=BYTESWAP(OutBuff);
#endif
fwrite(&OutBuff,4,1,TargetStream);
OutSize+=4;
OutBuff=(CurrCode->Code) << (32-OutBuffLen);
OutBuffLen=CurrCode->CodeLen-(32-OutBuffLen);
}
if ((InPos & 0xFFF)==0x800)
MyListener->Update(InPos);
}
//Write the final 4 bytes.
if (OutBuffLen)
{
#if HUFFY_LITTLEENDIAN
OutBuff=BYTESWAP(OutBuff);
#endif
fwrite(&OutBuff,4,1,TargetStream);
OutSize+=4;
}
return OutSize;
}
unsigned int HuffmanCoder::Decode(FILE *SourceStream, FILE *TargetStream, unsigned int OutMaxSize)
{
if ((!DecDict) || (!MyListener))
return 0;
unsigned int x;
HuffmanDict::NTTEntry *TransTable=DecDict->GetNTTable(x);
x=0;
HuffmanDict::NTTEntry *CurrEntry;
unsigned char CurrByte,CurrName=0;
while ((!feof(SourceStream)) && (OutMaxSize>x))
{
fread(&CurrByte,1,1,SourceStream);
/*Look up the current transition table entry,
based on the current state & the bytes in the stream.*/
CurrEntry=&(TransTable[(CurrName << 8) + CurrByte]);
if (x+CurrEntry->SymbolCount>OutMaxSize)
fwrite(CurrEntry->SymbolA,OutMaxSize-x,1,TargetStream);
else
fwrite(CurrEntry->SymbolA,CurrEntry->SymbolCount,1,TargetStream);
x+=CurrEntry->SymbolCount;
//Go to the next state.
CurrName=CurrEntry->NextNodeName;
if ((x & 0xFFF)==0x800)
MyListener->Update(x);
}
return x;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -