📄 main.cpp
字号:
// main.cpp: implementation of the Cmain class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Comp.h"
#include "main.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
Cmain::Cmain()
{
file_size = 0;
heap_length = 0;
compress_charcount = 0;
for (int m=0; m<256; m++)
{
code[m] = 0;
code_length[m] = 0;
heap[m] = 0;
}
heap[256] = 0;
for (m=0; m<512; m++)
{
father[m] = decomp_tree[m] = 0;
countf[m] = 0;
}
}
void Cmain::heap_function(unsigned short heap_login)
{
unsigned short child;
unsigned long temp_heap_value = heap[heap_login];
while( heap_login <= (heap_length / 2))
{
child = (heap_login * 2);
if(child < heap_length)
if(countf[heap[child]] > countf[heap[child + 1]])
child++;
if(countf[heap[child]] > countf[temp_heap_value])
break;
else
heap[heap_login] = heap[child];
heap_login = child;
}
heap[heap_login] = temp_heap_value;
}
void Cmain::build_tree()
{
unsigned long temp_heap_value_1;
unsigned short father_point_find_countf_pos ;//= 256;
while( heap_length != 1)
{
temp_heap_value_1 = heap[1];
heap[1] = heap[heap_length--];
heap_function(1);
father_point_find_countf_pos = heap_length + 255;//记录父节点的位置(倒序,父节点由小到大向256排)
countf[father_point_find_countf_pos] = countf[heap[1]] + countf[temp_heap_value_1];//记录子女节点的频率的和,用来寻找更大的一个父节点
father[temp_heap_value_1] = father_point_find_countf_pos; //正代表左孩子
father[heap[1]] = -father_point_find_countf_pos; //负代表右孩子
heap[1] = father_point_find_countf_pos;
heap_function(1);
}
father[256] = 0;
}
unsigned short Cmain::build_table()
{
unsigned short cur_bit;
unsigned short cur_length,allbit;
unsigned short m4;
short father_value; //记录父节点数组的值,当值为0(father[256] = 0)时,该叶子节点的编码完成。
//我在这里犯了一个严重的错误!!!原因时father的值因为带了方向,有正负之分,
//而我把它声明成unsigned short !!!
for(m4 = 0; m4 < 256; m4++)
{
if(countf[m4])
{
cur_bit = 1;
cur_length = allbit = 0;
father_value = father[m4];
while(father_value)
{
if(father_value < 0)
{
allbit += cur_bit; // 在右面子女,权值为1
father_value = -father_value;
}
father_value = father[father_value];
cur_bit <<= 1; //cur_bit每步都会向前进一位,为了防止出现1,每出现1,allbit+2,否则加0;
//这样便可以计算二进制数字所表示的大小
cur_length++; //二进制数字的长度。长度和大小确定一个二进制。
}
code[m4] = allbit;
if( cur_length > 16)
return (0);
else
code_length[m4] = (unsigned char)cur_length;
}
else
code[m4] = code_length[m4] = 0;
}
return (1);
}
void Cmain::compress_function(char* infilename,char* outfilename)
{
unsigned short cur_code;
unsigned short cur_length;
unsigned short temp_asc;
short m6;
unsigned long m5;
unsigned int thebyte = 0;
unsigned long curbyte = 0;
short curbit = 7;
FILE *ifile,*ofile;
ifile = fopen (infilename, "rb");
ofile = fopen (outfilename, "wb");
fwrite (&file_size, sizeof (file_size), 1, ofile); // 在这里记录了code[]和code_length[],为了解压缩提供了必要得信息
fwrite (code, 2, 256, ofile);
fwrite (code_length, 1, 256, ofile);
fseek (ifile, 0L, 0);
for(m5 = 0; m5 < file_size; m5++)
{
temp_asc = (unsigned short)getc(ifile);
//cout<<temp_asc<<" temp_asc"<<endl;
cur_code = code[temp_asc];
cur_length = (unsigned short)code_length[temp_asc];
for(m6 = cur_length - 1; m6 >= 0; m6--)
{
if((cur_code >> m6) & 1)
thebyte |= (char) (1 << curbit);
if(--curbit < 0)
{
putc(thebyte,ofile); //最高位为0.
thebyte = 0;
curbyte++;
curbit = 7;
}
}
}
putc(thebyte,ofile);
compress_charcount = ++curbyte;
fclose(ofile);
fclose(ifile);
}
void Cmain::build_decomp_tree ()
{
register unsigned short loop1;
register unsigned short current_index;
unsigned short loop;
unsigned short current_node = 1;
decomp_tree[1] = 1;
for (loop = 0; loop < 256; loop++)
{
if (code_length[loop])
{
current_index = 1;
for (loop1 = code_length[loop] - 1; loop1 > 0; loop1--)
{
current_index = (decomp_tree[current_index] << 1) +
((code[loop] >> loop1) & 1);
if (!(decomp_tree[current_index]))
decomp_tree[current_index] = ++current_node;
}
decomp_tree[(decomp_tree[current_index] << 1) +
(code[loop] & 1)] = -loop;
}
}
}
void Cmain::decompress_image (FILE *ifile,FILE *ofile)
{
register unsigned short ctemp = 1;
register char curchar;
register short bitshift;
unsigned long charcount = 0;
while (charcount < file_size)
{
curchar = (char) getc (ifile);
for (bitshift = 7; bitshift >= 0; --bitshift)
{
ctemp = (ctemp << 1) + ((curchar >> bitshift) & 1);
if (decomp_tree[ctemp] <= 0)
{
putc ((int) (-decomp_tree[ctemp]), ofile);
if ((++charcount) == file_size)
bitshift = 0;
else
ctemp = 1;
}
else
ctemp = decomp_tree[ctemp];
}
}
}
int Cmain::Decompression_function(char * infilename, char * outfilename)
{
FILE* ifile,*ofile;
if( ifile = fopen (infilename, "rb"))
{
fread (&file_size, sizeof (file_size), 1, ifile); //首先
fread (code, 2, 256, ifile);
fread (code_length, 1, 256, ifile);
build_decomp_tree ();
if ((ofile = fopen (outfilename, "wb")) != NULL)
{
decompress_image(ifile,ofile);
fclose (ofile);
}
else
{
return 0;
}
fclose (ifile);
}
else
{
MessageBox(NULL, TEXT("没找到需要解压缩的文件,请检查路径!"),TEXT("DECOM_ERROR"),MB_OK);
}
return 1;
}
void Cmain::Clear()
{
file_size = 0;
heap_length = 0;
compress_charcount = 0;
for (int m=0; m<256; m++)
{
code[m] = 0;
code_length[m] = 0;
heap[m] = 0;
}
heap[256] = 0;
for (m=0; m<512; m++)
{
father[m] = decomp_tree[m] = 0;
countf[m] = 0;
}
}
Cmain::~Cmain()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -