diff options
| -rw-r--r-- | MSVC8/mpqlib.vcproj | 4 | ||||
| -rw-r--r-- | MSVC9/mpqlib.vcproj | 4 | ||||
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | extract.c | 2018 | ||||
| -rw-r--r-- | mpq-file.c | 26 | ||||
| -rw-r--r-- | recycle.c | 4 | 
6 files changed, 28 insertions, 2033 deletions
| diff --git a/MSVC8/mpqlib.vcproj b/MSVC8/mpqlib.vcproj index 74100d9..6721b2c 100644 --- a/MSVC8/mpqlib.vcproj +++ b/MSVC8/mpqlib.vcproj @@ -153,10 +153,6 @@  				>  			</File>  			<File -				RelativePath="..\extract.c" -				> -			</File> -			<File  				RelativePath="..\hashtab.c"  				>  			</File> diff --git a/MSVC9/mpqlib.vcproj b/MSVC9/mpqlib.vcproj index c95c5c1..873b84b 100644 --- a/MSVC9/mpqlib.vcproj +++ b/MSVC9/mpqlib.vcproj @@ -154,10 +154,6 @@  				>  			</File>  			<File -				RelativePath=".\extract.c" -				> -			</File> -			<File  				RelativePath=".\hashtab.c"  				>  			</File> @@ -1,5 +1,5 @@ -CC = gcc -LD = gcc +CC = gcc -m32 +LD = gcc -m32  AR = ar rcs  CPPFLAGS = -g -Wall -Werror -D_FILE_OFFSET_BITS=64 -I. @@ -8,7 +8,6 @@ LDFLAGS = -g -lz  SOURCE_LIST = \  MPQCryptography.c \  errors.c \ -extract.c \  lookupa.c \  hashtab.c \  recycle.c \ diff --git a/extract.c b/extract.c deleted file mode 100644 index 07035b1..0000000 --- a/extract.c +++ /dev/null @@ -1,2018 +0,0 @@ -/* - *  extract.c -- global extracting function for all known file compressions - *               in a MPQ archive. - * - *  Copyright (C) 2003 Maik Broemme <mbroemme@plusserver.de> - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  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. - */ -  -/* - * Ripped from libmpq and compacted into this one large file. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <zlib.h> -#include <memory.h> - -#include "extract.h" - -#define FALSE 0 -#define TRUE !FALSE - -typedef int (*DECOMPRESS) (char *, int *, const char *, int); -typedef struct { -    unsigned long mask;         /* Decompression bit */ -    DECOMPRESS decompress;      /* Decompression function */ -} decompress_table; - -static int pkzip_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length); -static int zlib_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length); -static int huff_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length); -static int adpcm_decompress_mono(char *out_buf, int *out_length, const char *in_buf, int in_length); -static int adpcm_decompress_stereo(char *out_buf, int *out_length, const char *in_buf, int in_length); - -static decompress_table dcmp_table[] = { -    {0x08, pkzip_decompress},    /* Decompression with Pkware Data Compression Library */ -    {0x02, zlib_decompress},     /* Decompression with the "zlib" library */ -    {0x01, huff_decompress},     /* Huffmann decompression */ -    {0x80, adpcm_decompress_stereo},      /* adpcm decompression for stereo adpcms */ -    {0x40, adpcm_decompress_mono} /* adpcm decompression for mono adpcms */ -}; - -/* - * ADPCM decompression - */ - -typedef union { -    unsigned short *pw; -    unsigned char *pb; -} byte_and_short; - -/* - * Tables necessary for decompression  - */ -static unsigned long adpcm_step_changes[] = { -    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 adpcm_steps[] = { -    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 -}; - -/* - *  Decompress a adpcm file, mono or stereo - * - *  Offset: 1500F230 - */ -static int adpcm_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; - -    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; -        } - -       /* -        * 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 = adpcm_steps[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 += adpcm_step_changes[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); -} - -/* - * Huffman decompression - */ - -#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 */ - -/* - *  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' */ -}; - -/* - *  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 */ -}; - -/* - *  Structure used for quick decompress. The 'bits' contains - *  number of bits and dcmp_byte contains result decompressed byte - *  value. After each walk through Huffman tree are filled all entries - *  which are multiplies of number of bits loaded from input stream. - *  These entries contain number of bits and result value. At the next - *  7 bits is tested this structure first. If corresponding entry found, - *  decompression routine will not walk through Huffman tree and - *  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 */ -    }; -}; - -/* - *  Structure for Huffman tree. - */ -struct huffman_tree { -    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 */ - -   /* -    * 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 */ - -    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 */ -}; - -static unsigned char table1502A630[] = { - -   /* -    * Data for compression type 0x00  -    */ -    0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -    0x00, 0x00, - -   /* -    * Data for compression type 0x01  -    */ -    0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, -    0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, -    0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, -    0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, -    0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, -    0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, -    0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, -    0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, -    0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, -    0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, -    0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, -    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, -    0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, -    0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, -    0x00, 0x00, - -   /* -    * Data for compression type 0x02  -    */ -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, -    0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, -    0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, -    0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, -    0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, -    0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, - -   /* -    * Data for compression type 0x03  -    */ -    0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, -    0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, -    0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, -    0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, -    0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, -    0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, -    0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, -    0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, -    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, -    0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, -    0x00, 0x00, - -   /* -    * Data for compression type 0x04  -    */ -    0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, - -   /* -    * Data for compression type 0x05  -    */ -    0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, -    0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, -    0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, -    0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, - -   /* -    * Data for compression type 0x06  -    */ -    0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, - -   /* -    * Data for compression type 0x07  -    */ -    0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, - -   /* -    * Data for compression type 0x08  -    */ -    0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, -    0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, -    0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00 -}; - -/* - * Gets previous Huffman tree item (?)  - */ -static struct huffman_tree_item *huff_get_prev_item(struct huffman_tree_item *hi, long value) -{ -    if (PTR_INT(hi->prev) < 0) { -        return PTR_NOT(hi->prev); -    } -    if (value < 0) { -        value = hi - hi->next->prev; -    } -    return hi->prev + value; -} - -/* - * 1500BC90  - */ -static void huff_remove_item(struct huffman_tree_item *hi) -{ -    struct huffman_tree_item *temp;     /* EDX */ - -    if (hi->next != NULL) { -        temp = hi->prev; -        if (PTR_INT(temp) <= 0) { -            temp = PTR_NOT(temp); -        } else { -            temp += (hi - hi->next->prev); -        } -        temp->next = hi->next; -        hi->next->prev = hi->prev; -        hi->next = hi->prev = NULL; -    } -} - -static void huff_insert_item(struct huffman_tree_item **p_item, -                             struct huffman_tree_item *item, unsigned long where, -                             struct huffman_tree_item *item2) -{ -    struct huffman_tree_item *next = item->next;        /* EDI - next to the first item */ -    struct huffman_tree_item *prev = item->prev;        /* ESI - prev to the first item */ -    struct huffman_tree_item *prev2;    /* Pointer to previous item */ -    long next2;                 /* Pointer to the next item */ - -   /* -    * The same code like in mpq_huff_remove_item();  -    */ -    if (next != 0) {            /* If the first item already has next one */ -        if (PTR_INT(prev) < 0) { -            prev = PTR_NOT(prev); -        } else { -            prev += (item - next->prev); -        } - -       /* -        * 150083C1 -        * Remove the item from the tree -        */ -        prev->next = next; -        next->prev = prev; - -       /* -        * Invalidate 'prev' and 'next' pointer  -        */ -        item->next = 0; -        item->prev = 0; -    } - -    if (item2 == NULL) {        /* EDX - If the second item is not entered, */ -        item2 = PTR_PTR(&p_item[1]);    /* take the first tree item */ -    } - -    switch (where) { -    case SWITCH_ITEMS:         /* Switch the two items */ -        item->next = item2->next;       /* item2->next (Pointer to pointer to first) */ -        item->prev = item2->next->prev; -        item2->next->prev = item; -        item2->next = item;     /* Set the first item */ -        return; -    case INSERT_ITEM:          /* Insert as the last item */ -        item->next = item2;     /* Set next item (or pointer to pointer to first item) */ -        item->prev = item2->prev;       /* Set prev item (or last item in the tree) */ -        next2 = PTR_INT(p_item[0]);     /* Usually NULL */ -        prev2 = item2->prev;    /* Prev item to the second (or last tree item) */ -        if (PTR_INT(prev2) < 0) { -            prev2 = PTR_NOT(prev); -            prev2->next = item; -            item2->prev = item; /* Next after last item */ -            return; -        } -        if (next2 < 0) { -            next2 = item2 - item2->next->prev; -        } -        prev2 += next2; -        prev2->next = item; -        item2->prev = item;     /* Set the next/last item */ -        return; -    default: -        return; -    } -} - -/* - * Builds Huffman tree. Called with the first 8 bits loaded from input stream.  - */ -static void huff_build_tree(struct huffman_tree *ht, unsigned int cmp_type) -{ -    unsigned long max_byte;     /* [ESP+10] - The greatest character found in table */ -    unsigned char *byte_array;  /* [ESP+1C] - Pointer to unsigned char in table1502A630 */ -    unsigned long i;            /* egcs in linux doesn't like multiple for loops without an -                                 * explicit i */ -    unsigned int found;         /* Thats needed to replace the goto stuff from original source :) */ -    struct huffman_tree_item **p_item;  /* [ESP+14] - Pointer to Huffman tree item pointer array */ -    struct huffman_tree_item *child1; - -   /* -    * Loop while pointer has a negative value.  -    */ -    while (PTR_INT(ht->last) > 0) {     /* ESI - Last entry */ -        struct huffman_tree_item *temp; /* EAX */ - -        if (ht->last->next != NULL) {   /* ESI->next */ -            huff_remove_item(ht->last); -        } -        ht->item3058 = PTR_PTR(&ht->item3054);  /* [EDI+4] */ -        ht->last->prev = ht->item3058;  /* EAX */ -        temp = huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050)); -        temp->next = ht->last; -        ht->item3054 = ht->last; -    } - -   /* -    * Clear all pointers in huffman tree item array.  -    */ -    memset(ht->items306C, 0, sizeof(ht->items306C)); - -    max_byte = 0;               /* Greatest character found init to zero. */ -    p_item = (struct huffman_tree_item **) &ht->items306C;      /* Pointer to current entry in -                                                                 * huffman tree item pointer array */ - -   /* -    * Ensure we have low 8 bits only  -    */ -    cmp_type &= 0xFF; -    byte_array = table1502A630 + cmp_type * 258;        /* EDI also */ - -    for (i = 0; i < 0x100; i++, p_item++) { -        struct huffman_tree_item *item = ht->item3058;  /* Item to be created */ -        struct huffman_tree_item *p_item3 = ht->item3058; -        unsigned char one_byte = byte_array[i]; - -       /* -        * Skip all the bytes which are zero.  -        */ -        if (byte_array[i] == 0) { -            continue; -        } - -       /* -        * If not valid pointer, take the first available item in the array.  -        */ -        if (PTR_INT(item) <= 0) { -            item = &ht->items0008[ht->items++]; -        } - -       /* -        * Insert this item as the top of the tree.  -        */ -        huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); - -        item->parent = NULL;    /* Invalidate child and parent */ -        item->child = NULL; -        *p_item = item;         /* Store pointer into pointer array */ - -        item->dcmp_byte = i;    /* Store counter */ -        item->byte_value = one_byte;    /* Store byte value */ -        if (one_byte >= max_byte) { -            max_byte = one_byte; -            continue; -        } - -       /* -        * Find the first item which has byte value greater than current one byte  -        */ -        found = 0; -        if (PTR_INT((p_item3 = ht->last)) > 0) {        /* EDI - Pointer to the last item */ - -           /* -            * 15006AF7  -            */ -            if (p_item3 != NULL) { -                do {            /* 15006AFB */ -                    if (p_item3->byte_value >= one_byte) { -                        found = 1; -                        break; -                    } -                    p_item3 = p_item3->prev; -                } while (PTR_INT(p_item3) > 0); -            } -        } - -        if (found == 0) { -            p_item3 = NULL; -        } - -       /* -        * 15006B09  -        */ -        if (item->next != NULL) { -            huff_remove_item(item); -        } - -       /* -        * 15006B15  -        */ -        if (p_item3 == NULL) { -            p_item3 = PTR_PTR(&ht->first); -        } - -       /* -        * 15006B1F  -        */ -        item->next = p_item3->next; -        item->prev = p_item3->next->prev; -        p_item3->next->prev = item; -        p_item3->next = item; -    } - -   /* -    * 15006B4A  -    */ -    for (; i < 0x102; i++) { -        struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */ - -       /* -        * 15006B59  -        */ -        struct huffman_tree_item *item2 = ht->item3058; /* ESI */ - -        if (PTR_INT(item2) <= 0) { -            item2 = &ht->items0008[ht->items++]; -        } -        huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL); - -       /* -        * 15006B89  -        */ -        item2->dcmp_byte = i; -        item2->byte_value = 1; -        item2->parent = NULL; -        item2->child = NULL; -        *p_item2++ = item2; -    } - -   /* -    * 15006BAA  -    */ -    if (PTR_INT((child1 = ht->last)) > 0) {     /* EDI - last item (first child to item */ -        struct huffman_tree_item *child2;       /* EBP */ -        struct huffman_tree_item *item; /* ESI */ - -       /* -        * 15006BB8  -        */ -        while (PTR_INT((child2 = child1->prev)) > 0) { -            if (PTR_INT((item = ht->item3058)) <= 0) { -                item = &ht->items0008[ht->items++]; -            } -           /* -            * 15006BE3  -            */ -            huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); - -           /* -            * 15006BF3  -            */ -            item->parent = NULL; -            item->child = NULL; - -           /* -            * EDX = child2->byte_value + child1->byte_value; -            * EAX = child1->byte_value; -            * ECX = max_byte;              The greatest character (0xFF usually) -            */ -            item->byte_value = child1->byte_value + child2->byte_value; /* 0x02 */ -            item->child = child1;       /* Prev item in the */ -            child1->parent = item; -            child2->parent = item; - -           /* -            * EAX = item->byte_value;  -            */ -            if (item->byte_value >= max_byte) { -                max_byte = item->byte_value; -            } else { -                struct huffman_tree_item *p_item2 = child2->prev;       /* EDI */ - -                found = 0; -                if (PTR_INT(p_item2) > 0) { - -                   /* -                    * 15006C2D  -                    */ -                    do { -                        if (p_item2->byte_value >= item->byte_value) { -                            found = 1; -                            break; -                        } -                        p_item2 = p_item2->prev; -                    } while (PTR_INT(p_item2) > 0); -                } -                if (found == 0) { -                    p_item2 = NULL; -                } -                if (item->next != 0) { -                    struct huffman_tree_item *temp4 = huff_get_prev_item(item, -1); - -                    temp4->next = item->next;   /* The first item changed */ -                    item->next->prev = item->prev;      /* First->prev changed to negative value */ -                    item->next = NULL; -                    item->prev = NULL; -                } - -               /* -                * 15006C62  -                */ -                if (p_item2 == NULL) { -                    p_item2 = PTR_PTR(&ht->first); -                } -                item->next = p_item2->next;     /* Set item with 0x100 byte value */ -                item->prev = p_item2->next->prev;       /* Set item with 0x17 byte value */ -                p_item2->next->prev = item;     /* Changed prev of item with */ -                p_item2->next = item; -            } - -           /* -            * 15006C7B  -            */ -            if (PTR_INT((child1 = child2->prev)) <= 0) { -                break; -            } -        } -    } - -   /* -    * 15006C88  -    */ -    ht->offs0004 = 1; -} - -/* - * Gets the whole byte from the input stream.  - */ -static unsigned long huff_get_8bits(struct huffman_input_stream *is) -{ -    unsigned long one_byte; - -    if (is->bits <= 8) { -        is->bit_buf |= *(unsigned short *) is->in_buf << is->bits; -        is->in_buf += sizeof(unsigned short); -        is->bits += 16; -    } - -    one_byte = (is->bit_buf & 0xFF); -    is->bit_buf >>= 8; -    is->bits -= 8; - -    return one_byte; -} - -/* - * Gets 7 bits from the stream.  - */ -static unsigned long huff_get_7bits(struct huffman_input_stream *is) -{ -    if (is->bits <= 7) { -        is->bit_buf |= *(unsigned short *) is->in_buf << is->bits; -        is->in_buf += sizeof(unsigned short); -        is->bits += 16; -    } - -   /* -    * Get 7 bits from input stream.  -    */ -    return (is->bit_buf & 0x7F); -} - -/* - * Gets one bit from input stream.  - */ -static unsigned long huff_get_bit(struct huffman_input_stream *is) -{ -    unsigned long bit = (is->bit_buf & 1); - -    is->bit_buf >>= 1; -    if (--is->bits == 0) { -        is->bit_buf = *(unsigned long *) is->in_buf; -        is->in_buf += sizeof(unsigned long); -        is->bits = 32; -    } -    return bit; -} - -static struct huffman_tree_item *huff_call1500E740(struct huffman_tree *ht, unsigned int value) -{ -    struct huffman_tree_item *p_item1 = ht->item3058;   /* EDX */ -    struct huffman_tree_item *p_item2;  /* EAX */ -    struct huffman_tree_item *p_next; -    struct huffman_tree_item *p_prev; -    struct huffman_tree_item **pp_item; - -    if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { -        if ((p_item2 = &ht->items0008[ht->items++]) != NULL) { -            p_item1 = p_item2; -        } else { -            p_item1 = ht->first; -        } -    } else { -        p_item1 = p_item2; -    } - -    p_next = p_item1->next; -    if (p_next != NULL) { -        p_prev = p_item1->prev; -        if (PTR_INT(p_prev) <= 0) { -            p_prev = PTR_NOT(p_prev); -        } else { -            p_prev += (p_item1 - p_item1->next->prev); -        } - -        p_prev->next = p_next; -        p_next->prev = p_prev; -        p_item1->next = NULL; -        p_item1->prev = NULL; -    } -    pp_item = &ht->first;       /* ESI */ -    if (value > 1) { - -       /* -        * ECX = ht->first->next;  -        */ -        p_item1->next = *pp_item; -        p_item1->prev = (*pp_item)->prev; - -        (*pp_item)->prev = p_item2; -        *pp_item = p_item1; - -        p_item2->parent = NULL; -        p_item2->child = NULL; -    } else { -        p_item1->next = (struct huffman_tree_item *) pp_item; -        p_item1->prev = pp_item[1]; -       /* -        * EDI = ht->item305C;  -        */ -        p_prev = pp_item[1];    /* ECX */ -        if (p_prev <= 0) { -            p_prev = PTR_NOT(p_prev); -            p_prev->next = p_item1; -            p_prev->prev = p_item2; - -            p_item2->parent = NULL; -            p_item2->child = NULL; -        } else { -            if (PTR_INT(ht->item305C) < 0) { -                p_prev += (struct huffman_tree_item *) pp_item - (*pp_item)->prev; -            } else { -                p_prev += PTR_INT(ht->item305C); -            } - -            p_prev->next = p_item1; -            pp_item[1] = p_item2; -            p_item2->parent = NULL; -            p_item2->child = NULL; -        } -    } -    return p_item2; -} - -static void huff_call1500E820(struct huffman_tree *ht, struct huffman_tree_item *p_item) -{ -    struct huffman_tree_item *p_item1;  /* EDI */ -    struct huffman_tree_item *p_item2 = NULL;   /* EAX */ -    struct huffman_tree_item *p_item3;  /* EDX */ -    struct huffman_tree_item *p_prev;   /* EBX */ - -    for (; p_item != NULL; p_item = p_item->parent) { -        p_item->byte_value++; - -        for (p_item1 = p_item;; p_item1 = p_prev) { -            p_prev = p_item1->prev; -            if (PTR_INT(p_prev) <= 0) { -                p_prev = NULL; -                break; -            } -            if (p_prev->byte_value >= p_item->byte_value) { -                break; -            } -        } - -        if (p_item1 == p_item) { -            continue; -        } - -        if (p_item1->next != NULL) { -            p_item2 = huff_get_prev_item(p_item1, -1); -            p_item2->next = p_item1->next; -            p_item1->next->prev = p_item1->prev; -            p_item1->next = NULL; -            p_item1->prev = NULL; -        } -        p_item2 = p_item->next; -        p_item1->next = p_item2; -        p_item1->prev = p_item2->prev; -        p_item2->prev = p_item1; -        p_item->next = p_item1; -        if ((p_item2 = p_item1) != NULL) { -            p_item2 = huff_get_prev_item(p_item, -1); -            p_item2->next = p_item->next; -            p_item->next->prev = p_item->prev; -            p_item->next = NULL; -            p_item->prev = NULL; -        } - -        if (p_prev == NULL) { -            p_prev = PTR_PTR(&ht->first); -        } -        p_item2 = p_prev->next; -        p_item->next = p_item2; -        p_item->prev = p_item2->prev; -        p_item2->prev = p_item; -        p_prev->next = p_item; - -        p_item3 = p_item1->parent->child; -        p_item2 = p_item->parent; -        if (p_item2->child == p_item) { -            p_item2->child = p_item1; -        } - -        if (p_item3 == p_item1) { -            p_item1->parent->child = p_item; -        } - -        p_item2 = p_item->parent; -        p_item->parent = p_item1->parent; -        p_item1->parent = p_item2; -        ht->offs0004++; -    } -} - -static int huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, -                              unsigned char *out_buf, unsigned int out_length) -{ -    unsigned int n8bits;        /* 8 bits loaded from input stream */ -    unsigned int n7bits;        /* 7 bits loaded from input stream */ -    unsigned int found;         /* Thats needed to replace the goto stuff from original source :) */ -    unsigned int dcmp_byte = 0; -    unsigned long bit_count; -    struct huffman_decompress *qd; -    unsigned int has_qd;        /* Can we use quick decompression? */ -    struct huffman_tree_item *p_item1; -    struct huffman_tree_item *p_item2; -    unsigned char *out_pos = out_buf; - -   /* -    * Test the output length. Must not be non zero.  -    */ -    if (out_length == 0) { -        return 0; -    } - -   /* -    * Get the compression type from the input stream.  -    */ -    n8bits = huff_get_8bits(is); - -   /* -    * Build the Huffman tree  -    */ -    huff_build_tree(ht, n8bits); -    ht->cmp0 = (n8bits == 0) ? TRUE : FALSE; - -    for (;;) { -        n7bits = huff_get_7bits(is);     /* Get 7 bits from input stream */ - -       /* -        * Try to use quick decompression. Check huffman_decompress array for corresponding item. -        * If found, use the result byte instead. -        */ -        qd = &ht->qd3474[n7bits]; - -       /* -        * If there is a quick-pass possible (ebx)  -        */ -        has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE; - -       /* -        * If we can use quick decompress, use it.  -        */ -        if (has_qd) { -            found = 0; -            if (qd->bits > 7) { -                is->bit_buf >>= 7; -                is->bits -= 7; -                p_item1 = qd->p_item; -                found = 1; -            } -            if (found == 0) { -                is->bit_buf >>= qd->bits; -                is->bits -= qd->bits; -                dcmp_byte = qd->dcmp_byte; -            } -        } else { -            found = 1; -            p_item1 = ht->first->next->prev; -            if (PTR_INT(p_item1) <= 0) { -                p_item1 = NULL; -            } -        } - -        if (found == 1) { -            bit_count = 0; -            p_item2 = NULL; -            do { -                p_item1 = p_item1->child;       /* Move down by one level */ -                if (huff_get_bit(is)) {  /* If current bit is set, move to previous */ -                    p_item1 = p_item1->prev; -                } -                if (++bit_count == 7) { /* If we are at 7th bit, save current huffman tree item. */ -                    p_item2 = p_item1; -                } -            } while (p_item1->child != NULL);   /* Walk until tree has no deeper level */ - -            if (has_qd == FALSE) { -                if (bit_count > 7) { -                    qd->offs00 = ht->offs0004; -                    qd->bits = bit_count; -                    qd->p_item = p_item2; -                } else { -                    unsigned long index = n7bits & (0xFFFFFFFF >> (32 - bit_count)); -                    unsigned long add = (1 << bit_count); - -                    for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) { -                        qd->offs00 = ht->offs0004; -                        qd->bits = bit_count; -                        qd->dcmp_byte = p_item1->dcmp_byte; -                    } -                } -            } -            dcmp_byte = p_item1->dcmp_byte; -        } - -        if (dcmp_byte == 0x101) {       /* Huffman tree needs to be modified */ -            n8bits = huff_get_8bits(is); -            p_item1 = (ht->last <= 0) ? NULL : ht->last; - -            p_item2 = huff_call1500E740(ht, 1); -            p_item2->parent = p_item1; -            p_item2->dcmp_byte = p_item1->dcmp_byte; -            p_item2->byte_value = p_item1->byte_value; -            ht->items306C[p_item2->dcmp_byte] = p_item2; - -            p_item2 = huff_call1500E740(ht, 1); -            p_item2->parent = p_item1; -            p_item2->dcmp_byte = n8bits; -            p_item2->byte_value = 0; -            ht->items306C[p_item2->dcmp_byte] = p_item2; - -            p_item1->child = p_item2; -            huff_call1500E820(ht, p_item2); -            if (ht->cmp0 == 0) { -                huff_call1500E820(ht, ht->items306C[n8bits]); -            } -            dcmp_byte = n8bits; -        } - -        if (dcmp_byte == 0x100) { -            break; -        } - -        *out_pos++ = (unsigned char) dcmp_byte; -        if (--out_length == 0) { -            break; -        } -        if (ht->cmp0) { -            huff_call1500E820(ht, ht->items306C[dcmp_byte]); -        } -    } -    return (out_pos - out_buf); -} - -static void huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi) -{ -    int count; - -   /* -    * Clear links for all the items in the tree  -    */ -    for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) { -        hi->next = hi->prev = NULL; -    } - -    ht->item3050 = NULL; -    ht->item3054 = PTR_PTR(&ht->item3054); -    ht->item3058 = PTR_NOT(ht->item3054); - -    ht->item305C = NULL; -    ht->first = PTR_PTR(&ht->first); -    ht->last = PTR_NOT(ht->first); - -    ht->offs0004 = 1; -    ht->items = 0; - -   /* -    * Clear all huffman_decompress items. Do this only if preparing for decompression  -    */ -    for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress); count++) { -        ht->qd3474[count].offs00 = 0; -    } -} - -/* - * PKWARE's compression. - */ - -#define PKZIP_EXP_BUFFER_SIZE	12596   /* Size of decompress buffer */ -#define PKZIP_CMP_BINARY		0       /* Binary compression */ -#define PKZIP_CMP_ASCII		1       /* Ascii compression */ -#define PKZIP_CMP_NO_ERROR	0 -#define PKZIP_CMP_INV_DICTSIZE	1 -#define PKZIP_CMP_INV_MODE	2 -#define PKZIP_CMP_BAD_DATA	3 -#define PKZIP_CMP_ABORT		4 - -/* - * Compression structure (size: 12596 bytes on x86-32)  - */ -#ifdef _MSC_VER -#pragma pack(1) -#endif -typedef struct { -    unsigned long offs0000;     /* 0000 */ -    unsigned long cmp_type;     /* 0004 - Compression type (PZIP_CMP_BINARY or -                                 * 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) (const 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 */ -} -#ifndef _MSC_VER -__attribute__ ((packed)) -#endif -pkzip_data_cmp; - -typedef struct { -    const 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; -/* - * 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 -}; - -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 -}; - -static unsigned char pkzip_clen_bits[] = { -    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 -}; - -static unsigned char pkzip_slen_bits[] = { -    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 -}; - -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 -}; - -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 -}; - -/* - * Local functions  - */ -static void pkzip_gen_decode_tabs(long count, unsigned char *bits, unsigned char *code, unsigned char *buf2) -{ -    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); -    } -} - -static void pkzip_gen_asc_tabs(pkzip_data_cmp * mpq_pkzip) -{ -    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; - -        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); -            } -        } -    } -} - -/* - *  Skips given number of bits in bit buffer. Result is stored in mpq_pkzip->bit_buf - *  If no data in input buffer, returns true - */ -static int 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; -    } - -   /* -    * 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; -} - -/* - *  Decompress the imploded data using coded literals. - *  Returns: 0x000 - 0x0FF : One byte from compressed file. - *           0x100 - 0x305 : Copy previous block (0x100 = 1 byte) - *           0x306         : Out of buffer (?) - */ -static unsigned long pkzip_explode_lit(pkzip_data_cmp * mpq_pkzip) -{ -    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) { - -       /* -        * Skip current bit in the buffer.  -        */ -        if (pkzip_skip_bits(mpq_pkzip, 1)) { -            return 0x306; -        } - -       /* -        * The next bits are position in buffers.  -        */ -        value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)]; - -       /* -        * Get number of bits to skip  -        */ -        if (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 (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 (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 == PKZIP_CMP_BINARY) { -        value = mpq_pkzip->bit_buf & 0xFF; -        if (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 (pkzip_skip_bits(mpq_pkzip, 4)) { -                    return 0x306; -                } -                value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF]; -            } else { -                if (pkzip_skip_bits(mpq_pkzip, 6)) { -                    return 0x306; -                } -                value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F]; -            } -        } -    } else { -        if (pkzip_skip_bits(mpq_pkzip, 8)) { -            return 0x306; -        } -        value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF]; -    } -    return pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value; -} - -/* - *  Retrieves the number of bytes to move back. - */ -static unsigned long 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 */ - -   /* -    * Skip the appropriate number of bits  -    */ -    if (pkzip_skip_bits(mpq_pkzip, skip) == 1) { -        return 0; -    } -    if (length == 2) { -        pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03); -        if (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 (pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) { -            return 0; -        } -    } -    return pos + 1; -} - -static unsigned long 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; - -    mpq_pkzip->out_pos = 0x1000;        /* Initialize output buffer position */ - -   /* -    * If end of data or error, terminate decompress  -    */ -    while ((result = one_byte = 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; - -           /* -            * Get length of data to copy  -            */ -            if ((move_back = 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; -        } - -       /* -        * 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); - -           /* -            * 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. - */ -static unsigned int pkzip_explode(unsigned int (*read_buf) (char *buf, unsigned int *size, void *param), -                                  void (*write_buf) (const char *buf, unsigned int *size, void *param), -                                  char *work_buf, void *param) -{ - -    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)); - -   /* -    * 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 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 PKZIP_CMP_INV_DICTSIZE; -    } -    mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits);   /* Shifted by 'sar' -                                                                         * instruction */ -    if (mpq_pkzip->cmp_type != PKZIP_CMP_BINARY) { -        if (mpq_pkzip->cmp_type != PKZIP_CMP_ASCII) { -            return PKZIP_CMP_INV_MODE; -        } -        memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc)); -        pkzip_gen_asc_tabs(mpq_pkzip); -    } -    memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits)); -    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)); -    pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1); -    if (pkzip_expand(mpq_pkzip) != 0x306) { -        return PKZIP_CMP_NO_ERROR; -    } -    return PKZIP_CMP_ABORT; -} - - -/* - *  Support functions for PKWARE data compression library. - * - *  Function loads data from the input buffer. Used by mpq_pkzip - *  "implode" and "explode" function as user-defined callback. - *  Returns number of bytes loaded. - * - *  char * buf          - Pointer to a buffer where to store loaded data - *  unsigned int * size - Max. number of bytes to read - *  void * param        - Custom pointer, parameter of implode/explode - */ -static unsigned int 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; - -   /* -    * 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; - -    return to_read; -} - -/* - *  Support functions for PKWARE data compression library. - * - *  Function for store output data. Used by mpq_pkzip "implode" and - *  "explode" as user-defined callback. - * - *  char * buf          - Pointer to data to be written - *  unsigned int * size - Number of bytes to write - *  void * param        - Custom pointer, parameter of implode/explode - */ -static void pkzip_write_output_data(const 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; - -   /* -    * 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; -} - -static int pkzip_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length) -{ -    pkzip_data info;            /* Data information */ -    char *work_buf = malloc(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; - -   /* -    * Do the decompression  -    */ -    pkzip_explode(pkzip_read_input_data, pkzip_write_output_data, work_buf, &info); -    *out_length = info.out_pos; -    free(work_buf); -    return 0; -} - -static int adpcm_decompress_mono(char *out_buf, int *out_length, const char *in_buf, int in_length) -{ -    *out_length = adpcm_decompress((unsigned char *) out_buf, *out_length, (unsigned char *) in_buf, in_length, 1); -    return 1; -} - -static int adpcm_decompress_stereo(char *out_buf, int *out_length, const char *in_buf, int in_length) -{ -    *out_length = adpcm_decompress((unsigned char *) out_buf, *out_length, (unsigned char *) in_buf, in_length, 2); -    return 1; -} - -static int zlib_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length) -{ -    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; - -   /* -    * 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; -} - -/* - *  Huffmann decompression routine. The in_length parameter is not used, but needs - *  to be specified due to compatibility reasons. - * - *  1500F5F0 - */ -static int huff_decompress(char *out_buf, int *out_length, const char *in_buf, int in_length) -{ -    struct huffman_tree *ht = malloc(sizeof(struct huffman_tree)); -    struct huffman_input_stream *is = malloc(sizeof(struct huffman_input_stream)); -    struct huffman_tree_item *hi = 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 the Huffmann tree for decompression  -    */ -    huff_init_tree(ht, hi); - -    *out_length = huff_do_decompress(ht, is, (unsigned char *) out_buf, *out_length); - -    free(hi); -    free(is); -    free(ht); -    return 0; -} - -int __mpqlib_multi_decompress(char *out_buf, int *pout_length, const 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; - -   /* -    * 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--; - -   /* -    * 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; -    } - -   /* -    *  Check if there is some method unhandled -    *  (E.g. compressed by future versions) -    */ -    if (fDecompressions2 != 0) { -        printf("Unknown Compression - bitfield = %08x\n", fDecompressions2); -        return 0; -    } - -   /* -    * If there is more than only one compression, we have to allocate extra buffer  -    */ -    if (count >= 2) { -        temp_buf = malloc(out_length); -    } - -   /* -    * 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 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); - -           /* -            * 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; - -   /* -    * Delete temporary buffer, if necessary  -    */ -    if (temp_buf != NULL) { -        free(temp_buf); -    } -    return 1; -} - -int __mpqlib_pkzip_decompress(char *out_buf, int *pout_length, const char *in_buf, int in_length) -{ -    return pkzip_decompress(out_buf, pout_length, in_buf, in_length); -} @@ -1,5 +1,6 @@  #include <stdlib.h>  #include <memory.h> +#include <zlib.h>  #include "mpq-bios.h"  #include "mpq-file.h"  #include "mpq-errors.h" @@ -142,8 +143,29 @@ static int cache_sector(struct mpq_file_t * mpq_f, int sector) {  	mpq_f->current_sector = sector;          il = ol = sector == (mpq_f->number_of_sectors - 1) ? mpq_f->remaining_bytes : mpq_f->sector_size; - -        r = __mpqlib_multi_decompress(mpq_f->buffer, &ol, in_buf, mpq_f->sizes[sector]); +         +        if (ol == mpq_f->sizes[sector]) { +            memcpy(mpq_f->buffer, in_buf, ol); +        } else { +            char * cursor = in_buf; +            r = 0; +            if ((*cursor++) == 2) { +                z_stream z; +                z.next_in = (Bytef *) cursor; +                z.avail_in = mpq_f->sizes[sector]; +                z.total_in = mpq_f->sizes[sector]; +                z.next_out = (Bytef *) mpq_f->buffer; +                z.avail_out = ol; +                z.total_out = 0; +                z.zalloc = NULL; +                z.zfree = NULL; +                if (inflateInit(&z) == 0) { +                    r = inflate(&z, Z_FINISH) == 0 ? 1 : 0; +                    ol = z.total_out; +                    inflateEnd(&z); +                } +            } +        }          if (il != ol)              r = 0; @@ -78,8 +78,8 @@ char   *purpose;    char *x = (char *)malloc(len);    if (!x)    { -    fprintf(stderr, "malloc of %d failed for %s\n",  -	    len, purpose); +//    fprintf(stderr, "malloc of %d failed for %s\n",  +//	    len, purpose);      exit(-1);    }    return x; | 
