/*写入头部信息*/
hsize = sizeof(int);
if((comp = (unsigned char *)malloc(hsize)) == NULL)
return -1;
memcpy(comp,&size,sizeof(int));
/*初始化滑动窗口和前向缓冲区(用0填充)*/
memset(window, 0 , LZ77_WINDOW_SIZE);
memset(buffer, 0 , LZ77_BUFFER_SIZE);
/*加载前向缓冲区*/
ipos = 0;
for(i=0; i<LZ77_BUFFER_SIZE && ipos < size; i++)
{
buffer[i] = original[ipos];
ipos++;
}
/*压缩数据*/
opos = hsize * 8;
remaining = size;
while(remaining > 0)
{
if((length = compare_win(window,buffer,&offset,&next)) != 0)
{
/*编码短语标记*/
token = 0x00000001 << (LZ77_PHRASE_BITS - 1);
/*设置在滑动窗口找到匹配的偏移量*/
token = token | (offset << (LZ77_PHRASE_BITS - LZ77_TYPE_BITS - LZ77_WINOFF_BITS));
/*设置匹配串的长度*/
token = token | (length << (LZ77_PHRASE_BITS - LZ77_TYPE_BITS - LZ77_WINOFF_BITS - LZ77_BUFLEN_BITS));
/*设置前向缓冲区中匹配串后面紧邻的字符*/
token = token | next;
/*设置标记的位数*/
tbits = LZ77_PHRASE_BITS;
}
else
{
/*编码一个字符标记*/
token = 0x00000000;
/*设置未匹配的字符*/
token = token | next;
/*设置标记的位数*/
tbits = LZ77_SYMBOL_BITS;
}
/*确定标记是大端格式*/
token = htonl(token);
/*将标记写入压缩缓冲区*/
for(i=0; i<tbits; i++)
{
if(opos % 8 == 0)
{
/*为压缩缓冲区分配临时空间*/
if((temp = (unsigned char *)realloc(comp,(opos / 8) + 1)) == NULL)
{
free(comp);
return -1;
}
comp = temp;
}
tpos = (sizeof(unsigned long ) * 8) - tbits + i;
bit_set(comp,opos,bit_get((unsigned char *)&token,tpos));
opos++;
}
/*调整短语长度*/
length++;
/*从前向缓冲区中拷贝数据到滑动窗口中*/
memmove(&window[0],&window[length],LZ77_WINDOW_SIZE - length);
memmove(&window[LZ77_WINDOW_SIZE - length],&buffer[0],length);
memmove(&buffer[0],&buffer[length],LZ77_BUFFER_SIZE - length);
/*向前向缓冲区中读取更多数据*/
for(i = LZ77_BUFFER_SIZE - length; i<LZ77_BUFFER_SIZE && ipos <size; i++)
{
buffer[i] = original[ipos];
ipos++;
}
/*调整剩余未匹配的长度*/
remaining = remaining - length;
}
/*指向压缩数据缓冲区*/
*compressed = comp;
/*返回压缩数据中的字节数*/
return ((opos - 1) / 8) + 1;
}
/*lz77_uncompress 解压缩由lz77_compress压缩的数据*/
int lz77_uncompress(const unsigned char *compressed,unsigned char **original)
{
unsigned char window[LZ77_WINDOW_SIZE],
buffer[LZ77_BUFFER_SIZE]
*orig,
*temp,
next;
int offset,
length,
remaining,
hsize,
size,
ipos,
opos,
tpos,
state,
i;
/*使指向原始数据的指针暂时无效*/
*original = orig = NULL;
/*获取头部信息*/
hsize = sizeof(int);
memcpy(&size,compressed,sizeof(int));
/*初始化滑动窗口和前向缓冲区*/
memset(window, 0, LZ77_WINDOW_SIZE);
memset(buffer, 0, LZ77_BUFFER_SIZE);
/*解压缩数据*/
ipos = hsize * 8;
opos = 0;
remaining = size;