Skip to content

Instantly share code, notes, and snippets.

@uyjulian
Last active January 3, 2024 07:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save uyjulian/14388e84b008a6433aa805f5d0436c87 to your computer and use it in GitHub Desktop.
Save uyjulian/14388e84b008a6433aa805f5d0436c87 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
uint32_t decompress_osdsys(uint8_t *src, uint8_t *dst)
{
uint32_t run = 0;
uint32_t length = *((uint32_t *)src);
uint8_t *buffer = src + 4;
uint32_t _DAT_002c9250;
uint32_t _DAT_002c924c;
uint32_t _DAT_002c9254;
uint32_t _DAT_002c9258;
uint8_t *dst_cur = dst;
do {
if (run == 0) {
run = 0x1e;
_DAT_002c9250 = (uint32_t)(uint8_t)(buffer[3] & 3);
_DAT_002c924c = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);
_DAT_002c9254 = 0xe - _DAT_002c9250;
_DAT_002c9258 = 0x3fff >> _DAT_002c9250;
buffer += 4;
}
uint8_t uVar1 = *buffer;
uint8_t *puVar4 = buffer + 1;
if ((_DAT_002c924c & 0x80000000) == 0) {
buffer = puVar4;
*dst_cur = uVar1;
dst_cur += 1;
}
else {
buffer += 2;
uint16_t uVar2 = (uVar1 << 8) | (*puVar4);
puVar4 = dst_cur - ((uVar2 & _DAT_002c9258) + 1);
uint32_t iVar3 = (uint32_t)(uVar2 >> (_DAT_002c9254 & 0x1f)) + 2;
*dst_cur = *puVar4;
uint8_t *puVar6 = dst_cur + 1;
if (iVar3 == 0) {
dst_cur += 1;
}
else {
do {
puVar4 += 1;
iVar3 -= 1;
*puVar6 = *puVar4;
puVar6 += 1;
dst_cur = puVar6;
} while (iVar3 != 0);
}
}
if ((dst_cur - dst == length) ||
(run -= 1, length < dst_cur - dst)) {
return length;
}
_DAT_002c924c <<= 1;
} while( true );
return length;
}
int main(int argc, char** argv)
{
if (argc != 3)
return 1;
FILE* infile = fopen(argv[1], "rb");
if (!infile)
return 2;
fseek(infile, 0, SEEK_END);
uint32_t cmp_sz = ftell(infile);
fseek(infile, 0, SEEK_SET);
uint32_t unc_sz = 0;
size_t read_header_sz = fread(&unc_sz, 1, 4, infile);
if (read_header_sz != 4)
return 3;
fseek(infile, 0, SEEK_SET);
uint8_t *cmp_dat = malloc(cmp_sz);
if (!cmp_dat)
return 4;
uint8_t *unc_dat = malloc(unc_sz);
if (!unc_dat)
return 5;
size_t read_cmp_sz = fread(cmp_dat, 1, cmp_sz, infile);
if (read_cmp_sz != cmp_sz)
return 6;
fclose(infile);
uint32_t uncmp_sz = decompress_osdsys(cmp_dat, unc_dat);
free(cmp_dat);
FILE* outfile = fopen(argv[2], "wb");
if (!outfile)
return 7;
fwrite(unc_dat, 1, uncmp_sz, outfile);
fclose(outfile);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment