[數據結構和算法]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);
}
運行結果

在這裏插入圖片描述

也可以拿其他壓縮數據試試
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章