From 9e46a1928308b97c5762d1f9739cb51fbdfc72cf Mon Sep 17 00:00:00 2001 From: ranchuan Date: Thu, 23 Nov 2023 21:05:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96huffman.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- hello.c | 76 +++++++++++++++++++++++++++++++++++----- huffman.c => huffman.ctt | 0 huffman.h => huffman.htt | 0 huffman_.c | 66 ++++++++++++++++++++++------------ 5 files changed, 111 insertions(+), 33 deletions(-) rename huffman.c => huffman.ctt (100%) rename huffman.h => huffman.htt (100%) diff --git a/.gitignore b/.gitignore index f592887..0e8781b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .vs/ *.exe - +*.pkt diff --git a/hello.c b/hello.c index 861e7d6..b8f978a 100644 --- a/hello.c +++ b/hello.c @@ -2,8 +2,9 @@ #include "stdio.h" #include "string.h" // #include "coder_lib.h" -#include "huffman.h" - +// #include "huffman.h" +#include "huffman_.h" +#include // 验证管壳码算法 @@ -30,17 +31,74 @@ // 验证huffman算法 +// int main(int argc, char *argv[]) +// { +// uint8_t str_in[]="2023 5830628A000005830628A000015830628A000025830628A000035830628A000045830628A000055830628A000065830628A000075830628A000085830628A00009"; +// array_def *a=arr_creat(); +// arr_appends(a,str_in,strlen(str_in)); +// array_def *out=hm_encode(a); +// printf("endode:%s\n",arr_string(out)); +// array_def *de=hm_decode(out); +// printf("decde:%s\n",arr_data(de)); +// return 0; +// } + + + + +long calc_file_size(FILE *stream) +{ + long file_size = -1; + long cur_offset = ftell(stream); // 获取当前偏移位置 + if (cur_offset == -1) { + printf("ftell failed :%s\n", strerror(errno)); + return -1; + } + if (fseek(stream, 0, SEEK_END) != 0) { // 移动文件指针到文件末尾 + printf("fseek failed: %s\n", strerror(errno)); + return -1; + } + file_size = ftell(stream); // 获取此时偏移值,即文件大小 + if (file_size == -1) { + printf("ftell failed :%s\n", strerror(errno)); + } + if (fseek(stream, cur_offset, SEEK_SET) != 0) { // 将文件指针恢复初始位置 + printf("fseek failed: %s\n", strerror(errno)); + return -1; + } + return file_size; +} + + + +int encode_file(const char *filename) +{ + FILE *f=fopen(filename, "rb"); + int file_size=calc_file_size(f); + uint8_t *file_data=calloc(file_size+1,sizeof(uint8_t)); + uint8_t *encode_data=0; + int encode_size; + fread(file_data,1,file_size,f); + hm_encode(file_data,file_size,&encode_data,&encode_size); + free(file_data); + free(encode_data); + fclose(f); +} + + + + + int main(int argc, char *argv[]) { - uint8_t str_in[]="2023 5830628A000005830628A000015830628A000025830628A000035830628A000045830628A000055830628A000065830628A000075830628A000085830628A00009"; - array_def *a=arr_creat(); - arr_appends(a,str_in,strlen(str_in)); - array_def *out=hm_encode(a); - printf("endode:%s\n",arr_string(out)); - array_def *de=hm_decode(out); - printf("decde:%s\n",arr_data(de)); + encode_file(argv[1]); + // const uint8_t file_data[]="2023 5830628A000005830628A000015830628A000025830628A000035830628A000045830628A000055830628A000065830628A000075830628A000085830628A00009"; + // uint8_t *encode_data=0; + // int encode_size; + // hm_encode(file_data,sizeof(file_data),&encode_data,&encode_size); return 0; } + diff --git a/huffman.c b/huffman.ctt similarity index 100% rename from huffman.c rename to huffman.ctt diff --git a/huffman.h b/huffman.htt similarity index 100% rename from huffman.h rename to huffman.htt diff --git a/huffman_.c b/huffman_.c index 72e486f..795709f 100644 --- a/huffman_.c +++ b/huffman_.c @@ -3,7 +3,7 @@ #include "stdio.h" #include "string.h" #include "huffman_.h" - +#include // 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;iindex_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;iindex_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;