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




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[] = 
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)
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     }
176 static void GenAscTabs(TDcmpStruct * pWork)
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     }
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)
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;
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)
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)];
299         
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;
365 //-----------------------------------------------------------------------------
366 // Retrieves the number of bytes to move back 
368 static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long dwLength)
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;
395 static unsigned long Expand(TDcmpStruct * pWork)
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;
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);
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], &copyBytes, pWork->param);
448     return dwResult;
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)
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;
501         
502     return CMP_ABORT;