📄 encoder.cpp
字号:
#pragma warning (disable: 4996)
#include "Encoder.h"
#include <math.h>
using namespace std;
Encoder::Encoder(LPCWSTR inputFile, LPCWSTR outputFile)
{
//********************************************************************
/*if( _sopen_s(&m_inputFile,inputFile,_O_RDONLY,_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 writing
, 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;
}
Encoder::~Encoder(void)
{
/*_close(m_inputFile);
_close(m_outputFile);*/
CloseHandle(m_inputFile);
CloseHandle(m_outputFile);
}
void Encoder::Encode()
{
SYMBOL_TYPE symbol; // simbolul curent
DWORD bytesRead; // numarul de bytes cititi
DWORD bytesWritten; // numarul de bytes scrisi
bool isLeaf; // retine daca simbolul se afla printre frunze
//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)
{
isLeaf = false;
for(unsigned int i = 0; i < m_tree.nrLeaves; i++)
{
// Daca se afla in arbore scriu codul curent
if(m_tree.m_leaves[i]->symbol == symbol)
{
isLeaf = true;
WriteToBuffer(i);
m_tree.Insert(symbol);
m_tree.Sibling();
break;
}
}
// daca nu se afla in arboare scriu intai codul "esc"
if(!isLeaf)
{
WriteToBuffer((unsigned int)0);
m_tree.Insert(symbol);
m_tree.Sibling();
WriteToBuffer((SYMBOL_TYPE)symbol);
}
}
// La sfarsit mai adaug codul "esc" pentru a evita
// confuziile in caz de neumplere a bufferului
if(m_contorBuffer > 0)
{
WriteToBuffer((unsigned int)0);
// dupa codul "esc" adaug 0 pt ca noul caracter sa fie vid
if(m_contorBuffer != 0)
{
for(int i = m_contorBuffer; i < SYMBOL_SIZE; i++)
m_buffer[i] = 0;
WriteBufferToFile();
}
}
}
// Write the codification of the leaf in buffer
// When buffer become full it's written to file
void Encoder::WriteToBuffer(unsigned int leafNumber)
{
static bool bufferAux[SYMBOL_NUMBER]; // retine drumul frunze-> radacina
int contorBufferAux = 0;
NOD_HUFFMAN *pAux = m_tree.m_leaves[leafNumber]->pParrent;
if(pAux->pLeftChild == m_tree.m_leaves[leafNumber])
bufferAux[contorBufferAux++] = 0;
else
bufferAux[contorBufferAux++] = 1;
while((pAux != NULL) && (pAux != m_tree.m_pRoot))
{
if(pAux->pParrent->pLeftChild == pAux)
bufferAux[contorBufferAux++] = 0;
else
bufferAux[contorBufferAux++] = 1;
pAux = pAux->pParrent;
}
// scriu in buffer codul corect( inversul din bufferAux)
for(int i = (contorBufferAux - 1); i >= 0; i--)
{
m_buffer[m_contorBuffer++] = bufferAux[i];
if(m_contorBuffer == SYMBOL_SIZE)
{
WriteBufferToFile();
m_contorBuffer = 0;
}
}
}
// Write the codification of the leaf in buffer
// When buffer become full it's written to file
void Encoder::WriteToBuffer(SYMBOL_TYPE symbol)
{
unsigned int aux;
for(int i = (SYMBOL_SIZE - 1); i >= 0; i--)
{
aux = 1 << i;
m_buffer[m_contorBuffer++] = (((symbol & aux) == aux) ? 1 : 0);
if(m_contorBuffer == SYMBOL_SIZE)
{
WriteBufferToFile();
m_contorBuffer = 0;
}
}
}
// Write the buffer to file
void Encoder::WriteBufferToFile()
{
unsigned int aux = 0;
SYMBOL_TYPE symbol;
DWORD bytesWritten;
//static SYMBOL_TYPE fileBuffer[2000];
//static int fileBufferContor = 0;
// Creez intai simbolul ce va fi scris
for(int i = (SYMBOL_SIZE - 1); i >= 0 ; i--)
{
if(m_buffer[i])
aux += (1 << (SYMBOL_SIZE - 1 - i));
}
symbol = aux;
// fileBuffer[fileBufferContor++] = symbol;
//if (fileBufferContor == 1999)
//{
//_write(m_outputFile,&symbol,SYMBOL_SIZE);
WriteFile(m_outputFile, (LPCVOID)&symbol, sizeof(symbol), &bytesWritten, NULL);
//}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -