Imported Upstream version 1.3.14
[debian/gzip] / unlzw.c
1 /* unlzw.c -- decompress files in LZW format.
2  * The code in this file is directly derived from the public domain 'compress'
3  * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
4  * Ken Turkowski, Dave Mack and Peter Jannesen.
5  *
6  * This is a temporary version which will be rewritten in some future version
7  * to accommodate in-memory decompression.
8  */
9
10 #include <config.h>
11 #include "tailor.h"
12
13 #ifdef HAVE_UNISTD_H
14 #  include <unistd.h>
15 #endif
16 #ifdef HAVE_FCNTL_H
17 #  include <fcntl.h>
18 #endif
19
20 #include "gzip.h"
21 #include "lzw.h"
22
23 typedef unsigned char   char_type;
24 typedef          long   code_int;
25 typedef unsigned long   count_int;
26 typedef unsigned short  count_short;
27 typedef unsigned long   cmp_code_int;
28
29 #define MAXCODE(n)      (1L << (n))
30
31 #ifndef REGISTERS
32 #       define  REGISTERS       2
33 #endif
34 #define REG1
35 #define REG2
36 #define REG3
37 #define REG4
38 #define REG5
39 #define REG6
40 #define REG7
41 #define REG8
42 #define REG9
43 #define REG10
44 #define REG11
45 #define REG12
46 #define REG13
47 #define REG14
48 #define REG15
49 #define REG16
50 #if REGISTERS >= 1
51 #       undef   REG1
52 #       define  REG1    register
53 #endif
54 #if REGISTERS >= 2
55 #       undef   REG2
56 #       define  REG2    register
57 #endif
58 #if REGISTERS >= 3
59 #       undef   REG3
60 #       define  REG3    register
61 #endif
62 #if REGISTERS >= 4
63 #       undef   REG4
64 #       define  REG4    register
65 #endif
66 #if REGISTERS >= 5
67 #       undef   REG5
68 #       define  REG5    register
69 #endif
70 #if REGISTERS >= 6
71 #       undef   REG6
72 #       define  REG6    register
73 #endif
74 #if REGISTERS >= 7
75 #       undef   REG7
76 #       define  REG7    register
77 #endif
78 #if REGISTERS >= 8
79 #       undef   REG8
80 #       define  REG8    register
81 #endif
82 #if REGISTERS >= 9
83 #       undef   REG9
84 #       define  REG9    register
85 #endif
86 #if REGISTERS >= 10
87 #       undef   REG10
88 #       define  REG10   register
89 #endif
90 #if REGISTERS >= 11
91 #       undef   REG11
92 #       define  REG11   register
93 #endif
94 #if REGISTERS >= 12
95 #       undef   REG12
96 #       define  REG12   register
97 #endif
98 #if REGISTERS >= 13
99 #       undef   REG13
100 #       define  REG13   register
101 #endif
102 #if REGISTERS >= 14
103 #       undef   REG14
104 #       define  REG14   register
105 #endif
106 #if REGISTERS >= 15
107 #       undef   REG15
108 #       define  REG15   register
109 #endif
110 #if REGISTERS >= 16
111 #       undef   REG16
112 #       define  REG16   register
113 #endif
114
115 #ifndef BYTEORDER
116 #       define  BYTEORDER       0000
117 #endif
118
119 #ifndef NOALLIGN
120 #       define  NOALLIGN        0
121 #endif
122
123
124 union   bytes {
125     long  word;
126     struct {
127 #if BYTEORDER == 4321
128         char_type       b1;
129         char_type       b2;
130         char_type       b3;
131         char_type       b4;
132 #else
133 #if BYTEORDER == 1234
134         char_type       b4;
135         char_type       b3;
136         char_type       b2;
137         char_type       b1;
138 #else
139 #       undef   BYTEORDER
140         int  dummy;
141 #endif
142 #endif
143     } bytes;
144 };
145
146 #if BYTEORDER == 4321 && NOALLIGN == 1
147 #  define input(b,o,c,n,m){ \
148      (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
149      (o) += (n); \
150    }
151 #else
152 #  define input(b,o,c,n,m){ \
153      REG1 char_type *p = &(b)[(o)>>3]; \
154      (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
155      ((long)(p[2])<<16))>>((o)&0x7))&(m); \
156      (o) += (n); \
157    }
158 #endif
159
160 #ifndef MAXSEG_64K
161    /* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */
162 #  define tab_prefixof(i) tab_prefix[i]
163 #  define clear_tab_prefixof()  memzero(tab_prefix, 256);
164 #else
165    /* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */
166    /* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd  codes */
167    ush *tab_prefix[2];
168 #  define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]
169 #  define clear_tab_prefixof()  \
170       memzero(tab_prefix0, 128), \
171       memzero(tab_prefix1, 128);
172 #endif
173 #define de_stack        ((char_type *)(&d_buf[DIST_BUFSIZE-1]))
174 #define tab_suffixof(i) tab_suffix[i]
175
176 int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
177
178 /* ============================================================================
179  * Decompress in to out.  This routine adapts to the codes in the
180  * file building the "string" table on-the-fly; requiring no table to
181  * be stored in the compressed file.
182  * IN assertions: the buffer inbuf contains already the beginning of
183  *   the compressed data, from offsets iptr to insize-1 included.
184  *   The magic header has already been checked and skipped.
185  *   bytes_in and bytes_out have been initialized.
186  */
187 int unlzw(in, out)
188     int in, out;    /* input and output file descriptors */
189 {
190     REG2   char_type  *stackp;
191     REG3   code_int   code;
192     REG4   int        finchar;
193     REG5   code_int   oldcode;
194     REG6   code_int   incode;
195     REG7   long       inbits;
196     REG8   long       posbits;
197     REG9   int        outpos;
198 /*  REG10  int        insize; (global) */
199     REG11  unsigned   bitmask;
200     REG12  code_int   free_ent;
201     REG13  code_int   maxcode;
202     REG14  code_int   maxmaxcode;
203     REG15  int        n_bits;
204     REG16  int        rsize;
205
206 #ifdef MAXSEG_64K
207     tab_prefix[0] = tab_prefix0;
208     tab_prefix[1] = tab_prefix1;
209 #endif
210     maxbits = get_byte();
211     block_mode = maxbits & BLOCK_MODE;
212     if ((maxbits & LZW_RESERVED) != 0) {
213         WARN((stderr, "\n%s: %s: warning, unknown flags 0x%x\n",
214               program_name, ifname, maxbits & LZW_RESERVED));
215     }
216     maxbits &= BIT_MASK;
217     maxmaxcode = MAXCODE(maxbits);
218
219     if (maxbits > BITS) {
220         fprintf(stderr,
221                 "\n%s: %s: compressed with %d bits, can only handle %d bits\n",
222                 program_name, ifname, maxbits, BITS);
223         exit_code = ERROR;
224         return ERROR;
225     }
226     rsize = insize;
227     maxcode = MAXCODE(n_bits = INIT_BITS)-1;
228     bitmask = (1<<n_bits)-1;
229     oldcode = -1;
230     finchar = 0;
231     outpos = 0;
232     posbits = inptr<<3;
233
234     free_ent = ((block_mode) ? FIRST : 256);
235
236     clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */
237
238     for (code = 255 ; code >= 0 ; --code) {
239         tab_suffixof(code) = (char_type)code;
240     }
241     do {
242         REG1 int i;
243         int  e;
244         int  o;
245
246     resetbuf:
247         e = insize-(o = (posbits>>3));
248
249         for (i = 0 ; i < e ; ++i) {
250             inbuf[i] = inbuf[i+o];
251         }
252         insize = e;
253         posbits = 0;
254
255         if (insize < INBUF_EXTRA) {
256             rsize = read_buffer (in, (char *) inbuf + insize, INBUFSIZ);
257             if (rsize == -1) {
258                 read_error();
259             }
260             insize += rsize;
261             bytes_in += (off_t)rsize;
262         }
263         inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 :
264                   ((long)insize<<3)-(n_bits-1));
265
266         while (inbits > posbits) {
267             if (free_ent > maxcode) {
268                 posbits = ((posbits-1) +
269                            ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
270                 ++n_bits;
271                 if (n_bits == maxbits) {
272                     maxcode = maxmaxcode;
273                 } else {
274                     maxcode = MAXCODE(n_bits)-1;
275                 }
276                 bitmask = (1<<n_bits)-1;
277                 goto resetbuf;
278             }
279             input(inbuf,posbits,code,n_bits,bitmask);
280             Tracev((stderr, "%d ", code));
281
282             if (oldcode == -1) {
283                 if (256 <= code)
284                   gzip_error ("corrupt input.");
285                 outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code));
286                 continue;
287             }
288             if (code == CLEAR && block_mode) {
289                 clear_tab_prefixof();
290                 free_ent = FIRST - 1;
291                 posbits = ((posbits-1) +
292                            ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
293                 maxcode = MAXCODE(n_bits = INIT_BITS)-1;
294                 bitmask = (1<<n_bits)-1;
295                 goto resetbuf;
296             }
297             incode = code;
298             stackp = de_stack;
299
300             if (code >= free_ent) { /* Special case for KwKwK string. */
301                 if (code > free_ent) {
302 #ifdef DEBUG
303                     char_type *p;
304
305                     posbits -= n_bits;
306                     p = &inbuf[posbits>>3];
307                     fprintf(stderr,
308                             "code:%ld free_ent:%ld n_bits:%d insize:%u\n",
309                             code, free_ent, n_bits, insize);
310                     fprintf(stderr,
311                             "posbits:%ld inbuf:%02X %02X %02X %02X %02X\n",
312                             posbits, p[-1],p[0],p[1],p[2],p[3]);
313 #endif
314                     if (!test && outpos > 0) {
315                         write_buf(out, (char*)outbuf, outpos);
316                         bytes_out += (off_t)outpos;
317                     }
318                     gzip_error (to_stdout
319                                 ? "corrupt input."
320                                 : "corrupt input. Use zcat to recover some data.");
321                 }
322                 *--stackp = (char_type)finchar;
323                 code = oldcode;
324             }
325
326             while ((cmp_code_int)code >= (cmp_code_int)256) {
327                 /* Generate output characters in reverse order */
328                 *--stackp = tab_suffixof(code);
329                 code = tab_prefixof(code);
330             }
331             *--stackp = (char_type)(finchar = tab_suffixof(code));
332
333             /* And put them out in forward order */
334             {
335                 REG1 int        i;
336
337                 if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) {
338                     do {
339                         if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos;
340
341                         if (i > 0) {
342                             memcpy(outbuf+outpos, stackp, i);
343                             outpos += i;
344                         }
345                         if (outpos >= OUTBUFSIZ) {
346                             if (!test) {
347                                 write_buf(out, (char*)outbuf, outpos);
348                                 bytes_out += (off_t)outpos;
349                             }
350                             outpos = 0;
351                         }
352                         stackp+= i;
353                     } while ((i = (de_stack-stackp)) > 0);
354                 } else {
355                     memcpy(outbuf+outpos, stackp, i);
356                     outpos += i;
357                 }
358             }
359
360             if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
361
362                 tab_prefixof(code) = (unsigned short)oldcode;
363                 tab_suffixof(code) = (char_type)finchar;
364                 free_ent = code+1;
365             }
366             oldcode = incode;   /* Remember previous code.      */
367         }
368     } while (rsize != 0);
369
370     if (!test && outpos > 0) {
371         write_buf(out, (char*)outbuf, outpos);
372         bytes_out += (off_t)outpos;
373     }
374     return OK;
375 }