Current News Archived News Search News Discussion Forum Old Forum Install Programs More Downloads... Troubleshooting Source Code Format Specs. Misc. Information Non-SF Stuff Links Small banner for links to this site: |
1 /*****************************************************************************/
2 /* explode.c Copyright (c) Ladislav Zezula 2003 */
3 /*---------------------------------------------------------------------------*/
4 /* Explode 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 "pklib.h"
14 #include "SMem.h"
16 //-----------------------------------------------------------------------------
17 // Local structures
19 // Compression structure (Size 12596 bytes)
20 typedef struct
21 {
22 unsigned long offs0000; // 0000
23 unsigned long ctype; // 0004 - Compression type (CMP_BINARY or CMP_ASCII)
24 unsigned long outputPos; // 0008 - Position in output buffer
25 unsigned long dsize_bits; // 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000)
26 unsigned long dsize_mask; // 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000)
27 unsigned long bit_buff; // 0014 - 16-bit buffer for processing input data
28 unsigned long extra_bits; // 0018 - Number of extra (above 8) bits in bit buffer
29 unsigned int in_pos; // 001C - Position in in_buff
30 unsigned long in_bytes; // 0020 - Number of bytes in input buffer
31 void * param; // 0024 - Custom parameter
32 unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 0028
33 void (*write_buf)(char *buf, unsigned int *size, void *param);// 002C
34 unsigned char out_buff[0x2000]; // 0030 - Output circle buffer. Starting position is 0x1000
35 unsigned char offs2030[0x204]; // 2030 - ???
36 unsigned char in_buff[0x800]; // 2234 - Buffer for data to be decompressed
37 unsigned char position1[0x100]; // 2A34 - Positions in buffers
38 unsigned char position2[0x100]; // 2B34 - Positions in buffers
39 unsigned char offs2C34[0x100]; // 2C34 - Buffer for
40 unsigned char offs2D34[0x100]; // 2D34 - Buffer for
41 unsigned char offs2E34[0x80]; // 2EB4 - Buffer for
42 unsigned char offs2EB4[0x100]; // 2EB4 - Buffer for
43 unsigned char ChBitsAsc[0x100]; // 2FB4 - Buffer for
44 unsigned char DistBits[0x40]; // 30B4 - Numbers of bytes to skip copied block length
45 unsigned char LenBits[0x10]; // 30F4 - Numbers of bits for skip copied block length
46 unsigned char ExLenBits[0x10]; // 3104 - Number of valid bits for copied block
47 unsigned short LenBase[0x10]; // 3114 - Buffer for
48 } TDcmpStruct;
50 //-----------------------------------------------------------------------------
51 // Tables
53 static unsigned char DistBits[] =
54 {
55 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
56 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
57 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
58 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
59 };
61 static unsigned char DistCode[] =
62 {
63 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
64 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
65 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
66 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
67 };
69 static unsigned char ExLenBits[] =
70 {
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
72 };
74 static unsigned short LenBase[] =
75 {
76 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
77 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
78 };
80 static unsigned char LenBits[] =
81 {
82 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
83 };
85 static unsigned char LenCode[] =
86 {
87 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
88 };
90 static unsigned char ChBitsAsc[] =
91 {
92 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
93 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
94 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
95 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
96 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
97 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
98 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
99 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
100 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
101 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
102 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
103 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
104 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
105 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
106 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
107 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
108 };
110 static unsigned short ChCodeAsc[] =
111 {
112 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
113 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
114 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
115 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
116 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
117 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
118 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
119 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
120 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
121 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
122 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
123 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
124 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
125 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
126 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
127 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
128 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
129 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
130 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
131 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
132 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
133 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
134 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
135 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
136 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
137 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
138 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
139 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
140 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
141 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
142 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
143 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
144 };
146 //-----------------------------------------------------------------------------
147 // Local variables
149 static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n"
150 "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
151 "Patent No. 5,051,745\r\n"
152 "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
153 "Version 1.11";
155 //-----------------------------------------------------------------------------
156 // Local functions
158 static void GenDecodeTabs(long count, unsigned char * bits, unsigned char * pCode, unsigned char * buffer2)
159 {
160 long i;
162 for(i = count-1; i >= 0; i--) // EBX - count
163 {
164 unsigned long idx1 = pCode[i];
165 unsigned long idx2 = 1 << bits[i];
167 do
168 {
169 buffer2[idx1] = (unsigned char)i;
170 idx1 += idx2;
171 }
172 while(idx1 < 0x100);
173 }
174 }
176 static void GenAscTabs(TDcmpStruct * pWork)
177 {
178 unsigned short * pChCodeAsc = &ChCodeAsc[0xFF];
179 unsigned long acc, add;
180 unsigned short count;
182 for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--)
183 {
184 unsigned char * pChBitsAsc = pWork->ChBitsAsc + count;
185 unsigned char bits_asc = *pChBitsAsc;
187 if(bits_asc <= 8)
188 {
189 add = (1 << bits_asc);
190 acc = *pChCodeAsc;
192 do
193 {
194 pWork->offs2C34[acc] = (unsigned char)count;
195 acc += add;
196 }
197 while(acc < 0x100);
198 }
199 else if((acc = (*pChCodeAsc & 0xFF)) != 0)
200 {
201 pWork->offs2C34[acc] = 0xFF;
203 if(*pChCodeAsc & 0x3F)
204 {
205 bits_asc -= 4;
206 *pChBitsAsc = bits_asc;
208 add = (1 << bits_asc);
209 acc = *pChCodeAsc >> 4;
210 do
211 {
212 pWork->offs2D34[acc] = (unsigned char)count;
213 acc += add;
214 }
215 while(acc < 0x100);
216 }
217 else
218 {
219 bits_asc -= 6;
220 *pChBitsAsc = bits_asc;
222 add = (1 << bits_asc);
223 acc = *pChCodeAsc >> 6;
224 do
225 {
226 pWork->offs2E34[acc] = (unsigned char)count;
227 acc += add;
228 }
229 while(acc < 0x80);
230 }
231 }
232 else
233 {
234 bits_asc -= 8;
235 *pChBitsAsc = bits_asc;
237 add = (1 << bits_asc);
238 acc = *pChCodeAsc >> 8;
239 do
240 {
241 pWork->offs2EB4[acc] = (unsigned char)count;
242 acc += add;
243 }
244 while(acc < 0x100);
245 }
246 }
247 }
249 //-----------------------------------------------------------------------------
250 // Skips given number of bits in bit buffer. Result is stored in pWork->bit_buff
251 // If no data in input buffer, returns true
253 static int WasteBits(TDcmpStruct * pWork, unsigned long nBits)
254 {
255 // If number of bits required is less than number of (bits in the buffer) ?
256 if(nBits <= pWork->extra_bits)
257 {
258 pWork->extra_bits -= nBits;
259 pWork->bit_buff >>= nBits;
260 return 0;
261 }
263 // Load input buffer if necessary
264 pWork->bit_buff >>= pWork->extra_bits;
265 if(pWork->in_pos == pWork->in_bytes)
266 {
267 pWork->in_pos = sizeof(pWork->in_buff);
268 if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0)
269 return 1;
270 pWork->in_pos = 0;
271 }
273 // Update bit buffer
274 pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8);
275 pWork->bit_buff >>= (nBits - pWork->extra_bits);
276 pWork->extra_bits = (pWork->extra_bits - nBits) + 8;
277 return 0;
278 }
280 //-----------------------------------------------------------------------------
281 // Returns : 0x000 - 0x0FF : One byte from compressed file.
282 // 0x100 - 0x305 : Copy previous block (0x100 = 1 byte)
283 // 0x306 : Out of buffer (?)
285 static unsigned long DecodeLit(TDcmpStruct * pWork)
286 {
287 unsigned long nBits; // Number of bits to skip
288 unsigned long value; // Position in buffers
290 // Test the current bit in byte buffer. If is not set, simply return the next byte.
291 if(pWork->bit_buff & 1)
292 {
293 // Skip current bit in the buffer
294 if(WasteBits(pWork, 1))
295 return 0x306;
297 // The next bits are position in buffers
298 value = pWork->position2[(pWork->bit_buff & 0xFF)];
300 // Get number of bits to skip
301 if(WasteBits(pWork, pWork->LenBits[value]))
302 return 0x306;
304 if((nBits = pWork->ExLenBits[value]) != 0)
305 {
306 unsigned long val2 = pWork->bit_buff & ((1 << nBits) - 1);
308 if(WasteBits(pWork, nBits))
309 {
310 if((value + val2) != 0x10E)
311 return 0x306;
312 }
313 value = pWork->LenBase[value] + val2;
314 }
315 return value + 0x100; // Return number of bytes to repeat
316 }
318 // Waste one bit
319 if(WasteBits(pWork, 1))
320 return 0x306;
322 // If the binary compression type, read 8 bits and return them as one byte.
323 if(pWork->ctype == CMP_BINARY)
324 {
325 value = pWork->bit_buff & 0xFF;
326 if(WasteBits(pWork, 8))
327 return 0x306;
328 return value;
329 }
331 // When ASCII compression ...
332 if(pWork->bit_buff & 0xFF)
333 {
334 value = pWork->offs2C34[pWork->bit_buff & 0xFF];
336 if(value == 0xFF)
337 {
338 if(pWork->bit_buff & 0x3F)
339 {
340 if(WasteBits(pWork, 4))
341 return 0x306;
343 value = pWork->offs2D34[pWork->bit_buff & 0xFF];
344 }
345 else
346 {
347 if(WasteBits(pWork, 6))
348 return 0x306;
350 value = pWork->offs2E34[pWork->bit_buff & 0x7F];
351 }
352 }
353 }
354 else
355 {
356 if(WasteBits(pWork, 8))
357 return 0x306;
359 value = pWork->offs2EB4[pWork->bit_buff & 0xFF];
360 }
362 return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value;
363 }
365 //-----------------------------------------------------------------------------
366 // Retrieves the number of bytes to move back
368 static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long dwLength)
369 {
370 unsigned long pos = pWork->position1[(pWork->bit_buff & 0xFF)];
371 unsigned long nSkip = pWork->DistBits[pos]; // Number of bits to skip
373 // Skip the appropriate number of bits
374 if(WasteBits(pWork, nSkip) == 1)
375 return 0;
377 if(dwLength == 2)
378 {
379 pos = (pos << 2) | (pWork->bit_buff & 0x03);
381 if(WasteBits(pWork, 2) == 1)
382 return 0;
383 }
384 else
385 {
386 pos = (pos << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask);
388 // Skip the bits
389 if(WasteBits(pWork, pWork->dsize_bits) == 1)
390 return 0;
391 }
392 return pos+1;
393 }
395 static unsigned long Expand(TDcmpStruct * pWork)
396 {
397 unsigned int copyBytes; // Number of bytes to copy
398 unsigned long oneByte; // One byte from compressed file
399 unsigned long dwResult;
401 pWork->outputPos = 0x1000; // Initialize output buffer position
403 // If end of data or error, terminate decompress
404 while((dwResult = oneByte = DecodeLit(pWork)) < 0x305)
405 {
406 // If one byte is greater than 0x100, means "Repeat n - 0xFE bytes"
407 if(oneByte >= 0x100)
408 {
409 unsigned char * source; // ECX
410 unsigned char * target; // EDX
411 unsigned long copyLength = oneByte - 0xFE;
412 unsigned long moveBack;
414 // Get length of data to copy
415 if((moveBack = DecodeDist(pWork, copyLength)) == 0)
416 {
417 dwResult = 0x306;
418 break;
419 }
421 // Target and source pointer
422 target = &pWork->out_buff[pWork->outputPos];
423 source = target - moveBack;
424 pWork->outputPos += copyLength;
426 while(copyLength-- > 0)
427 *target++ = *source++;
428 }
429 else
430 pWork->out_buff[pWork->outputPos++] = (unsigned char)oneByte;
432 // If number of extracted bytes has reached 1/2 of output buffer,
433 // flush output buffer.
434 if(pWork->outputPos >= 0x2000)
435 {
436 // Copy decompressed data into user buffer
437 copyBytes = 0x1000;
438 pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param);
440 // If there are some data left, keep them alive
441 SMemCopy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000);
442 pWork->outputPos -= 0x1000;
443 }
444 }
446 copyBytes = pWork->outputPos - 0x1000;
447 pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param);
448 return dwResult;
449 }
452 //-----------------------------------------------------------------------------
453 // Main exploding function.
455 unsigned int PKEXPORT explode(
456 unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
457 void (*write_buf)(char *buf, unsigned int *size, void *param),
458 char *work_buf,
459 void *param)
460 {
461 TDcmpStruct * pWork = (TDcmpStruct *)work_buf;
463 // Initialize work struct and load compressed data
464 pWork->read_buf = read_buf;
465 pWork->write_buf = write_buf;
466 pWork->param = param;
467 pWork->in_pos = sizeof(pWork->in_buff);
468 pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param);
469 if(pWork->in_bytes <= 4)
470 return CMP_BAD_DATA;
472 pWork->ctype = pWork->in_buff[0]; // Get the compression type
473 pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size
474 pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer
475 pWork->extra_bits = 0; // Extra (over 8) bits
476 pWork->in_pos = 3; // Position in input buffer
478 // Test for the valid dictionary size
479 if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
480 return CMP_INVALID_DICTSIZE;
482 pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
484 if(pWork->ctype != CMP_BINARY)
485 {
486 if(pWork->ctype != CMP_ASCII)
487 return CMP_INVALID_MODE;
489 SMemCopy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc));
490 GenAscTabs(pWork);
491 }
493 SMemCopy(pWork->LenBits, LenBits, sizeof(pWork->LenBits));
494 GenDecodeTabs(0x10, pWork->LenBits, LenCode, pWork->position2);
495 SMemCopy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits));
496 SMemCopy(pWork->LenBase, LenBase, sizeof(pWork->LenBase));
497 SMemCopy(pWork->DistBits, DistBits, sizeof(pWork->DistBits));
498 GenDecodeTabs(0x40, pWork->DistBits, DistCode, pWork->position1);
499 if(Expand(pWork) != 0x306)
500 return CMP_NO_ERROR;
502 return CMP_ABORT;
503 }
|