LZ77解壓演算法程式(C語言版)
阿新 • • 發佈:2018-12-17
壓縮演算法後面有需要再補寫,先記錄一下解壓演算法吧。 壓縮演算法用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("%d groups\n",sizeof(table)/sizeof(table[0])); for( i=0;i<param.strLen;i++) printf("%02x ",param.str[i]); printf("\ntotal: %d bytes\n",param.strLen); }
執行結果
也可以拿其他壓縮資料試試