Exemple #1
0
int main (void )
{
	
	HuffmanTree ht;
    HuffmanCode hc;
    printf ("\n\n\t\t\tWellcome!!!\n\n");

    char ch ;
    ch = getchar ();
    
	int w[N] = {0}; //字符频度
    Init (ht, w);
    CrtHuffmanTree (ht, w);
    CrtHuffmanCode (ht, hc);
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf ("-----------------------简单文本压缩工具------------------------\n");
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf ("****                                                       ****\n");
    printf ("****              1、压缩. (Local.souce -> Local.zig)      ****\n");
    printf ("****                                                       ****\n");
    printf ("****              2、解压. (Local.zig -> Local.final)      ****\n");
    printf ("****                                                       ****\n");
    printf ("****                                local.code (编码文件)  ****\n");
    printf ("****                                ( 自行检查相应文件 )   ****\n");
    printf ("****                                  Enter 'q' to quit    ****\n");
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    printf ("Now your choice: ");
    setbuf (stdin, NULL);
    ch = getchar ();
    if (ch == '1')
        compress (ht, hc);
    else if(ch == '2')
        uncompress ();
    else if (ch == 'q')
        return 0;
	return 0;
}
Exemple #2
0
//压缩
void Compress(char *desFile)
{
    MyType maxLen,minLen,ch,bits,n,finalLength;
    int i;
    short LeafNum,codeNum;
    WeightType count = 0,Length=0,FileLength;
    FILE *fp,*compressFile;
    SeqQueue *Q;
    HTNode *ht = NULL;
    char **hc= NULL,**Map = NULL,*p;
    char zip[100];

    strcpy(zip, desFile);
    strcat(zip, ".hf");


    compressFile = fopen(zip,"wb");
    fp = fopen(desFile,"rb");//原文件

    if(!fp || !compressFile)
    {
        puts("Cannot open file.");
        return ;
    }

    ht = CreatHFM(fp,&LeafNum,&FileLength);//创建哈夫曼树,统计叶子个数和原文件长度
    if( !FileLength )
    {	//	printf("文件为空,无须压缩...");
        fclose(fp);
        fclose(compressFile);
        free(ht);
        return ;
    }
    Q = (SeqQueue *)malloc(sizeof(SeqQueue));
    InitQueue(Q);
    hc = CrtHuffmanCode(ht,LeafNum);//取得哈夫曼0、1编码,hc的长度为LeafNum
    //Map为了取编码好定位,再建立全部(256个)//
    Map = (char **)malloc(N*sizeof(char *));//字符编码表
    if(!Map)
    {
        puts("申请空间失败");
        return ;
    }

    for(i = 0;i < N;i++)//初始化
        Map[i] = NULL;

    for(i = 0;i < LeafNum;i++)// 定位,编码指针数组Map[256]
        Map[(int)(ht[i].ch)] = hc[i];

    fseek(compressFile,sizeof(WeightType)+sizeof(short)+6*sizeof(MyType),SEEK_SET);//先占个位置
    //填压缩叶子编码剩几个和最长编码长getchar();

    MaxMinLength(compressFile,ht,hc,LeafNum,&maxLen,&minLen);//获得最长码串长度,顺便填写字符对应编码长
    free(ht);
    codeNum = CodeToFile(compressFile,hc,LeafNum,Q,&finalLength);//把字符转成其二进制编码写入文件,返回压成多少个

    rewind(compressFile);//使文件指针移到开始printf("ftelll = %d\n",ftell(compressFile));
    fseek(compressFile,sizeof(WeightType)+sizeof(MyType),SEEK_SET);
    fwrite(&LeafNum,sizeof(short),1,compressFile);//写入叶子个数
    fwrite(&maxLen,sizeof(MyType),1,compressFile);//最长码串长度
    fwrite(&minLen,sizeof(MyType),1,compressFile);//最短码串长度
    fwrite(&codeNum,sizeof(short),1,compressFile); //填写叶子编码压多少个
    fwrite(&finalLength,sizeof(MyType),1,compressFile); //最后剩
    fseek(compressFile,2*LeafNum*sizeof(MyType)+codeNum,SEEK_CUR);

    fseek(fp,0,SEEK_SET);
    printf("Please wait a minute,compressing...");
    while(count < FileLength)
    {
        ch = fgetc(fp);
        ++count;
        for(p = Map[ch];*p != '\0';p++)
            In_seqQueue(Q,*p);
        while(Q->length > 8)//	printf("OutQueue: ");
        {
            bits = GetBits(Q);//出队8个元素,合成一个字节
            fputc(bits,compressFile);//fwrite(&bits,1,1,compressFile);
            Length++;//	printf("压:%c\n",bits);
        }
    }
    //最后一个bits ;
    finalLength = Q->length;//printf("最后剩Qlength:%d\n",Q->length);
    n = 8 - finalLength;
    bits = GetBits(Q);
    //printf("最后Qlength:%d\n",Q->length);
    for(i = 0;i < n;i++)
        bits = bits << 1;//以‘0’补
    fwrite(&bits,sizeof(MyType),1,compressFile);
    Length++;

    rewind(compressFile);//原文件长fwrite(&FileLength,sizeof(WeightType),1,compressFile);
    fwrite(&Length,sizeof(WeightType),1,compressFile);//压缩后的长
    fwrite(&finalLength,sizeof(char),1,compressFile);//最后的串长

    Length = Length + 12 + codeNum;

    if(Length >= FileLength)
        puts("\nCompression rate: 0.0%");
    else
        printf("\nCompression rate: %.2lf%c\n",(double)((FileLength-Length)/(double)FileLength)*100.0,'%');

    fclose(fp);
    fclose(compressFile);
    free(Q);
    free(hc);
    free(Map);
}
Exemple #3
0
//解压缩
void uncompress ()
{
	FILE *cfp, *ucfp, *message, *data;
	char *code ;//解压文本编码
	int ch, i, j;
	int flag;
	int length = 0; //压缩文件长度
    int hcount = 0;
	static int size = 8 * sizeof (char);
    char temp[N];
    int count1 ;//解压文本关键字数
    HuffmanTree ht;
    HuffmanCode hc;
    if ((data = fopen ("Local.data", "rb")) == NULL)
    {
        printf ("Open failed\n");
        exit (0);
    }
    fread (ht, sizeof (HuffmanTree), 1, data);
    for (count1 = 1; ht[count1].ch ; count1++);
    count1--;
    CrtHuffmanCode (ht, hc);
    //解压
    if ((code = (char *) malloc (MAX * sizeof (char))) == NULL)
	{
		printf ("failed!\n");
		exit (0);
	}
	memset (code, 0, sizeof (code));
	if ((cfp = fopen ("Local.zig", "rb")) == NULL)
	{
		printf ("Open %s failed!\n", "Local.zig");
		exit (0);
	}
    if ((message = fopen ("message.f", "r")) == NULL)
        exit (0);
    fread (&flag, sizeof (int), 1, message);
	fread (&length, sizeof (int), 1, message);
	while ((ch = getc (cfp)) != EOF)
	{
		hcount++;
        memset (temp, 0, sizeof (temp));
		for (i = size - 1; i >= 0; i--, ch >>= 1)
			temp[i] = (1&ch) + '0';
        if (hcount == length) 
            temp[flag] = '\0';
		strcat (code, temp);
	}
 //译码
	int len_cd;//最长字符编码	
	char cd_1[MAX] = {0, 0, 0};
    char str[MAX] = {0,0,0};
	int tag; //判断是否匹配成功
    int len_ch = 0;//解压后文本长
	int len = 0;//已译码数
    len_cd = strlen (hc[1]);
	
    for (i = 2; i <= count1; i++)
		if (strlen (hc[i]) > len_cd)
			len_cd = strlen (hc[i]);
	while (copy (code, cd_1, len))
	{
		for (i = len_cd; i > 0; i--)
		{
			memset (temp, 0, sizeof (temp)); //清空temp[]
			strncpy (temp, cd_1, i);
			tag = 0;
			for (j = 1; j <= count1 && tag == 0; j++)
				if (strcmp (temp, hc[j]) == 0)
				{
					str[len_ch++] = ht[j].ch;
					tag = 1;
					len += i;
				}
			if (tag == 1)
				break;	
		}
	}
   
	if ((ucfp  = fopen ("Local.final", "wb")) == NULL)
	{
		printf ("Open %s failed!\n", "Local.decode");
		exit (0);
	}
    fputs (str, ucfp);
    fclose (ucfp);
    fclose (message);
	fclose (cfp);
    fclose (data);
	free (code);
    printf ("Uncompress succeed!\n");
}