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

📄 main.cpp

📁 一个小老乡写的压缩、解压软件
💻 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 + -