📄 huffcode&decode.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 + -