优化huffman.c

This commit is contained in:
ranchuan
2023-11-23 21:05:27 +08:00
parent c475f0e4f0
commit 9e46a19283
5 changed files with 111 additions and 33 deletions

View File

@@ -3,7 +3,7 @@
#include "stdio.h"
#include "string.h"
#include "huffman_.h"
#include <stdlib.h>
// huffman编码的实现
#define DBG_WARN printf
@@ -12,7 +12,7 @@
typedef struct _huff_tree{
uint8_t data;
uint8_t pos;// 位置左为1右为0
uint16_t count;
uint32_t count;
struct _huff_tree *parant;
struct _huff_tree *left;
struct _huff_tree *right;
@@ -22,21 +22,41 @@ typedef struct _huff_tree{
typedef struct{
huff_tree *tree;
int index_table_index;
uint32_t index_table_index;
huff_tree *index_table[256];
uint16_t count_table[256];
uint32_t count_table[256];
uint8_t *out;
int out_len;
uint8_t *in;
int in_len;
int in_bit_count;
int arr_bit_index;
uint32_t out_len;
const uint8_t *in;
uint32_t in_len;
uint32_t in_bit_count;
uint32_t arr_bit_index;
/* 以下成员调试时使用 */
uint32_t tree_point_num;// 使用的树节点个数
}huffman_def;
static int hm_calc_value_of_tree(huff_tree *t);
static int hm_calc_deep_of_child(huff_tree* t);
// 生成一个树节点
static huff_tree *hm_creat_tree_point(huffman_def *h)
{
h->tree_point_num++;
return calloc(1,sizeof(huff_tree));
}
// 删除一个树节点
static void hm_del_tree_point(huffman_def *h,huff_tree *t)
{
if(h->tree_point_num>0){
h->tree_point_num--;
free(t);
}
}
// 按出现频次排序
static void hm_sort_index_table(huff_tree **table,int num)
{
@@ -98,7 +118,7 @@ static void hm_calc_count(huffman_def *h,const uint8_t *d,const int d_len)
{
if(h->count_table[i]>0){
index=h->index_table_index;
h->index_table[index]=calloc(1,sizeof(huff_tree));
h->index_table[index]=hm_creat_tree_point(h);
h->index_table[index]->count=h->count_table[i];
h->index_table[index]->data=i;
h->index_table_index++;
@@ -188,7 +208,7 @@ static void hm_creat_tree(huffman_def *h)
sub1=table[tail-1];
sub2=table[tail-2];
// 大在左,小在右
temp=calloc(1,sizeof(huff_tree));
temp=hm_creat_tree_point(h);
sub1->parant=temp;
sub2->parant=temp;
// 左为1右为0
@@ -217,13 +237,13 @@ static void hm_creat_tree(huffman_def *h)
// 删除树
static void hm_del_tree(huff_tree *t)
static void hm_del_tree(huffman_def *h,huff_tree *t)
{
if(t->left&&t->right){
hm_del_tree(t->left);
hm_del_tree(t->right);
hm_del_tree(h,t->left);
hm_del_tree(h,t->right);
}
free(t);
hm_del_tree_point(h,t);
}
// 数据中添加一个bit
@@ -256,14 +276,10 @@ static int hm_encode_byte(huffman_def *h,uint8_t d)
DBG_WARN("can not encode.\n");
exit(-1);
}
while(t->parant){
hm_add_bit(h->out,&h->out_len,t->pos,&h->arr_bit_index);
t=t->parant;
}
// char *str=arr_string(h->out);
// DBG_LOG("index:%d,out data:%s\n",h->arr_bit_index,str);
// free(str);
return 0;
}
@@ -274,7 +290,7 @@ static int hm_creat_index_table(huffman_def *h,uint8_t *data,int *data_len)
int diff;
int temp_num;
data[*data_len] = h->index_table_index; (*data_len)++;
hm_index_table_print(h);
// hm_index_table_print(h);
for(int i=0;i<h->index_table_index;i++)
{
data[*data_len] = h->index_table[i]->data; (*data_len)++;
@@ -313,6 +329,7 @@ int hm_encode(const uint8_t* in, const int in_len, uint8_t** out, int* out_len)
huffman_def *h=calloc(1,sizeof(huffman_def));
hm_calc_count(h,in, input_len);
hm_creat_tree(h);
DBG_LOG("huffman tree point num:%d\n",h->tree_point_num);
output_len = hm_calc_encode_len(h);
(*out) = calloc(output_len + 1, sizeof(uint8_t));
hm_creat_index_table(h, *out, &output_index);
@@ -326,7 +343,8 @@ int hm_encode(const uint8_t* in, const int in_len, uint8_t** out, int* out_len)
(*out)[output_index-1] = h->out_len*8- h->arr_bit_index;
DBG_LOG("fill with 0 by:%d\n", (*out)[output_index - 1]);
(*out_len) = output_len;
hm_del_tree(h->tree);
hm_del_tree(h,h->tree);
DBG_LOG("after del tree point num:%d\n",h->tree_point_num);
DBG_LOG("lenth_in:%d,length_encode:%d\n",input_len, output_len);
free(h);
@@ -342,7 +360,7 @@ static int hm_unpack_count(huffman_def *h,const uint8_t *d,int d_len)
uint8_t temp;
for(int i=0;i<num;i++)
{
h->index_table[i]=calloc(1,sizeof(huff_tree));
h->index_table[i]=hm_creat_tree_point(h);
h->index_table[i]->data=d[index];index++;
do{
temp= d[index];index++;
@@ -437,6 +455,7 @@ int hm_decode(const uint8_t* in, const int in_len, uint8_t** out, int* out_len)
hm_creat_tree(h);
// hm_data_code_print(h);
// hm_tree_print(h->tree);
DBG_LOG("huffman tree point num:%d\n",h->tree_point_num);
decode_len=hm_calc_decode_len(h);
decode_index=decode_len;
decode_data=calloc(decode_len+1,sizeof(uint8_t));
@@ -446,7 +465,8 @@ int hm_decode(const uint8_t* in, const int in_len, uint8_t** out, int* out_len)
decode_data[decode_index-1]=c;
decode_index--;
}
hm_del_tree(h->tree);
hm_del_tree(h,h->tree);
DBG_LOG("after del tree point num:%d\n",h->tree_point_num);
free(h);
(*out) = decode_data;
(*out_len) = decode_len;