#include #include
#include
#defineDNUM 64//define data number 8*8#defineLOOP 10000 //times of compressiontypedef struct
{unsigned
short weight, data;unsigned
short parent, lchild, rchild;} HuffNode;
typedef struct
{unsigned
char code;unsigned
short codelength;} HuffCode;
unsigned int fCount[256] = {0};
unsigned int data_num;
unsigned int code_size;
unsigned int last_bit;
void FrequencyCount(unsigned char*);//频率统计void HuffSelect(HuffNode*, int, int*,
int*); //从结点中选出权最小的两个节点void HuffmanCodeTable(HuffNode*,
HuffCode*); //构造huffman树,生成huffman编码表void HuffmanCompress(unsigned char*,
unsigned char *, HuffCode*); //压缩数据void BitPrint(unsigned char*);//按位打印结果,用于调试void main()
{int
i, j, loop;//variable for loopHuffNode
hfdata[2*DNUM] = {{0, 0, 0, 0, 0}};//Huffman nodeHuffCode
code_table[256] = {{0, 0}};//code table will be searched by
subscriptunsigned
char hfcode[2*DNUM];//output codetime_t
time1, time2;/*unsigned char pixel[DNUM] = {1,2,3,4,
1,2,3,4, 1,2,3,4, 1,1,1,1};*/
/*unsigned char pixel[DNUM] = {139,144,149,153,155,155,155,155,144,151,153,156,159,156,156,156,150,155,160,163,158,156,156,156,159,161,162,160,160,159,159,159,159,160,161,162,162,155,155,155,161,161,161,161,160,157,157,157,162,162,161,163,162,157,157,157,162,162,161,161,163,158,158,158};*/unsigned
char pixel[DNUM] = { //random data141,
101, 126, 111, 163, 112, 133, 156,103,
144, 111, 176, 117, 120, 188, 187,175,
164, 190, 156, 112, 179, 142, 119,140,
111, 127, 186, 196, 190, 189, 127,185,
103, 185, 110, 192, 139, 159, 104,151,
193, 178, 198, 114, 170, 179, 149,124,
149, 165, 108, 141, 176, 113, 164,101,
140, 120, 126, 173, 189, 158, 184};/*unsigned char pixel[DNUM] = {202,
221, 159, 183, 41, 136, 247, 66,146,
29, 101, 108, 45, 61, 210, 236,90,
130, 54, 66, 132, 206, 119, 232,184,
135, 96, 78, 120, 41, 231, 203,150,
94, 172, 142, 122, 180, 150, 204,232,
121, 180, 221, 3, 207, 115, 147,72,
149, 169, 121, 76, 208, 235, 43,107,
58, 0, 237, 197, 7, 210, 89};*/FrequencyCount(pixel);time1
= time(NULL);for
(loop=0; loop
huffman nodes data and weight, i=0:255, j=1:64for
(i=0, j=1, data_num=0; i<256; i++) {if
(fCount[i]) {hfdata[j].weight
= fCount[i];hfdata[j++].data
= i;data_num
++;}}//build
huffman tree and generate huffman code tableHuffmanCodeTable(hfdata,
code_table);//compress
source data to huffman code using code tableHuffmanCompress(pixel,
hfcode, code_table);//initial
hfdata and code_tablefor
(j=0; j<2*DNUM; j++) {hfdata[j].data=0;hfdata[j].lchild=0;hfdata[j].parent=0;hfdata[j].rchild=0;hfdata[j].weight=0;}}time2
= time(NULL);//concludeprintf("n哈夫曼编码压缩图块,压缩报告n");printf("n◎源数据(%d字节):n ", DNUM);for
(i=0; i
? "%02Xn " : "%02X ", pixel[i]);}printf("n◎压缩数据(%d字节):n ", code_size);for
(i=0; i
? "%02Xn " : "%02X ", hfcode[i]);}//打印码表printf("nn◎码表-编码字典(%d项)n", data_num);for
(i=0; i<256; i++) {if
(code_table[i].codelength) {printf("%3d|%02X:
", i, i);for
(j=0; j
((code_table[i].code << j)&0x80)>>7);}printf("t");}}printf("nn◎压缩率:%2.0f%%
t压缩时间:%.3f毫秒n",(float)code_size/DNUM * 100,
1E3*(time2-time1)/LOOP);}
void BitPrint(unsigned char *hfcode)
{int
i, j;int
endbit = last_bit;unsigned
char thebyte;for
(i=0; i < code_size-1; i++) {thebyte
= hfcode[i];for
(j=0; j<8; j++) {printf("%d",
((thebyte<>7);}}if
(last_bit == 7) {endbit
= -1;}thebyte
= hfcode[i];for
(j=7; j>endbit; j--) {printf("%d",
((thebyte<>7);}}
void HuffmanCompress(unsigned char
*pixel, unsigned char *hfcode, HuffCode * code_table)
{int
i, j;int
curbit=7; //current bit in _thebyte_unsigned
int bytenum=0; //number of destination code can also be position of byte
processed in destinationunsigned
int ptbyte=0; //position of byte processed in destinationunsigned
int curlength; //code's length of _curcode_unsigned
char curcode; //current byte's huffman codeunsigned
char thebyte=0; //destination byte writeunsigned
char value; //current byte's value (pixel[])//process
every bytefor
(i=0; i
= pixel[i];curcode
= (code_table[value]).code;curlength
= (code_table[value]).codelength;//move
out every bit from curcode to destinationfor
(j=0;j<=curlength;j++) {if
((curcode<
|= (unsigned char)(0x01<
--;if
(curbit < 0) {hfcode[ptbyte++]
= thebyte;thebyte
= 0;curbit= 7;bytenum
++;}}}//think
about which bit is the endif
(curbit != 7) {hfcode[ptbyte]
= thebyte;bytenum
++;}code_size
= bytenum;last_bit= curbit;}
void HuffmanCodeTable(HuffNode *hfdata,
HuffCode *code_table)
{int
i, j; //variable for loopint
tree_num = 2*data_num - 1; //node of huffman treeint
min1, min2; //two minimum weightint
p; //the id of parent nodeunsigned
char curcode; //current code being processingint
curlength; //current code's length//build
huffman treefor
(i=data_num; i
i, &min1, &min2);hfdata[min1].parent
= i+1;hfdata[min2].parent
= i+1;hfdata[i+1].lchild
= min1;hfdata[i+1].rchild
= min2;hfdata[i+1].weight
= hfdata[min1].weight + hfdata[min2].weight;}//generate
huffman code//i
present the i th code, j present from leaf to root in huffman tree//hfdata[i].data
(0:255) is a byte number//编码从叶读到根,按位从高往低压入一个字节,读编码从左向右for
(i=1; i<=data_num; i++) {curcode
= 0;curlength
= 0;for
(j=i, p=hfdata[j].parent; p!=0; j=p, p=hfdata[j].parent) {curlength
++;if
(j==hfdata[p].lchild) curcode >>= 1;else
curcode = (curcode >> 1) | 0x80; //0x80 = 128 = B1000 0000}code_table[hfdata[i].data].code
= curcode;code_table[hfdata[i].data].codelength
= curlength;}}
void HuffSelect(HuffNode *hfdata, int
end, int *min1, int *min2)
{int
i; //variable for loopint
s1, s2;HuffNode
wath[30];for
(i=0; i<30; i++) {wath[i]
= hfdata[i];}s1
= s2 = 1;while
(hfdata[s1].parent) {s1++;}for
(i=2; i<=end; i++) {if
(hfdata[i].parent == 0 && hfdata[i].weight < hfdata[s1].weight) {s1
= i;}}while
(hfdata[s2].parent || s1 == s2) {s2++;}for
(i=1; i<=end; i++) {if
(hfdata[i].parent ==0 && hfdata[i].weight < hfdata[s2].weight
&& (i - s1)) {s2
= i;}}*min1
= s1;*min2
= s2;}
void FrequencyCount(unsigned char *chs)
{int
i;for
(i=0; i
++;}}