Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / contrib / vmap_extractor_v2 / stormlib / pklib / explode.c
bloba5b41e3dcf9c6e6a2b5df67943c0c97068f4db94
1 /*****************************************************************************/
2 /* explode.c Copyright (c) Ladislav Zezula 2003 */
3 /*---------------------------------------------------------------------------*/
4 /* Implode function of PKWARE Data Compression library */
5 /*---------------------------------------------------------------------------*/
6 /* Date Ver Who Comment */
7 /* -------- ---- --- ------- */
8 /* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
9 /* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */
10 /* 02.05.03 1.01 Lad Stress test done */
11 /*****************************************************************************/
13 #include <assert.h>
14 #include <string.h>
16 #include "pklib.h"
18 //-----------------------------------------------------------------------------
19 // Tables
21 static unsigned char DistBits[] =
23 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
24 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
25 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
26 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
29 static unsigned char DistCode[] =
31 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
32 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
33 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
34 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
37 static unsigned char ExLenBits[] =
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
42 static unsigned short LenBase[] =
44 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
45 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
48 static unsigned char LenBits[] =
50 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
53 static unsigned char LenCode[] =
55 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
58 static unsigned char ChBitsAsc[] =
60 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
61 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
62 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
63 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
64 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
65 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
66 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
67 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
68 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
69 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
70 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
71 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
72 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
73 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
74 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
75 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
78 static unsigned short ChCodeAsc[] =
80 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
81 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
82 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
83 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
84 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
85 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
86 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
87 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
88 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
89 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
90 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
91 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
92 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
93 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
94 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
95 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
96 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
97 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
98 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
99 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
100 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
101 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
102 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
103 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
104 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
105 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
106 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
107 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
108 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
109 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
110 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
111 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
114 //-----------------------------------------------------------------------------
115 // Local variables
117 static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n"
118 "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
119 "Patent No. 5,051,745\r\n"
120 "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
121 "Version 1.11\r\n";
123 //-----------------------------------------------------------------------------
124 // Local functions
126 // Copies a block to another location
127 static void lmemcpy(void * trg, const void * src, size_t count)
129 memcpy(trg, src, count);
132 static void GenDecodeTabs(long count, unsigned char * bits, unsigned char * pCode, unsigned char * buffer2)
134 long i;
136 for(i = count-1; i >= 0; i--) // EBX - count
138 unsigned long idx1 = pCode[i];
139 unsigned long idx2 = 1 << bits[i];
143 buffer2[idx1] = (unsigned char)i;
144 idx1 += idx2;
146 while(idx1 < 0x100);
150 static void GenAscTabs(TDcmpStruct * pWork)
152 unsigned short * pChCodeAsc = &ChCodeAsc[0xFF];
153 unsigned long acc, add;
154 unsigned short count;
156 for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--)
158 unsigned char * pChBitsAsc = pWork->ChBitsAsc + count;
159 unsigned char bits_asc = *pChBitsAsc;
161 if(bits_asc <= 8)
163 add = (1 << bits_asc);
164 acc = *pChCodeAsc;
168 pWork->offs2C34[acc] = (unsigned char)count;
169 acc += add;
171 while(acc < 0x100);
173 else if((acc = (*pChCodeAsc & 0xFF)) != 0)
175 pWork->offs2C34[acc] = 0xFF;
177 if(*pChCodeAsc & 0x3F)
179 bits_asc -= 4;
180 *pChBitsAsc = bits_asc;
182 add = (1 << bits_asc);
183 acc = *pChCodeAsc >> 4;
186 pWork->offs2D34[acc] = (unsigned char)count;
187 acc += add;
189 while(acc < 0x100);
191 else
193 bits_asc -= 6;
194 *pChBitsAsc = bits_asc;
196 add = (1 << bits_asc);
197 acc = *pChCodeAsc >> 6;
200 pWork->offs2E34[acc] = (unsigned char)count;
201 acc += add;
203 while(acc < 0x80);
206 else
208 bits_asc -= 8;
209 *pChBitsAsc = bits_asc;
211 add = (1 << bits_asc);
212 acc = *pChCodeAsc >> 8;
215 pWork->offs2EB4[acc] = (unsigned char)count;
216 acc += add;
218 while(acc < 0x100);
223 //-----------------------------------------------------------------------------
224 // Skips given number of bits in bit buffer. Result is stored in pWork->bit_buff
225 // If no data in input buffer, returns true
227 static int WasteBits(TDcmpStruct * pWork, unsigned long nBits)
229 // If number of bits required is less than number of (bits in the buffer) ?
230 if(nBits <= pWork->extra_bits)
232 pWork->extra_bits -= nBits;
233 pWork->bit_buff >>= nBits;
234 return 0;
237 // Load input buffer if necessary
238 pWork->bit_buff >>= pWork->extra_bits;
239 if(pWork->in_pos == pWork->in_bytes)
241 pWork->in_pos = sizeof(pWork->in_buff);
242 if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0)
243 return 1;
244 pWork->in_pos = 0;
247 // Update bit buffer
248 pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8);
249 pWork->bit_buff >>= (nBits - pWork->extra_bits);
250 pWork->extra_bits = (pWork->extra_bits - nBits) + 8;
251 return 0;
254 //-----------------------------------------------------------------------------
255 // Returns : 0x000 - 0x0FF : One byte from compressed file.
256 // 0x100 - 0x305 : Copy previous block (0x100 = 1 byte)
257 // 0x306 : Out of buffer (?)
259 static unsigned long DecodeLit(TDcmpStruct * pWork)
261 unsigned long nBits; // Number of bits to skip
262 unsigned long value; // Position in buffers
264 // Test the current bit in byte buffer. If is not set, simply return the next byte.
265 if(pWork->bit_buff & 1)
267 // Skip current bit in the buffer
268 if(WasteBits(pWork, 1))
269 return 0x306;
271 // The next bits are position in buffers
272 value = pWork->position2[(pWork->bit_buff & 0xFF)];
274 // Get number of bits to skip
275 if(WasteBits(pWork, pWork->LenBits[value]))
276 return 0x306;
278 if((nBits = pWork->ExLenBits[value]) != 0)
280 unsigned long val2 = pWork->bit_buff & ((1 << nBits) - 1);
282 if(WasteBits(pWork, nBits))
284 if((value + val2) != 0x10E)
285 return 0x306;
287 value = pWork->LenBase[value] + val2;
289 return value + 0x100; // Return number of bytes to repeat
292 // Waste one bit
293 if(WasteBits(pWork, 1))
294 return 0x306;
296 // If the binary compression type, read 8 bits and return them as one byte.
297 if(pWork->ctype == CMP_BINARY)
299 value = pWork->bit_buff & 0xFF;
300 if(WasteBits(pWork, 8))
301 return 0x306;
302 return value;
305 // When ASCII compression ...
306 if(pWork->bit_buff & 0xFF)
308 value = pWork->offs2C34[pWork->bit_buff & 0xFF];
310 if(value == 0xFF)
312 if(pWork->bit_buff & 0x3F)
314 if(WasteBits(pWork, 4))
315 return 0x306;
317 value = pWork->offs2D34[pWork->bit_buff & 0xFF];
319 else
321 if(WasteBits(pWork, 6))
322 return 0x306;
324 value = pWork->offs2E34[pWork->bit_buff & 0x7F];
328 else
330 if(WasteBits(pWork, 8))
331 return 0x306;
333 value = pWork->offs2EB4[pWork->bit_buff & 0xFF];
336 return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value;
339 //-----------------------------------------------------------------------------
340 // Retrieves the number of bytes to move back
342 static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long dwLength)
344 unsigned long pos = pWork->position1[(pWork->bit_buff & 0xFF)];
345 unsigned long nSkip = pWork->DistBits[pos]; // Number of bits to skip
347 // Skip the appropriate number of bits
348 if(WasteBits(pWork, nSkip) == 1)
349 return 0;
351 if(dwLength == 2)
353 pos = (pos << 2) | (pWork->bit_buff & 0x03);
355 if(WasteBits(pWork, 2) == 1)
356 return 0;
358 else
360 pos = (pos << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask);
362 // Skip the bits
363 if(WasteBits(pWork, pWork->dsize_bits) == 1)
364 return 0;
366 return pos+1;
369 static unsigned long Expand(TDcmpStruct * pWork)
371 unsigned int copyBytes; // Number of bytes to copy
372 unsigned long oneByte; // One byte from compressed file
373 unsigned long dwResult;
375 pWork->outputPos = 0x1000; // Initialize output buffer position
377 // If end of data or error, terminate decompress
378 while((dwResult = oneByte = DecodeLit(pWork)) < 0x305)
380 // If one byte is greater than 0x100, means "Repeat n - 0xFE bytes"
381 if(oneByte >= 0x100)
383 unsigned char * source; // ECX
384 unsigned char * target; // EDX
385 unsigned long copyLength = oneByte - 0xFE;
386 unsigned long moveBack;
388 // Get length of data to copy
389 if((moveBack = DecodeDist(pWork, copyLength)) == 0)
391 dwResult = 0x306;
392 break;
395 // Target and source pointer
396 target = &pWork->out_buff[pWork->outputPos];
397 source = target - moveBack;
398 pWork->outputPos += copyLength;
400 while(copyLength-- > 0)
401 *target++ = *source++;
403 else
404 pWork->out_buff[pWork->outputPos++] = (unsigned char)oneByte;
406 // If number of extracted bytes has reached 1/2 of output buffer,
407 // flush output buffer.
408 if(pWork->outputPos >= 0x2000)
410 // Copy decompressed data into user buffer
411 copyBytes = 0x1000;
412 pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
414 // If there are some data left, keep them alive
415 lmemcpy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000);
416 pWork->outputPos -= 0x1000;
420 copyBytes = pWork->outputPos - 0x1000;
421 pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
422 return dwResult;
426 //-----------------------------------------------------------------------------
427 // Main exploding function.
429 unsigned int explode(
430 unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
431 void (*write_buf)(char *buf, unsigned int *size, void *param),
432 char *work_buf,
433 void *param)
435 TDcmpStruct * pWork = (TDcmpStruct *)work_buf;
437 // Set the whole work buffer to zeros
438 memset(pWork, 0, sizeof(TDcmpStruct));
440 // Initialize work struct and load compressed data
441 pWork->read_buf = read_buf;
442 pWork->write_buf = write_buf;
443 pWork->param = param;
444 pWork->in_pos = sizeof(pWork->in_buff);
445 pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param);
446 if(pWork->in_bytes <= 4)
447 return CMP_BAD_DATA;
449 pWork->ctype = pWork->in_buff[0]; // Get the compression type
450 pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size
451 pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer
452 pWork->extra_bits = 0; // Extra (over 8) bits
453 pWork->in_pos = 3; // Position in input buffer
455 // Test for the valid dictionary size
456 if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
457 return CMP_INVALID_DICTSIZE;
459 pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
461 if(pWork->ctype != CMP_BINARY)
463 if(pWork->ctype != CMP_ASCII)
464 return CMP_INVALID_MODE;
466 lmemcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc));
467 GenAscTabs(pWork);
470 lmemcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits));
471 GenDecodeTabs(0x10, pWork->LenBits, LenCode, pWork->position2);
472 lmemcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits));
473 lmemcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase));
474 lmemcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits));
475 GenDecodeTabs(0x40, pWork->DistBits, DistCode, pWork->position1);
476 if(Expand(pWork) != 0x306)
477 return CMP_NO_ERROR;
479 return CMP_ABORT;