Skip to content

Instantly share code, notes, and snippets.

@leecher1337
Last active July 8, 2023 19:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leecher1337/d5ea763aafc4bd251e060c3c8378f935 to your computer and use it in GitHub Desktop.
Save leecher1337/d5ea763aafc4bd251e060c3c8378f935 to your computer and use it in GitHub Desktop.
Uncompress Zyxel WAP3205 etc. LZSS compressed config files ( <Config_Information_File_8671> )
// 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: leecher@dose.0wnz.at 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