/*将字符对应的编码写入压缩数据的缓存中*/
for(i=0; i<table[c].size; i++)
{
if(opos % 8 == 0)
{
/*为压缩数据的缓存区分配另一个字节*/
if((temp = (unsigned char *)realloc(comp,(opos/8)+1)) == NULL)
{
free(comp);
return -1;
}
comp = temp;
}
cpos = (sizeof(short)*8) - table[c].size + i;
bit_set(comp, opos, bit_get((unsigned char *)&table[c].code,cpos));
opos++;
}
ipos++;
}
/*指向压缩数据的缓冲区*/
*compressed = comp;
/*返回压缩缓冲区中的字节数*/
return ((opos - 1) / 8) + 1;
}
/*huffman_uncompress 解压缩霍夫曼数据*/
int huffman_uncompress(const unsigned char *compressed, unsigned char **original)
{
BiTree *tree;
BiTreeNode *node;
int freqs[UCHAR_MAX + 1],
hsize,
size,
ipos,opos,
state,
c;
unsigned char *orig,*temp;
/*初始化*/
*original = orig = NULL;
/*从压缩数据缓冲区中获取头文件信息*/
hize = sizeof(int) + (UCHAR_MAX + 1);
memcpy(&size,compressed,sizeof(int));
for(c=0; c<=UCHAR_MAX; c++)
freqs[c] = compressed[sizeof(int) + c];
/*重建前面压缩数据时的霍夫曼树*/
if(bulid_tree(freqs,&tree) != 0)
return -1;
/*解压缩数据*/
ipos = hsize * 8;
opos = 0;
node = bitree_root(tree);
while(opos < size)
{
/*从压缩数据中获取位状态*/
state = bit_get(compressed,ipos);
ipos++;
if(state == 0)
{
/*向左移动*/
if(bitree_is_eob(node) || bitree_is_eob(bitree_left(node)))
{
bitree_destroy(tree);
free(tree);
return -1;
}
else node = bitree_left(node);
}
else
{
/*向右移动*/
if(bitree_is_eob(node) || bitree_is_eob(bitree_right(node)))
{
bitree_destroy(tree);
free(tree);
return -1;
}
else node = bitree_right(node);
}
if(bitree_is_eob(bitree_left(node)) && bitree_is_eob(bitree_right(node)))
{
/*将叶子结点中的符号写入原始数据缓冲区*/
if(opos > 0)
{
if((temp = (unsigned char *)realloc(orig,opos+1)) == NULL)
{
bitree_destroy(tree);
free(tree);
free(orig);
return -1;
}
orig = temp;
}
else
{
if((orig = (unsigned char *)malloc(1)) == NULL)
{
bitree_destroy(tree);
free(tree);
return -1;
}
}
orig[opos] = ((HuffNode *)bitree_data(node))->symbol;
opos++;
/*返回到霍夫曼树的顶部*/
node = bitree_root(tree);
}
}
bitree_destroy(tree);
free(tree);
/*把向原始数据缓冲区*/
*original = orig;
/*返回原始数据中的字节数*/
return opos;
}
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx