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

📄 decoder.cpp

📁 Implementation for the Huffman Cod in Visual C++. Both, the encoder and the decoder take as input
💻 CPP
字号:
#pragma warning (disable: 4996) 

#include "Decoder.h"

using namespace std;
//int extern errno;

Decoder::Decoder(LPCWSTR inputFile, LPCWSTR outputFile)
{
	//********************************************************************
	/*if( _sopen_s(&m_inputFile,inputFile,_O_RDWR ,_SH_DENYNO,_S_IREAD) != 0)
	{
		cout << "Fisierul nu a putut fi deschis" << endl;
		perror("Motiv: ");
		exit(-1);
	}
	perror("Motiv");

		
	if( _sopen_s(&m_outputFile,outputFile,_O_CREAT,_SH_DENYNO,_S_IWRITE | _S_IREAD) != 0)
	{
		cout << "Fisierul de iesire nu a putut fi creat" << endl;
		perror("Motiv: ");
		exit(-1);
	}
	perror("Motiv");*/
	//********************************************************************
	
	// Deschide fisierele.
	m_inputFile = CreateFileW((LPCWSTR)inputFile    // file to open
								   , GENERIC_READ          // open for reading
								   , FILE_SHARE_READ       // share for reading
								   , NULL                  // default security
								   , OPEN_EXISTING         // existing file only
								   , FILE_ATTRIBUTE_NORMAL // normal file
								   , NULL
								   );
	
	if(m_inputFile == INVALID_HANDLE_VALUE)
	{
		cout << "Fisierul de intrare nu a putut fi deschis" << endl;
		exit(-1);
	}
	
	m_outputFile = CreateFileW((LPCWSTR)outputFile    // file to create
								   , GENERIC_WRITE          // open for reading
								   , FILE_SHARE_READ       // share for reading
								   , NULL                  // default security
								   , CREATE_ALWAYS         // existing file only
								   , FILE_ATTRIBUTE_NORMAL // normal file
								   , NULL
								   );
	if(m_outputFile == INVALID_HANDLE_VALUE)
	{
		// Inchide handleul fisierul de input.
		CloseHandle(m_inputFile);
		cout << "Fisierul de iesire nu a putut fi deschis" << endl;
		exit(-1);
	}

	m_contorBuffer = 0;
}

Decoder::~Decoder(void)
{
	/*_close(m_inputFile);
	_close(m_outputFile);*/

	CloseHandle(m_inputFile);
	CloseHandle(m_outputFile);
}

// Decode the input file
void Decoder::Decode()
{

	SYMBOL_TYPE symbol;		// simbolul curent
	DWORD bytesRead;		// nr de bytes cititi
	DWORD bytesWritten;		// numarul de bytes scrisi

	//citesc primul caracter
	//if((bytesRead = _read(m_inputFile,&symbol,sizeof(SYMBOL_TYPE))) > 0)
	if(ReadFile(m_inputFile, (LPVOID)&symbol, sizeof(symbol), &bytesRead, NULL) && bytesRead > 0) 
	{
	//	_write(m_outputFile,&symbol,bytesRead);
		WriteFile(m_outputFile, (LPCVOID)&symbol, sizeof(symbol), &bytesWritten, NULL);
		m_tree.Insert(symbol);
		m_tree.Sibling();
	}
	else
	{
		cout << "Nu s-a putut citi din fisier sau fiserul este gol" << endl;
		exit(-1);
	}

	// citesc restul caracterelor
	//while((bytesRead = _read(m_inputFile,&symbol,sizeof(SYMBOL_TYPE))) > 0)
	while(ReadFile(m_inputFile, (LPVOID)&symbol, sizeof(symbol), &bytesRead, NULL) && bytesRead > 0) 
	{
		// fiecare caracter este prelucrat in buffer
		WriteToBuffer(symbol);
	}
}


void Decoder::WriteToBuffer(SYMBOL_TYPE symbol)
{
	int aux;

	// newSymbol precizeaza daca am intalnit sau nu un simbol "esc"
	static bool newSymbol = false;

	for(int i = 0; i < SYMBOL_SIZE; i++)
	{
		// Adaug elementele in buffer
		aux = 1 << (SYMBOL_SIZE - 1 - i);
		m_buffer[m_contorBuffer++] = (((symbol & aux) == aux) ? 1 : 0);
		
		if(!newSymbol)
		{
			// Testez daca bufferul contine un caracter
			aux = TestBuffer();
			if(aux == -1)
			{
				// Am detectat codul "esc" si deci urmeaza un simbol nou
				newSymbol = true;
				m_contorBuffer = 0;
			}
			else
				if(aux != -2)
				{
					// codificarea curenta apartine simbolului "aux"
					// scriu simbolul "aux" in fisier
					WriteSymbolToFile((SYMBOL_TYPE)aux);
					m_contorBuffer = 0;
				}
		}

		// In caz ca am intalnit un simbol nou il afisez
		// si il introduc in arbore
		if(newSymbol == true && m_contorBuffer == SYMBOL_SIZE)
		{
			newSymbol = false;
			WriteBufferToFile();
			m_contorBuffer = 0;
		}
	}
}

// Tests if the buffer reprezent a symbol
	// Return:
	//		-1 : for "esc" symbol
	//		0  : if the buffer contains no symbol
	//		1  : if the buffer contains a symbol
int Decoder::TestBuffer()
{
	NOD_HUFFMAN *pAux = m_tree.GetRoot();

//	for(int i = (m_contorBuffer - 1); i >= 0; i--)
	for(unsigned int i = 0; i < m_contorBuffer; i++)
	{
		if(m_buffer[i])
			pAux = pAux->pRightChild;
		else
			pAux = pAux->pLeftChild;
	}
	
	// intorc -1 , corespunzator lui esc
	if(pAux->nrAparition == 0)
		return -1;
	// intorc simbolul
	if(pAux->symbol != L'')
		return pAux->symbol;
	// in buffer nu se afla nici o codifcare, intorc -2s
	return -2 ;
}

// Write the buffer to file
// Insert the written symbol in the tree
void Decoder::WriteBufferToFile()
{
	unsigned int aux = 0;
	SYMBOL_TYPE symbol;
	DWORD bytesWritten;

	for(unsigned int i = 0; i < m_contorBuffer; i++)
	{
		if(m_buffer[i])
			aux += (1 << (m_contorBuffer - 1 - i));
	}
	symbol = aux;

//	if(aux == 0)
//		exit(0);

	//_write(m_outputFile,&symbol,sizeof(SYMBOL_TYPE));
	WriteFile(m_outputFile, (LPCVOID)&symbol, sizeof(symbol), &bytesWritten, NULL);

	m_tree.Insert(symbol);
	m_tree.Sibling();
}

// Write a symbol to file
void Decoder::WriteSymbolToFile(SYMBOL_TYPE symbol)
{
	DWORD bytesWritten;

	//_write(m_outputFile,&symbol,sizeof(SYMBOL_TYPE));
	WriteFile(m_outputFile, (LPCVOID)&symbol, sizeof(symbol), &bytesWritten, NULL);
	m_tree.Insert(symbol);
	m_tree.Sibling();
}

⌨️ 快捷键说明

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