Replace tabs with spaces in more files.
--HG-- branch : trunk
This commit is contained in:
+567
-567
File diff suppressed because it is too large
Load Diff
@@ -20,33 +20,33 @@
|
||||
* $Id: common.h,v 1.4 2004/02/12 00:41:55 mbroemme Exp $
|
||||
*/
|
||||
|
||||
#define LIBMPQ_CONF_FL_INCREMENT 512 /* i hope we did not need more :) */
|
||||
#define LIBMPQ_CONF_EXT ".conf" /* listdb file seems to be valid with this extension */
|
||||
#define LIBMPQ_CONF_HEADER "LIBMPQ_VERSION" /* listdb file must include this entry to be valid */
|
||||
#define LIBMPQ_CONF_BUFSIZE 4096 /* maximum number of bytes a line in the file could contain */
|
||||
#define LIBMPQ_CONF_FL_INCREMENT 512 /* i hope we did not need more :) */
|
||||
#define LIBMPQ_CONF_EXT ".conf" /* listdb file seems to be valid with this extension */
|
||||
#define LIBMPQ_CONF_HEADER "LIBMPQ_VERSION" /* listdb file must include this entry to be valid */
|
||||
#define LIBMPQ_CONF_BUFSIZE 4096 /* maximum number of bytes a line in the file could contain */
|
||||
|
||||
#define LIBMPQ_CONF_TYPE_CHAR 1 /* value in config file is from type char */
|
||||
#define LIBMPQ_CONF_TYPE_INT 2 /* value in config file is from type int */
|
||||
#define LIBMPQ_CONF_TYPE_CHAR 1 /* value in config file is from type char */
|
||||
#define LIBMPQ_CONF_TYPE_INT 2 /* value in config file is from type int */
|
||||
|
||||
#define LIBMPQ_CONF_EOPEN_DIR -1 /* error on open directory */
|
||||
#define LIBMPQ_CONF_EVALUE_NOT_FOUND -2 /* value for the option was not found */
|
||||
#define LIBMPQ_CONF_EOPEN_DIR -1 /* error on open directory */
|
||||
#define LIBMPQ_CONF_EVALUE_NOT_FOUND -2 /* value for the option was not found */
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define _lseek lseek
|
||||
#define _read read
|
||||
#define _open open
|
||||
#define _write write
|
||||
#define _close close
|
||||
#define _strdup strdup
|
||||
#define _lseek lseek
|
||||
#define _read read
|
||||
#define _open open
|
||||
#define _write write
|
||||
#define _close close
|
||||
#define _strdup strdup
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
@@ -56,7 +56,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a < b) ? a : b)
|
||||
#define min(a, b) ((a < b) ? a : b)
|
||||
#endif
|
||||
|
||||
int libmpq_init_buffer(mpq_archive *mpq_a);
|
||||
|
||||
@@ -31,88 +31,88 @@
|
||||
|
||||
/* Tables */
|
||||
static unsigned char pkzip_dist_bits[] = {
|
||||
0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
||||
0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
||||
};
|
||||
|
||||
static unsigned char pkzip_dist_code[] = {
|
||||
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
|
||||
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
|
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
|
||||
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
|
||||
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
|
||||
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
|
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
|
||||
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
|
||||
};
|
||||
|
||||
static unsigned char pkzip_clen_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
||||
};
|
||||
|
||||
static unsigned short pkzip_len_base[] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||
0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||
0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
|
||||
};
|
||||
|
||||
static unsigned char pkzip_slen_bits[] = {
|
||||
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
|
||||
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
|
||||
};
|
||||
|
||||
static unsigned char pkzip_len_code[] = {
|
||||
0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
|
||||
0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
|
||||
};
|
||||
|
||||
static unsigned char pkzip_bits_asc[] = {
|
||||
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
|
||||
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
|
||||
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
|
||||
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
|
||||
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
|
||||
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
|
||||
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
|
||||
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
|
||||
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
|
||||
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
|
||||
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
|
||||
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
|
||||
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
|
||||
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
|
||||
};
|
||||
|
||||
static unsigned short pkzip_code_asc[] = {
|
||||
0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
|
||||
0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
|
||||
0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
|
||||
0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
|
||||
0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
|
||||
0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
|
||||
0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
|
||||
0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
|
||||
0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
|
||||
0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
|
||||
0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
|
||||
0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
|
||||
0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
|
||||
0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
|
||||
0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
|
||||
0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
|
||||
0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
|
||||
0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
|
||||
0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
|
||||
0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
|
||||
0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
|
||||
0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
|
||||
0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
|
||||
0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
|
||||
0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
|
||||
0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
|
||||
0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
|
||||
0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
|
||||
0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
|
||||
0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
|
||||
0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
|
||||
0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
|
||||
0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
|
||||
0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
|
||||
0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
|
||||
0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
|
||||
0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
|
||||
0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
|
||||
0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
|
||||
0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
|
||||
0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
|
||||
0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
|
||||
0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
|
||||
0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
|
||||
0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
|
||||
0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
|
||||
0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
|
||||
0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
|
||||
0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
|
||||
0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
|
||||
0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
|
||||
0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
|
||||
0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
|
||||
0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
|
||||
0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
|
||||
0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
|
||||
0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
|
||||
0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
|
||||
0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
|
||||
0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
|
||||
0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
|
||||
0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
|
||||
0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
|
||||
0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
|
||||
};
|
||||
|
||||
/* Local variables */
|
||||
@@ -124,68 +124,68 @@ static char copyright[] = "PKWARE Data Compression Library for Win32\r\n"
|
||||
|
||||
/* Local functions */
|
||||
static void libmpq_pkzip_gen_decode_tabs(long count, unsigned char *bits, unsigned char *code, unsigned char *buf2) {
|
||||
long i;
|
||||
long i;
|
||||
|
||||
for (i = count-1; i >= 0; i--) { /* EBX - count */
|
||||
unsigned long idx1 = code[i];
|
||||
unsigned long idx2 = 1 << bits[i];
|
||||
do {
|
||||
buf2[idx1] = (unsigned char)i;
|
||||
idx1 += idx2;
|
||||
} while (idx1 < 0x100);
|
||||
}
|
||||
for (i = count-1; i >= 0; i--) { /* EBX - count */
|
||||
unsigned long idx1 = code[i];
|
||||
unsigned long idx2 = 1 << bits[i];
|
||||
do {
|
||||
buf2[idx1] = (unsigned char)i;
|
||||
idx1 += idx2;
|
||||
} while (idx1 < 0x100);
|
||||
}
|
||||
}
|
||||
|
||||
static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) {
|
||||
unsigned short *code_asc = &pkzip_code_asc[0xFF];
|
||||
unsigned long acc, add;
|
||||
unsigned short count;
|
||||
unsigned short *code_asc = &pkzip_code_asc[0xFF];
|
||||
unsigned long acc, add;
|
||||
unsigned short count;
|
||||
|
||||
for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) {
|
||||
unsigned char *bits_asc = mpq_pkzip->bits_asc + count;
|
||||
unsigned char bits_tmp = *bits_asc;
|
||||
for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) {
|
||||
unsigned char *bits_asc = mpq_pkzip->bits_asc + count;
|
||||
unsigned char bits_tmp = *bits_asc;
|
||||
|
||||
if (bits_tmp <= 8) {
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc;
|
||||
do {
|
||||
mpq_pkzip->offs_2c34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
} else {
|
||||
if ((acc = (*code_asc & 0xFF)) != 0) {
|
||||
mpq_pkzip->offs_2c34[acc] = 0xFF;
|
||||
if (*code_asc & 0x3F) {
|
||||
bits_tmp -= 4;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 4;
|
||||
do {
|
||||
mpq_pkzip->offs_2d34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
} else {
|
||||
bits_tmp -= 6;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 6;
|
||||
do {
|
||||
mpq_pkzip->offs_2e34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x80);
|
||||
}
|
||||
} else {
|
||||
bits_tmp -= 8;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 8;
|
||||
do {
|
||||
mpq_pkzip->offs_2eb4[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bits_tmp <= 8) {
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc;
|
||||
do {
|
||||
mpq_pkzip->offs_2c34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
} else {
|
||||
if ((acc = (*code_asc & 0xFF)) != 0) {
|
||||
mpq_pkzip->offs_2c34[acc] = 0xFF;
|
||||
if (*code_asc & 0x3F) {
|
||||
bits_tmp -= 4;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 4;
|
||||
do {
|
||||
mpq_pkzip->offs_2d34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
} else {
|
||||
bits_tmp -= 6;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 6;
|
||||
do {
|
||||
mpq_pkzip->offs_2e34[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x80);
|
||||
}
|
||||
} else {
|
||||
bits_tmp -= 8;
|
||||
*bits_asc = bits_tmp;
|
||||
add = (1 << bits_tmp);
|
||||
acc = *code_asc >> 8;
|
||||
do {
|
||||
mpq_pkzip->offs_2eb4[acc] = (unsigned char)count;
|
||||
acc += add;
|
||||
} while (acc < 0x100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -193,28 +193,28 @@ static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) {
|
||||
* If no data in input buffer, returns true
|
||||
*/
|
||||
static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits) {
|
||||
/* If number of bits required is less than number of (bits in the buffer) ? */
|
||||
if (bits <= mpq_pkzip->extra_bits) {
|
||||
mpq_pkzip->extra_bits -= bits;
|
||||
mpq_pkzip->bit_buf >>= bits;
|
||||
return 0;
|
||||
}
|
||||
/* If number of bits required is less than number of (bits in the buffer) ? */
|
||||
if (bits <= mpq_pkzip->extra_bits) {
|
||||
mpq_pkzip->extra_bits -= bits;
|
||||
mpq_pkzip->bit_buf >>= bits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load input buffer if necessary */
|
||||
mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits;
|
||||
if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) {
|
||||
mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
|
||||
if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
mpq_pkzip->in_pos = 0;
|
||||
}
|
||||
/* Load input buffer if necessary */
|
||||
mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits;
|
||||
if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) {
|
||||
mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
|
||||
if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
mpq_pkzip->in_pos = 0;
|
||||
}
|
||||
|
||||
/* Update bit buffer */
|
||||
mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8);
|
||||
mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits);
|
||||
mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8;
|
||||
return 0;
|
||||
/* Update bit buffer */
|
||||
mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8);
|
||||
mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits);
|
||||
mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -224,205 +224,205 @@ static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits)
|
||||
* 0x306 : Out of buffer (?)
|
||||
*/
|
||||
static unsigned long libmpq_pkzip_explode_lit(pkzip_data_cmp *mpq_pkzip) {
|
||||
unsigned long bits; /* Number of bits to skip */
|
||||
unsigned long value; /* Position in buffers */
|
||||
unsigned long bits; /* Number of bits to skip */
|
||||
unsigned long value; /* Position in buffers */
|
||||
|
||||
/* Test the current bit in byte buffer. If is not set, simply return the next byte. */
|
||||
if (mpq_pkzip->bit_buf & 1) {
|
||||
/* Test the current bit in byte buffer. If is not set, simply return the next byte. */
|
||||
if (mpq_pkzip->bit_buf & 1) {
|
||||
|
||||
/* Skip current bit in the buffer. */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
|
||||
return 0x306;
|
||||
}
|
||||
/* Skip current bit in the buffer. */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
|
||||
return 0x306;
|
||||
}
|
||||
|
||||
/* The next bits are position in buffers. */
|
||||
value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)];
|
||||
/* The next bits are position in buffers. */
|
||||
value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)];
|
||||
|
||||
/* Get number of bits to skip */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) {
|
||||
return 0x306;
|
||||
}
|
||||
if ((bits = mpq_pkzip->clen_bits[value]) != 0) {
|
||||
unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1);
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) {
|
||||
if ((value + val2) != 0x10E) {
|
||||
return 0x306;
|
||||
}
|
||||
}
|
||||
value = mpq_pkzip->len_base[value] + val2;
|
||||
}
|
||||
return value + 0x100; /* Return number of bytes to repeat */
|
||||
}
|
||||
/* Get number of bits to skip */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) {
|
||||
return 0x306;
|
||||
}
|
||||
if ((bits = mpq_pkzip->clen_bits[value]) != 0) {
|
||||
unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1);
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) {
|
||||
if ((value + val2) != 0x10E) {
|
||||
return 0x306;
|
||||
}
|
||||
}
|
||||
value = mpq_pkzip->len_base[value] + val2;
|
||||
}
|
||||
return value + 0x100; /* Return number of bytes to repeat */
|
||||
}
|
||||
|
||||
/* Skip one bit */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
|
||||
return 0x306;
|
||||
}
|
||||
/* Skip one bit */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
|
||||
return 0x306;
|
||||
}
|
||||
|
||||
/* If the binary compression type, read 8 bits and return them as one byte. */
|
||||
if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) {
|
||||
value = mpq_pkzip->bit_buf & 0xFF;
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
|
||||
return 0x306;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/* If the binary compression type, read 8 bits and return them as one byte. */
|
||||
if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) {
|
||||
value = mpq_pkzip->bit_buf & 0xFF;
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
|
||||
return 0x306;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* When ASCII compression ... */
|
||||
if (mpq_pkzip->bit_buf & 0xFF) {
|
||||
value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF];
|
||||
if (value == 0xFF) {
|
||||
if (mpq_pkzip->bit_buf & 0x3F) {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF];
|
||||
} else {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF];
|
||||
}
|
||||
return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value;
|
||||
/* When ASCII compression ... */
|
||||
if (mpq_pkzip->bit_buf & 0xFF) {
|
||||
value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF];
|
||||
if (value == 0xFF) {
|
||||
if (mpq_pkzip->bit_buf & 0x3F) {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF];
|
||||
} else {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
|
||||
return 0x306;
|
||||
}
|
||||
value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF];
|
||||
}
|
||||
return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the number of bytes to move back.
|
||||
*/
|
||||
static unsigned long libmpq_pkzip_explode_dist(pkzip_data_cmp *mpq_pkzip, unsigned long length) {
|
||||
unsigned long pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)];
|
||||
unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */
|
||||
unsigned long pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)];
|
||||
unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */
|
||||
|
||||
/* Skip the appropriate number of bits */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) {
|
||||
return 0;
|
||||
}
|
||||
if (length == 2) {
|
||||
pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03);
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask);
|
||||
/* Skip the appropriate number of bits */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) {
|
||||
return 0;
|
||||
}
|
||||
if (length == 2) {
|
||||
pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03);
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask);
|
||||
|
||||
/* Skip the bits */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return pos + 1;
|
||||
/* Skip the bits */
|
||||
if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
static unsigned long libmpq_pkzip_expand(pkzip_data_cmp *mpq_pkzip) {
|
||||
unsigned int copy_bytes; /* Number of bytes to copy */
|
||||
unsigned long one_byte; /* One byte from compressed file */
|
||||
unsigned long result;
|
||||
unsigned int copy_bytes; /* Number of bytes to copy */
|
||||
unsigned long one_byte; /* One byte from compressed file */
|
||||
unsigned long result;
|
||||
|
||||
mpq_pkzip->out_pos = 0x1000; /* Initialize output buffer position */
|
||||
mpq_pkzip->out_pos = 0x1000; /* Initialize output buffer position */
|
||||
|
||||
/* If end of data or error, terminate decompress */
|
||||
while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) {
|
||||
/* If end of data or error, terminate decompress */
|
||||
while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) {
|
||||
|
||||
/* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */
|
||||
if (one_byte >= 0x100) {
|
||||
unsigned char *source; /* ECX */
|
||||
unsigned char *target; /* EDX */
|
||||
unsigned long copy_length = one_byte - 0xFE;
|
||||
unsigned long move_back;
|
||||
/* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */
|
||||
if (one_byte >= 0x100) {
|
||||
unsigned char *source; /* ECX */
|
||||
unsigned char *target; /* EDX */
|
||||
unsigned long copy_length = one_byte - 0xFE;
|
||||
unsigned long move_back;
|
||||
|
||||
/* Get length of data to copy */
|
||||
if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) {
|
||||
result = 0x306;
|
||||
break;
|
||||
}
|
||||
/* Get length of data to copy */
|
||||
if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) {
|
||||
result = 0x306;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Target and source pointer */
|
||||
target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos];
|
||||
source = target - move_back;
|
||||
mpq_pkzip->out_pos += copy_length;
|
||||
while (copy_length-- > 0) {
|
||||
*target++ = *source++;
|
||||
}
|
||||
} else {
|
||||
mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte;
|
||||
}
|
||||
/* Target and source pointer */
|
||||
target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos];
|
||||
source = target - move_back;
|
||||
mpq_pkzip->out_pos += copy_length;
|
||||
while (copy_length-- > 0) {
|
||||
*target++ = *source++;
|
||||
}
|
||||
} else {
|
||||
mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte;
|
||||
}
|
||||
|
||||
/*
|
||||
* If number of extracted bytes has reached 1/2 of output buffer,
|
||||
* flush output buffer.
|
||||
*/
|
||||
if (mpq_pkzip->out_pos >= 0x2000) {
|
||||
/*
|
||||
* If number of extracted bytes has reached 1/2 of output buffer,
|
||||
* flush output buffer.
|
||||
*/
|
||||
if (mpq_pkzip->out_pos >= 0x2000) {
|
||||
|
||||
/* Copy decompressed data into user buffer. */
|
||||
copy_bytes = 0x1000;
|
||||
mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param);
|
||||
/* Copy decompressed data into user buffer. */
|
||||
copy_bytes = 0x1000;
|
||||
mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param);
|
||||
|
||||
/* If there are some data left, keep them alive */
|
||||
memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000);
|
||||
mpq_pkzip->out_pos -= 0x1000;
|
||||
}
|
||||
}
|
||||
copy_bytes = mpq_pkzip->out_pos - 0x1000;
|
||||
mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param);
|
||||
return result;
|
||||
/* If there are some data left, keep them alive */
|
||||
memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000);
|
||||
mpq_pkzip->out_pos -= 0x1000;
|
||||
}
|
||||
}
|
||||
copy_bytes = mpq_pkzip->out_pos - 0x1000;
|
||||
mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main exploding function.
|
||||
*/
|
||||
unsigned int libmpq_pkzip_explode(
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param),
|
||||
char *work_buf,
|
||||
void *param) {
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param),
|
||||
char *work_buf,
|
||||
void *param) {
|
||||
|
||||
pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf;
|
||||
pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf;
|
||||
|
||||
/* Set the whole work buffer to zeros */
|
||||
memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp));
|
||||
/* Set the whole work buffer to zeros */
|
||||
memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp));
|
||||
|
||||
/* Initialize work struct and load compressed data */
|
||||
mpq_pkzip->read_buf = read_buf;
|
||||
mpq_pkzip->write_buf = write_buf;
|
||||
mpq_pkzip->param = param;
|
||||
mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
|
||||
mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param);
|
||||
if (mpq_pkzip->in_bytes <= 4) {
|
||||
return LIBMPQ_PKZIP_CMP_BAD_DATA;
|
||||
}
|
||||
mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0]; /* Get the compression type */
|
||||
mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1]; /* Get the dictionary size */
|
||||
mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2]; /* Initialize 16-bit bit buffer */
|
||||
mpq_pkzip->extra_bits = 0; /* Extra (over 8) bits */
|
||||
mpq_pkzip->in_pos = 3; /* Position in input buffer */
|
||||
/* Initialize work struct and load compressed data */
|
||||
mpq_pkzip->read_buf = read_buf;
|
||||
mpq_pkzip->write_buf = write_buf;
|
||||
mpq_pkzip->param = param;
|
||||
mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
|
||||
mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param);
|
||||
if (mpq_pkzip->in_bytes <= 4) {
|
||||
return LIBMPQ_PKZIP_CMP_BAD_DATA;
|
||||
}
|
||||
mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0]; /* Get the compression type */
|
||||
mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1]; /* Get the dictionary size */
|
||||
mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2]; /* Initialize 16-bit bit buffer */
|
||||
mpq_pkzip->extra_bits = 0; /* Extra (over 8) bits */
|
||||
mpq_pkzip->in_pos = 3; /* Position in input buffer */
|
||||
|
||||
/* Test for the valid dictionary size */
|
||||
if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) {
|
||||
return LIBMPQ_PKZIP_CMP_INV_DICTSIZE;
|
||||
}
|
||||
mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits); /* Shifted by 'sar' instruction */
|
||||
if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) {
|
||||
if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) {
|
||||
return LIBMPQ_PKZIP_CMP_INV_MODE;
|
||||
}
|
||||
memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc));
|
||||
libmpq_pkzip_gen_asc_tabs(mpq_pkzip);
|
||||
}
|
||||
memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits));
|
||||
libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2);
|
||||
memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits));
|
||||
memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base));
|
||||
memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits));
|
||||
libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1);
|
||||
if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) {
|
||||
return LIBMPQ_PKZIP_CMP_NO_ERROR;
|
||||
}
|
||||
return LIBMPQ_PKZIP_CMP_ABORT;
|
||||
/* Test for the valid dictionary size */
|
||||
if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) {
|
||||
return LIBMPQ_PKZIP_CMP_INV_DICTSIZE;
|
||||
}
|
||||
mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits); /* Shifted by 'sar' instruction */
|
||||
if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) {
|
||||
if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) {
|
||||
return LIBMPQ_PKZIP_CMP_INV_MODE;
|
||||
}
|
||||
memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc));
|
||||
libmpq_pkzip_gen_asc_tabs(mpq_pkzip);
|
||||
}
|
||||
memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits));
|
||||
libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2);
|
||||
memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits));
|
||||
memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base));
|
||||
memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits));
|
||||
libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1);
|
||||
if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) {
|
||||
return LIBMPQ_PKZIP_CMP_NO_ERROR;
|
||||
}
|
||||
return LIBMPQ_PKZIP_CMP_ABORT;
|
||||
}
|
||||
|
||||
@@ -27,60 +27,60 @@
|
||||
#ifndef _EXPLODE_H
|
||||
#define _EXPLODE_H
|
||||
|
||||
#define LIBMPQ_PKZIP_EXP_BUFFER_SIZE 12596 /* Size of decompress buffer */
|
||||
#define LIBMPQ_PKZIP_CMP_BINARY 0 /* Binary compression */
|
||||
#define LIBMPQ_PKZIP_CMP_ASCII 1 /* Ascii compression */
|
||||
#define LIBMPQ_PKZIP_CMP_NO_ERROR 0
|
||||
#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1
|
||||
#define LIBMPQ_PKZIP_CMP_INV_MODE 2
|
||||
#define LIBMPQ_PKZIP_CMP_BAD_DATA 3
|
||||
#define LIBMPQ_PKZIP_CMP_ABORT 4
|
||||
#define LIBMPQ_PKZIP_EXP_BUFFER_SIZE 12596 /* Size of decompress buffer */
|
||||
#define LIBMPQ_PKZIP_CMP_BINARY 0 /* Binary compression */
|
||||
#define LIBMPQ_PKZIP_CMP_ASCII 1 /* Ascii compression */
|
||||
#define LIBMPQ_PKZIP_CMP_NO_ERROR 0
|
||||
#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1
|
||||
#define LIBMPQ_PKZIP_CMP_INV_MODE 2
|
||||
#define LIBMPQ_PKZIP_CMP_BAD_DATA 3
|
||||
#define LIBMPQ_PKZIP_CMP_ABORT 4
|
||||
|
||||
/* Compression structure (size: 12596 bytes on x86-32) */
|
||||
typedef struct {
|
||||
unsigned long offs0000; /* 0000 */
|
||||
unsigned long cmp_type; /* 0004 - Compression type (LIBMPQ_PZIP_CMP_BINARY or LIBMPQ_PKZIP_CMP_ASCII) */
|
||||
unsigned long out_pos; /* 0008 - Position in output buffer */
|
||||
unsigned long dsize_bits; /* 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) */
|
||||
unsigned long dsize_mask; /* 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) */
|
||||
unsigned long bit_buf; /* 0014 - 16-bit buffer for processing input data */
|
||||
unsigned long extra_bits; /* 0018 - Number of extra (above 8) bits in bit buffer */
|
||||
unsigned int in_pos; /* 001C - Position in in_buf */
|
||||
unsigned long in_bytes; /* 0020 - Number of bytes in input buffer */
|
||||
void *param; /* 0024 - Custom parameter */
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); /* 0028 */
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param); /* 002C */
|
||||
unsigned char out_buf[0x2000]; /* 0030 - Output circle buffer. Starting position is 0x1000 */
|
||||
unsigned char offs_2030[0x204]; /* 2030 - ??? */
|
||||
unsigned char in_buf[0x800]; /* 2234 - Buffer for data to be decompressed */
|
||||
unsigned char pos1[0x100]; /* 2A34 - Positions in buffers */
|
||||
unsigned char pos2[0x100]; /* 2B34 - Positions in buffers */
|
||||
unsigned char offs_2c34[0x100]; /* 2C34 - Buffer for */
|
||||
unsigned char offs_2d34[0x100]; /* 2D34 - Buffer for */
|
||||
unsigned char offs_2e34[0x80]; /* 2EB4 - Buffer for */
|
||||
unsigned char offs_2eb4[0x100]; /* 2EB4 - Buffer for */
|
||||
unsigned char bits_asc[0x100]; /* 2FB4 - Buffer for */
|
||||
unsigned char dist_bits[0x40]; /* 30B4 - Numbers of bytes to skip copied block length */
|
||||
unsigned char slen_bits[0x10]; /* 30F4 - Numbers of bits for skip copied block length */
|
||||
unsigned char clen_bits[0x10]; /* 3104 - Number of valid bits for copied block */
|
||||
unsigned short len_base[0x10]; /* 3114 - Buffer for */
|
||||
unsigned long offs0000; /* 0000 */
|
||||
unsigned long cmp_type; /* 0004 - Compression type (LIBMPQ_PZIP_CMP_BINARY or LIBMPQ_PKZIP_CMP_ASCII) */
|
||||
unsigned long out_pos; /* 0008 - Position in output buffer */
|
||||
unsigned long dsize_bits; /* 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) */
|
||||
unsigned long dsize_mask; /* 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) */
|
||||
unsigned long bit_buf; /* 0014 - 16-bit buffer for processing input data */
|
||||
unsigned long extra_bits; /* 0018 - Number of extra (above 8) bits in bit buffer */
|
||||
unsigned int in_pos; /* 001C - Position in in_buf */
|
||||
unsigned long in_bytes; /* 0020 - Number of bytes in input buffer */
|
||||
void *param; /* 0024 - Custom parameter */
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); /* 0028 */
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param); /* 002C */
|
||||
unsigned char out_buf[0x2000]; /* 0030 - Output circle buffer. Starting position is 0x1000 */
|
||||
unsigned char offs_2030[0x204]; /* 2030 - ??? */
|
||||
unsigned char in_buf[0x800]; /* 2234 - Buffer for data to be decompressed */
|
||||
unsigned char pos1[0x100]; /* 2A34 - Positions in buffers */
|
||||
unsigned char pos2[0x100]; /* 2B34 - Positions in buffers */
|
||||
unsigned char offs_2c34[0x100]; /* 2C34 - Buffer for */
|
||||
unsigned char offs_2d34[0x100]; /* 2D34 - Buffer for */
|
||||
unsigned char offs_2e34[0x80]; /* 2EB4 - Buffer for */
|
||||
unsigned char offs_2eb4[0x100]; /* 2EB4 - Buffer for */
|
||||
unsigned char bits_asc[0x100]; /* 2FB4 - Buffer for */
|
||||
unsigned char dist_bits[0x40]; /* 30B4 - Numbers of bytes to skip copied block length */
|
||||
unsigned char slen_bits[0x10]; /* 30F4 - Numbers of bits for skip copied block length */
|
||||
unsigned char clen_bits[0x10]; /* 3104 - Number of valid bits for copied block */
|
||||
unsigned short len_base[0x10]; /* 3114 - Buffer for */
|
||||
} pkzip_data_cmp;
|
||||
// __attribute__ ((packed)) pkzip_data_cmp;
|
||||
|
||||
typedef struct {
|
||||
char *in_buf; /* Pointer to input data buffer */
|
||||
unsigned int in_pos; /* Current offset in input data buffer */
|
||||
int in_bytes; /* Number of bytes in the input buffer */
|
||||
char *out_buf; /* Pointer to output data buffer */
|
||||
unsigned int out_pos; /* Position in the output buffer */
|
||||
int max_out; /* Maximum number of bytes in the output buffer */
|
||||
char *in_buf; /* Pointer to input data buffer */
|
||||
unsigned int in_pos; /* Current offset in input data buffer */
|
||||
int in_bytes; /* Number of bytes in the input buffer */
|
||||
char *out_buf; /* Pointer to output data buffer */
|
||||
unsigned int out_pos; /* Position in the output buffer */
|
||||
int max_out; /* Maximum number of bytes in the output buffer */
|
||||
} pkzip_data;
|
||||
|
||||
extern unsigned int libmpq_pkzip_explode(
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param),
|
||||
char *work_buf,
|
||||
void *param
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param),
|
||||
char *work_buf,
|
||||
void *param
|
||||
);
|
||||
|
||||
#endif /* _EXPLODE_H */
|
||||
#endif /* _EXPLODE_H */
|
||||
|
||||
@@ -50,20 +50,20 @@
|
||||
* void * param - Custom pointer, parameter of implode/explode
|
||||
*/
|
||||
static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size, void *param) {
|
||||
pkzip_data *info = (pkzip_data *)param;
|
||||
unsigned int max_avail = (info->in_bytes - info->in_pos);
|
||||
unsigned int to_read = *size;
|
||||
pkzip_data *info = (pkzip_data *)param;
|
||||
unsigned int max_avail = (info->in_bytes - info->in_pos);
|
||||
unsigned int to_read = *size;
|
||||
|
||||
/* Check the case when not enough data available */
|
||||
if (to_read > max_avail) {
|
||||
to_read = max_avail;
|
||||
}
|
||||
/* Check the case when not enough data available */
|
||||
if (to_read > max_avail) {
|
||||
to_read = max_avail;
|
||||
}
|
||||
|
||||
/* Load data and increment offsets */
|
||||
memcpy(buf, info->in_buf + info->in_pos, to_read);
|
||||
info->in_pos += to_read;
|
||||
/* Load data and increment offsets */
|
||||
memcpy(buf, info->in_buf + info->in_pos, to_read);
|
||||
info->in_pos += to_read;
|
||||
|
||||
return to_read;
|
||||
return to_read;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -77,76 +77,76 @@ static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size,
|
||||
* void * param - Custom pointer, parameter of implode/explode
|
||||
*/
|
||||
static void libmpq_pkzip_write_output_data(char *buf, unsigned int *size, void *param) {
|
||||
pkzip_data *info = (pkzip_data *)param;
|
||||
unsigned int max_write = (info->max_out - info->out_pos);
|
||||
unsigned int to_write = *size;
|
||||
pkzip_data *info = (pkzip_data *)param;
|
||||
unsigned int max_write = (info->max_out - info->out_pos);
|
||||
unsigned int to_write = *size;
|
||||
|
||||
/* Check the case when not enough space in the output buffer */
|
||||
if (to_write > max_write) {
|
||||
to_write = max_write;
|
||||
}
|
||||
/* Check the case when not enough space in the output buffer */
|
||||
if (to_write > max_write) {
|
||||
to_write = max_write;
|
||||
}
|
||||
|
||||
/* Write output data and increments offsets */
|
||||
memcpy(info->out_buf + info->out_pos, buf, to_write);
|
||||
info->out_pos += to_write;
|
||||
/* Write output data and increments offsets */
|
||||
memcpy(info->out_buf + info->out_pos, buf, to_write);
|
||||
info->out_pos += to_write;
|
||||
}
|
||||
|
||||
int libmpq_pkzip_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {
|
||||
pkzip_data info; /* Data information */
|
||||
char *work_buf = (char *)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE); /* mpq_pkzip work buffer */
|
||||
pkzip_data info; /* Data information */
|
||||
char *work_buf = (char *)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE); /* mpq_pkzip work buffer */
|
||||
|
||||
/* Fill data information structure */
|
||||
info.in_buf = in_buf;
|
||||
info.in_pos = 0;
|
||||
info.in_bytes = in_length;
|
||||
info.out_buf = out_buf;
|
||||
info.out_pos = 0;
|
||||
info.max_out = *out_length;
|
||||
/* Fill data information structure */
|
||||
info.in_buf = in_buf;
|
||||
info.in_pos = 0;
|
||||
info.in_bytes = in_length;
|
||||
info.out_buf = out_buf;
|
||||
info.out_pos = 0;
|
||||
info.max_out = *out_length;
|
||||
|
||||
/* Do the decompression */
|
||||
libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info);
|
||||
*out_length = info.out_pos;
|
||||
free(work_buf);
|
||||
return 0;
|
||||
/* Do the decompression */
|
||||
libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info);
|
||||
*out_length = info.out_pos;
|
||||
free(work_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_buf, int in_length) {
|
||||
*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1);
|
||||
return 1;
|
||||
*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int libmpq_wave_decompress_stereo(char *out_buf, int *out_length, char *in_buf, int in_length) {
|
||||
*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2);
|
||||
return 1;
|
||||
*out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {
|
||||
#ifdef HAVE_LIBZ
|
||||
z_stream z; /* Stream information for zlib */
|
||||
int result;
|
||||
z_stream z; /* Stream information for zlib */
|
||||
int result;
|
||||
|
||||
/* Fill the stream structure for zlib */
|
||||
z.next_in = (Bytef *)in_buf;
|
||||
z.avail_in = (uInt)in_length;
|
||||
z.total_in = in_length;
|
||||
z.next_out = (Bytef *)out_buf;
|
||||
z.avail_out = *out_length;
|
||||
z.total_out = 0;
|
||||
z.zalloc = NULL;
|
||||
z.zfree = NULL;
|
||||
/* Fill the stream structure for zlib */
|
||||
z.next_in = (Bytef *)in_buf;
|
||||
z.avail_in = (uInt)in_length;
|
||||
z.total_in = in_length;
|
||||
z.next_out = (Bytef *)out_buf;
|
||||
z.avail_out = *out_length;
|
||||
z.total_out = 0;
|
||||
z.zalloc = NULL;
|
||||
z.zfree = NULL;
|
||||
|
||||
/* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */
|
||||
if ((result = inflateInit(&z)) == 0) {
|
||||
/* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */
|
||||
if ((result = inflateInit(&z)) == 0) {
|
||||
|
||||
/* Call zlib to decompress the data */
|
||||
result = inflate(&z, Z_FINISH);
|
||||
*out_length = z.total_out;
|
||||
inflateEnd(&z);
|
||||
}
|
||||
return result;
|
||||
/* Call zlib to decompress the data */
|
||||
result = inflate(&z, Z_FINISH);
|
||||
*out_length = z.total_out;
|
||||
inflateEnd(&z);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
memset(out_buf, '0', *out_length);
|
||||
return 0;
|
||||
memset(out_buf, '0', *out_length);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -157,106 +157,106 @@ int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_
|
||||
* 1500F5F0
|
||||
*/
|
||||
int libmpq_huff_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) {
|
||||
struct huffman_tree *ht = (huffman_tree *)malloc(sizeof(struct huffman_tree));
|
||||
struct huffman_input_stream *is = (huffman_input_stream *)malloc(sizeof(struct huffman_input_stream));
|
||||
struct huffman_tree_item *hi = (huffman_tree_item *)malloc(sizeof(struct huffman_tree_item));
|
||||
memset(ht, 0, sizeof(struct huffman_tree));
|
||||
memset(is, 0, sizeof(struct huffman_input_stream));
|
||||
memset(hi, 0, sizeof(struct huffman_tree_item));
|
||||
struct huffman_tree *ht = (huffman_tree *)malloc(sizeof(struct huffman_tree));
|
||||
struct huffman_input_stream *is = (huffman_input_stream *)malloc(sizeof(struct huffman_input_stream));
|
||||
struct huffman_tree_item *hi = (huffman_tree_item *)malloc(sizeof(struct huffman_tree_item));
|
||||
memset(ht, 0, sizeof(struct huffman_tree));
|
||||
memset(is, 0, sizeof(struct huffman_input_stream));
|
||||
memset(hi, 0, sizeof(struct huffman_tree_item));
|
||||
|
||||
/* Initialize input stream */
|
||||
is->bit_buf = *(unsigned long *)in_buf;
|
||||
in_buf += sizeof(unsigned long);
|
||||
is->in_buf = (unsigned char *)in_buf;
|
||||
is->bits = 32;
|
||||
/* Initialize input stream */
|
||||
is->bit_buf = *(unsigned long *)in_buf;
|
||||
in_buf += sizeof(unsigned long);
|
||||
is->in_buf = (unsigned char *)in_buf;
|
||||
is->bits = 32;
|
||||
|
||||
/* Initialize the Huffmann tree for decompression */
|
||||
libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS);
|
||||
/* Initialize the Huffmann tree for decompression */
|
||||
libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS);
|
||||
|
||||
*out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length);
|
||||
*out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length);
|
||||
|
||||
free(hi);
|
||||
free(is);
|
||||
free(ht);
|
||||
return 0;
|
||||
free(hi);
|
||||
free(is);
|
||||
free(ht);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length) {
|
||||
char *temp_buf = NULL; /* Temporary storage for decompressed data */
|
||||
char *work_buf = NULL; /* Where to store decompressed data */
|
||||
int out_length = *pout_length; /* For storage number of output bytes */
|
||||
unsigned fDecompressions1; /* Decompressions applied to the block */
|
||||
unsigned fDecompressions2; /* Just another copy of decompressions applied to the block */
|
||||
int count = 0; /* Counter for every use */
|
||||
int entries = (sizeof(dcmp_table) / sizeof(decompress_table));
|
||||
int i;
|
||||
char *temp_buf = NULL; /* Temporary storage for decompressed data */
|
||||
char *work_buf = NULL; /* Where to store decompressed data */
|
||||
int out_length = *pout_length; /* For storage number of output bytes */
|
||||
unsigned fDecompressions1; /* Decompressions applied to the block */
|
||||
unsigned fDecompressions2; /* Just another copy of decompressions applied to the block */
|
||||
int count = 0; /* Counter for every use */
|
||||
int entries = (sizeof(dcmp_table) / sizeof(decompress_table));
|
||||
int i;
|
||||
|
||||
/* If the input length is the same as output, do nothing. */
|
||||
if (in_length == out_length) {
|
||||
if (in_buf == out_buf) {
|
||||
return 1;
|
||||
}
|
||||
memcpy(out_buf, in_buf, in_length);
|
||||
return 1;
|
||||
}
|
||||
/* If the input length is the same as output, do nothing. */
|
||||
if (in_length == out_length) {
|
||||
if (in_buf == out_buf) {
|
||||
return 1;
|
||||
}
|
||||
memcpy(out_buf, in_buf, in_length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get applied compression types and decrement data length */
|
||||
fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++;
|
||||
in_length--;
|
||||
/* Get applied compression types and decrement data length */
|
||||
fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++;
|
||||
in_length--;
|
||||
|
||||
/* Search decompression table type and get all types of compression */
|
||||
for (i = 0; i < entries; i++) {
|
||||
/* We have to apply this decompression? */
|
||||
if (fDecompressions1 & dcmp_table[i].mask) {
|
||||
count++;
|
||||
}
|
||||
/* Search decompression table type and get all types of compression */
|
||||
for (i = 0; i < entries; i++) {
|
||||
/* We have to apply this decompression? */
|
||||
if (fDecompressions1 & dcmp_table[i].mask) {
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Clear this flag from temporary variable. */
|
||||
fDecompressions2 &= ~dcmp_table[i].mask;
|
||||
}
|
||||
/* Clear this flag from temporary variable. */
|
||||
fDecompressions2 &= ~dcmp_table[i].mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there is some method unhandled
|
||||
* (E.g. compressed by future versions)
|
||||
*/
|
||||
if (fDecompressions2 != 0) {
|
||||
printf("Unknown Compression\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if there is some method unhandled
|
||||
* (E.g. compressed by future versions)
|
||||
*/
|
||||
if (fDecompressions2 != 0) {
|
||||
printf("Unknown Compression\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If there is more than only one compression, we have to allocate extra buffer */
|
||||
if (count >= 2) {
|
||||
temp_buf = (char *)malloc(out_length);
|
||||
}
|
||||
/* If there is more than only one compression, we have to allocate extra buffer */
|
||||
if (count >= 2) {
|
||||
temp_buf = (char *)malloc(out_length);
|
||||
}
|
||||
|
||||
/* Apply all decompressions */
|
||||
for (i = 0, count = 0; i < entries; i++) {
|
||||
/* Apply all decompressions */
|
||||
for (i = 0, count = 0; i < entries; i++) {
|
||||
|
||||
/* If not used this kind of compression, skip the loop */
|
||||
if (fDecompressions1 & dcmp_table[i].mask) {
|
||||
/* If not used this kind of compression, skip the loop */
|
||||
if (fDecompressions1 & dcmp_table[i].mask) {
|
||||
|
||||
/* If odd case, use target buffer for output, otherwise use allocated tempbuf */
|
||||
work_buf = (count++ & 1) ? temp_buf : out_buf;
|
||||
out_length = *pout_length;
|
||||
/* If odd case, use target buffer for output, otherwise use allocated tempbuf */
|
||||
work_buf = (count++ & 1) ? temp_buf : out_buf;
|
||||
out_length = *pout_length;
|
||||
|
||||
/* Decompress buffer using corresponding function */
|
||||
dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length);
|
||||
/* Decompress buffer using corresponding function */
|
||||
dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length);
|
||||
|
||||
/* Move output length to src length for next compression */
|
||||
in_length = out_length;
|
||||
in_buf = work_buf;
|
||||
}
|
||||
}
|
||||
/* Move output length to src length for next compression */
|
||||
in_length = out_length;
|
||||
in_buf = work_buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* If output buffer is not the same like target buffer, we have to copy data */
|
||||
if (work_buf != out_buf) {
|
||||
memcpy(out_buf, in_buf, out_length);
|
||||
}
|
||||
*pout_length = out_length;
|
||||
/* If output buffer is not the same like target buffer, we have to copy data */
|
||||
if (work_buf != out_buf) {
|
||||
memcpy(out_buf, in_buf, out_length);
|
||||
}
|
||||
*pout_length = out_length;
|
||||
|
||||
/* Delete temporary buffer, if necessary */
|
||||
if (temp_buf != NULL) {
|
||||
free(temp_buf);
|
||||
}
|
||||
return 1;
|
||||
/* Delete temporary buffer, if necessary */
|
||||
if (temp_buf != NULL) {
|
||||
free(temp_buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,32 +27,32 @@
|
||||
#ifndef _HUFFMAN_H
|
||||
#define _HUFFMAN_H
|
||||
|
||||
#define PTR_NOT(ptr) (struct huffman_tree_item *)(~(unsigned long)(ptr))
|
||||
#define PTR_PTR(ptr) ((struct huffman_tree_item *)(ptr))
|
||||
#define PTR_INT(ptr) (long)(ptr)
|
||||
#define PTR_NOT(ptr) (struct huffman_tree_item *)(~(unsigned long)(ptr))
|
||||
#define PTR_PTR(ptr) ((struct huffman_tree_item *)(ptr))
|
||||
#define PTR_INT(ptr) (long)(ptr)
|
||||
|
||||
#define INSERT_ITEM 1
|
||||
#define SWITCH_ITEMS 2 /* Switch the item1 and item2 */
|
||||
#define INSERT_ITEM 1
|
||||
#define SWITCH_ITEMS 2 /* Switch the item1 and item2 */
|
||||
|
||||
/*
|
||||
* Input stream for Huffmann decompression
|
||||
*/
|
||||
struct huffman_input_stream {
|
||||
unsigned char *in_buf; /* 00 - Input data */
|
||||
unsigned long bit_buf; /* 04 - Input bit buffer */
|
||||
unsigned int bits; /* 08 - Number of bits remaining in 'byte' */
|
||||
unsigned char *in_buf; /* 00 - Input data */
|
||||
unsigned long bit_buf; /* 04 - Input bit buffer */
|
||||
unsigned int bits; /* 08 - Number of bits remaining in 'byte' */
|
||||
};
|
||||
|
||||
/*
|
||||
* Huffmann tree item.
|
||||
*/
|
||||
struct huffman_tree_item {
|
||||
struct huffman_tree_item *next; /* 00 - Pointer to next huffman_tree_item */
|
||||
struct huffman_tree_item *prev; /* 04 - Pointer to prev huffman_tree_item (< 0 if none) */
|
||||
unsigned long dcmp_byte; /* 08 - Index of this item in item pointer array, decompressed byte value */
|
||||
unsigned long byte_value; /* 0C - Some byte value */
|
||||
struct huffman_tree_item *parent; /* 10 - Pointer to parent huffman_tree_item (NULL if none) */
|
||||
struct huffman_tree_item *child; /* 14 - Pointer to child huffman_tree_item */
|
||||
struct huffman_tree_item *next; /* 00 - Pointer to next huffman_tree_item */
|
||||
struct huffman_tree_item *prev; /* 04 - Pointer to prev huffman_tree_item (< 0 if none) */
|
||||
unsigned long dcmp_byte; /* 08 - Index of this item in item pointer array, decompressed byte value */
|
||||
unsigned long byte_value; /* 0C - Some byte value */
|
||||
struct huffman_tree_item *parent; /* 10 - Pointer to parent huffman_tree_item (NULL if none) */
|
||||
struct huffman_tree_item *child; /* 14 - Pointer to child huffman_tree_item */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -66,40 +66,40 @@ struct huffman_tree_item {
|
||||
* directly stores output byte to output stream.
|
||||
*/
|
||||
struct huffman_decompress {
|
||||
unsigned long offs00; /* 00 - 1 if resolved */
|
||||
unsigned long bits; /* 04 - Bit count */
|
||||
union {
|
||||
unsigned long dcmp_byte; /* 08 - Byte value for decompress (if bitCount <= 7) */
|
||||
struct huffman_tree_item *p_item; /* 08 - THTreeItem (if number of bits is greater than 7 */
|
||||
};
|
||||
unsigned long offs00; /* 00 - 1 if resolved */
|
||||
unsigned long bits; /* 04 - Bit count */
|
||||
union {
|
||||
unsigned long dcmp_byte; /* 08 - Byte value for decompress (if bitCount <= 7) */
|
||||
struct huffman_tree_item *p_item; /* 08 - THTreeItem (if number of bits is greater than 7 */
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for Huffman tree.
|
||||
*/
|
||||
struct huffman_tree {
|
||||
unsigned long cmp0; /* 0000 - 1 if compression type 0 */
|
||||
unsigned long offs0004; /* 0004 - Some flag */
|
||||
unsigned long cmp0; /* 0000 - 1 if compression type 0 */
|
||||
unsigned long offs0004; /* 0004 - Some flag */
|
||||
|
||||
struct huffman_tree_item items0008[0x203]; /* 0008 - huffman tree items */
|
||||
struct huffman_tree_item items0008[0x203]; /* 0008 - huffman tree items */
|
||||
|
||||
/* Sometimes used as huffman tree item */
|
||||
struct huffman_tree_item *item3050; /* 3050 - Always NULL (?) */
|
||||
struct huffman_tree_item *item3054; /* 3054 - Pointer to huffman_tree_item */
|
||||
struct huffman_tree_item *item3058; /* 3058 - Pointer to huffman_tree_item (< 0 if invalid) */
|
||||
/* Sometimes used as huffman tree item */
|
||||
struct huffman_tree_item *item3050; /* 3050 - Always NULL (?) */
|
||||
struct huffman_tree_item *item3054; /* 3054 - Pointer to huffman_tree_item */
|
||||
struct huffman_tree_item *item3058; /* 3058 - Pointer to huffman_tree_item (< 0 if invalid) */
|
||||
|
||||
/* Sometimes used as huffman tree item */
|
||||
struct huffman_tree_item *item305C; /* 305C - Usually NULL */
|
||||
struct huffman_tree_item *first; /* 3060 - Pointer to top (first) Huffman tree item */
|
||||
struct huffman_tree_item *last; /* 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) */
|
||||
unsigned long items; /* 3068 - Number of used huffman tree items */
|
||||
/* Sometimes used as huffman tree item */
|
||||
struct huffman_tree_item *item305C; /* 305C - Usually NULL */
|
||||
struct huffman_tree_item *first; /* 3060 - Pointer to top (first) Huffman tree item */
|
||||
struct huffman_tree_item *last; /* 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) */
|
||||
unsigned long items; /* 3068 - Number of used huffman tree items */
|
||||
|
||||
struct huffman_tree_item *items306C[0x102]; /* 306C - huffman_tree_item pointer array */
|
||||
struct huffman_decompress qd3474[0x80]; /* 3474 - Array for quick decompression */
|
||||
struct huffman_tree_item *items306C[0x102]; /* 306C - huffman_tree_item pointer array */
|
||||
struct huffman_decompress qd3474[0x80]; /* 3474 - Array for quick decompression */
|
||||
|
||||
//unsigned char table1502A630[]; /* Some table to make struct size flexible */
|
||||
//unsigned char table1502A630[]; /* Some table to make struct size flexible */
|
||||
};
|
||||
|
||||
int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp);
|
||||
int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length);
|
||||
#endif /* _HUFFMAN_H */
|
||||
#endif /* _HUFFMAN_H */
|
||||
|
||||
+422
-422
@@ -36,9 +36,9 @@
|
||||
* format: MAJOR.MINOR.PATCH
|
||||
*/
|
||||
char *libmpq_version() {
|
||||
static char version[10];
|
||||
sprintf(version, "%i.%i.%i", LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION);
|
||||
return version;
|
||||
static char version[10];
|
||||
sprintf(version, "%i.%i.%i", LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION);
|
||||
return version;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -47,94 +47,94 @@ char *libmpq_version() {
|
||||
* table.
|
||||
*/
|
||||
int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) {
|
||||
int fd = 0;
|
||||
int rb = 0;
|
||||
int ncnt = FALSE;
|
||||
struct stat fileinfo;
|
||||
int fd = 0;
|
||||
int rb = 0;
|
||||
int ncnt = FALSE;
|
||||
struct stat fileinfo;
|
||||
|
||||
/* allocate memory */
|
||||
mpq_a->mpq_l = (mpq_list *)malloc(sizeof(mpq_list));
|
||||
memset(mpq_a->mpq_l, 0, sizeof(mpq_list));
|
||||
mpq_a->header = (mpq_header *)malloc(sizeof(mpq_header));
|
||||
memset(mpq_a->header, 0, sizeof(mpq_header));
|
||||
/* allocate memory */
|
||||
mpq_a->mpq_l = (mpq_list *)malloc(sizeof(mpq_list));
|
||||
memset(mpq_a->mpq_l, 0, sizeof(mpq_list));
|
||||
mpq_a->header = (mpq_header *)malloc(sizeof(mpq_header));
|
||||
memset(mpq_a->header, 0, sizeof(mpq_header));
|
||||
|
||||
/* Check if file exists and is readable */
|
||||
fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS);
|
||||
if (fd == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
/* Check if file exists and is readable */
|
||||
fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS);
|
||||
if (fd == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
|
||||
/* fill the structures with informations */
|
||||
strcpy((char *)mpq_a->filename, (char *)mpq_filename);
|
||||
libmpq_init_buffer(mpq_a);
|
||||
mpq_a->fd = fd;
|
||||
mpq_a->header->id = 0;
|
||||
mpq_a->maxblockindex = 0;
|
||||
mpq_a->mpq_l->mpq_files = NULL;
|
||||
/* fill the structures with informations */
|
||||
strcpy((char *)mpq_a->filename, (char *)mpq_filename);
|
||||
libmpq_init_buffer(mpq_a);
|
||||
mpq_a->fd = fd;
|
||||
mpq_a->header->id = 0;
|
||||
mpq_a->maxblockindex = 0;
|
||||
mpq_a->mpq_l->mpq_files = NULL;
|
||||
|
||||
mpq_a->mpqpos = 0; //k
|
||||
|
||||
while (!ncnt) {
|
||||
mpq_a->header->id = 0;
|
||||
#ifdef WIN32
|
||||
_lseeki64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET);
|
||||
#else
|
||||
lseek64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET);
|
||||
#endif
|
||||
rb = _read(mpq_a->fd, mpq_a->header, sizeof(mpq_header));
|
||||
while (!ncnt) {
|
||||
mpq_a->header->id = 0;
|
||||
#ifdef WIN32
|
||||
_lseeki64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET);
|
||||
#else
|
||||
lseek64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET);
|
||||
#endif
|
||||
rb = _read(mpq_a->fd, mpq_a->header, sizeof(mpq_header));
|
||||
|
||||
/* if different number of bytes read, break the loop */
|
||||
if (rb != sizeof(mpq_header)) {
|
||||
return LIBMPQ_EFILE_FORMAT;
|
||||
}
|
||||
/* if different number of bytes read, break the loop */
|
||||
if (rb != sizeof(mpq_header)) {
|
||||
return LIBMPQ_EFILE_FORMAT;
|
||||
}
|
||||
|
||||
/* special offset for protected MPQs */
|
||||
if (mpq_a->header->offset == LIBMPQ_HEADER_W3M) {
|
||||
mpq_a->flags |= LIBMPQ_FLAG_PROTECTED;
|
||||
mpq_a->header->offset = sizeof(mpq_header);
|
||||
}
|
||||
/* special offset for protected MPQs */
|
||||
if (mpq_a->header->offset == LIBMPQ_HEADER_W3M) {
|
||||
mpq_a->flags |= LIBMPQ_FLAG_PROTECTED;
|
||||
mpq_a->header->offset = sizeof(mpq_header);
|
||||
}
|
||||
|
||||
/* if valid signature has been found, break the loop */
|
||||
/* if valid signature has been found, break the loop */
|
||||
if (mpq_a->header->id == LIBMPQ_ID_MPQ) {
|
||||
ncnt = true;
|
||||
}
|
||||
/*if (mpq_a->header->id == LIBMPQ_ID_MPQ &&
|
||||
mpq_a->header->offset == sizeof(mpq_header) &&
|
||||
mpq_a->header->hashtablepos < mpq_a->header->archivesize &&
|
||||
mpq_a->header->blocktablepos < mpq_a->header->archivesize) {
|
||||
ncnt = TRUE;
|
||||
}*/
|
||||
mpq_a->header->offset == sizeof(mpq_header) &&
|
||||
mpq_a->header->hashtablepos < mpq_a->header->archivesize &&
|
||||
mpq_a->header->blocktablepos < mpq_a->header->archivesize) {
|
||||
ncnt = TRUE;
|
||||
}*/
|
||||
|
||||
/* move to the next possible offset */
|
||||
if (!ncnt) {
|
||||
mpq_a->mpqpos += 0x200;
|
||||
}
|
||||
}
|
||||
/* move to the next possible offset */
|
||||
if (!ncnt) {
|
||||
mpq_a->mpqpos += 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the right positions of the hash table and the block table. */
|
||||
mpq_a->blocksize = (0x200 << mpq_a->header->blocksize);
|
||||
fstat(mpq_a->fd, &fileinfo);
|
||||
/* get the right positions of the hash table and the block table. */
|
||||
mpq_a->blocksize = (0x200 << mpq_a->header->blocksize);
|
||||
fstat(mpq_a->fd, &fileinfo);
|
||||
|
||||
/* Normal MPQs must have position of */
|
||||
/*if (mpq_a->header->hashtablepos + mpq_a->mpqpos < fileinfo.st_size &&
|
||||
mpq_a->header->blocktablepos + mpq_a->mpqpos < fileinfo.st_size) {
|
||||
mpq_a->header->hashtablepos += mpq_a->mpqpos;
|
||||
mpq_a->header->blocktablepos += mpq_a->mpqpos;
|
||||
} else {
|
||||
return LIBMPQ_EFILE_FORMAT;
|
||||
}*/
|
||||
/* Normal MPQs must have position of */
|
||||
/*if (mpq_a->header->hashtablepos + mpq_a->mpqpos < fileinfo.st_size &&
|
||||
mpq_a->header->blocktablepos + mpq_a->mpqpos < fileinfo.st_size) {
|
||||
mpq_a->header->hashtablepos += mpq_a->mpqpos;
|
||||
mpq_a->header->blocktablepos += mpq_a->mpqpos;
|
||||
} else {
|
||||
return LIBMPQ_EFILE_FORMAT;
|
||||
}*/
|
||||
|
||||
/* Try to read and decrypt the hashtable */
|
||||
if (libmpq_read_hashtable(mpq_a) != 0) {
|
||||
return LIBMPQ_EHASHTABLE;
|
||||
}
|
||||
/* Try to read and decrypt the hashtable */
|
||||
if (libmpq_read_hashtable(mpq_a) != 0) {
|
||||
return LIBMPQ_EHASHTABLE;
|
||||
}
|
||||
|
||||
/* Try to read and decrypt the blocktable */
|
||||
if (libmpq_read_blocktable(mpq_a) != 0) {
|
||||
return LIBMPQ_EBLOCKTABLE;
|
||||
}
|
||||
/* Try to read and decrypt the blocktable */
|
||||
if (libmpq_read_blocktable(mpq_a) != 0) {
|
||||
return LIBMPQ_EBLOCKTABLE;
|
||||
}
|
||||
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,18 +142,18 @@ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) {
|
||||
* mpq_open_archive(); and frees the decryption buffer.
|
||||
*/
|
||||
int libmpq_archive_close(mpq_archive *mpq_a) {
|
||||
memset(mpq_a->buf, 0, sizeof(mpq_a->buf));
|
||||
memset(mpq_a->buf, 0, sizeof(mpq_a->buf));
|
||||
|
||||
/* free the allocated memory. */
|
||||
free(mpq_a->header);
|
||||
free(mpq_a->mpq_l);
|
||||
/* free the allocated memory. */
|
||||
free(mpq_a->header);
|
||||
free(mpq_a->mpq_l);
|
||||
|
||||
/* Check if file descriptor is valid. */
|
||||
if ((_close(mpq_a->fd)) == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
/* Check if file descriptor is valid. */
|
||||
if ((_close(mpq_a->fd)) == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -161,95 +161,95 @@ int libmpq_archive_close(mpq_archive *mpq_a) {
|
||||
* If an error occurs something < 0 is returned.
|
||||
*/
|
||||
int libmpq_archive_info(mpq_archive *mpq_a, unsigned int infotype) {
|
||||
unsigned int filecount = 0;
|
||||
unsigned int fsize = 0;
|
||||
unsigned int csize = 0;
|
||||
mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->header->blocktablesize;
|
||||
mpq_block *mpq_b = NULL;
|
||||
unsigned int filecount = 0;
|
||||
unsigned int fsize = 0;
|
||||
unsigned int csize = 0;
|
||||
mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->header->blocktablesize;
|
||||
mpq_block *mpq_b = NULL;
|
||||
|
||||
switch (infotype) {
|
||||
case LIBMPQ_MPQ_ARCHIVE_SIZE:
|
||||
return mpq_a->header->archivesize;
|
||||
case LIBMPQ_MPQ_HASHTABLE_SIZE:
|
||||
return mpq_a->header->hashtablesize;
|
||||
case LIBMPQ_MPQ_BLOCKTABLE_SIZE:
|
||||
return mpq_a->header->blocktablesize;
|
||||
case LIBMPQ_MPQ_BLOCKSIZE:
|
||||
return mpq_a->blocksize;
|
||||
case LIBMPQ_MPQ_NUMFILES:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
filecount++;
|
||||
}
|
||||
return filecount;
|
||||
case LIBMPQ_MPQ_COMPRESSED_SIZE:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
csize += mpq_b->csize;
|
||||
}
|
||||
return csize;
|
||||
case LIBMPQ_MPQ_UNCOMPRESSED_SIZE:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
fsize += mpq_b->fsize;
|
||||
}
|
||||
return fsize;
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
switch (infotype) {
|
||||
case LIBMPQ_MPQ_ARCHIVE_SIZE:
|
||||
return mpq_a->header->archivesize;
|
||||
case LIBMPQ_MPQ_HASHTABLE_SIZE:
|
||||
return mpq_a->header->hashtablesize;
|
||||
case LIBMPQ_MPQ_BLOCKTABLE_SIZE:
|
||||
return mpq_a->header->blocktablesize;
|
||||
case LIBMPQ_MPQ_BLOCKSIZE:
|
||||
return mpq_a->blocksize;
|
||||
case LIBMPQ_MPQ_NUMFILES:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
filecount++;
|
||||
}
|
||||
return filecount;
|
||||
case LIBMPQ_MPQ_COMPRESSED_SIZE:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
csize += mpq_b->csize;
|
||||
}
|
||||
return csize;
|
||||
case LIBMPQ_MPQ_UNCOMPRESSED_SIZE:
|
||||
for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) {
|
||||
fsize += mpq_b->fsize;
|
||||
}
|
||||
return fsize;
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns some useful file information.
|
||||
*/
|
||||
int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const int unsigned number) {
|
||||
int blockindex = number; //-1;
|
||||
int i = 0;
|
||||
mpq_block *mpq_b = NULL;
|
||||
mpq_hash *mpq_h = NULL;
|
||||
int blockindex = number; //-1;
|
||||
int i = 0;
|
||||
mpq_block *mpq_b = NULL;
|
||||
mpq_hash *mpq_h = NULL;
|
||||
|
||||
/* check if given number is not out of range */
|
||||
if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}
|
||||
/* check if given number is not out of range */
|
||||
if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}
|
||||
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* check if file was found */
|
||||
/*if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}*/
|
||||
/* check if file was found */
|
||||
/*if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}*/
|
||||
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
switch (infotype) {
|
||||
case LIBMPQ_FILE_COMPRESSED_SIZE:
|
||||
return mpq_b->csize;
|
||||
case LIBMPQ_FILE_UNCOMPRESSED_SIZE:
|
||||
return mpq_b->fsize;
|
||||
case LIBMPQ_FILE_COMPRESSION_TYPE:
|
||||
if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) {
|
||||
return LIBMPQ_FILE_COMPRESS_PKWARE;
|
||||
}
|
||||
if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) {
|
||||
return LIBMPQ_FILE_COMPRESS_MULTI;
|
||||
}
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
switch (infotype) {
|
||||
case LIBMPQ_FILE_COMPRESSED_SIZE:
|
||||
return mpq_b->csize;
|
||||
case LIBMPQ_FILE_UNCOMPRESSED_SIZE:
|
||||
return mpq_b->fsize;
|
||||
case LIBMPQ_FILE_COMPRESSION_TYPE:
|
||||
if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) {
|
||||
return LIBMPQ_FILE_COMPRESS_PKWARE;
|
||||
}
|
||||
if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) {
|
||||
return LIBMPQ_FILE_COMPRESS_MULTI;
|
||||
}
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -259,17 +259,17 @@ int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const int unsign
|
||||
* returns NULL.
|
||||
*/
|
||||
char *libmpq_file_name(mpq_archive *mpq_a, const int number) {
|
||||
static char tempfile[PATH_MAX];
|
||||
static char tempfile[PATH_MAX];
|
||||
|
||||
/* check if we are in the range of available files. */
|
||||
if (number > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || number < 1) {
|
||||
return NULL;
|
||||
}
|
||||
/* check if we are in the range of available files. */
|
||||
if (number > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || number < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this is safe because we built a fallback filelist, if something was wrong. */
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[number - 1], number);
|
||||
/* this is safe because we built a fallback filelist, if something was wrong. */
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[number - 1], number);
|
||||
|
||||
return tempfile;
|
||||
return tempfile;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -277,20 +277,20 @@ char *libmpq_file_name(mpq_archive *mpq_a, const int number) {
|
||||
* filename.
|
||||
*/
|
||||
int libmpq_file_number(mpq_archive *mpq_a, const char *name) {
|
||||
int i;
|
||||
char tempfile[PATH_MAX];
|
||||
int i;
|
||||
char tempfile[PATH_MAX];
|
||||
|
||||
for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i + 1);
|
||||
if (strncmp(tempfile, name, strlen(name)) == 0) {
|
||||
for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i + 1);
|
||||
if (strncmp(tempfile, name, strlen(name)) == 0) {
|
||||
|
||||
/* if file found return the number */
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
/* if file found return the number */
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if no matching entry found return LIBMPQ_EFILE_NOT_FOUND */
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
/* if no matching entry found return LIBMPQ_EFILE_NOT_FOUND */
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -299,39 +299,39 @@ int libmpq_file_number(mpq_archive *mpq_a, const char *name) {
|
||||
* it returns 0, otherwise LIBMPQ_EFILE_NOT_FOUND.
|
||||
*/
|
||||
int libmpq_file_check(mpq_archive *mpq_a, void *file, int type) {
|
||||
int found = 0;
|
||||
int i;
|
||||
char tempfile[PATH_MAX];
|
||||
int found = 0;
|
||||
int i;
|
||||
char tempfile[PATH_MAX];
|
||||
|
||||
switch (type) {
|
||||
case LIBMPQ_FILE_TYPE_INT:
|
||||
switch (type) {
|
||||
case LIBMPQ_FILE_TYPE_INT:
|
||||
|
||||
/* check if we are in the range of available files. */
|
||||
if (*(int *)file > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || *(int *)file < 1) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
} else {
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
case LIBMPQ_FILE_TYPE_CHAR:
|
||||
for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i);
|
||||
if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) {
|
||||
/* check if we are in the range of available files. */
|
||||
if (*(int *)file > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || *(int *)file < 1) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
} else {
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
case LIBMPQ_FILE_TYPE_CHAR:
|
||||
for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) {
|
||||
sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i);
|
||||
if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) {
|
||||
|
||||
/* if file found break */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if file found break */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if a file was found return 0 */
|
||||
if (found == 1) {
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
} else {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
/* if a file was found return 0 */
|
||||
if (found == 1) {
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
} else {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
default:
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -339,102 +339,102 @@ int libmpq_file_check(mpq_archive *mpq_a, void *file, int type) {
|
||||
* by the given number.
|
||||
*/
|
||||
int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename) {
|
||||
int blockindex = number; //-1;
|
||||
int fd = 0;
|
||||
int i = 0;
|
||||
char buffer[0x1000];
|
||||
//char tempfile[PATH_MAX];
|
||||
unsigned int transferred = 1;
|
||||
mpq_file *mpq_f = NULL;
|
||||
mpq_block *mpq_b = NULL;
|
||||
mpq_hash *mpq_h = NULL;
|
||||
int blockindex = number; //-1;
|
||||
int fd = 0;
|
||||
int i = 0;
|
||||
char buffer[0x1000];
|
||||
//char tempfile[PATH_MAX];
|
||||
unsigned int transferred = 1;
|
||||
mpq_file *mpq_f = NULL;
|
||||
mpq_block *mpq_b = NULL;
|
||||
mpq_hash *mpq_h = NULL;
|
||||
|
||||
/* if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}*/
|
||||
/* if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}*/
|
||||
/*
|
||||
sprintf(tempfile, libmpq_file_name(mpq_a, number));
|
||||
sprintf(tempfile, libmpq_file_name(mpq_a, number));
|
||||
*/
|
||||
/* check if mpq_f->filename could be written here. */
|
||||
fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
|
||||
if (fd == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
/* check if mpq_f->filename could be written here. */
|
||||
fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
|
||||
if (fd == LIBMPQ_EFILE) {
|
||||
return LIBMPQ_EFILE;
|
||||
}
|
||||
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* check if file was found */
|
||||
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* check if file was found */
|
||||
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* allocate memory for file structure */
|
||||
mpq_f = (mpq_file *)malloc(sizeof(mpq_file));
|
||||
if (!mpq_f) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
/* allocate memory for file structure */
|
||||
mpq_f = (mpq_file *)malloc(sizeof(mpq_file));
|
||||
if (!mpq_f) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
|
||||
/* initialize file structure */
|
||||
memset(mpq_f, 0, sizeof(mpq_file));
|
||||
mpq_f->fd = fd;
|
||||
mpq_f->mpq_b = mpq_b;
|
||||
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
|
||||
mpq_f->mpq_h = mpq_h;
|
||||
mpq_f->accessed = FALSE;
|
||||
mpq_f->blockposloaded = FALSE;
|
||||
sprintf((char *)mpq_f->filename, filename);
|
||||
/* initialize file structure */
|
||||
memset(mpq_f, 0, sizeof(mpq_file));
|
||||
mpq_f->fd = fd;
|
||||
mpq_f->mpq_b = mpq_b;
|
||||
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
|
||||
mpq_f->mpq_h = mpq_h;
|
||||
mpq_f->accessed = FALSE;
|
||||
mpq_f->blockposloaded = FALSE;
|
||||
sprintf((char *)mpq_f->filename, filename);
|
||||
|
||||
/* allocate buffers for decompression. */
|
||||
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
|
||||
/* allocate buffers for decompression. */
|
||||
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
|
||||
|
||||
/*
|
||||
* Allocate buffer for block positions. At the begin of file are stored
|
||||
* unsigned ints holding positions of each block relative from begin of
|
||||
* file in the archive.
|
||||
*/
|
||||
if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate buffer for block positions. At the begin of file are stored
|
||||
* unsigned ints holding positions of each block relative from begin of
|
||||
* file in the archive.
|
||||
*/
|
||||
if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
}
|
||||
|
||||
while (transferred > 0) {
|
||||
transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer));
|
||||
if (transferred == 0) {
|
||||
break;
|
||||
} else {
|
||||
mpq_f->accessed = TRUE;
|
||||
mpq_f->filepos += transferred;
|
||||
}
|
||||
while (transferred > 0) {
|
||||
transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer));
|
||||
if (transferred == 0) {
|
||||
break;
|
||||
} else {
|
||||
mpq_f->accessed = TRUE;
|
||||
mpq_f->filepos += transferred;
|
||||
}
|
||||
|
||||
transferred = _write(mpq_f->fd, buffer, transferred);
|
||||
if (transferred == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
transferred = _write(mpq_f->fd, buffer, transferred);
|
||||
if (transferred == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_close(fd);
|
||||
_close(fd);
|
||||
|
||||
/* freeing the file structure */
|
||||
free(mpq_f);
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
/* freeing the file structure */
|
||||
free(mpq_f);
|
||||
return LIBMPQ_TOOLS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -444,183 +444,183 @@ int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filena
|
||||
*/
|
||||
|
||||
int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]) {
|
||||
FILE *fp;
|
||||
//char **filelist;
|
||||
int i = 0;
|
||||
//int fl_count;
|
||||
//int fl_size;
|
||||
int fl_count_fb;
|
||||
int fl_size_fb;
|
||||
int result = LIBMPQ_TOOLS_SUCCESS;
|
||||
struct stat statbuf;
|
||||
FILE *fp;
|
||||
//char **filelist;
|
||||
int i = 0;
|
||||
//int fl_count;
|
||||
//int fl_size;
|
||||
int fl_count_fb;
|
||||
int fl_size_fb;
|
||||
int result = LIBMPQ_TOOLS_SUCCESS;
|
||||
struct stat statbuf;
|
||||
|
||||
/* get file status */
|
||||
if (stat(file, &statbuf) < 0) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* get file status */
|
||||
if (stat(file, &statbuf) < 0) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* check if file is a filename or directory */
|
||||
/*if (S_ISDIR(statbuf.st_mode)) {
|
||||
/* check if file is a filename or directory */
|
||||
/*if (S_ISDIR(statbuf.st_mode)) {
|
||||
|
||||
// allocate memory for the file list
|
||||
filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count = 0;
|
||||
fl_size = LIBMPQ_CONF_FL_INCREMENT;
|
||||
// allocate memory for the file list
|
||||
filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count = 0;
|
||||
fl_size = LIBMPQ_CONF_FL_INCREMENT;
|
||||
|
||||
// check if it is a valid listfile
|
||||
if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) {
|
||||
filelist == NULL;
|
||||
}
|
||||
// check if it is a valid listfile
|
||||
if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) {
|
||||
filelist == NULL;
|
||||
}
|
||||
|
||||
filelist[fl_count] = NULL;
|
||||
filelist[fl_count] = NULL;
|
||||
|
||||
// return if no listfile was found
|
||||
if (filelist == NULL) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
// return if no listfile was found
|
||||
if (filelist == NULL) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (i = 0; filelist[i]; i++) {
|
||||
if ((fp = fopen(filelist[i], "r")) != NULL ) {
|
||||
result = libmpq_read_listfile(mpq_a, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
for (i = 0; filelist[i]; i++) {
|
||||
if ((fp = fopen(filelist[i], "r")) != NULL ) {
|
||||
result = libmpq_read_listfile(mpq_a, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// freeing the listfile struct
|
||||
libmpq_free_listfile(filelist);
|
||||
}*/
|
||||
// freeing the listfile struct
|
||||
libmpq_free_listfile(filelist);
|
||||
}*/
|
||||
|
||||
/* if file is a regular file use it */
|
||||
//if (S_ISREG(statbuf.st_mode)) {
|
||||
/* if file is a regular file use it */
|
||||
//if (S_ISREG(statbuf.st_mode)) {
|
||||
|
||||
/* if specific listfile was forced. */
|
||||
if ((fp = fopen(file, "r")) != NULL ) {
|
||||
result = libmpq_read_listfile(mpq_a, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
result = LIBMPQ_CONF_EFILE_OPEN;
|
||||
}
|
||||
//}
|
||||
/* if specific listfile was forced. */
|
||||
if ((fp = fopen(file, "r")) != NULL ) {
|
||||
result = libmpq_read_listfile(mpq_a, fp);
|
||||
fclose(fp);
|
||||
} else {
|
||||
result = LIBMPQ_CONF_EFILE_OPEN;
|
||||
}
|
||||
//}
|
||||
|
||||
/* if error occured we need to create a fallback filelist. */
|
||||
if (mpq_a->mpq_l->mpq_files == NULL) {
|
||||
/* if error occured we need to create a fallback filelist. */
|
||||
if (mpq_a->mpq_l->mpq_files == NULL) {
|
||||
|
||||
/* allocate memory for the file list */
|
||||
mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count_fb = 0;
|
||||
fl_size_fb = LIBMPQ_CONF_FL_INCREMENT;
|
||||
/* allocate memory for the file list */
|
||||
mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count_fb = 0;
|
||||
fl_size_fb = LIBMPQ_CONF_FL_INCREMENT;
|
||||
|
||||
for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) {
|
||||
for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) {
|
||||
|
||||
/* set the next filelist entry to a copy of the file */
|
||||
mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx");
|
||||
/* set the next filelist entry to a copy of the file */
|
||||
mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx");
|
||||
|
||||
/* increase the array size */
|
||||
if (fl_count_fb == fl_size_fb) {
|
||||
mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
|
||||
fl_size_fb += LIBMPQ_CONF_FL_INCREMENT;
|
||||
}
|
||||
}
|
||||
mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL;
|
||||
/* increase the array size */
|
||||
if (fl_count_fb == fl_size_fb) {
|
||||
mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
|
||||
fl_size_fb += LIBMPQ_CONF_FL_INCREMENT;
|
||||
}
|
||||
}
|
||||
mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL;
|
||||
|
||||
/* if no error occurs and no listfile was assigned, we think there was no matching listfile. */
|
||||
if (result == 0) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
/* if no error occurs and no listfile was assigned, we think there was no matching listfile. */
|
||||
if (result == 0) {
|
||||
result = LIBMPQ_CONF_EFILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function frees the allocated memory for the listfile.
|
||||
*/
|
||||
int libmpq_listfile_close(mpq_archive *mpq_a) {
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
/* safety check if we really have a filelist. */
|
||||
if (mpq_a->mpq_l->mpq_files != NULL) {
|
||||
/* freeing the filelist */
|
||||
while (mpq_a->mpq_l->mpq_files[i]) {
|
||||
free(mpq_a->mpq_l->mpq_files[i++]);
|
||||
}
|
||||
free(mpq_a->mpq_l->mpq_files);
|
||||
}
|
||||
/* safety check if we really have a filelist. */
|
||||
if (mpq_a->mpq_l->mpq_files != NULL) {
|
||||
/* freeing the filelist */
|
||||
while (mpq_a->mpq_l->mpq_files[i]) {
|
||||
free(mpq_a->mpq_l->mpq_files[i++]);
|
||||
}
|
||||
free(mpq_a->mpq_l->mpq_files);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest) {
|
||||
int blockindex = number; //-1;
|
||||
int i = 0;
|
||||
mpq_file *mpq_f = NULL;
|
||||
mpq_block *mpq_b = NULL;
|
||||
int success = 0;
|
||||
int blockindex = number; //-1;
|
||||
int i = 0;
|
||||
mpq_file *mpq_f = NULL;
|
||||
mpq_block *mpq_b = NULL;
|
||||
int success = 0;
|
||||
|
||||
/*if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}*/
|
||||
/*if (number < 1 || number > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EINV_RANGE;
|
||||
}*/
|
||||
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
/* search for correct hashtable */
|
||||
/*for (i = 0; i < mpq_a->header->hashtablesize; i++) {
|
||||
if ((number - 1) == (mpq_a->hashtable[i]).blockindex) {
|
||||
blockindex = (mpq_a->hashtable[i]).blockindex;
|
||||
mpq_h = &(mpq_a->hashtable[i]);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
/* check if file was found */
|
||||
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* check if file was found */
|
||||
if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
/* check if sizes are correct */
|
||||
mpq_b = mpq_a->blocktable + blockindex;
|
||||
if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) {
|
||||
return LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
/* check if file exists */
|
||||
if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) {
|
||||
return LIBMPQ_EFILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* allocate memory for file structure */
|
||||
mpq_f = (mpq_file*)malloc(sizeof(mpq_file));
|
||||
if (!mpq_f) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
/* allocate memory for file structure */
|
||||
mpq_f = (mpq_file*)malloc(sizeof(mpq_file));
|
||||
if (!mpq_f) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
|
||||
/* initialize file structure */
|
||||
memset(mpq_f, 0, sizeof(mpq_file));
|
||||
mpq_f->mpq_b = mpq_b;
|
||||
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
|
||||
mpq_f->mpq_h = &mpq_h;
|
||||
mpq_f->accessed = FALSE;
|
||||
mpq_f->blockposloaded = FALSE;
|
||||
/* initialize file structure */
|
||||
memset(mpq_f, 0, sizeof(mpq_file));
|
||||
mpq_f->mpq_b = mpq_b;
|
||||
mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize;
|
||||
mpq_f->mpq_h = &mpq_h;
|
||||
mpq_f->accessed = FALSE;
|
||||
mpq_f->blockposloaded = FALSE;
|
||||
|
||||
/* allocate buffers for decompression. */
|
||||
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
|
||||
/* allocate buffers for decompression. */
|
||||
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
|
||||
|
||||
/*
|
||||
* Allocate buffer for block positions. At the begin of file are stored
|
||||
* unsigned ints holding positions of each block relative from begin of
|
||||
* file in the archive.
|
||||
*/
|
||||
if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate buffer for block positions. At the begin of file are stored
|
||||
* unsigned ints holding positions of each block relative from begin of
|
||||
* file in the archive.
|
||||
*/
|
||||
if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) {
|
||||
return LIBMPQ_EALLOCMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if(libmpq_file_read_file(mpq_a, mpq_f, 0, (char*)dest, mpq_b->fsize) == mpq_b->fsize)
|
||||
success = 1;
|
||||
|
||||
if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) {
|
||||
// Free buffer for block positions
|
||||
|
||||
free(mpq_f->blockpos);
|
||||
}
|
||||
/* freeing the file structure */
|
||||
free(mpq_f);
|
||||
return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT;
|
||||
|
||||
free(mpq_f->blockpos);
|
||||
}
|
||||
/* freeing the file structure */
|
||||
free(mpq_f);
|
||||
return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT;
|
||||
}
|
||||
|
||||
+106
-106
@@ -33,61 +33,61 @@
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 260
|
||||
#define PATH_MAX 260
|
||||
#endif
|
||||
|
||||
|
||||
#define LIBMPQ_MAJOR_VERSION 0 /* Major version number... maybe sometimes we reach version 1 :) */
|
||||
#define LIBMPQ_MINOR_VERSION 3 /* Minor version number - increased only for small changes */
|
||||
#define LIBMPQ_PATCH_VERSION 0 /* Patchlevel - changed on bugfixes etc... */
|
||||
#define LIBMPQ_MAJOR_VERSION 0 /* Major version number... maybe sometimes we reach version 1 :) */
|
||||
#define LIBMPQ_MINOR_VERSION 3 /* Minor version number - increased only for small changes */
|
||||
#define LIBMPQ_PATCH_VERSION 0 /* Patchlevel - changed on bugfixes etc... */
|
||||
|
||||
#define LIBMPQ_TOOLS_SUCCESS 0 /* return value for all functions which success */
|
||||
#define LIBMPQ_TOOLS_BUFSIZE 0x500 /* buffer size for the decryption engine */
|
||||
#define LIBMPQ_TOOLS_SUCCESS 0 /* return value for all functions which success */
|
||||
#define LIBMPQ_TOOLS_BUFSIZE 0x500 /* buffer size for the decryption engine */
|
||||
|
||||
#define LIBMPQ_EFILE -1 /* error on file operation */
|
||||
#define LIBMPQ_EFILE_FORMAT -2 /* bad file format */
|
||||
#define LIBMPQ_EFILE_CORRUPT -3 /* file corrupt */
|
||||
#define LIBMPQ_EFILE_NOT_FOUND -4 /* file in archive not found */
|
||||
#define LIBMPQ_EFILE_READ -5 /* Read error in archive */
|
||||
#define LIBMPQ_EALLOCMEM -6 /* maybe not enough memory? :) */
|
||||
#define LIBMPQ_EFREEMEM -7 /* can not free memory */
|
||||
#define LIBMPQ_EINV_RANGE -8 /* Given filenumber is out of range */
|
||||
#define LIBMPQ_EHASHTABLE -9 /* error in reading hashtable */
|
||||
#define LIBMPQ_EBLOCKTABLE -10 /* error in reading blocktable */
|
||||
#define LIBMPQ_EFILE -1 /* error on file operation */
|
||||
#define LIBMPQ_EFILE_FORMAT -2 /* bad file format */
|
||||
#define LIBMPQ_EFILE_CORRUPT -3 /* file corrupt */
|
||||
#define LIBMPQ_EFILE_NOT_FOUND -4 /* file in archive not found */
|
||||
#define LIBMPQ_EFILE_READ -5 /* Read error in archive */
|
||||
#define LIBMPQ_EALLOCMEM -6 /* maybe not enough memory? :) */
|
||||
#define LIBMPQ_EFREEMEM -7 /* can not free memory */
|
||||
#define LIBMPQ_EINV_RANGE -8 /* Given filenumber is out of range */
|
||||
#define LIBMPQ_EHASHTABLE -9 /* error in reading hashtable */
|
||||
#define LIBMPQ_EBLOCKTABLE -10 /* error in reading blocktable */
|
||||
|
||||
#define LIBMPQ_ID_MPQ 0x1A51504D /* MPQ archive header ID ('MPQ\x1A') */
|
||||
#define LIBMPQ_HEADER_W3M 0x6D9E4B86 /* special value used by W3M Map Protector */
|
||||
#define LIBMPQ_FLAG_PROTECTED 0x00000002 /* Set on protected MPQs (like W3M maps) */
|
||||
#define LIBMPQ_HASH_ENTRY_DELETED 0xFFFFFFFE /* Block index for deleted hash entry */
|
||||
#define LIBMPQ_ID_MPQ 0x1A51504D /* MPQ archive header ID ('MPQ\x1A') */
|
||||
#define LIBMPQ_HEADER_W3M 0x6D9E4B86 /* special value used by W3M Map Protector */
|
||||
#define LIBMPQ_FLAG_PROTECTED 0x00000002 /* Set on protected MPQs (like W3M maps) */
|
||||
#define LIBMPQ_HASH_ENTRY_DELETED 0xFFFFFFFE /* Block index for deleted hash entry */
|
||||
|
||||
#define LIBMPQ_FILE_COMPRESS_PKWARE 0x00000100 /* Compression made by PKWARE Data Compression Library */
|
||||
#define LIBMPQ_FILE_COMPRESS_MULTI 0x00000200 /* Multiple compressions */
|
||||
#define LIBMPQ_FILE_COMPRESSED 0x0000FF00 /* File is compressed */
|
||||
#define LIBMPQ_FILE_EXISTS 0x80000000 /* Set if file exists, reset when the file was deleted */
|
||||
#define LIBMPQ_FILE_ENCRYPTED 0x00010000 /* Indicates whether file is encrypted */
|
||||
#define LIBMPQ_FILE_COMPRESS_PKWARE 0x00000100 /* Compression made by PKWARE Data Compression Library */
|
||||
#define LIBMPQ_FILE_COMPRESS_MULTI 0x00000200 /* Multiple compressions */
|
||||
#define LIBMPQ_FILE_COMPRESSED 0x0000FF00 /* File is compressed */
|
||||
#define LIBMPQ_FILE_EXISTS 0x80000000 /* Set if file exists, reset when the file was deleted */
|
||||
#define LIBMPQ_FILE_ENCRYPTED 0x00010000 /* Indicates whether file is encrypted */
|
||||
#define LIBMPQ_FILE_HAS_METADATA 0x04000000
|
||||
|
||||
#define LIBMPQ_FILE_COMPRESSED_SIZE 1 /* MPQ compressed filesize of given file */
|
||||
#define LIBMPQ_FILE_UNCOMPRESSED_SIZE 2 /* MPQ uncompressed filesize of given file */
|
||||
#define LIBMPQ_FILE_COMPRESSION_TYPE 3 /* MPQ compression type of given file */
|
||||
#define LIBMPQ_FILE_TYPE_INT 4 /* file is given by number */
|
||||
#define LIBMPQ_FILE_TYPE_CHAR 5 /* file is given by name */
|
||||
#define LIBMPQ_FILE_COMPRESSED_SIZE 1 /* MPQ compressed filesize of given file */
|
||||
#define LIBMPQ_FILE_UNCOMPRESSED_SIZE 2 /* MPQ uncompressed filesize of given file */
|
||||
#define LIBMPQ_FILE_COMPRESSION_TYPE 3 /* MPQ compression type of given file */
|
||||
#define LIBMPQ_FILE_TYPE_INT 4 /* file is given by number */
|
||||
#define LIBMPQ_FILE_TYPE_CHAR 5 /* file is given by name */
|
||||
|
||||
#define LIBMPQ_MPQ_ARCHIVE_SIZE 1 /* MPQ archive size */
|
||||
#define LIBMPQ_MPQ_HASHTABLE_SIZE 2 /* MPQ archive hashtable size */
|
||||
#define LIBMPQ_MPQ_BLOCKTABLE_SIZE 3 /* MPQ archive blocktable size */
|
||||
#define LIBMPQ_MPQ_BLOCKSIZE 4 /* MPQ archive blocksize */
|
||||
#define LIBMPQ_MPQ_NUMFILES 5 /* Number of files in the MPQ archive */
|
||||
#define LIBMPQ_MPQ_COMPRESSED_SIZE 6 /* Compressed archive size */
|
||||
#define LIBMPQ_MPQ_UNCOMPRESSED_SIZE 7 /* Uncompressed archive size */
|
||||
#define LIBMPQ_MPQ_ARCHIVE_SIZE 1 /* MPQ archive size */
|
||||
#define LIBMPQ_MPQ_HASHTABLE_SIZE 2 /* MPQ archive hashtable size */
|
||||
#define LIBMPQ_MPQ_BLOCKTABLE_SIZE 3 /* MPQ archive blocktable size */
|
||||
#define LIBMPQ_MPQ_BLOCKSIZE 4 /* MPQ archive blocksize */
|
||||
#define LIBMPQ_MPQ_NUMFILES 5 /* Number of files in the MPQ archive */
|
||||
#define LIBMPQ_MPQ_COMPRESSED_SIZE 6 /* Compressed archive size */
|
||||
#define LIBMPQ_MPQ_UNCOMPRESSED_SIZE 7 /* Uncompressed archive size */
|
||||
|
||||
#define LIBMPQ_HUFF_DECOMPRESS 0 /* Defines that we want to decompress using huffman trees. */
|
||||
#define LIBMPQ_HUFF_DECOMPRESS 0 /* Defines that we want to decompress using huffman trees. */
|
||||
|
||||
#define LIBMPQ_CONF_EFILE_OPEN -1 /* error if a specific listfile was forced and could not be opened. */
|
||||
#define LIBMPQ_CONF_EFILE_CORRUPT -2 /* listfile seems to be corrupt */
|
||||
#define LIBMPQ_CONF_EFILE_LIST_CORRUPT -3 /* listfile seems correct, but filelist is broken */
|
||||
#define LIBMPQ_CONF_EFILE_NOT_FOUND -4 /* error if no matching listfile found */
|
||||
#define LIBMPQ_CONF_EFILE_VERSION -5 /* libmpq version does not match required listfile version */
|
||||
#define LIBMPQ_CONF_EFILE_OPEN -1 /* error if a specific listfile was forced and could not be opened. */
|
||||
#define LIBMPQ_CONF_EFILE_CORRUPT -2 /* listfile seems to be corrupt */
|
||||
#define LIBMPQ_CONF_EFILE_LIST_CORRUPT -3 /* listfile seems correct, but filelist is broken */
|
||||
#define LIBMPQ_CONF_EFILE_NOT_FOUND -4 /* error if no matching listfile found */
|
||||
#define LIBMPQ_CONF_EFILE_VERSION -5 /* libmpq version does not match required listfile version */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
@@ -102,95 +102,95 @@
|
||||
#endif
|
||||
*/
|
||||
|
||||
typedef unsigned int mpq_buffer[LIBMPQ_TOOLS_BUFSIZE];
|
||||
typedef int (*DECOMPRESS)(char *, int *, char *, int);
|
||||
typedef unsigned int mpq_buffer[LIBMPQ_TOOLS_BUFSIZE];
|
||||
typedef int (*DECOMPRESS)(char *, int *, char *, int);
|
||||
typedef struct {
|
||||
unsigned long mask; /* Decompression bit */
|
||||
DECOMPRESS decompress; /* Decompression function */
|
||||
unsigned long mask; /* Decompression bit */
|
||||
DECOMPRESS decompress; /* Decompression function */
|
||||
} decompress_table;
|
||||
|
||||
/* MPQ file header */
|
||||
typedef struct {
|
||||
unsigned int id; /* The 0x1A51504D ('MPQ\x1A') signature */
|
||||
unsigned int offset; /* Offset of the first file (Relative to MPQ start) */
|
||||
unsigned int archivesize; /* Size of MPQ archive */
|
||||
unsigned short offsetsc; /* 0000 for SC and BW */
|
||||
unsigned short blocksize; /* Size of file block is (0x200 << blockSize) */
|
||||
unsigned int hashtablepos; /* File position of hashTable */
|
||||
unsigned int blocktablepos; /* File position of blockTable. Each entry has 16 bytes */
|
||||
unsigned int hashtablesize; /* Number of entries in hash table */
|
||||
unsigned int blocktablesize; /* Number of entries in the block table */
|
||||
unsigned int id; /* The 0x1A51504D ('MPQ\x1A') signature */
|
||||
unsigned int offset; /* Offset of the first file (Relative to MPQ start) */
|
||||
unsigned int archivesize; /* Size of MPQ archive */
|
||||
unsigned short offsetsc; /* 0000 for SC and BW */
|
||||
unsigned short blocksize; /* Size of file block is (0x200 << blockSize) */
|
||||
unsigned int hashtablepos; /* File position of hashTable */
|
||||
unsigned int blocktablepos; /* File position of blockTable. Each entry has 16 bytes */
|
||||
unsigned int hashtablesize; /* Number of entries in hash table */
|
||||
unsigned int blocktablesize; /* Number of entries in the block table */
|
||||
} mpq_header;
|
||||
//} __attribute__ ((packed)) mpq_header;
|
||||
|
||||
|
||||
/* Hash entry. All files in the archive are searched by their hashes. */
|
||||
typedef struct {
|
||||
unsigned int name1; /* The first two unsigned ints */
|
||||
unsigned int name2; /* are the encrypted file name */
|
||||
unsigned int locale; /* Locale information. */
|
||||
unsigned int blockindex; /* Index to file description block */
|
||||
unsigned int name1; /* The first two unsigned ints */
|
||||
unsigned int name2; /* are the encrypted file name */
|
||||
unsigned int locale; /* Locale information. */
|
||||
unsigned int blockindex; /* Index to file description block */
|
||||
} mpq_hash;
|
||||
|
||||
/* File description block contains informations about the file */
|
||||
typedef struct {
|
||||
unsigned int filepos; /* Block file starting position in the archive */
|
||||
unsigned int csize; /* Compressed file size */
|
||||
unsigned int fsize; /* Uncompressed file size */
|
||||
unsigned int flags; /* Flags */
|
||||
unsigned int filepos; /* Block file starting position in the archive */
|
||||
unsigned int csize; /* Compressed file size */
|
||||
unsigned int fsize; /* Uncompressed file size */
|
||||
unsigned int flags; /* Flags */
|
||||
} mpq_block;
|
||||
|
||||
/* File handle structure used since Diablo 1.00 (0x38 bytes) */
|
||||
typedef struct {
|
||||
unsigned char filename[PATH_MAX]; /* filename of the actual file in the archive */
|
||||
int fd; /* File handle */
|
||||
unsigned int seed; /* Seed used for file decrypt */
|
||||
unsigned int filepos; /* Current file position */
|
||||
unsigned int offset;
|
||||
unsigned int nblocks; /* Number of blocks in the file (incl. the last noncomplete one) */
|
||||
unsigned int *blockpos; /* Position of each file block (only for compressed files) */
|
||||
int blockposloaded; /* TRUE if block positions loaded */
|
||||
unsigned int offset2; /* (Number of bytes somewhere ?) */
|
||||
mpq_hash *mpq_h; /* Hash table entry */
|
||||
mpq_block *mpq_b; /* File block pointer */
|
||||
unsigned char filename[PATH_MAX]; /* filename of the actual file in the archive */
|
||||
int fd; /* File handle */
|
||||
unsigned int seed; /* Seed used for file decrypt */
|
||||
unsigned int filepos; /* Current file position */
|
||||
unsigned int offset;
|
||||
unsigned int nblocks; /* Number of blocks in the file (incl. the last noncomplete one) */
|
||||
unsigned int *blockpos; /* Position of each file block (only for compressed files) */
|
||||
int blockposloaded; /* TRUE if block positions loaded */
|
||||
unsigned int offset2; /* (Number of bytes somewhere ?) */
|
||||
mpq_hash *mpq_h; /* Hash table entry */
|
||||
mpq_block *mpq_b; /* File block pointer */
|
||||
|
||||
/* Non-Storm.dll members */
|
||||
/* Non-Storm.dll members */
|
||||
|
||||
unsigned int accessed; /* Was something from the file already read? */
|
||||
unsigned int accessed; /* Was something from the file already read? */
|
||||
} mpq_file;
|
||||
|
||||
/* List handle structure */
|
||||
typedef struct {
|
||||
unsigned char mpq_version[10]; /* libmpq version required by the listfile */
|
||||
unsigned char mpq_name[PATH_MAX]; /* mpq archive name without full path */
|
||||
unsigned char mpq_type[20]; /* mpq archive type */
|
||||
unsigned char mpq_game[40]; /* blizzard title the file matches */
|
||||
unsigned char mpq_game_version[10]; /* game version */
|
||||
unsigned char **mpq_files; /* filelist */
|
||||
unsigned char mpq_version[10]; /* libmpq version required by the listfile */
|
||||
unsigned char mpq_name[PATH_MAX]; /* mpq archive name without full path */
|
||||
unsigned char mpq_type[20]; /* mpq archive type */
|
||||
unsigned char mpq_game[40]; /* blizzard title the file matches */
|
||||
unsigned char mpq_game_version[10]; /* game version */
|
||||
unsigned char **mpq_files; /* filelist */
|
||||
} mpq_list;
|
||||
|
||||
/* Archive handle structure used since Diablo 1.00 */
|
||||
typedef struct {
|
||||
unsigned char filename[PATH_MAX]; /* Opened archive file name */
|
||||
int fd; /* File handle */
|
||||
unsigned int blockpos; /* Position of loaded block in the file */
|
||||
unsigned int blocksize; /* Size of file block */
|
||||
unsigned char *blockbuf; /* Buffer (cache) for file block */
|
||||
unsigned int bufpos; /* Position in block buffer */
|
||||
unsigned int mpqpos; /* MPQ archive position in the file */
|
||||
unsigned int filepos; /* Current file pointer */
|
||||
unsigned int openfiles; /* Number of open files + 1 */
|
||||
mpq_buffer buf; /* MPQ buffer */
|
||||
mpq_header *header; /* MPQ file header */
|
||||
mpq_hash *hashtable; /* Hash table */
|
||||
mpq_block *blocktable; /* Block table */
|
||||
unsigned char filename[PATH_MAX]; /* Opened archive file name */
|
||||
int fd; /* File handle */
|
||||
unsigned int blockpos; /* Position of loaded block in the file */
|
||||
unsigned int blocksize; /* Size of file block */
|
||||
unsigned char *blockbuf; /* Buffer (cache) for file block */
|
||||
unsigned int bufpos; /* Position in block buffer */
|
||||
unsigned int mpqpos; /* MPQ archive position in the file */
|
||||
unsigned int filepos; /* Current file pointer */
|
||||
unsigned int openfiles; /* Number of open files + 1 */
|
||||
mpq_buffer buf; /* MPQ buffer */
|
||||
mpq_header *header; /* MPQ file header */
|
||||
mpq_hash *hashtable; /* Hash table */
|
||||
mpq_block *blocktable; /* Block table */
|
||||
|
||||
/* Non-Storm.dll members */
|
||||
/* Non-Storm.dll members */
|
||||
|
||||
mpq_list *mpq_l; /* Handle to file list from database */
|
||||
mpq_list *mpq_l; /* Handle to file list from database */
|
||||
|
||||
unsigned int flags; /* See LIBMPQ_TOOLS_FLAG_XXXXX */
|
||||
unsigned int maxblockindex; /* The highest block table entry */
|
||||
unsigned int flags; /* See LIBMPQ_TOOLS_FLAG_XXXXX */
|
||||
unsigned int maxblockindex; /* The highest block table entry */
|
||||
} mpq_archive;
|
||||
|
||||
extern char *libmpq_version();
|
||||
@@ -213,13 +213,13 @@ extern int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_
|
||||
extern int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length);
|
||||
|
||||
static decompress_table dcmp_table[] = {
|
||||
{0x08, libmpq_pkzip_decompress}, /* Decompression with Pkware Data Compression Library */
|
||||
{0x02, libmpq_zlib_decompress}, /* Decompression with the "zlib" library */
|
||||
{0x01, libmpq_huff_decompress}, /* Huffmann decompression */
|
||||
{0x80, libmpq_wave_decompress_stereo}, /* WAVE decompression for stereo waves */
|
||||
{0x40, libmpq_wave_decompress_mono} /* WAVE decompression for mono waves */
|
||||
{0x08, libmpq_pkzip_decompress}, /* Decompression with Pkware Data Compression Library */
|
||||
{0x02, libmpq_zlib_decompress}, /* Decompression with the "zlib" library */
|
||||
{0x01, libmpq_huff_decompress}, /* Huffmann decompression */
|
||||
{0x80, libmpq_wave_decompress_stereo}, /* WAVE decompression for stereo waves */
|
||||
{0x40, libmpq_wave_decompress_mono} /* WAVE decompression for mono waves */
|
||||
};
|
||||
|
||||
int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename);
|
||||
int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest);
|
||||
#endif /* _MPQ_H */
|
||||
#endif /* _MPQ_H */
|
||||
|
||||
+188
-188
@@ -34,21 +34,21 @@
|
||||
* deleted but \" would not.
|
||||
*/
|
||||
char *libmpq_conf_delete_char(char *buf, char *chars) {
|
||||
static char *temp;
|
||||
char ch;
|
||||
static char *temp;
|
||||
char ch;
|
||||
|
||||
temp = buf;
|
||||
temp = buf;
|
||||
|
||||
/* strip out special chars like " */
|
||||
while (temp = strpbrk(temp, chars)) {
|
||||
ch = temp[0];
|
||||
memmove(&temp[0], &temp[1], strlen(temp));
|
||||
if (ch == '\\') {
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
/* strip out special chars like " */
|
||||
while (temp = strpbrk(temp, chars)) {
|
||||
ch = temp[0];
|
||||
memmove(&temp[0], &temp[1], strlen(temp));
|
||||
if (ch == '\\') {
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -56,65 +56,65 @@ char *libmpq_conf_delete_char(char *buf, char *chars) {
|
||||
* return 1 on success and the byte array or 0 and null.
|
||||
*/
|
||||
int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, int size) {
|
||||
int level = 0;
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
int pos = 0;
|
||||
int level = 0;
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
int pos = 0;
|
||||
|
||||
/* search value */
|
||||
while (*(++line)) {
|
||||
/* search value */
|
||||
while (*(++line)) {
|
||||
|
||||
/* check for spaces */
|
||||
if (!isspace(*line) && level == 1) {
|
||||
/* check for spaces */
|
||||
if (!isspace(*line) && level == 1) {
|
||||
|
||||
/* we found our value so break */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
/* we found our value so break */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for '=' so the value follows as next parameter */
|
||||
if (*line == '=' && level == 0) {
|
||||
level = 1;
|
||||
}
|
||||
}
|
||||
/* check for '=' so the value follows as next parameter */
|
||||
if (*line == '=' && level == 0) {
|
||||
level = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* now search for comment in this line */
|
||||
for (i = 0; i < int(strlen(line)); i++) {
|
||||
if (line[i] == '#') {
|
||||
pos = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* now search for comment in this line */
|
||||
for (i = 0; i < int(strlen(line)); i++) {
|
||||
if (line[i] == '#') {
|
||||
pos = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now set end of byte array behind value, but only if comment was found */
|
||||
if (pos != 0) {
|
||||
for (i = pos; i >= 0; i--) {
|
||||
if (line[i] != ' ' && line[i] != '\t') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* now set end of byte array behind value, but only if comment was found */
|
||||
if (pos != 0) {
|
||||
for (i = pos; i >= 0; i--) {
|
||||
if (line[i] != ' ' && line[i] != '\t') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now check if line has trailing spaces */
|
||||
for (i = strlen(line); i >= 0; i--) {
|
||||
if (line[i] != ' ' && line[i] != '\t') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* now check if line has trailing spaces */
|
||||
for (i = strlen(line); i >= 0; i--) {
|
||||
if (line[i] != ' ' && line[i] != '\t') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now check if value is quoted with "" and if there is a char behind. */
|
||||
for (i = strlen(line); i >= 0; i--) {
|
||||
if (line[i] == '"') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* now check if value is quoted with "" and if there is a char behind. */
|
||||
for (i = strlen(line); i >= 0; i--) {
|
||||
if (line[i] == '"') {
|
||||
line[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the values */
|
||||
strncpy(return_value, line, size);
|
||||
return found;
|
||||
/* return the values */
|
||||
strncpy(return_value, line, size);
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -122,70 +122,70 @@ int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, i
|
||||
* listdb or config file. On success it returns 1, otherwise 0.
|
||||
*/
|
||||
int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int type, int size) {
|
||||
char buf[LIBMPQ_CONF_BUFSIZE];
|
||||
int found = 0;
|
||||
int result = LIBMPQ_TOOLS_SUCCESS;
|
||||
char buf[LIBMPQ_CONF_BUFSIZE];
|
||||
int found = 0;
|
||||
int result = LIBMPQ_TOOLS_SUCCESS;
|
||||
|
||||
while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
|
||||
char *line;
|
||||
while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
|
||||
char *line;
|
||||
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
|
||||
/* skip whitespace */
|
||||
for (line = buf; isspace(*line); line++) {
|
||||
continue;
|
||||
}
|
||||
/* skip whitespace */
|
||||
for (line = buf; isspace(*line); line++) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip empty line */
|
||||
if (line[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
/* skip empty line */
|
||||
if (line[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip comments */
|
||||
if (line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
/* skip comments */
|
||||
if (line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process the line */
|
||||
//if (!strncasecmp(line, search_value, strlen(search_value))) {
|
||||
/* process the line */
|
||||
//if (!strncasecmp(line, search_value, strlen(search_value))) {
|
||||
if (!strcmp(line, search_value)) {
|
||||
found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE);
|
||||
if (found == 1) {
|
||||
libmpq_conf_delete_char(line, "\"\\");
|
||||
found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE);
|
||||
if (found == 1) {
|
||||
libmpq_conf_delete_char(line, "\"\\");
|
||||
|
||||
switch (type) {
|
||||
case LIBMPQ_CONF_TYPE_INT:
|
||||
switch (type) {
|
||||
case LIBMPQ_CONF_TYPE_INT:
|
||||
|
||||
/* if it is no valid number it is safe to return 0 */
|
||||
*(int *)return_value = atoi(line);
|
||||
break;
|
||||
default:
|
||||
strncpy((char *)return_value, line, size);
|
||||
break;
|
||||
}
|
||||
/* if it is no valid number it is safe to return 0 */
|
||||
*(int *)return_value = atoi(line);
|
||||
break;
|
||||
default:
|
||||
strncpy((char *)return_value, line, size);
|
||||
break;
|
||||
}
|
||||
|
||||
/* value found, so rewind stream */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* value found, so rewind stream */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if value was not found */
|
||||
if (found == 0) {
|
||||
switch (type) {
|
||||
case LIBMPQ_CONF_TYPE_INT:
|
||||
*(int *)return_value = 0;
|
||||
result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
strncpy((char *)return_value, "", size);
|
||||
result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
/* if value was not found */
|
||||
if (found == 0) {
|
||||
switch (type) {
|
||||
case LIBMPQ_CONF_TYPE_INT:
|
||||
*(int *)return_value = 0;
|
||||
result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
strncpy((char *)return_value, "", size);
|
||||
result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -194,101 +194,101 @@ int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int
|
||||
* entries in the byte array. On success it returns 1, otherwise 0.
|
||||
*/
|
||||
int libmpq_conf_get_array(FILE *fp, char *search_value, char ***filelist, int *entries) {
|
||||
char buf[LIBMPQ_CONF_BUFSIZE];
|
||||
char temp[LIBMPQ_CONF_BUFSIZE];
|
||||
int level = 0;
|
||||
int array_start = 0;
|
||||
int array_end = 0;
|
||||
int fl_count;
|
||||
int fl_size;
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
char buf[LIBMPQ_CONF_BUFSIZE];
|
||||
char temp[LIBMPQ_CONF_BUFSIZE];
|
||||
int level = 0;
|
||||
int array_start = 0;
|
||||
int array_end = 0;
|
||||
int fl_count;
|
||||
int fl_size;
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
|
||||
*entries = 0;
|
||||
*entries = 0;
|
||||
|
||||
/* allocate memory for the file list */
|
||||
(*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count = 0;
|
||||
fl_size = LIBMPQ_CONF_FL_INCREMENT;
|
||||
/* allocate memory for the file list */
|
||||
(*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
|
||||
fl_count = 0;
|
||||
fl_size = LIBMPQ_CONF_FL_INCREMENT;
|
||||
|
||||
while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
|
||||
char *line;
|
||||
while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
|
||||
char *line;
|
||||
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
|
||||
/* skip whitespace */
|
||||
for (line = buf; isspace(*line); line++) {
|
||||
continue;
|
||||
}
|
||||
/* skip whitespace */
|
||||
for (line = buf; isspace(*line); line++) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip empty line */
|
||||
if (line[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
/* skip empty line */
|
||||
if (line[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip comments */
|
||||
if (line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
/* skip comments */
|
||||
if (line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check for array end ) */
|
||||
if (*line == ')') {
|
||||
array_end = 1;
|
||||
break;
|
||||
}
|
||||
/* check for array end ) */
|
||||
if (*line == ')') {
|
||||
array_end = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* process entries between () */
|
||||
if (array_start == 1 && array_end == 0) {
|
||||
/* process entries between () */
|
||||
if (array_start == 1 && array_end == 0) {
|
||||
|
||||
/* add dummy option to use with libmpq_conf_parse_line() */
|
||||
strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE);
|
||||
strncat(temp, line, LIBMPQ_CONF_BUFSIZE);
|
||||
found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE);
|
||||
/* add dummy option to use with libmpq_conf_parse_line() */
|
||||
strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE);
|
||||
strncat(temp, line, LIBMPQ_CONF_BUFSIZE);
|
||||
found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE);
|
||||
|
||||
if (found == 1) {
|
||||
libmpq_conf_delete_char(temp, "\"\\");
|
||||
if (found == 1) {
|
||||
libmpq_conf_delete_char(temp, "\"\\");
|
||||
|
||||
/* set the next filelist entry to a copy of the file */
|
||||
(*filelist)[fl_count++] = _strdup(temp);
|
||||
/* set the next filelist entry to a copy of the file */
|
||||
(*filelist)[fl_count++] = _strdup(temp);
|
||||
|
||||
/* increase the array size */
|
||||
if (fl_count == fl_size) {
|
||||
(*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
|
||||
fl_size += LIBMPQ_CONF_FL_INCREMENT;
|
||||
}
|
||||
/* increase the array size */
|
||||
if (fl_count == fl_size) {
|
||||
(*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
|
||||
fl_size += LIBMPQ_CONF_FL_INCREMENT;
|
||||
}
|
||||
|
||||
/* increase number of entries */
|
||||
(*entries)++;
|
||||
}
|
||||
}
|
||||
/* increase number of entries */
|
||||
(*entries)++;
|
||||
}
|
||||
}
|
||||
|
||||
/* process the line and search array start */
|
||||
//if (!strncasecmp(line, search_value, strlen(search_value))) {
|
||||
/* process the line and search array start */
|
||||
//if (!strncasecmp(line, search_value, strlen(search_value))) {
|
||||
if (!strcmp(line, search_value)) {
|
||||
|
||||
/* search value */
|
||||
while (*(++line)) {
|
||||
/* search value */
|
||||
while (*(++line)) {
|
||||
|
||||
/* check for array start ( */
|
||||
if (*line == '(' && level == 1) {
|
||||
/* check for array start ( */
|
||||
if (*line == '(' && level == 1) {
|
||||
|
||||
/* we found our value so break */
|
||||
array_start = 1;
|
||||
break;
|
||||
}
|
||||
/* we found our value so break */
|
||||
array_start = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for '=' so the value follows as next parameter */
|
||||
if (*line == '=' && level == 0) {
|
||||
level = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* check for '=' so the value follows as next parameter */
|
||||
if (*line == '=' && level == 0) {
|
||||
level = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we got all files, so rewind stream */
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
/* we got all files, so rewind stream */
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
|
||||
(*filelist)[fl_count] = NULL;
|
||||
(*filelist)[fl_count] = NULL;
|
||||
|
||||
return found;
|
||||
return found;
|
||||
}
|
||||
|
||||
+137
-137
@@ -29,25 +29,25 @@
|
||||
|
||||
/* Tables necessary dor decompression */
|
||||
static unsigned long wave_table_1503f120[] = {
|
||||
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
|
||||
0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
|
||||
0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
|
||||
0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
|
||||
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
|
||||
0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
|
||||
0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
|
||||
0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
|
||||
};
|
||||
|
||||
static unsigned long wave_table_1503f1a0[] = {
|
||||
0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
|
||||
0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
|
||||
0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
|
||||
0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
|
||||
0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
|
||||
0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
|
||||
0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
|
||||
0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
|
||||
0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
|
||||
0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
|
||||
0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
|
||||
0x00007FFF
|
||||
0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
|
||||
0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
|
||||
0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
|
||||
0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
|
||||
0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
|
||||
0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
|
||||
0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
|
||||
0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
|
||||
0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
|
||||
0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
|
||||
0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
|
||||
0x00007FFF
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -56,130 +56,130 @@ static unsigned long wave_table_1503f1a0[] = {
|
||||
* Offset: 1500F230
|
||||
*/
|
||||
int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels) {
|
||||
byte_and_short out;
|
||||
byte_and_short in;
|
||||
unsigned char *in_end = in_buf + in_length; /* End on input buffer */
|
||||
unsigned long index;
|
||||
long nr_array1[2];
|
||||
long nr_array2[2];
|
||||
int count = 0;
|
||||
byte_and_short out;
|
||||
byte_and_short in;
|
||||
unsigned char *in_end = in_buf + in_length; /* End on input buffer */
|
||||
unsigned long index;
|
||||
long nr_array1[2];
|
||||
long nr_array2[2];
|
||||
int count = 0;
|
||||
|
||||
out.pb = out_buf;
|
||||
in.pb = in_buf;
|
||||
nr_array1[0] = 0x2C;
|
||||
nr_array1[1] = 0x2C;
|
||||
in.pw++;
|
||||
out.pb = out_buf;
|
||||
in.pb = in_buf;
|
||||
nr_array1[0] = 0x2C;
|
||||
nr_array1[1] = 0x2C;
|
||||
in.pw++;
|
||||
|
||||
/* 15007AD7 */
|
||||
for (count = 0; count < channels; count++) {
|
||||
long temp;
|
||||
temp = *(short *)in.pw++;
|
||||
nr_array2[count] = temp;
|
||||
if (out_length < 2) {
|
||||
return out.pb - out_buf;
|
||||
}
|
||||
*out.pw++ = (unsigned short)temp;
|
||||
out_length -= 2;
|
||||
}
|
||||
index = channels - 1;
|
||||
while (in.pb < in_end) {
|
||||
unsigned char one_byte = *in.pb++;
|
||||
if (channels == 2) {
|
||||
index = (index == 0) ? 1 : 0;
|
||||
}
|
||||
/* 15007AD7 */
|
||||
for (count = 0; count < channels; count++) {
|
||||
long temp;
|
||||
temp = *(short *)in.pw++;
|
||||
nr_array2[count] = temp;
|
||||
if (out_length < 2) {
|
||||
return out.pb - out_buf;
|
||||
}
|
||||
*out.pw++ = (unsigned short)temp;
|
||||
out_length -= 2;
|
||||
}
|
||||
index = channels - 1;
|
||||
while (in.pb < in_end) {
|
||||
unsigned char one_byte = *in.pb++;
|
||||
if (channels == 2) {
|
||||
index = (index == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get one byte from input buffer
|
||||
* 15007B25
|
||||
*/
|
||||
if (one_byte & 0x80) {
|
||||
/* 15007B32 */
|
||||
switch(one_byte & 0x7F) {
|
||||
case 0: /* 15007B8E */
|
||||
if (nr_array1[index] != 0) {
|
||||
nr_array1[index]--;
|
||||
}
|
||||
if (out_length < 2) {
|
||||
break;
|
||||
}
|
||||
*out.pw++ = (unsigned short)nr_array2[index];
|
||||
out_length -= 2;
|
||||
continue;
|
||||
case 1: /* 15007B72 */
|
||||
nr_array1[index] += 8; /* EBX also */
|
||||
if (nr_array1[index] > 0x58) {
|
||||
nr_array1[index] = 0x58;
|
||||
}
|
||||
if (channels == 2) {
|
||||
index = (index == 0) ? 1 : 0;
|
||||
}
|
||||
continue;
|
||||
case 2:
|
||||
continue;
|
||||
default:
|
||||
nr_array1[index] -= 8;
|
||||
if (nr_array1[index] < 0) {
|
||||
nr_array1[index] = 0;
|
||||
}
|
||||
if (channels != 2) {
|
||||
continue;
|
||||
}
|
||||
index = (index == 0) ? 1 : 0;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
unsigned long temp1 = wave_table_1503f1a0[nr_array1[index]]; /* EDI */
|
||||
unsigned long temp2 = temp1 >> in_buf[1]; /* ESI */
|
||||
long temp3 = nr_array2[index]; /* ECX */
|
||||
if (one_byte & 0x01) { /* EBX = one_byte */
|
||||
temp2 += (temp1 >> 0);
|
||||
}
|
||||
if (one_byte & 0x02) {
|
||||
temp2 += (temp1 >> 1);
|
||||
}
|
||||
if (one_byte & 0x04) {
|
||||
temp2 += (temp1 >> 2);
|
||||
}
|
||||
if (one_byte & 0x08) {
|
||||
temp2 += (temp1 >> 3);
|
||||
}
|
||||
if (one_byte & 0x10) {
|
||||
temp2 += (temp1 >> 4);
|
||||
}
|
||||
if (one_byte & 0x20) {
|
||||
temp2 += (temp1 >> 5);
|
||||
}
|
||||
if(one_byte & 0x40) {
|
||||
temp3 -= temp2;
|
||||
if (temp3 <= (long)0xFFFF8000) {
|
||||
temp3 = (long)0xFFFF8000;
|
||||
}
|
||||
} else {
|
||||
temp3 += temp2;
|
||||
if (temp3 >= 0x7FFF) {
|
||||
temp3 = 0x7FFF;
|
||||
}
|
||||
}
|
||||
nr_array2[index] = temp3;
|
||||
if (out_length < 2) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Get one byte from input buffer
|
||||
* 15007B25
|
||||
*/
|
||||
if (one_byte & 0x80) {
|
||||
/* 15007B32 */
|
||||
switch(one_byte & 0x7F) {
|
||||
case 0: /* 15007B8E */
|
||||
if (nr_array1[index] != 0) {
|
||||
nr_array1[index]--;
|
||||
}
|
||||
if (out_length < 2) {
|
||||
break;
|
||||
}
|
||||
*out.pw++ = (unsigned short)nr_array2[index];
|
||||
out_length -= 2;
|
||||
continue;
|
||||
case 1: /* 15007B72 */
|
||||
nr_array1[index] += 8; /* EBX also */
|
||||
if (nr_array1[index] > 0x58) {
|
||||
nr_array1[index] = 0x58;
|
||||
}
|
||||
if (channels == 2) {
|
||||
index = (index == 0) ? 1 : 0;
|
||||
}
|
||||
continue;
|
||||
case 2:
|
||||
continue;
|
||||
default:
|
||||
nr_array1[index] -= 8;
|
||||
if (nr_array1[index] < 0) {
|
||||
nr_array1[index] = 0;
|
||||
}
|
||||
if (channels != 2) {
|
||||
continue;
|
||||
}
|
||||
index = (index == 0) ? 1 : 0;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
unsigned long temp1 = wave_table_1503f1a0[nr_array1[index]]; /* EDI */
|
||||
unsigned long temp2 = temp1 >> in_buf[1]; /* ESI */
|
||||
long temp3 = nr_array2[index]; /* ECX */
|
||||
if (one_byte & 0x01) { /* EBX = one_byte */
|
||||
temp2 += (temp1 >> 0);
|
||||
}
|
||||
if (one_byte & 0x02) {
|
||||
temp2 += (temp1 >> 1);
|
||||
}
|
||||
if (one_byte & 0x04) {
|
||||
temp2 += (temp1 >> 2);
|
||||
}
|
||||
if (one_byte & 0x08) {
|
||||
temp2 += (temp1 >> 3);
|
||||
}
|
||||
if (one_byte & 0x10) {
|
||||
temp2 += (temp1 >> 4);
|
||||
}
|
||||
if (one_byte & 0x20) {
|
||||
temp2 += (temp1 >> 5);
|
||||
}
|
||||
if(one_byte & 0x40) {
|
||||
temp3 -= temp2;
|
||||
if (temp3 <= (long)0xFFFF8000) {
|
||||
temp3 = (long)0xFFFF8000;
|
||||
}
|
||||
} else {
|
||||
temp3 += temp2;
|
||||
if (temp3 >= 0x7FFF) {
|
||||
temp3 = 0x7FFF;
|
||||
}
|
||||
}
|
||||
nr_array2[index] = temp3;
|
||||
if (out_length < 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
temp2 = nr_array1[index];
|
||||
one_byte &= 0x1F;
|
||||
*out.pw++ = (unsigned short)temp3;
|
||||
out_length -= 2;
|
||||
temp2 += wave_table_1503f120[one_byte];
|
||||
nr_array1[index] = temp2;
|
||||
temp2 = nr_array1[index];
|
||||
one_byte &= 0x1F;
|
||||
*out.pw++ = (unsigned short)temp3;
|
||||
out_length -= 2;
|
||||
temp2 += wave_table_1503f120[one_byte];
|
||||
nr_array1[index] = temp2;
|
||||
|
||||
if (nr_array1[index] < 0) {
|
||||
nr_array1[index] = 0;
|
||||
} else {
|
||||
if (nr_array1[index] > 0x58) {
|
||||
nr_array1[index] = 0x58;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (out.pb - out_buf);
|
||||
if (nr_array1[index] < 0) {
|
||||
nr_array1[index] = 0;
|
||||
} else {
|
||||
if (nr_array1[index] > 0x58) {
|
||||
nr_array1[index] = 0x58;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (out.pb - out_buf);
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef _WAVE_H
|
||||
#define _WAVE_H
|
||||
|
||||
typedef union {
|
||||
unsigned short *pw;
|
||||
unsigned char *pb;
|
||||
unsigned short *pw;
|
||||
unsigned char *pb;
|
||||
} byte_and_short;
|
||||
|
||||
int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels);
|
||||
|
||||
#endif /* _WAVE_H */
|
||||
#endif /* _WAVE_H */
|
||||
|
||||
Reference in New Issue
Block a user