添加huffman算法
This commit is contained in:
@@ -299,7 +299,7 @@
|
|||||||
<OPTFL>
|
<OPTFL>
|
||||||
<tvExp>1</tvExp>
|
<tvExp>1</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<IsCurrentTarget>1</IsCurrentTarget>
|
<IsCurrentTarget>0</IsCurrentTarget>
|
||||||
</OPTFL>
|
</OPTFL>
|
||||||
<CpuCode>18</CpuCode>
|
<CpuCode>18</CpuCode>
|
||||||
<DebugOpt>
|
<DebugOpt>
|
||||||
@@ -523,7 +523,7 @@
|
|||||||
<OPTFL>
|
<OPTFL>
|
||||||
<tvExp>1</tvExp>
|
<tvExp>1</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<IsCurrentTarget>0</IsCurrentTarget>
|
<IsCurrentTarget>1</IsCurrentTarget>
|
||||||
</OPTFL>
|
</OPTFL>
|
||||||
<CpuCode>18</CpuCode>
|
<CpuCode>18</CpuCode>
|
||||||
<DebugOpt>
|
<DebugOpt>
|
||||||
@@ -1920,6 +1920,18 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<bShared>0</bShared>
|
<bShared>0</bShared>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<GroupNumber>9</GroupNumber>
|
||||||
|
<FileNumber>96</FileNumber>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<tvExp>0</tvExp>
|
||||||
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
<bDave2>0</bDave2>
|
||||||
|
<PathWithFileName>.\source\soft\huffman.c</PathWithFileName>
|
||||||
|
<FilenameWithoutPath>huffman.c</FilenameWithoutPath>
|
||||||
|
<RteFlg>0</RteFlg>
|
||||||
|
<bShared>0</bShared>
|
||||||
|
</File>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group>
|
<Group>
|
||||||
@@ -1930,7 +1942,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>10</GroupNumber>
|
<GroupNumber>10</GroupNumber>
|
||||||
<FileNumber>96</FileNumber>
|
<FileNumber>97</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -1942,7 +1954,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>10</GroupNumber>
|
<GroupNumber>10</GroupNumber>
|
||||||
<FileNumber>97</FileNumber>
|
<FileNumber>98</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -1954,7 +1966,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>10</GroupNumber>
|
<GroupNumber>10</GroupNumber>
|
||||||
<FileNumber>98</FileNumber>
|
<FileNumber>99</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -1966,7 +1978,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>10</GroupNumber>
|
<GroupNumber>10</GroupNumber>
|
||||||
<FileNumber>99</FileNumber>
|
<FileNumber>100</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -1978,7 +1990,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>10</GroupNumber>
|
<GroupNumber>10</GroupNumber>
|
||||||
<FileNumber>100</FileNumber>
|
<FileNumber>101</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -1998,7 +2010,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>11</GroupNumber>
|
<GroupNumber>11</GroupNumber>
|
||||||
<FileNumber>101</FileNumber>
|
<FileNumber>102</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2018,7 +2030,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>102</FileNumber>
|
<FileNumber>103</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2030,7 +2042,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>103</FileNumber>
|
<FileNumber>104</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2042,7 +2054,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>104</FileNumber>
|
<FileNumber>105</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2054,7 +2066,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>105</FileNumber>
|
<FileNumber>106</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2066,7 +2078,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>106</FileNumber>
|
<FileNumber>107</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2078,7 +2090,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>12</GroupNumber>
|
<GroupNumber>12</GroupNumber>
|
||||||
<FileNumber>107</FileNumber>
|
<FileNumber>108</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2098,7 +2110,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>13</GroupNumber>
|
<GroupNumber>13</GroupNumber>
|
||||||
<FileNumber>108</FileNumber>
|
<FileNumber>109</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2118,7 +2130,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>14</GroupNumber>
|
<GroupNumber>14</GroupNumber>
|
||||||
<FileNumber>109</FileNumber>
|
<FileNumber>110</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@@ -2130,7 +2142,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>14</GroupNumber>
|
<GroupNumber>14</GroupNumber>
|
||||||
<FileNumber>110</FileNumber>
|
<FileNumber>111</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
@@ -2330,6 +2330,11 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>.\source\soft\cJSON.c</FilePath>
|
<FilePath>.\source\soft\cJSON.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>huffman.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>.\source\soft\huffman.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
@@ -3940,6 +3945,11 @@
|
|||||||
</FileArmAds>
|
</FileArmAds>
|
||||||
</FileOption>
|
</FileOption>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>huffman.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>.\source\soft\huffman.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
@@ -5190,6 +5200,11 @@
|
|||||||
</FileArmAds>
|
</FileArmAds>
|
||||||
</FileOption>
|
</FileOption>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>huffman.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>.\source\soft\huffman.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
|
@@ -509,8 +509,8 @@ void elec_exe_task(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
checker_runcfg.rtv_index+=checker_runcfg.rtv_count;
|
checker_runcfg.rtv_index+=checker_runcfg.rtv_count;
|
||||||
DBG_LOG("task_index:%d,taskid:%d,ret=%d,rtv_index=%d.",s->task_index,taskid,checker_runcfg.excue_rtv,
|
DBG_LOG("task_index:%d,taskid:%d,ret=%d,rtv_index=%d.",s->task_index,
|
||||||
checker_runcfg.rtv_index);
|
s->task_par->taskid,checker_runcfg.excue_rtv,checker_runcfg.rtv_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_DATE "2023-11-20 10:44:09"
|
#define BUILD_DATE "2023-11-22 14:44:51"
|
||||||
#define SOFT_VERSION "2.06"
|
#define SOFT_VERSION "2.06"
|
||||||
|
|
||||||
|
|
||||||
|
@@ -106,6 +106,17 @@ uint8_t arr_get(array_def *a,int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void arr_reset(array_def *a,uint8_t d,int index)
|
||||||
|
{
|
||||||
|
param_check(a);
|
||||||
|
rt_mutex_take(a->mutex,RT_WAITING_FOREVER);
|
||||||
|
if(index<0) index=a->used+index;
|
||||||
|
if((index>=0&&index<a->used)==0){}
|
||||||
|
else a->data[index]=d;
|
||||||
|
rt_mutex_release(a->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t *arr_data(array_def *a)
|
uint8_t *arr_data(array_def *a)
|
||||||
{
|
{
|
||||||
param_check(a);
|
param_check(a);
|
||||||
|
@@ -10,6 +10,7 @@ typedef struct _array_def array_def;
|
|||||||
|
|
||||||
array_def *arr_creat(void);
|
array_def *arr_creat(void);
|
||||||
uint8_t arr_get(array_def *a,int index);
|
uint8_t arr_get(array_def *a,int index);
|
||||||
|
void arr_reset(array_def *a,uint8_t d,int index);
|
||||||
array_def *arr_mid(array_def *a,int start,int len);
|
array_def *arr_mid(array_def *a,int start,int len);
|
||||||
uint8_t *arr_data(array_def *a);
|
uint8_t *arr_data(array_def *a);
|
||||||
int arr_length(array_def *a);
|
int arr_length(array_def *a);
|
||||||
|
308
source/soft/huffman.c
Normal file
308
source/soft/huffman.c
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
|
||||||
|
#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;i<h->index_table_index;i++)
|
||||||
|
{
|
||||||
|
huff_tree *item=h->index_table[i];
|
||||||
|
for (int j=i;j<h->index_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;i<num;i++)
|
||||||
|
{
|
||||||
|
h->count_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(*index<len*8){
|
||||||
|
uint8_t c=arr_get(d,-1);
|
||||||
|
c|=bit<<(*index%8);
|
||||||
|
arr_reset(d,c,-1);
|
||||||
|
}else{
|
||||||
|
arr_append(d,bit);
|
||||||
|
}
|
||||||
|
(*index)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 根据数据添加bit
|
||||||
|
static int hm_encode_byte(huffman_def *h,uint8_t d)
|
||||||
|
{
|
||||||
|
huff_tree *t=0;
|
||||||
|
// 这里默认一定能找到对应的值
|
||||||
|
for(int i=0;i<h->index_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;i<h->index_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;i<input_len;i++)
|
||||||
|
{
|
||||||
|
hm_encode_byte(h,arr_get(data,i));
|
||||||
|
}
|
||||||
|
hm_del_tree(h->tree);
|
||||||
|
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;i<num;i++)
|
||||||
|
{
|
||||||
|
h->index_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;i<h->index_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_index<h->in_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
19
source/soft/huffman.h
Normal file
19
source/soft/huffman.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#ifndef huffman_h__
|
||||||
|
#define huffman_h__
|
||||||
|
|
||||||
|
#include "bytearray.h"
|
||||||
|
|
||||||
|
// huffman编码的实现
|
||||||
|
|
||||||
|
array_def *hm_encode(array_def *data);
|
||||||
|
|
||||||
|
array_def *hm_decode(array_def *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -2,7 +2,7 @@
|
|||||||
#define mystdlib_h__
|
#define mystdlib_h__
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
|
||||||
void mem_init(void);
|
void mem_init(void);
|
||||||
|
Reference in New Issue
Block a user