mirror of
https://github.com/yquake2/pakextract.git
synced 2024-11-30 23:52:59 +00:00
Very first cut of data decompression
This is a best effort implementation, mostly done with gazing at a hex editor and after the third beer. :) The decompressed .bsp maps are loading fine, but who knows if things are really correct...
This commit is contained in:
parent
bb50d7486e
commit
f14c10c65e
1 changed files with 91 additions and 2 deletions
93
pakextract.c
93
pakextract.c
|
@ -178,10 +178,99 @@ read_directory(FILE *fd, int listOnly)
|
||||||
|
|
||||||
static void extract_compressed(FILE* in, directory *d)
|
static void extract_compressed(FILE* in, directory *d)
|
||||||
{
|
{
|
||||||
|
FILE *out;
|
||||||
|
int offset;
|
||||||
|
int read;
|
||||||
|
int written;
|
||||||
|
int x;
|
||||||
|
int num;
|
||||||
|
unsigned char *in_buf;
|
||||||
|
unsigned char *out_buf;
|
||||||
|
|
||||||
// TODO: implement according to https://gist.github.com/DanielGibson/8bde6241c93e5efe8b75e5e00d0b9858
|
if ((out = fopen(d->file_name, "w")) == NULL)
|
||||||
fprintf(stderr, "## TODO: Implement support for compressed files to extract '%s'!!\n", d->file_name);
|
{
|
||||||
|
perror("Couldn't open outputfile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((in_buf = malloc(d->compressed_length)) == NULL)
|
||||||
|
{
|
||||||
|
perror("Couldn't allocate memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((out_buf = calloc(1, d->file_length)) == NULL)
|
||||||
|
{
|
||||||
|
perror("Couldn't allocate memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(in, d->file_pos, SEEK_SET);
|
||||||
|
fread(in_buf, d->compressed_length, 1, in);
|
||||||
|
|
||||||
|
read = 0;
|
||||||
|
written = 0;
|
||||||
|
|
||||||
|
while (read < d->compressed_length)
|
||||||
|
{
|
||||||
|
x = in_buf[read];
|
||||||
|
++read;
|
||||||
|
|
||||||
|
// x + 1 bytes of uncompressed data
|
||||||
|
if (x < 64)
|
||||||
|
{
|
||||||
|
num = x + 1;
|
||||||
|
memmove(out_buf + written, in_buf + read, num);
|
||||||
|
|
||||||
|
read += num;
|
||||||
|
written += num;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// x - 62 zeros
|
||||||
|
else if (x < 128)
|
||||||
|
{
|
||||||
|
num = x - 62;
|
||||||
|
memset(out_buf + written, 0, num);
|
||||||
|
|
||||||
|
written += num;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// x - 126 times the next byte
|
||||||
|
else if (x < 192)
|
||||||
|
{
|
||||||
|
num = x - 126;
|
||||||
|
memset(out_buf + written, in_buf[read], num);
|
||||||
|
|
||||||
|
++read;
|
||||||
|
written += num;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Reference previously uncompressed data
|
||||||
|
else if (x < 254)
|
||||||
|
{
|
||||||
|
num = x - 190;
|
||||||
|
|
||||||
|
offset = (int)in_buf[read] + 2;
|
||||||
|
++read;
|
||||||
|
|
||||||
|
memmove(out_buf + written, (out_buf + written) - offset, num);
|
||||||
|
written += num;
|
||||||
|
}
|
||||||
|
// Terminate
|
||||||
|
else if (x == 255)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(out_buf, d->file_length, 1, out);
|
||||||
|
fclose(out);
|
||||||
|
|
||||||
|
free(in_buf);
|
||||||
|
free(out_buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue