[数据结构和算法]LZ77压缩算法三部曲——3.解压算法(C语言)

压缩算法后面有需要再补写,先记录一下解压算法吧。
压缩算法用Java写的,压缩的是字节流。(测试原数据1024bytes–压缩后为201bytes)

直接上菜吧
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_LEN	128
#define SLIDE_LEN	512
#define MAX_STRING_LEN 2000

typedef struct ENCODE{
	short off;
	unsigned char len;
	unsigned char ch;
}ENCODE_TypeDef;

typedef struct unzip{
	int strLen;	//解压字符偏移值 
	unsigned char str[MAX_STRING_LEN];	//原字符串 
	unsigned char slide[SLIDE_LEN];	//滑动窗口大小
	unsigned char buf[BUFFER_LEN];	//前向缓冲区 
}unzip_TypeDef;

const unsigned char table[] = {
	0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x80,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0xE0,0x00,0x00,0xC0,0xF9,0x03,0x00,0xFE,0x05,0x00,0xFB,0x0B,0x00,0xF5,0x17,0x00,0xE9,0x2F,0x00,
	0xFD,0x07,0x07,0xC8,0x03,0x70,0x00,0x00,0xE3,0xF7,0x0B,0x3F,0xFE,0x03,0x38,0xF6,0x03,0x0C,0xBA,0x03,0x0E,0x00,0x00,0x06,0xF6,0x05,0x70,0xFD,0x05,0xE0,0xB0,0x73,0x06,0xFE,0x03,0xF0,
	0xB0,0x03,0x80,0xF7,0x09,0x7C,0x00,0x00,0x7F,0x00,0x00,0xFF,0x00,0x00,0xF8,0x00,0x00,0x18,0xA2,0x03,0x0E,0xFF,0x03,0x00,0xB0,0x0D,0xF3,0xEB,0x03,0x3F,0xF0,0x03,0xFF,0xB0,0x67,0x00,
	0x00,0x00,0x01,0xCB,0x03,0xFF,0xB0,0x0B,0x30,0x00,0x00,0x20,0xFC,0x05,0x18,0x00,0x00,0x1C,0x00,0x00,0x0F,0xFF,0x03,0x00,0xB0,0x0D,0x3F,0x60,0x05,0x00,0xFF,0x03,0xC0,0xB0,0x67,0x03,
	0xC7,0x03,0x7F,0xF8,0x0B,0x20,0xAC,0x09,0x70,0x5F,0x03,0xFE,0xB0,0x0F,0x0F,0x01,0x05,0x00,0xB0,0x6B,0x0C,0xF4,0x17,0x60,0xBF,0x0B,0x60,0xB7,0x09,0x04,0xA3,0x05,0x00,0xFF,0x03,0x80,
	0xB0,0x67,0x00,0xCC,0x69,0x00,0x97,0xD3,0x00,0x81,0xFF,0x00,0x81,0xFF,0x00,0x81,0xFF,0x00,0xEB,0x2B,0x00
};

unzip_TypeDef unzip;
ENCODE_TypeDef encode_str[MAX_STRUCT_LEN]; 

void new_pic(uint16_t type_len, const unsigned char *pic){
    for(uint16_t i=0;i<type_len/3;i++){
        encode_str[i].off = ((pic[i*3+1]&0x01)<<8 | pic[i*3])&0x1ff;
        encode_str[i].len = (pic[i*3+1]>>1)&0x7f;
        encode_str[i].ch = pic[i*3+2];
    }
}

void update_slide(int strLen, unsigned char *slide){
	memset(unzip.slide, 0, SLIDE_LEN);	//清除缓存 
	for(int i=0;i<SLIDE_LEN;i++){	//更新滑动窗口 
		if(strLen-i >= 0) unzip.slide[SLIDE_LEN-i] = unzip.str[strLen-i]; 
	}
}

void decode(uint16_t type_len, const unsigned char *pic){
	int i,j;
	int struct_len = 0;
	unzip.strLen = 0;
	new_pic(type_len, pic);
	memset(unzip.str, 0, MAX_STRING_LEN);
	struct_len = type_len/3;//sizeof(encode_str)/sizeof(encode_str[0]);	//计算多少组压缩数据 
	for(i=0;i<struct_len;i++){			//循环解析压缩的数据 
		update_slide(unzip.strLen, unzip.slide);	//更新滑动窗口 
		for(j=0;j<encode_str[i].len;j++){//根据字典解析出压缩的字符
			unzip.str[unzip.strLen++] = unzip.slide[encode_str[i].off+j];//根据字典、len、offset解析原字符 
		}
		unzip.str[unzip.strLen++] = encode_str[i].ch;		//压缩数据后面的字符 
	}
}

int main(void){
	uint16_t i;
	decode(sizeof(table)/sizeof(table[0]), table);
	printf("zip %d bytes\n",sizeof(table)/sizeof(table[0]));
	for( i=0;i<param.strLen;i++)
		printf("%02x ",param.str[i]);
	printf("\nunzip: %d bytes\n",param.strLen);
}
运行结果

在这里插入图片描述

也可以拿其他压缩数据试试
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值