#include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <zlib.h> #include "tools.h" #include "types.h" static u8 *qgl = NULL; const u32 QRCF = 0x51524346; const u32 QRCC = 0x51524343; #define BUFFER_SIZE 0x80000 int Decompress(u8 *in, u32 in_len, u8 *out, u32 out_len){ z_stream s; int ret; memset(&s, 0, sizeof(s)); s.zalloc = Z_NULL; s.zfree = Z_NULL; s.opaque = Z_NULL; ret = inflateInit(&s); if (ret != Z_OK) fail("inflateInit returned %d", ret); s.avail_in = in_len; s.next_in = in; s.avail_out = out_len; s.next_out = out; ret = inflate(&s, Z_FINISH); if (ret != Z_OK && ret != Z_STREAM_END) fail("inflate returned %d", ret); inflateEnd(&s); return ret; } u8* Compress(u8 *in, u32 in_len, u32 *out_len){ static u8 out[BUFFER_SIZE]; z_stream s; int ret; memset(&s, 0, sizeof(s)); s.zalloc = Z_NULL; s.zfree = Z_NULL; s.opaque = Z_NULL; ret = deflateInit(&s,9); if (ret != Z_OK) fail("deflateInit returned %d", ret); s.avail_in = in_len; s.next_in = in; s.avail_out = BUFFER_SIZE; s.next_out = out+0x8; ret = deflate(&s, Z_FINISH); if (ret != Z_OK && ret != Z_STREAM_END) fail("deflate returned %d", ret); *out_len = BUFFER_SIZE - s.avail_out +0x8; deflateEnd(&s); char hdr[] = {0x51, 0x52, 0x43, 0x43}; memcpy(out,hdr,4); char size[4]; size[0] = (uint8_t)(in_len >> 24); size[1] = (uint8_t)(in_len >> 16); size[2] = (uint8_t)(in_len >> 8); size[3] = (uint8_t)(in_len); memcpy(out+0x4,size,4); return out; } void decompress_qgl(const char* file, const char* fileout){ if(be32(qgl)!=QRCC) fail("invalid file! not a qrc"); u32 size_unpacked = be32(qgl+0x04); FILE *fp = fopen(file,"rb"); fseek (fp, 0, SEEK_END); u32 size_file = ftell (fp); fclose(fp); printf("Decompressed file size: %d Bytes\n",size_unpacked); printf("File size: %d Bytes\n",size_file); u8 qgl_dec[size_unpacked]; Decompress(qgl+0x08, size_file-0x08, qgl_dec, size_unpacked); memcpy_to_file(fileout, qgl_dec, size_unpacked); printf("File Decompressed!! file %s created!\n",fileout); } void compress_qgl(const char* file, const char* fileout){ if(be32(qgl)!=QRCF) fail("invalid file! not a qrc"); u32 size_packed = 0; FILE *fp = fopen(file,"rb"); fseek (fp, 0, SEEK_END); // non-portable u32 size_file = ftell (fp); fclose(fp); printf("File size: %d Bytes\n",size_file); u8 *qgl_comp = Compress(qgl, size_file, &size_packed); printf("Compressed file size: %d Bytes\n",size_packed); memcpy_to_file(fileout, qgl_comp, size_packed); printf("File Compressed!! file %s created!\n",fileout); } int main(int argc, char *argv[]){ if (argc == 4) { qgl = mmap_file(argv[2]); if (strcmp(argv[1], "-x") == 0) decompress_qgl(argv[2],argv[3]); else if (strcmp(argv[1], "-c") == 0) compress_qgl(argv[2],argv[3]); else fail("invalid option: %s", argv[1]); } else { fail("usage: %s [OPTION: -x -c] file.qrc out_file.qrc\n" "\t-x | decompress qrc\n" "\t-c | compress qrc" ,argv[0]); } return 0; }