Last active
July 8, 2023 19:14
-
-
Save leecher1337/d5ea763aafc4bd251e060c3c8378f935 to your computer and use it in GitHub Desktop.
Uncompress Zyxel WAP3205 etc. LZSS compressed config files ( <Config_Information_File_8671> )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Uncompress Zyxel WAP3205 etc. LZSS compressed config files | |
// These are in format <Config_Information_File_8671> | |
// Format description: https://qhimm-modding.fandom.com/wiki/FF7/LZS_format | |
// Author: [email protected] 05/2023 | |
// | |
// gcc -o lzss lzss.c | |
// | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <limits.h> | |
#include <errno.h> | |
#include <stdint.h> | |
int lzssDecompress(const uint8_t *src, uint8_t *dst, uint32_t size) { | |
uint8_t flags = 0, mask = 0; | |
uint32_t len, disp, os=0, od=0, i; | |
while(os < size) { | |
if(mask == 0) { | |
// read in the flags data | |
// from bit 7 to bit 0: | |
// 1: raw byte | |
// 0: compressed block | |
flags = ~src[os++]; | |
mask = 0x01; | |
} | |
if(flags & mask) { // compressed block | |
// disp: displacement | |
// len: length | |
disp = (src[os] | (((src[os+1]) & 0xF0) << 4)); os++; | |
len = ((src[os++])&0x0F)+3; | |
disp=od - ((od - 18 - disp) % 4096); | |
// printf ("Offset: %04X, len: %d\n", disp, len); | |
// for len, copy data from the displacement | |
// to the current buffer position | |
if (dst) | |
{ | |
// NB: memcpy implementations are different and decompression | |
// relies on memcpy bein REBE MOVSB, so roll manually | |
// memcpy(&dst[od], &dst[disp], len); | |
for (i=0; i<len; i++) dst[od+i]=dst[disp+i]; | |
} | |
od += len; | |
} | |
else { // uncompressed block | |
// copy a raw byte from the input to the output | |
if (dst) dst[od]=src[os]; | |
od++; os++; | |
} | |
mask <<= 1; | |
} | |
return od; | |
} | |
int main(int argc, char **argv) | |
{ | |
char destfile[PATH_MAX]; | |
FILE *fp; | |
uint32_t size, sizeout, unk; | |
int ret=0; | |
uint8_t *memIn, *memOut; | |
if (argc<2) | |
{ | |
printf ("Usage: %s <source file> [dest file]\n", argv[0]); | |
return -1; | |
} | |
if (argc<3) sprintf(destfile, "%s.xml", argv[1]); | |
else strcpy(destfile, argv[2]); | |
if (!(fp = fopen(argv[1], "rb"))) | |
{ | |
perror("Cannot open source file"); | |
return -1; | |
} | |
if (fread(&size, 4, 1, fp) != 1 || fread(&unk, 4, 1, fp) != 1) | |
{ | |
perror("Cannot read header"); | |
fclose(fp); | |
return -1; | |
} | |
size = htonl(size); | |
if (!(memIn = malloc(size))) | |
{ | |
fprintf(stderr, "Cannot allocate memory buffer of %d bytes\n", size); | |
fclose(fp); | |
return -1; | |
} | |
if (fread(memIn, size, 1, fp) != 1) | |
{ | |
fprintf(stderr, "Cannot read %d bytes from file: %s\n", size, strerror(errno)); | |
fclose(fp); | |
return -1; | |
} | |
fclose(fp); | |
sizeout = lzssDecompress(memIn, NULL, size); | |
if (!(memOut = malloc(sizeout))) | |
{ | |
fprintf(stderr, "Cannot allocate output memory buffer of %d bytes\n", sizeout); | |
fclose(fp); | |
return -1; | |
} | |
size = lzssDecompress(memIn, memOut, size); | |
printf ("Decompressed file to %d bytes.\n", size); | |
if (!(fp = fopen(destfile, "w"))) | |
{ | |
perror("Cannot open destination file"); | |
return -1; | |
} | |
if (fwrite(memOut, size, 1, fp) != 1) | |
{ | |
fprintf(stderr, "Cannot write %d bytes to destination file: %s\n", size, strerror(errno)); | |
ret = -1; | |
} | |
fclose(fp); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment