From 1ba813f068518cf5c45854319a93d1e22f69175a Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Sun, 28 Dec 2025 14:30:49 -0600 Subject: [PATCH] Add src and linux binaries for (de)compression code --- bin/linux/compress | Bin 0 -> 16544 bytes bin/linux/decompress | Bin 0 -> 16312 bytes bin/src/compress.c | 237 +++++++++++++++++++++++++++++++++++++++++++ bin/src/decompress.c | 145 ++++++++++++++++++++++++++ 4 files changed, 382 insertions(+) create mode 100644 bin/linux/compress create mode 100644 bin/linux/decompress create mode 100644 bin/src/compress.c create mode 100644 bin/src/decompress.c diff --git a/bin/linux/compress b/bin/linux/compress new file mode 100644 index 0000000000000000000000000000000000000000..fb8342d01c021c3f9200272ded319efbddfaefdf GIT binary patch literal 16544 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 Wu9szLx;4_jNDnro6+Q(YEB+7rRVC#B literal 0 HcmV?d00001 diff --git a/bin/src/compress.c b/bin/src/compress.c new file mode 100644 index 0000000..f314537 --- /dev/null +++ b/bin/src/compress.c @@ -0,0 +1,237 @@ +#include +#include +#include + +const int MAXLENGTH = 0x300; + +struct section { + int mode; + int length; + char data[2]; + int datalength; +}; + +int find_duplicate(off_t loc, off_t size, char buf[], struct section *out) { + int i, j; + struct section result; + result.mode = 4; + result.length = 0; + for (i = 0; i < loc && i < 0x10000; i++) { + if (buf[i] != buf[loc]) { + continue; + } + for (j = 0; j < MAXLENGTH; j++) { + if (buf[i + j] != buf[loc + j]) { + break; + } + } + if (j > result.length) { + result.length = j; + result.data[0] = i & 0xFF; + result.data[1] = (i >> 8) & 0xFF; + result.datalength = 2; + } + } + if (result.length < 4) { + return -1; + } + *out = result; + return 0; +} + +int find_repeat_byte(off_t loc, off_t size, char buf[], struct section *out) { + int i; + for (i = 0; i < MAXLENGTH && loc + i < size; i++) { + if (buf[loc + i] != buf[loc]) { + break; + } + } + if (i > 2) { + struct section result; + result.mode = 1; + result.length = i; + result.data[0] = buf[loc]; + result.datalength = 1; + *out = result; + return 0; + } + return -1; +} + +int find_repeat_word(off_t loc, off_t size, char buf[], struct section *out) { + int i; + for (i = 0; i < MAXLENGTH && loc + i + 1 < size; i += 1) { + if (buf[loc + i] != buf[loc + (i & 1)]) { + break; + } + } + if (i > 3) { + struct section result; + result.mode = 2; + result.length = i; + result.data[0] = buf[loc]; + result.data[1] = buf[loc + 1]; + result.datalength = 2; + *out = result; + return 0; + } + return -1; +} + +int find_incrementing_byte(off_t loc, off_t size, char buf[], struct section *out) { + int i; + for (i = 0; i < MAXLENGTH && loc + i < size; i++) { + if (buf[loc] + i < i) { + break; + } + if (buf[loc + i] != buf[loc] + i) { + break; + } + } + if (i > 2) { + struct section result; + result.mode = 3; + result.length = i; + result.data[0] = buf[loc]; + result.datalength = 1; + *out = result; + return 0; + } + return -1; +} + +int get_section(off_t loc, off_t size, char buf[], struct section *out) { + struct section best, current; + best.length = 0; + if (!find_repeat_byte(loc, size, buf, ¤t)) { + if (current.length > best.length) { + best = current; + } + } + if (!find_repeat_word(loc, size, buf, ¤t)) { + if (current.length > best.length) { + best = current; + } + } + if (!find_incrementing_byte(loc, size, buf, ¤t)) { + if (current.length > best.length) { + best = current; + } + } + if (!find_duplicate(loc, size, buf, ¤t)) { + if (current.length > best.length) { + best = current; + } + } + if (best.length > 0) { + // printf("byte %06X: mode %d length %02X\n", loc, best.mode, best.length); + *out = best; + return 0; + } else { + return -1; + } +} + +int write_section(struct section section, char data[], char buf[], int loc) { + int nloc = loc; + int len = section.length - 1; + if (len > 0x1F) { + buf[nloc++] = 0xE0 | (section.mode << 2) | (len >> 8); + buf[nloc++] = len & 0xFF; + } else { + buf[nloc++] = (section.mode << 5) | len; + } + for (int i = 0; i < section.datalength; i++) { + buf[nloc++] = data[i]; + } + return nloc; +} + +int main(int argc, char *argv[]) { + if (argc < 3) { + printf("Usage: %s infile outfile\n", argv[0]); + return 1; + } + + FILE *inptr; + if ((inptr = fopen(argv[1], "rb")) == NULL) { + printf("%s does not exist.\n", argv[1]); + return 1; + } + + int fd = fileno(inptr); + if (fd < 0) { + printf("Error stating file: %s\n", argv[1]); + return 1; + } + + struct stat buf; + if (fstat(fd, &buf) != 0) { + printf("Error stating file: %s\n", argv[1]); + return 1; + } + off_t size = buf.st_size; + + char inbuf[size]; + + if (fread(inbuf, 1, size, inptr) < size) { + printf("Error reading file: %s\n", argv[1]); + return 1; + } + + fclose(inptr); + + + char outbuf[size * 2]; + char m0data[MAXLENGTH]; + + int oloc = 0; + struct section m0; + m0.mode = 0; + m0.length = 0; + int i; + + off_t loc = 0; + while (loc < size) { + struct section section; + if (!get_section(loc, size, inbuf, §ion)) { + if (m0.length > 0) { + m0.datalength = m0.length; + oloc = write_section(m0, m0data, outbuf, oloc); + m0.length = 0; + } + oloc = write_section(section, section.data, outbuf, oloc); + loc += section.length; + } else { + if (m0.length == MAXLENGTH) { + m0.datalength = m0.length; + oloc = write_section(m0, m0data, outbuf, oloc); + m0.length = 0; + } + m0data[m0.length++] = inbuf[loc]; + loc += 1; + } + } + + if (m0.length > 0) { + m0.datalength = m0.length; + oloc = write_section(m0, m0data, outbuf, oloc); + m0.length = 0; + } + + outbuf[oloc++] = 0xFF; + + FILE *outptr; + if ((outptr = fopen(argv[2], "wb")) == NULL) { + printf("Error opening file: %s\n", argv[2]); + return 1; + } + + if (fwrite(outbuf, 1, oloc, outptr) < oloc) { + printf("Error writing to file: %s\n", argv[2]); + return 1; + } + + fclose(outptr); + printf("Input file: %X bytes. Compressed: %X bytes.\n", size, oloc); +} diff --git a/bin/src/decompress.c b/bin/src/decompress.c new file mode 100644 index 0000000..38a2a70 --- /dev/null +++ b/bin/src/decompress.c @@ -0,0 +1,145 @@ +#include +#include +#include + +struct section { + int mode; + int length; + char data[2]; + int datalength; +}; + +int read_section(char buf[], int loc, struct section *out) { + int nloc = loc; + char header = buf[nloc++]; + + printf("%x: ", header & 0xff); + + if (header == -1) { + return -1; + } + + struct section result; + result.data[0] = buf[loc]; + result.datalength = 1; + + if ((header & 0xE0) == 0xE0) { + result.mode = (header & 0x1C) >> 2; + result.length = (((header & 0x03) << 8) | buf[nloc++]) + 1; + } else { + result.mode = (header & 0xE0) >> 5; + result.length = (header & 0x1F) + 1; + } + + printf("%d: %x\n", result.mode, result.length); + + switch (result.mode) { + case 0: + result.datalength = 0; + break; + case 1: + result.datalength = 1; + break; + case 2: + result.datalength = 2; + break; + case 3: + result.datalength = 1; + break; + case 4: + result.datalength = 2; + break; + } + + for (int i = 0; i < result.datalength; i++) { + result.data[i] = buf[nloc++]; + } + + *out = result; + return nloc; +} + +int main(int argc, char *argv[]) { + if (argc < 3) { + printf("Usage: %s infile outfile\n", argv[0]); + return 1; + } + + FILE *inptr; + if ((inptr = fopen(argv[1], "rb")) == NULL) { + printf("%s does not exist.\n", argv[1]); + return 1; + } + + int fd = fileno(inptr); + if (fd < 0) { + printf("Error stating file: %s\n", argv[1]); + return 1; + } + + struct stat buf; + if (fstat(fd, &buf) != 0) { + printf("Error stating file: %s\n", argv[1]); + return 1; + } + off_t size = buf.st_size; + + char inbuf[size]; + + if (fread(inbuf, 1, size, inptr) < size) { + printf("Error reading file: %s\n", argv[1]); + return 1; + } + + fclose(inptr); + + char outbuf[size * 256]; + + int oloc = 0; + struct section section; + int i; + + off_t loc = 0; + + while ((loc = read_section(inbuf, loc, §ion)) >= 0) { + if (section.mode == 0) { + for (i = 0; i < section.length; i++) { + outbuf[oloc++] = inbuf[loc++]; + } + } else if (section.mode == 1) { + for (i = 0; i < section.length; i++) { + outbuf[oloc++] = section.data[0]; + } + } else if (section.mode == 2) { + for (i = 0; i < section.length; i++) { + outbuf[oloc++] = section.data[0]; + if (++i < section.length) { + outbuf[oloc++] = section.data[1]; + } + } + } else if (section.mode == 3) { + for (i = 0; i < section.length; i++) { + outbuf[oloc++] = (section.data[0] + i) & 0xff; + } + } else if (section.mode == 4) { + int offset = section.data[0] | (section.data[1] << 8); + for (i = 0; i < section.length; i++) { + outbuf[oloc++] = outbuf[offset + i]; + } + } + } + + FILE *outptr; + if ((outptr = fopen(argv[2], "wb")) == NULL) { + printf("Error opening file: %s\n", argv[2]); + return 1; + } + + if (fwrite(outbuf, 1, oloc, outptr) < oloc) { + printf("Error writing to file: %s\n", argv[2]); + return 1; + } + + fclose(outptr); + printf("Input file: %X bytes. Decompressed: %X bytes.\n", size, oloc); +}