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

📄 huffman.c

📁 Implementation of Huffman code in C
💻 C
字号:
/* * Definition for Huffman coding  * * vim: ts=4 sw=4 cindent nowrap */#include <stdlib.h>#include <stdio.h>#include "bitio.h"typedef struct{	unsigned long count;	int parent, lchild, rchild;} HNODE;HNODE hTree[512];typedef struct{	unsigned long code;	int codelength;} HCODE;HCODE hCode[256];unsigned long counts[256];void BuildCounts( FILE *fp);int BuildTree( void);void BuildCode( void);void HuffmanEncode( FILE *fp, BITFILE *bf);void HuffmanDecode( BITFILE *bf, FILE *fp);void BuildCounts( FILE *fp){	int c;	for( c=0; c<256; c++) counts[c] = 0;	while( EOF!=(c=fgetc(fp))) counts[c]++;}int BuildTree( void){	int i;	int min1, min2, nextfree;	for( i=0; i<256; i++){		hTree[i].count = counts[i];		hTree[i].parent = 0;		hTree[i].lchild = 0;		hTree[i].rchild = 0;	}	for( i=256; i<512; i++){		hTree[i].count = 0;		hTree[i].parent = 0;		hTree[i].lchild = 0;		hTree[i].rchild = 0;	}	hTree[511].count = 0xFFFFFFFFL;	nextfree = 256;	for( ;;nextfree++){		min1=min2=511;		for( i=0; i<nextfree; i++){			if( 0<hTree[i].count && 0==hTree[i].parent){ // free node				// update min1,min2, for min1, min2 and i				if( hTree[i].count < hTree[min1].count){					min2=min1;					min1=i;				}else if( hTree[i].count < hTree[min2].count){					min2=i;				}			}		}		if( 511==min2)  break;  //done if only one node left( the root)		// now min1,min2 are the least weighted nodes before nextfree		// update nextfree as parents of min1,min2		hTree[nextfree].count = hTree[min1].count + hTree[min2].count;		hTree[nextfree].lchild = min1;		hTree[nextfree].rchild = min2;		// min1 and min2 need to be updated too		hTree[min1].parent = nextfree;		hTree[min2].parent = nextfree;	}	nextfree --;	return nextfree;}void BuildCode( void){	unsigned long code;	unsigned long mask;	int n, codelength;	int currentNode, parentNode;	for( n=0; n<256; n++){		codelength = 0;		code = 0;		mask = 1;		for( currentNode=n, parentNode=hTree[currentNode].parent; 				0!=parentNode; 				currentNode=parentNode, parentNode=hTree[parentNode].parent){			if( currentNode == hTree[parentNode].rchild)				code |= mask;			mask <<= 1;			codelength++;		}		hCode[n].code = code;		hCode[n].codelength = codelength;	}}void HuffmanEncode( FILE *fp, BITFILE *bf){	unsigned long filelength;	int i;	BuildCounts( fp);	fseek( fp, 0, SEEK_END);	filelength = ftell( fp);	BitsOutput( bf, filelength, 4*8);	for( i=0; i<256; i++) BitsOutput( bf, counts[i], 4*8);	BuildTree( );	BuildCode( );	fseek( fp, 0, SEEK_SET);	while( EOF!=(i=fgetc(fp))){		BitsOutput( bf, hCode[i].code, hCode[i].codelength);	}}void HuffmanDecode( BITFILE *bf, FILE *fp){	unsigned long filelength;	int i;	int rootNode;	int node;	filelength = BitsInput( bf, 4*8);	if( -1 == filelength) filelength = 0;	// reading the counts	for( i=0; i<256; i++) counts[i] = BitsInput( bf, 4*8);	rootNode = BuildTree( );	while( 0<filelength){		node = rootNode;		do{			if( 0 == BitInput( bf)) node = hTree[node].lchild;			else node = hTree[node].rchild;		}while( 255<node);		fputc( node, fp);		filelength --;	}}int main( int argc, char **argv){	FILE *fp;	BITFILE *bf;	if( 4>argc){		fprintf( stdout, "usage: %s <o> <ifile> <ofile>\n", argv[0]);		fprintf( stdout, "\t<o>: E or D reffers encode or decode\n");		fprintf( stdout, "\t<ifile>: input file name\n");		fprintf( stdout, "\t<ofile>: output file name\n");		return -1;	}	if( 'E' == argv[1][0]){ // do encoding		fp = fopen( argv[2], "rb");		bf = OpenBitFileOutput( argv[3]);		if( NULL!=fp && NULL!=bf){			HuffmanEncode( fp, bf);			fclose( fp);			CloseBitFileOutput( bf);			fprintf( stdout, "encoding done\n");		}	}else if( 'D' == argv[1][0]){	// do decoding		bf = OpenBitFileInput( argv[2]);		fp = fopen( argv[3], "wb");		if( NULL!=fp && NULL!=bf){			HuffmanDecode( bf, fp);			fclose( fp);			CloseBitFileInput( bf);			fprintf( stdout, "decoding done\n");		}	}else{	// otherwise		fprintf( stderr, "not supported operation\n");	}	return 0;}

⌨️ 快捷键说明

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