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




CommitLineData
3e09a0ee 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/*****************************************************************************/
12
13#include "pklib.h"
14#include "SMem.h"
15
16//-----------------------------------------------------------------------------
17// Local structures
18
19// Compression structure (Size 12596 bytes)
20typedef 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;
49
50//-----------------------------------------------------------------------------
51// Tables
52
53static 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};
60
61static 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};
68
69static unsigned char ExLenBits[] =
70{
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
72};
73
74static unsigned short LenBase[] =
75{
76 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
77 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
78};
79
80static unsigned char LenBits[] =
81{
82 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
83};
84
85static unsigned char LenCode[] =
86{
87 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
88};
89
90static 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};
109
110static 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};
145
146//-----------------------------------------------------------------------------
147// Local variables
148
149static 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";
154
155//-----------------------------------------------------------------------------
156// Local functions
157
158static void GenDecodeTabs(long count, unsigned char * bits, unsigned char * pCode, unsigned char * buffer2)
159{
160 long i;
161
162 for(i = count-1; i >= 0; i--) // EBX - count
163 {
164 unsigned long idx1 = pCode[i];
165 unsigned long idx2 = 1 << bits[i];
166
167 do
168 {
169 buffer2[idx1] = (unsigned char)i;
170 idx1 += idx2;
171 }
172 while(idx1 < 0x100);
173 }
174}
175
176static void GenAscTabs(TDcmpStruct * pWork)
177{
178 unsigned short * pChCodeAsc = &ChCodeAsc[0xFF];
179 unsigned long acc, add;
180 unsigned short count;
181
182 for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--)
183 {
184 unsigned char * pChBitsAsc = pWork->ChBitsAsc + count;
185 unsigned char bits_asc = *pChBitsAsc;
186
187 if(bits_asc <= 8)
188 {
189 add = (1 << bits_asc);
190 acc = *pChCodeAsc;
191
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;
202
203 if(*pChCodeAsc & 0x3F)
204 {
205 bits_asc -= 4;
206 *pChBitsAsc = bits_asc;
207
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;
221
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;
236
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}
248
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
252
253static 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 }
262
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 }
272
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}
279
280//-----------------------------------------------------------------------------
281// Returns : 0x000 - 0x0FF : One byte from compressed file.
282// 0x100 - 0x305 : Copy previous block (0x100 = 1 byte)
283// 0x306 : Out of buffer (?)
284
285static unsigned long DecodeLit(TDcmpStruct * pWork)
286{
287 unsigned long nBits; // Number of bits to skip
288 unsigned long value; // Position in buffers
289
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;
296
297 // The next bits are position in buffers
298 value = pWork->position2[(pWork->bit_buff & 0xFF)];
299
300 // Get number of bits to skip
301 if(WasteBits(pWork, pWork->LenBits[value]))
302 return 0x306;
303
304 if((nBits = pWork->ExLenBits[value]) != 0)
305 {
306 unsigned long val2 = pWork->bit_buff & ((1 << nBits) - 1);
307
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 }
317
318 // Waste one bit
319 if(WasteBits(pWork, 1))
320 return 0x306;
321
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 }
330
331 // When ASCII compression ...
332 if(pWork->bit_buff & 0xFF)
333 {
334 value = pWork->offs2C34[pWork->bit_buff & 0xFF];
335
336 if(value == 0xFF)
337 {
338 if(pWork->bit_buff & 0x3F)
339 {
340 if(WasteBits(pWork, 4))
341 return 0x306;
342
343 value = pWork->offs2D34[pWork->bit_buff & 0xFF];
344 }
345 else
346 {
347 if(WasteBits(pWork, 6))
348 return 0x306;
349
350 value = pWork->offs2E34[pWork->bit_buff & 0x7F];
351 }
352 }
353 }
354 else
355 {
356 if(WasteBits(pWork, 8))
357 return 0x306;
358
359 value = pWork->offs2EB4[pWork->bit_buff & 0xFF];
360 }
361
362 return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value;
363}
364
365//-----------------------------------------------------------------------------
366// Retrieves the number of bytes to move back
367
368static 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
372
373 // Skip the appropriate number of bits
374 if(WasteBits(pWork, nSkip) == 1)
375 return 0;
376
377 if(dwLength == 2)
378 {
379 pos = (pos << 2) | (pWork->bit_buff & 0x03);
380
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);
387
388 // Skip the bits
389 if(WasteBits(pWork, pWork->dsize_bits) == 1)
390 return 0;
391 }
392 return pos+1;
393}
394
395static 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;
400
401 pWork->outputPos = 0x1000; // Initialize output buffer position
402
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;
413
414 // Get length of data to copy
415 if((moveBack = DecodeDist(pWork, copyLength)) == 0)
416 {
417 dwResult = 0x306;
418 break;
419 }
420
421 // Target and source pointer
422 target = &pWork->out_buff[pWork->outputPos];
423 source = target - moveBack;
424 pWork->outputPos += copyLength;
425
426 while(copyLength-- > 0)
427 *target++ = *source++;
428 }
429 else
430 pWork->out_buff[pWork->outputPos++] = (unsigned char)oneByte;
431
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], &copyBytes, pWork->param);
439
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 }
445
446 copyBytes = pWork->outputPos - 0x1000;
447 pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
448 return dwResult;
449}
450
451
452//-----------------------------------------------------------------------------
453// Main exploding function.
454
455unsigned 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;
462
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;
471
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
477
478 // Test for the valid dictionary size
479 if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
480 return CMP_INVALID_DICTSIZE;
481
482 pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
483
484 if(pWork->ctype != CMP_BINARY)
485 {
486 if(pWork->ctype != CMP_ASCII)
487 return CMP_INVALID_MODE;
488
489 SMemCopy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc));
490 GenAscTabs(pWork);
491 }
492
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;
501
502 return CMP_ABORT;
503}