#include #include /* cc ulzdec.c -o ulzdec && ./ulzdec compressed.bin */ static int error(const char *name, const char *msg) { fprintf(stderr, "%s: %s\n", name, msg); return 0; } void decode_byte(FILE *fp, char *res, unsigned char c) { if(c & 0x80) { if(c & 0x40) { /* DICT3 */ unsigned short length = ((c & 0x3f) << 8 | getc(fp)) + 4; unsigned char offset = getc(fp) + 1; printf("DIC3 %04x, %02x\n", length, offset); } else { /* DICT2 */ unsigned char length = (c & 0x3f) + 4; unsigned char offset = getc(fp) + 1; printf("DIC1 %02x, %02x\n", length, offset); } } else { /* LIT */ unsigned char i, length = c + 1; printf("LIT%02x ", length); for(i = 0; i < length; ++i) { unsigned char c2 = getc(fp); printf("%c", c2 == '\n' ? ' ' : c2); } printf("\n"); } } int main(int argc, char *argv[]) { char c, *res; FILE *src; if(argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v') return !fprintf(stdout, "Ulzdec - ULZ Decoder, 15 Nov 2023.\n"); if(argc != 2) return error("usage", "ulzdec [-v] compressed.bin"); if(!(src = fopen(argv[1], "rb"))) return !error("Invalid input", argv[1]); res = malloc(0x10000); while((c = getc(src)) != EOF) decode_byte(src, res, c); return 0; }