root/trunk/contrib/extractor/libmpq/explode.cpp

Revision 2, 16.1 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 *  explode.c -- explode function of PKWARE data compression library.
3 *
4 *  Copyright (C) 2003 Maik Broemme <mbroemme@plusserver.de>
5 *
6 *  This source was adepted from the C++ version of pkware.cpp included
7 *  in stormlib. The C++ version belongs to the following authors,
8 *
9 *  Ladislav Zezula <ladik.zezula.net>
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26#include <assert.h>
27#include <string.h>
28
29#include "mpq.h"
30#include "explode.h"
31
32/* Tables */
33static unsigned char pkzip_dist_bits[] = {
34        0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
35        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
36        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
37        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
38};
39
40static unsigned char pkzip_dist_code[] = {
41        0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
42        0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
43        0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
44        0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
45};
46
47static unsigned char pkzip_clen_bits[] = {
48        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
49};
50
51static unsigned short pkzip_len_base[] = {
52        0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
53        0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
54};
55
56static unsigned char pkzip_slen_bits[] = {
57        0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
58};
59
60static unsigned char pkzip_len_code[] = {
61        0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
62};
63
64static unsigned char pkzip_bits_asc[] = {
65        0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
66        0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
67        0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
68        0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
69        0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
70        0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
71        0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
72        0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
73        0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
74        0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
75        0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
76        0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
77        0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
78        0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
79        0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
80        0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
81};
82
83static unsigned short pkzip_code_asc[] = {
84        0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
85        0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
86        0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
87        0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
88        0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
89        0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
90        0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
91        0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
92        0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
93        0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
94        0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
95        0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
96        0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
97        0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
98        0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
99        0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
100        0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
101        0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
102        0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
103        0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
104        0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
105        0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
106        0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
107        0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
108        0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
109        0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
110        0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
111        0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
112        0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
113        0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
114        0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
115        0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 
116};
117
118/* Local variables */
119static char copyright[] = "PKWARE Data Compression Library for Win32\r\n"
120                          "Copyright 1989-1995 PKWARE Inc.  All Rights Reserved\r\n"
121                          "Patent No. 5,051,745\r\n"
122                          "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
123                          "Version 1.11\r\n";
124
125/* Local functions */
126static void libmpq_pkzip_gen_decode_tabs(long count, unsigned char *bits, unsigned char *code, unsigned char *buf2) {
127        long i;
128
129        for (i = count-1; i >= 0; i--) {                /* EBX - count */
130                unsigned long idx1 = code[i];
131                unsigned long idx2 = 1 << bits[i];
132                do {
133                        buf2[idx1] = (unsigned char)i;
134                        idx1      += idx2;
135                } while (idx1 < 0x100);
136        }
137}
138
139static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) {
140        unsigned short *code_asc = &pkzip_code_asc[0xFF];
141        unsigned long acc, add;
142        unsigned short count;
143
144        for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) {
145                unsigned char *bits_asc = mpq_pkzip->bits_asc + count;
146                unsigned char bits_tmp = *bits_asc;
147
148                if (bits_tmp <= 8) {
149                        add = (1 << bits_tmp);
150                        acc = *code_asc;
151                        do {
152                                mpq_pkzip->offs_2c34[acc] = (unsigned char)count;
153                                acc += add;
154                        } while (acc < 0x100);
155                } else {
156                        if ((acc = (*code_asc & 0xFF)) != 0) {
157                                mpq_pkzip->offs_2c34[acc] = 0xFF;
158                                if (*code_asc & 0x3F) {
159                                        bits_tmp -= 4;
160                                        *bits_asc = bits_tmp;
161                                        add = (1 << bits_tmp);
162                                        acc = *code_asc >> 4;
163                                        do {
164                                                mpq_pkzip->offs_2d34[acc] = (unsigned char)count;
165                                                acc += add;
166                                        } while (acc < 0x100);
167                                } else {
168                                        bits_tmp -= 6;
169                                        *bits_asc = bits_tmp;
170                                        add = (1 << bits_tmp);
171                                        acc = *code_asc >> 6;
172                                        do {
173                                                mpq_pkzip->offs_2e34[acc] = (unsigned char)count;
174                                                acc += add;
175                                        } while (acc < 0x80);
176                                }
177                        } else {
178                                bits_tmp -= 8;
179                                *bits_asc = bits_tmp;
180                                add = (1 << bits_tmp);
181                                acc = *code_asc >> 8;
182                                do {
183                                        mpq_pkzip->offs_2eb4[acc] = (unsigned char)count;
184                                        acc += add;
185                                } while (acc < 0x100);
186                        }
187                }
188        }
189}
190
191/*
192 *  Skips given number of bits in bit buffer. Result is stored in mpq_pkzip->bit_buf
193 *  If no data in input buffer, returns true
194 */
195static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits) {
196        /* If number of bits required is less than number of (bits in the buffer) ? */
197        if (bits <= mpq_pkzip->extra_bits) {
198                mpq_pkzip->extra_bits -= bits;
199                mpq_pkzip->bit_buf >>= bits;
200                return 0;
201        }
202
203        /* Load input buffer if necessary */
204        mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits;
205        if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) {
206                mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
207                if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) {
208                        return 1;
209                }
210                mpq_pkzip->in_pos = 0;
211        }
212
213        /* Update bit buffer */
214        mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8);
215        mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits);
216        mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8;
217        return 0;
218}
219
220/*
221 *  Decompress the imploded data using coded literals.
222 *  Returns: 0x000 - 0x0FF : One byte from compressed file.
223 *           0x100 - 0x305 : Copy previous block (0x100 = 1 byte)
224 *           0x306         : Out of buffer (?)
225 */
226static unsigned long libmpq_pkzip_explode_lit(pkzip_data_cmp *mpq_pkzip) {
227        unsigned long bits;                             /* Number of bits to skip */
228        unsigned long value;                            /* Position in buffers */
229
230        /* Test the current bit in byte buffer. If is not set, simply return the next byte. */
231        if (mpq_pkzip->bit_buf & 1) {
232
233                /* Skip current bit in the buffer. */
234                if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
235                        return 0x306;
236                }
237
238                /* The next bits are position in buffers. */
239                value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)];
240
241                /* Get number of bits to skip */
242                if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) {
243                        return 0x306;
244                }
245                if ((bits = mpq_pkzip->clen_bits[value]) != 0) {
246                        unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1);
247                        if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) {
248                                if ((value + val2) != 0x10E) {
249                                        return 0x306;
250                                }
251                        }
252                        value = mpq_pkzip->len_base[value] + val2;
253                }
254                return value + 0x100;                   /* Return number of bytes to repeat */
255        }
256
257        /* Skip one bit */
258        if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) {
259                return 0x306;
260        }
261
262        /* If the binary compression type, read 8 bits and return them as one byte. */
263        if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) {
264                value = mpq_pkzip->bit_buf & 0xFF;
265                if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
266                        return 0x306;
267                }
268                return value;
269        }
270
271        /* When ASCII compression ... */
272        if (mpq_pkzip->bit_buf & 0xFF) {
273                value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF];
274                if (value == 0xFF) {
275                        if (mpq_pkzip->bit_buf & 0x3F) {
276                                if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) {
277                                        return 0x306;
278                                }
279                                value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF];
280                        } else {
281                                if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) {
282                                        return 0x306;
283                                }
284                                value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F];
285                        }
286                }
287        } else {
288                if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) {
289                        return 0x306;
290                }
291                value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF];
292        }
293        return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value;
294}
295
296/*
297 *  Retrieves the number of bytes to move back.
298 */
299static unsigned long libmpq_pkzip_explode_dist(pkzip_data_cmp *mpq_pkzip, unsigned long length) {
300        unsigned long pos  = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)];
301        unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */
302
303        /* Skip the appropriate number of bits */
304        if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) {
305                return 0;
306        }
307        if (length == 2) {
308                pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03);
309                if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) {
310                        return 0;
311                }
312        } else {
313                pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask);
314
315                /* Skip the bits */
316                if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) {
317                        return 0;
318                }
319        }
320        return pos + 1;
321}
322
323static unsigned long libmpq_pkzip_expand(pkzip_data_cmp *mpq_pkzip) {
324        unsigned int copy_bytes;                        /* Number of bytes to copy */
325        unsigned long one_byte;                         /* One byte from compressed file */
326        unsigned long result;
327
328        mpq_pkzip->out_pos = 0x1000;                    /* Initialize output buffer position */
329
330        /* If end of data or error, terminate decompress */
331        while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) {
332
333                /* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */
334                if (one_byte >= 0x100) {
335                        unsigned char *source;          /* ECX */
336                        unsigned char *target;          /* EDX */
337                        unsigned long copy_length = one_byte - 0xFE;
338                        unsigned long move_back;
339
340                        /* Get length of data to copy */
341                        if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) {
342                                result = 0x306;
343                                break;
344                        }
345
346                        /* Target and source pointer */
347                        target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos];
348                        source = target - move_back;
349                        mpq_pkzip->out_pos += copy_length;
350                        while (copy_length-- > 0) {
351                                *target++ = *source++;
352                        }
353                } else {
354                        mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte;
355                }
356
357                /*
358                 * If number of extracted bytes has reached 1/2 of output buffer,
359                 * flush output buffer.
360                 */
361                if (mpq_pkzip->out_pos >= 0x2000) {
362
363                        /* Copy decompressed data into user buffer. */
364                        copy_bytes = 0x1000;
365                        mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], &copy_bytes, mpq_pkzip->param);
366
367                        /* If there are some data left, keep them alive */
368                        memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000);
369                        mpq_pkzip->out_pos -= 0x1000;
370                }
371        }
372        copy_bytes = mpq_pkzip->out_pos - 0x1000;
373        mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], &copy_bytes, mpq_pkzip->param);
374        return result;
375}
376
377/*
378 * Main exploding function.
379 */
380unsigned int libmpq_pkzip_explode(
381        unsigned int    (*read_buf)(char *buf, unsigned  int *size, void *param),
382        void            (*write_buf)(char *buf, unsigned  int *size, void *param),
383        char            *work_buf,
384        void            *param) {
385
386        pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf;
387
388        /* Set the whole work buffer to zeros */
389        memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp));
390
391        /* Initialize work struct and load compressed data */
392        mpq_pkzip->read_buf   = read_buf;
393        mpq_pkzip->write_buf  = write_buf;
394        mpq_pkzip->param      = param;
395        mpq_pkzip->in_pos     = sizeof(mpq_pkzip->in_buf);
396        mpq_pkzip->in_bytes   = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param);
397        if (mpq_pkzip->in_bytes <= 4) {
398                return LIBMPQ_PKZIP_CMP_BAD_DATA;
399        }
400        mpq_pkzip->cmp_type   = mpq_pkzip->in_buf[0];   /* Get the compression type */
401        mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1];   /* Get the dictionary size */
402        mpq_pkzip->bit_buf    = mpq_pkzip->in_buf[2];   /* Initialize 16-bit bit buffer */
403        mpq_pkzip->extra_bits = 0;                      /* Extra (over 8) bits */
404        mpq_pkzip->in_pos     = 3;                      /* Position in input buffer */
405
406        /* Test for the valid dictionary size */
407        if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) {
408                return LIBMPQ_PKZIP_CMP_INV_DICTSIZE;
409        }
410        mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits);       /* Shifted by 'sar' instruction */
411        if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) {
412                if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) {
413                        return LIBMPQ_PKZIP_CMP_INV_MODE;
414                }
415                memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc));
416                libmpq_pkzip_gen_asc_tabs(mpq_pkzip);
417        }
418        memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits));
419        libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2);
420        memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits));
421        memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base));
422        memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits));
423        libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1);
424        if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) {
425                return LIBMPQ_PKZIP_CMP_NO_ERROR;
426        }
427        return LIBMPQ_PKZIP_CMP_ABORT;
428}
Note: See TracBrowser for help on using the browser.