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

📄 huffcode&decode.h

📁 数据结构的一个作业
💻 H
字号:
#include "struct.h"
# include "string.h"
#include <iostream>
#include<fstream>
#include "hufftree.h"
#include "huff_encode.h"


/***************************************
*                  蔡敏
***************************************/


void HaffCompress(HaffCode* hc,int n,char* filename, char_record* w,char* dir)
{
	int i,j;
	char ch;
	char*newfilename;
	newfilename=(char* )malloc(30*sizeof(char));
	ofstream ofile;
	ifstream infile;

	infile.open(filename,ios_base::binary);
	if(!infile){
		cout<<"error: unable to open input file!\n";
	}

	for(i=0;filename[i]!=0;i++)
		;
	strcpy(newfilename, dir);
	strcat(newfilename, ".var"); //  may be  "war"
	ofile.open(newfilename,ios_base::binary|ios_base::app);

	// 写入文件名长度,一字节
	ofile.put((unsigned char)i);
	
	cout<<"HaffCompress...[ ";
	for(j = 0; j < i; j++){
		ofile.put(filename[j]);
		cout<<filename[j];
	}
	cout<<" ]"<<endl;

	char mask=0x000000ff;
	// 写入 不同字符数量
	ofile.put((unsigned char)n);

	// 写入 各个编码的权重
	for(i=0;i<n;i++) {
		ofile.put(w[i].ascii_code);
		char *s = new char[4];
		//char *s=new char(4);/////////////////////////////   X
		for(int j=3;j>=0;j--) {
			s[j] = (unsigned long)(unsigned char)w[i].weight & mask;
			w[i].weight >>= 8;
		}
		for(int j = 0; j <= 3; j++)
			ofile.put(s[j]);
	}

	// 将文件内容按照huff编码写入文件
	char ch2  = 0x00;
	int count = 0;
	bool  left = true;
	ch = infile.get();
	while(!infile.eof()) {
		for(i = 0; i < n; i++) {
			if((unsigned char)ch == hc[i].ascii_code) {
				for(j = hc[i].start + 1; j < n; j++) {
					if(hc[i].bit[j]==1) {
						ch2 += 1;
					}
					else {
						ch2 += 0;
					}
					count++;
					if(count!=8) {
						ch2 <<= 1;
						left = true;
					}
					else {
						ofile.put(ch2);
						count = 0;
						ch2   = 0;
						left = false;
					}
				}
				break;
			}
		}
		infile.get(ch);//继续读下一个字符 
	}
	if( left ) {
	//if(count!=8) {
		for(i = 1; i < 8 - count; i++) {
			ch2<<=1;
		}
		ofile.put(ch2);
	}
	ofile.close();
	infile.close();
}



void HaffDecompress(char* filename,char* dir)//解压文件 
{
	ofstream ofile;
	ifstream infile;
	char * newfilename;
	char ch;
	newfilename =(char* )malloc(30*sizeof(char));
	strcpy(newfilename,dir);
	strcat(newfilename,"copy");

	char* temppath;
	temppath = (char* )malloc(30*sizeof(char));

	int k;
	for(k=0;dir[k] != 0;k++)
		;

	CreateDirectory((LPCSTR)newfilename, NULL);////////////////////////		X
	infile.open(filename,ios_base::binary);
	// 读入的是文件名长度
	infile.get(ch);
	while(!infile.eof()){

		cout<<"file name len:"<<(int)ch<<endl;
		if(ch <= 0) {  system("pause"); exit(5);      }

		int i = 0, j = 0, n = 0, n2 = 0;
		n2 = (unsigned int) ch;
		char * chs = new char[n2+1];
		// 读入文件名
		//char chs[n2+1];	//////////////////							X
		for(i=0;i<n2;i++){
			infile.get(ch);
			chs[j++] = ch;
		}
		chs[j] = 0; 
		for(i = 0; i < n2; i++) {
			chs[i] = chs[i+k-4];
		}
		strcpy(temppath, newfilename);
		strcat(temppath, chs);

		char p[256];
		j = 0;
		for(i=0; temppath[i] != 0; i++) {
			p[j] = temppath[i];
			if(temppath[i]=='\\') {
				p[j]=0;
				CreateDirectory(&p[0],NULL);/////////////////////		X
				p[j]='\\';
			}
			j++;
		}

		ofile.open(temppath,ios_base::binary);
		cout<<"Decompress ... "<<temppath<<endl;      

		// 字典大小
		infile.get(ch);
		n = (unsigned int)ch;
		if(n == 0)
			n = 256; 
		if(n < 0)
			n += 256;

		char_record *w = new char_record[n];///////////////////////////////////////////		X
		//char_record w[n];///////////////////////////////////////////		X
		memset(w, 0, sizeof(w));//把结构数组w赋值为0       //////////////    X

		// 读入各个权重
		unsigned long long m;
		for(j = 0; j < n; j++) {
			infile.get(ch);
			w[j].ascii_code=ch;
			m=0;
			for(i=1;i<=4;i++){
				infile.get(ch);
				m|=(unsigned long)(unsigned char)ch&0x000000ff;
				m<<=8;
				m &= 0xffffff00;
			}
			m>>=8;
			w[j].weight=m;
		}

		// 重新根据这些权重生成haff树
		HaffNode* ht = hufftree(w,n);
		HaffCode* hc = huff_encode(w,n,ht);

		unsigned long long size=0,tempsize=0;
		for(i=0;i<n;i++)//输出编码信息 
			size += (n-hc[i].start-1) * hc[i].weight;

		int count = 0, y;
		char mask = 0x80, temp;
		j = 2 * n - 2;

		//infile.get(ch);
		while(tempsize < size)//逐字符读入,直到文件读结束 
		{
			infile.get(ch);
			temp = ch;
			if(size - tempsize < 8) {
				y = size - tempsize;
			}
			else {
				y=8;
			}

			for(count = 0; count < y; count++) {
				if(temp & mask) {
					j = ht[j].rchild;
				}
				else {
					j = ht[j].lchild;
				}
				if(ht[j].lchild == -1 && ht[j].rchild == -1) {
					ofile.put(ht[j].ascii_code);
					j = 2*n-2;
				}
				temp <<= 1;
				tempsize ++;
			}
			//infile.get(ch);
		}
		ofile.close();
		infile.get(ch);
	}
	// cout<<"您解压后的文件的文件名为"<<chs<<endl;     
	infile.close();
	// ofile.close();
}    

⌨️ 快捷键说明

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