#include "mystdlib.h" #include "stdlib.h" #include "bytearray.h" //#include "list.h" //#include "mystring.h" #include "string.h" #include "debug.h" // huffman编码的实现 typedef struct _huff_tree{ uint8_t data; uint8_t pos;// 位置,左为1,右为0 uint16_t count; struct _huff_tree *parant; struct _huff_tree *left; struct _huff_tree *right; }huff_tree; typedef struct{ huff_tree *tree; int index_table_index; huff_tree *index_table[256]; uint16_t count_table[256]; array_def *out; array_def *in; int in_bit_count; int arr_bit_index; }huffman_def; // 按出现频次排序 static void hm_sort_index_table(huffman_def *h) { for(int i=0;iindex_table_index;i++) { huff_tree *item=h->index_table[i]; for (int j=i;jindex_table_index;j++) { if(h->index_table[j]->count>item->count) { h->index_table[i]=h->index_table[j]; h->index_table[j]=item; item=h->index_table[i]; } } } } static void hm_calc_count(huffman_def *h,array_def *d) { int num=arr_length(d); memset(h->count_table,0,256); for(int i=0;icount_table[arr_get(d,i)]++; } for(int i=0;i<256;i++) { if(h->count_table[i]>0){ h->index_table[i]=calloc(1,sizeof(huff_tree)); h->index_table[i]->count=h->count_table[i]; h->index_table[i]->data=i; h->index_table_index++; } } hm_sort_index_table(h); } // 计算树的值 static int hm_calc_value_of_tree(huff_tree *t) { int sum=0; if(t->left&&t->right) sum=hm_calc_value_of_tree(t->left)+hm_calc_value_of_tree(t->right); else sum=t->count; return sum; } // 建立huffman树 static void hm_creat_tree(huffman_def *h) { int tail=h->index_table_index; huff_tree *sub=0; h->tree=h->index_table[tail-1]; tail--; while(tail>0){ sub=h->index_table[tail-1]; tail--; // 大在左,小在右 huff_tree *temp=h->tree; h->tree=calloc(1,sizeof(huff_tree)); sub->parant=h->tree; temp->parant=h->tree; // 左为1,右为0 if(hm_calc_value_of_tree(sub)>hm_calc_value_of_tree(h->tree)){ h->tree->left=sub; sub->pos=1; h->tree->right=temp; temp->pos=0; }else{ h->tree->left=temp; temp->pos=1; h->tree->right=sub; sub->pos=0; } } } // 删除树 static void hm_del_tree(huff_tree *t) { if(t->left&&t->right){ hm_del_tree(t->left); hm_del_tree(t->right); } free(t); } // 数据中添加一个bit static void hm_add_bit(array_def *d,int bit,int *index) { int len=arr_length(d); if(*indexindex_table_index;i++) { t=h->index_table[i]; if(t->data==d) break; } while(t){ hm_add_bit(h->out,t->pos,&h->arr_bit_index); t=t->parant; } return 0; } // 生成索引 static array_def *hm_creat_index_table(huffman_def *h) { array_def *a=arr_creat(); int temp; int diff; arr_append(a,h->index_table_index); for(int i=0;iindex_table_index;i++) { arr_append(a,h->index_table[i]->data); temp=h->index_table[i]->count; while(temp>0){ if(temp>=255) diff=255; else diff=temp; arr_append(a,diff); temp-=diff; } } // 填充0个数 temp=arr_length(h->out)*8-h->arr_bit_index; arr_append(a,temp); return arr_temp(a); } // huffman编码 /* 压缩后数据格式 data[0]:索引表长度 data[1~n]:索引表,每个索引由值(1byte)和频次(1byte,小于255)(2byte,大于等于255,频次由两个字节相加) data[n+1]:数据中填充0个数 data[n+2~m]:压缩后的数据 */ array_def *hm_encode(array_def *data) { int input_len=arr_length(data); huffman_def *h=calloc(1,sizeof(huffman_def)); array_def *ret=0; h->out=arr_creat(); hm_calc_count(h,data); hm_creat_tree(h); for(int i=0;itree); ret=hm_creat_index_table(h); arr_appends_from(ret,h->out); arr_delete(h->out); free(h); return arr_temp(ret); } // 读取编码表,返回数据开始的位置 static int hm_unpack_count(huffman_def *h,array_def *d) { int num=arr_get(d,0); int index=1; uint8_t temp; for(int i=0;iindex_table[i]=calloc(1,sizeof(huff_tree)); h->index_table[i]->data=arr_get(d,index);index++; do{ temp=arr_get(d,index);index++; h->index_table[i]->count+=temp; }while(temp==0xff); h->index_table_index++; } temp=arr_get(d,index);index++; h->in_bit_count=(arr_length(d)-index)*8-temp; h->in=arr_mid(d,index,arr_length(d)-index); return index; } // 获取指定index的bit值 static inline int hm_get_bit(array_def *d,int index) { uint8_t t=arr_get(d,index/8); return t&(1<<(index%8))?1:0; } // 对比树节点,匹配返回bit数,不匹配返回0 static inline int hm_cmp_bits(huffman_def *h,huff_tree *t) { int count=0; while(t){ if(hm_get_bit(h->in,h->arr_bit_index+count)!=t->pos) return 0; else{ count++; t=t->parant; } } h->arr_bit_index+=count; return count; } static uint8_t hm_decode_byte(huffman_def *h) { huff_tree *t=0; for(int i=0;iindex_table_index;i++){ t=h->index_table[i]; if(hm_cmp_bits(h,t)){ return t->data; } } DBG_WARN("can not decode byte"); return 0; } // huffman解码 /* */ array_def *hm_decode(array_def *data) { huffman_def *h=calloc(1,sizeof(huffman_def)); array_def *ret=arr_creat(); uint8_t c; hm_unpack_count(h,data); hm_creat_tree(h); while(h->arr_bit_indexin_bit_count){ c=hm_decode_byte(h); arr_append(ret,c); } hm_del_tree(h->tree); arr_delete(h->in); free(h); return arr_temp(ret); }