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

📄 huffmancoder.cpp

📁 有关huffman的程序对大家学习数据结构有好处但不是所有人都用得上
💻 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 + -