优化huffman.c
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
.vs/
|
.vs/
|
||||||
*.exe
|
*.exe
|
||||||
|
*.pkt
|
||||||
|
|
||||||
|
|||||||
76
hello.c
76
hello.c
@@ -2,8 +2,9 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
// #include "coder_lib.h"
|
// #include "coder_lib.h"
|
||||||
#include "huffman.h"
|
// #include "huffman.h"
|
||||||
|
#include "huffman_.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
// 验证管壳码算法
|
// 验证管壳码算法
|
||||||
@@ -30,17 +31,74 @@
|
|||||||
|
|
||||||
// 验证huffman算法
|
// 验证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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint8_t str_in[]="2023 5830628A000005830628A000015830628A000025830628A000035830628A000045830628A000055830628A000065830628A000075830628A000085830628A00009";
|
encode_file(argv[1]);
|
||||||
array_def *a=arr_creat();
|
// const uint8_t file_data[]="2023 5830628A000005830628A000015830628A000025830628A000035830628A000045830628A000055830628A000065830628A000075830628A000085830628A00009";
|
||||||
arr_appends(a,str_in,strlen(str_in));
|
// uint8_t *encode_data=0;
|
||||||
array_def *out=hm_encode(a);
|
// int encode_size;
|
||||||
printf("endode:%s\n",arr_string(out));
|
// hm_encode(file_data,sizeof(file_data),&encode_data,&encode_size);
|
||||||
array_def *de=hm_decode(out);
|
|
||||||
printf("decde:%s\n",arr_data(de));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
66
huffman_.c
66
huffman_.c
@@ -3,7 +3,7 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "huffman_.h"
|
#include "huffman_.h"
|
||||||
|
#include <stdlib.h>
|
||||||
// huffman编码的实现
|
// huffman编码的实现
|
||||||
|
|
||||||
#define DBG_WARN printf
|
#define DBG_WARN printf
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
typedef struct _huff_tree{
|
typedef struct _huff_tree{
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
uint8_t pos;// 位置,左为1,右为0
|
uint8_t pos;// 位置,左为1,右为0
|
||||||
uint16_t count;
|
uint32_t count;
|
||||||
struct _huff_tree *parant;
|
struct _huff_tree *parant;
|
||||||
struct _huff_tree *left;
|
struct _huff_tree *left;
|
||||||
struct _huff_tree *right;
|
struct _huff_tree *right;
|
||||||
@@ -22,21 +22,41 @@ typedef struct _huff_tree{
|
|||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
huff_tree *tree;
|
huff_tree *tree;
|
||||||
int index_table_index;
|
uint32_t index_table_index;
|
||||||
huff_tree *index_table[256];
|
huff_tree *index_table[256];
|
||||||
uint16_t count_table[256];
|
uint32_t count_table[256];
|
||||||
uint8_t *out;
|
uint8_t *out;
|
||||||
int out_len;
|
uint32_t out_len;
|
||||||
uint8_t *in;
|
const uint8_t *in;
|
||||||
int in_len;
|
uint32_t in_len;
|
||||||
int in_bit_count;
|
uint32_t in_bit_count;
|
||||||
int arr_bit_index;
|
uint32_t arr_bit_index;
|
||||||
|
/* 以下成员调试时使用 */
|
||||||
|
uint32_t tree_point_num;// 使用的树节点个数
|
||||||
}huffman_def;
|
}huffman_def;
|
||||||
|
|
||||||
|
|
||||||
static int hm_calc_value_of_tree(huff_tree *t);
|
static int hm_calc_value_of_tree(huff_tree *t);
|
||||||
static int hm_calc_deep_of_child(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)
|
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){
|
if(h->count_table[i]>0){
|
||||||
index=h->index_table_index;
|
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]->count=h->count_table[i];
|
||||||
h->index_table[index]->data=i;
|
h->index_table[index]->data=i;
|
||||||
h->index_table_index++;
|
h->index_table_index++;
|
||||||
@@ -188,7 +208,7 @@ static void hm_creat_tree(huffman_def *h)
|
|||||||
sub1=table[tail-1];
|
sub1=table[tail-1];
|
||||||
sub2=table[tail-2];
|
sub2=table[tail-2];
|
||||||
// 大在左,小在右
|
// 大在左,小在右
|
||||||
temp=calloc(1,sizeof(huff_tree));
|
temp=hm_creat_tree_point(h);
|
||||||
sub1->parant=temp;
|
sub1->parant=temp;
|
||||||
sub2->parant=temp;
|
sub2->parant=temp;
|
||||||
// 左为1,右为0
|
// 左为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){
|
if(t->left&&t->right){
|
||||||
hm_del_tree(t->left);
|
hm_del_tree(h,t->left);
|
||||||
hm_del_tree(t->right);
|
hm_del_tree(h,t->right);
|
||||||
}
|
}
|
||||||
free(t);
|
hm_del_tree_point(h,t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据中添加一个bit
|
// 数据中添加一个bit
|
||||||
@@ -256,14 +276,10 @@ static int hm_encode_byte(huffman_def *h,uint8_t d)
|
|||||||
DBG_WARN("can not encode.\n");
|
DBG_WARN("can not encode.\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(t->parant){
|
while(t->parant){
|
||||||
hm_add_bit(h->out,&h->out_len,t->pos,&h->arr_bit_index);
|
hm_add_bit(h->out,&h->out_len,t->pos,&h->arr_bit_index);
|
||||||
t=t->parant;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +290,7 @@ static int hm_creat_index_table(huffman_def *h,uint8_t *data,int *data_len)
|
|||||||
int diff;
|
int diff;
|
||||||
int temp_num;
|
int temp_num;
|
||||||
data[*data_len] = h->index_table_index; (*data_len)++;
|
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++)
|
for(int i=0;i<h->index_table_index;i++)
|
||||||
{
|
{
|
||||||
data[*data_len] = h->index_table[i]->data; (*data_len)++;
|
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));
|
huffman_def *h=calloc(1,sizeof(huffman_def));
|
||||||
hm_calc_count(h,in, input_len);
|
hm_calc_count(h,in, input_len);
|
||||||
hm_creat_tree(h);
|
hm_creat_tree(h);
|
||||||
|
DBG_LOG("huffman tree point num:%d\n",h->tree_point_num);
|
||||||
output_len = hm_calc_encode_len(h);
|
output_len = hm_calc_encode_len(h);
|
||||||
(*out) = calloc(output_len + 1, sizeof(uint8_t));
|
(*out) = calloc(output_len + 1, sizeof(uint8_t));
|
||||||
hm_creat_index_table(h, *out, &output_index);
|
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;
|
(*out)[output_index-1] = h->out_len*8- h->arr_bit_index;
|
||||||
DBG_LOG("fill with 0 by:%d\n", (*out)[output_index - 1]);
|
DBG_LOG("fill with 0 by:%d\n", (*out)[output_index - 1]);
|
||||||
(*out_len) = output_len;
|
(*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);
|
DBG_LOG("lenth_in:%d,length_encode:%d\n",input_len, output_len);
|
||||||
free(h);
|
free(h);
|
||||||
@@ -342,7 +360,7 @@ static int hm_unpack_count(huffman_def *h,const uint8_t *d,int d_len)
|
|||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
for(int i=0;i<num;i++)
|
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++;
|
h->index_table[i]->data=d[index];index++;
|
||||||
do{
|
do{
|
||||||
temp= d[index];index++;
|
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_creat_tree(h);
|
||||||
// hm_data_code_print(h);
|
// hm_data_code_print(h);
|
||||||
// hm_tree_print(h->tree);
|
// 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_len=hm_calc_decode_len(h);
|
||||||
decode_index=decode_len;
|
decode_index=decode_len;
|
||||||
decode_data=calloc(decode_len+1,sizeof(uint8_t));
|
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_data[decode_index-1]=c;
|
||||||
decode_index--;
|
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);
|
free(h);
|
||||||
(*out) = decode_data;
|
(*out) = decode_data;
|
||||||
(*out_len) = decode_len;
|
(*out_len) = decode_len;
|
||||||
|
|||||||
Reference in New Issue
Block a user