netgraph.4: manlint and style nitpicking
[dragonfly.git] / usr.bin / compress / zopen.c
1 /*-
2  * Copyright (c) 1985, 1986, 1992, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Diomidis Spinellis and James A. Woods, derived from original
7  * work by Spencer Thomas and Joseph Orost.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#)zopen.c  8.1 (Berkeley) 6/27/93
34  * $FreeBSD: src/usr.bin/compress/zopen.c,v 1.5.6.1 2002/07/16 00:52:08 tjr Exp $
35  * $DragonFly: src/usr.bin/compress/zopen.c,v 1.3 2003/10/02 17:42:27 hmp Exp $
36  */
37
38 /*-
39  * fcompress.c - File compression ala IEEE Computer, June 1984.
40  *
41  * Compress authors:
42  *              Spencer W. Thomas       (decvax!utah-cs!thomas)
43  *              Jim McKie               (decvax!mcvax!jim)
44  *              Steve Davies            (decvax!vax135!petsd!peora!srd)
45  *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
46  *              James A. Woods          (decvax!ihnp4!ames!jaw)
47  *              Joe Orost               (decvax!vax135!petsd!joe)
48  *
49  * Cleaned up and converted to library returning I/O streams by
50  * Diomidis Spinellis <dds@doc.ic.ac.uk>.
51  *
52  * zopen(filename, mode, bits)
53  *      Returns a FILE * that can be used for read or write.  The modes
54  *      supported are only "r" and "w".  Seeking is not allowed.  On
55  *      reading the file is decompressed, on writing it is compressed.
56  *      The output is compatible with compress(1) with 16 bit tables.
57  *      Any file produced by compress(1) can be read.
58  */
59
60 #include <sys/param.h>
61 #include <sys/stat.h>
62
63 #include <ctype.h>
64 #include <errno.h>
65 #include <signal.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <unistd.h>
70 #include "zopen.h"
71
72 #define BITS            16              /* Default bits. */
73 #define HSIZE           69001           /* 95% occupancy */
74
75 /* A code_int must be able to hold 2**BITS values of type int, and also -1. */
76 typedef long code_int;
77 typedef long count_int;
78
79 typedef u_char char_type;
80 static char_type magic_header[] =
81         {'\037', '\235'};               /* 1F 9D */
82
83 #define BIT_MASK        0x1f            /* Defines for third byte of header. */
84 #define BLOCK_MASK      0x80
85
86 /*
87  * Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
88  * a fourth header byte (for expansion).
89  */
90 #define INIT_BITS 9                     /* Initial number of bits/code. */
91
92 #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
93
94 struct s_zstate {
95         FILE *zs_fp;                    /* File stream for I/O */
96         char zs_mode;                   /* r or w */
97         enum {
98                 S_START, S_MIDDLE, S_EOF
99         } zs_state;                     /* State of computation */
100         u_int zs_n_bits;                /* Number of bits/code. */
101         u_int zs_maxbits;               /* User settable max # bits/code. */
102         code_int zs_maxcode;            /* Maximum code, given n_bits. */
103         code_int zs_maxmaxcode;         /* Should NEVER generate this code. */
104         count_int zs_htab [HSIZE];
105         u_short zs_codetab [HSIZE];
106         code_int zs_hsize;              /* For dynamic table sizing. */
107         code_int zs_free_ent;           /* First unused entry. */
108         /*
109          * Block compression parameters -- after all codes are used up,
110          * and compression rate changes, start over.
111          */
112         int zs_block_compress;
113         int zs_clear_flg;
114         long zs_ratio;
115         count_int zs_checkpoint;
116         u_int zs_offset;
117         long zs_in_count;               /* Length of input. */
118         long zs_bytes_out;              /* Length of compressed output. */
119         long zs_out_count;              /* # of codes output (for debugging). */
120         char_type zs_buf[BITS];
121         union {
122                 struct {
123                         long zs_fcode;
124                         code_int zs_ent;
125                         code_int zs_hsize_reg;
126                         int zs_hshift;
127                 } w;                    /* Write paramenters */
128                 struct {
129                         char_type *zs_stackp;
130                         int zs_finchar;
131                         code_int zs_code, zs_oldcode, zs_incode;
132                         int zs_roffset, zs_size;
133                         char_type zs_gbuf[BITS];
134                 } r;                    /* Read parameters */
135         } u;
136 };
137
138 /* Definitions to retain old variable names */
139 #define fp              zs->zs_fp
140 #define zmode           zs->zs_mode
141 #define state           zs->zs_state
142 #define n_bits          zs->zs_n_bits
143 #define maxbits         zs->zs_maxbits
144 #define maxcode         zs->zs_maxcode
145 #define maxmaxcode      zs->zs_maxmaxcode
146 #define htab            zs->zs_htab
147 #define codetab         zs->zs_codetab
148 #define hsize           zs->zs_hsize
149 #define free_ent        zs->zs_free_ent
150 #define block_compress  zs->zs_block_compress
151 #define clear_flg       zs->zs_clear_flg
152 #define ratio           zs->zs_ratio
153 #define checkpoint      zs->zs_checkpoint
154 #define offset          zs->zs_offset
155 #define in_count        zs->zs_in_count
156 #define bytes_out       zs->zs_bytes_out
157 #define out_count       zs->zs_out_count
158 #define buf             zs->zs_buf
159 #define fcode           zs->u.w.zs_fcode
160 #define hsize_reg       zs->u.w.zs_hsize_reg
161 #define ent             zs->u.w.zs_ent
162 #define hshift          zs->u.w.zs_hshift
163 #define stackp          zs->u.r.zs_stackp
164 #define finchar         zs->u.r.zs_finchar
165 #define code            zs->u.r.zs_code
166 #define oldcode         zs->u.r.zs_oldcode
167 #define incode          zs->u.r.zs_incode
168 #define roffset         zs->u.r.zs_roffset
169 #define size            zs->u.r.zs_size
170 #define gbuf            zs->u.r.zs_gbuf
171
172 /*
173  * To save much memory, we overlay the table used by compress() with those
174  * used by decompress().  The tab_prefix table is the same size and type as
175  * the codetab.  The tab_suffix table needs 2**BITS characters.  We get this
176  * from the beginning of htab.  The output stack uses the rest of htab, and
177  * contains characters.  There is plenty of room for any possible stack
178  * (stack used to be 8000 characters).
179  */
180
181 #define htabof(i)       htab[i]
182 #define codetabof(i)    codetab[i]
183
184 #define tab_prefixof(i) codetabof(i)
185 #define tab_suffixof(i) ((char_type *)(htab))[i]
186 #define de_stack        ((char_type *)&tab_suffixof(1 << BITS))
187
188 #define CHECK_GAP 10000         /* Ratio check interval. */
189
190 /*
191  * the next two codes should not be changed lightly, as they must not
192  * lie within the contiguous general code space.
193  */
194 #define FIRST   257             /* First free entry. */
195 #define CLEAR   256             /* Table clear output code. */
196
197 static int      cl_block(struct s_zstate *);
198 static void     cl_hash(struct s_zstate *, count_int);
199 static code_int getcode(struct s_zstate *);
200 static int      output(struct s_zstate *, code_int);
201 static int      zclose(void *);
202 static int      zread(void *, char *, int);
203 static int      zwrite(void *, const char *, int);
204
205 /*-
206  * Algorithm from "A Technique for High Performance Data Compression",
207  * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
208  *
209  * Algorithm:
210  *      Modified Lempel-Ziv method (LZW).  Basically finds common
211  * substrings and replaces them with a variable size code.  This is
212  * deterministic, and can be done on the fly.  Thus, the decompression
213  * procedure needs no input table, but tracks the way the table was built.
214  */
215
216 /*-
217  * compress write
218  *
219  * Algorithm:  use open addressing double hashing (no chaining) on the
220  * prefix code / next character combination.  We do a variant of Knuth's
221  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
222  * secondary probe.  Here, the modular division first probe is gives way
223  * to a faster exclusive-or manipulation.  Also do block compression with
224  * an adaptive reset, whereby the code table is cleared when the compression
225  * ratio decreases, but after the table fills.  The variable-length output
226  * codes are re-sized at this point, and a special CLEAR code is generated
227  * for the decompressor.  Late addition:  construct the table according to
228  * file size for noticeable speed improvement on small files.  Please direct
229  * questions about this implementation to ames!jaw.
230  */
231 static int
232 zwrite(void *cookie, const char *wbp, int num)
233 {
234         code_int i;
235         int c, disp;
236         struct s_zstate *zs;
237         const u_char *bp;
238         u_char tmp;
239         int count;
240
241         if (num == 0)
242                 return (0);
243
244         zs = cookie;
245         count = num;
246         bp = wbp;
247         if (state == S_MIDDLE)
248                 goto middle;
249         state = S_MIDDLE;
250
251         maxmaxcode = 1L << maxbits;
252         if (fwrite(magic_header,
253             sizeof(char), sizeof(magic_header), fp) != sizeof(magic_header))
254                 return (-1);
255         tmp = (u_char)((maxbits) | block_compress);
256         if (fwrite(&tmp, sizeof(char), sizeof(tmp), fp) != sizeof(tmp))
257                 return (-1);
258
259         offset = 0;
260         bytes_out = 3;          /* Includes 3-byte header mojo. */
261         out_count = 0;
262         clear_flg = 0;
263         ratio = 0;
264         in_count = 1;
265         checkpoint = CHECK_GAP;
266         maxcode = MAXCODE(n_bits = INIT_BITS);
267         free_ent = ((block_compress) ? FIRST : 256);
268
269         ent = *bp++;
270         --count;
271
272         hshift = 0;
273         for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L)
274                 hshift++;
275         hshift = 8 - hshift;    /* Set hash code range bound. */
276
277         hsize_reg = hsize;
278         cl_hash(zs, (count_int)hsize_reg);      /* Clear hash table. */
279
280 middle: for (i = 0; count--;) {
281                 c = *bp++;
282                 in_count++;
283                 fcode = (long)(((long)c << maxbits) + ent);
284                 i = ((c << hshift) ^ ent);      /* Xor hashing. */
285
286                 if (htabof(i) == fcode) {
287                         ent = codetabof(i);
288                         continue;
289                 } else if ((long)htabof(i) < 0) /* Empty slot. */
290                         goto nomatch;
291                 disp = hsize_reg - i;   /* Secondary hash (after G. Knott). */
292                 if (i == 0)
293                         disp = 1;
294 probe:          if ((i -= disp) < 0)
295                         i += hsize_reg;
296
297                 if (htabof(i) == fcode) {
298                         ent = codetabof(i);
299                         continue;
300                 }
301                 if ((long)htabof(i) >= 0)
302                         goto probe;
303 nomatch:        if (output(zs, (code_int) ent) == -1)
304                         return (-1);
305                 out_count++;
306                 ent = c;
307                 if (free_ent < maxmaxcode) {
308                         codetabof(i) = free_ent++;      /* code -> hashtable */
309                         htabof(i) = fcode;
310                 } else if ((count_int)in_count >=
311                     checkpoint && block_compress) {
312                         if (cl_block(zs) == -1)
313                                 return (-1);
314                 }
315         }
316         return (num);
317 }
318
319 static int
320 zclose(void *cookie)
321 {
322         struct s_zstate *zs;
323         int rval;
324
325         zs = cookie;
326         if (zmode == 'w') {             /* Put out the final code. */
327                 if (output(zs, (code_int) ent) == -1) {
328                         (void)fclose(fp);
329                         free(zs);
330                         return (-1);
331                 }
332                 out_count++;
333                 if (output(zs, (code_int) - 1) == -1) {
334                         (void)fclose(fp);
335                         free(zs);
336                         return (-1);
337                 }
338         }
339         rval = fclose(fp) == EOF ? -1 : 0;
340         free(zs);
341         return (rval);
342 }
343
344 /*-
345  * Output the given code.
346  * Inputs:
347  *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
348  *              that n_bits =< (long)wordsize - 1.
349  * Outputs:
350  *      Outputs code to the file.
351  * Assumptions:
352  *      Chars are 8 bits long.
353  * Algorithm:
354  *      Maintain a BITS character long buffer (so that 8 codes will
355  * fit in it exactly).  Use the VAX insv instruction to insert each
356  * code in turn.  When the buffer fills up empty it and start over.
357  */
358
359 static char_type lmask[9] =
360         {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
361 static char_type rmask[9] =
362         {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
363
364 static int
365 output(struct s_zstate *zs, code_int ocode)
366 {
367         int r_off;
368         u_int bits;
369         char_type *bp;
370
371         r_off = offset;
372         bits = n_bits;
373         bp = buf;
374         if (ocode >= 0) {
375                 /* Get to the first byte. */
376                 bp += (r_off >> 3);
377                 r_off &= 7;
378                 /*
379                  * Since ocode is always >= 8 bits, only need to mask the first
380                  * hunk on the left.
381                  */
382                 *bp = (*bp & rmask[r_off]) | ((ocode << r_off) & lmask[r_off]);
383                 bp++;
384                 bits -= (8 - r_off);
385                 ocode >>= 8 - r_off;
386                 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
387                 if (bits >= 8) {
388                         *bp++ = ocode;
389                         ocode >>= 8;
390                         bits -= 8;
391                 }
392                 /* Last bits. */
393                 if (bits)
394                         *bp = ocode;
395                 offset += n_bits;
396                 if (offset == (n_bits << 3)) {
397                         bp = buf;
398                         bits = n_bits;
399                         bytes_out += bits;
400                         if (fwrite(bp, sizeof(char), bits, fp) != bits)
401                                 return (-1);
402                         bp += bits;
403                         bits = 0;
404                         offset = 0;
405                 }
406                 /*
407                  * If the next entry is going to be too big for the ocode size,
408                  * then increase it, if possible.
409                  */
410                 if (free_ent > maxcode || (clear_flg > 0)) {
411                        /*
412                         * Write the whole buffer, because the input side won't
413                         * discover the size increase until after it has read it.
414                         */
415                         if (offset > 0) {
416                                 if (fwrite(buf, 1, n_bits, fp) != n_bits)
417                                         return (-1);
418                                 bytes_out += n_bits;
419                         }
420                         offset = 0;
421
422                         if (clear_flg) {
423                                 maxcode = MAXCODE(n_bits = INIT_BITS);
424                                 clear_flg = 0;
425                         } else {
426                                 n_bits++;
427                                 if (n_bits == maxbits)
428                                         maxcode = maxmaxcode;
429                                 else
430                                         maxcode = MAXCODE(n_bits);
431                         }
432                 }
433         } else {
434                 /* At EOF, write the rest of the buffer. */
435                 if (offset > 0) {
436                         offset = (offset + 7) / 8;
437                         if (fwrite(buf, 1, offset, fp) != offset)
438                                 return (-1);
439                         bytes_out += offset;
440                 }
441                 offset = 0;
442         }
443         return (0);
444 }
445
446 /*
447  * Decompress read.  This routine adapts to the codes in the file building
448  * the "string" table on-the-fly; requiring no table to be stored in the
449  * compressed file.  The tables used herein are shared with those of the
450  * compress() routine.  See the definitions above.
451  */
452 static int
453 zread(void *cookie, char *rbp, int num)
454 {
455         u_int count;
456         struct s_zstate *zs;
457         u_char *bp, header[3];
458
459         if (num == 0)
460                 return (0);
461
462         zs = cookie;
463         count = num;
464         bp = (u_char *)rbp;
465         switch (state) {
466         case S_START:
467                 state = S_MIDDLE;
468                 break;
469         case S_MIDDLE:
470                 goto middle;
471         case S_EOF:
472                 goto eof;
473         }
474
475         /* Check the magic number */
476         if (fread(header,
477             sizeof(char), sizeof(header), fp) != sizeof(header) ||
478             memcmp(header, magic_header, sizeof(magic_header)) != 0) {
479                 errno = EFTYPE;
480                 return (-1);
481         }
482         maxbits = header[2];    /* Set -b from file. */
483         block_compress = maxbits & BLOCK_MASK;
484         maxbits &= BIT_MASK;
485         maxmaxcode = 1L << maxbits;
486         if (maxbits > BITS) {
487                 errno = EFTYPE;
488                 return (-1);
489         }
490         /* As above, initialize the first 256 entries in the table. */
491         maxcode = MAXCODE(n_bits = INIT_BITS);
492         for (code = 255; code >= 0; code--) {
493                 tab_prefixof(code) = 0;
494                 tab_suffixof(code) = (char_type) code;
495         }
496         free_ent = block_compress ? FIRST : 256;
497
498         finchar = oldcode = getcode(zs);
499         if (oldcode == -1)      /* EOF already? */
500                 return (0);     /* Get out of here */
501
502         /* First code must be 8 bits = char. */
503         *bp++ = (u_char)finchar;
504         count--;
505         stackp = de_stack;
506
507         while ((code = getcode(zs)) > -1) {
508
509                 if ((code == CLEAR) && block_compress) {
510                         for (code = 255; code >= 0; code--)
511                                 tab_prefixof(code) = 0;
512                         clear_flg = 1;
513                         free_ent = FIRST - 1;
514                         if ((code = getcode(zs)) == -1) /* O, untimely death! */
515                                 break;
516                 }
517                 incode = code;
518
519                 /* Special case for KwKwK string. */
520                 if (code >= free_ent) {
521                         *stackp++ = finchar;
522                         code = oldcode;
523                 }
524
525                 /* Generate output characters in reverse order. */
526                 while (code >= 256) {
527                         *stackp++ = tab_suffixof(code);
528                         code = tab_prefixof(code);
529                 }
530                 *stackp++ = finchar = tab_suffixof(code);
531
532                 /* And put them out in forward order.  */
533 middle:         do {
534                         if (count-- == 0)
535                                 return (num);
536                         *bp++ = *--stackp;
537                 } while (stackp > de_stack);
538
539                 /* Generate the new entry. */
540                 if ((code = free_ent) < maxmaxcode) {
541                         tab_prefixof(code) = (u_short) oldcode;
542                         tab_suffixof(code) = finchar;
543                         free_ent = code + 1;
544                 }
545
546                 /* Remember previous code. */
547                 oldcode = incode;
548         }
549         state = S_EOF;
550 eof:    return (num - count);
551 }
552
553 /*-
554  * Read one code from the standard input.  If EOF, return -1.
555  * Inputs:
556  *      stdin
557  * Outputs:
558  *      code or -1 is returned.
559  */
560 static code_int
561 getcode(struct s_zstate *zs)
562 {
563         code_int gcode;
564         int r_off, bits;
565         char_type *bp;
566
567         bp = gbuf;
568         if (clear_flg > 0 || roffset >= size || free_ent > maxcode) {
569                 /*
570                  * If the next entry will be too big for the current gcode
571                  * size, then we must increase the size.  This implies reading
572                  * a new buffer full, too.
573                  */
574                 if (free_ent > maxcode) {
575                         n_bits++;
576                         if (n_bits == maxbits)  /* Won't get any bigger now. */
577                                 maxcode = maxmaxcode;
578                         else
579                                 maxcode = MAXCODE(n_bits);
580                 }
581                 if (clear_flg > 0) {
582                         maxcode = MAXCODE(n_bits = INIT_BITS);
583                         clear_flg = 0;
584                 }
585                 size = fread(gbuf, 1, n_bits, fp);
586                 if (size <= 0)                  /* End of file. */
587                         return (-1);
588                 roffset = 0;
589                 /* Round size down to integral number of codes. */
590                 size = (size << 3) - (n_bits - 1);
591         }
592         r_off = roffset;
593         bits = n_bits;
594
595         /* Get to the first byte. */
596         bp += (r_off >> 3);
597         r_off &= 7;
598
599         /* Get first part (low order bits). */
600         gcode = (*bp++ >> r_off);
601         bits -= (8 - r_off);
602         r_off = 8 - r_off;      /* Now, roffset into gcode word. */
603
604         /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
605         if (bits >= 8) {
606                 gcode |= *bp++ << r_off;
607                 r_off += 8;
608                 bits -= 8;
609         }
610
611         /* High order bits. */
612         gcode |= (*bp & rmask[bits]) << r_off;
613         roffset += n_bits;
614
615         return (gcode);
616 }
617
618 static int
619 cl_block(struct s_zstate *zs)                   /* Table clear for block compress. */
620 {
621         long rat;
622
623         checkpoint = in_count + CHECK_GAP;
624
625         if (in_count > 0x007fffff) {    /* Shift will overflow. */
626                 rat = bytes_out >> 8;
627                 if (rat == 0)           /* Don't divide by zero. */
628                         rat = 0x7fffffff;
629                 else
630                         rat = in_count / rat;
631         } else
632                 rat = (in_count << 8) / bytes_out;      /* 8 fractional bits. */
633         if (rat > ratio)
634                 ratio = rat;
635         else {
636                 ratio = 0;
637                 cl_hash(zs, (count_int) hsize);
638                 free_ent = FIRST;
639                 clear_flg = 1;
640                 if (output(zs, (code_int) CLEAR) == -1)
641                         return (-1);
642         }
643         return (0);
644 }
645
646 static void
647 cl_hash(struct s_zstate *zs, count_int cl_hsize)                        /* Reset code table. */
648 {
649         count_int *htab_p;
650         long i, m1;
651
652         m1 = -1;
653         htab_p = htab + cl_hsize;
654         i = cl_hsize - 16;
655         do {                    /* Might use Sys V memset(3) here. */
656                 *(htab_p - 16) = m1;
657                 *(htab_p - 15) = m1;
658                 *(htab_p - 14) = m1;
659                 *(htab_p - 13) = m1;
660                 *(htab_p - 12) = m1;
661                 *(htab_p - 11) = m1;
662                 *(htab_p - 10) = m1;
663                 *(htab_p - 9) = m1;
664                 *(htab_p - 8) = m1;
665                 *(htab_p - 7) = m1;
666                 *(htab_p - 6) = m1;
667                 *(htab_p - 5) = m1;
668                 *(htab_p - 4) = m1;
669                 *(htab_p - 3) = m1;
670                 *(htab_p - 2) = m1;
671                 *(htab_p - 1) = m1;
672                 htab_p -= 16;
673         } while ((i -= 16) >= 0);
674         for (i += 16; i > 0; i--)
675                 *--htab_p = m1;
676 }
677
678 FILE *
679 zopen(const char *fname, const char *mode, int bits)
680 {
681         struct s_zstate *zs;
682
683         if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0' ||
684             bits < 0 || bits > BITS) {
685                 errno = EINVAL;
686                 return (NULL);
687         }
688
689         if ((zs = calloc(1, sizeof(struct s_zstate))) == NULL)
690                 return (NULL);
691
692         maxbits = bits ? bits : BITS;   /* User settable max # bits/code. */
693         maxmaxcode = 1L << maxbits;     /* Should NEVER generate this code. */
694         hsize = HSIZE;                  /* For dynamic table sizing. */
695         free_ent = 0;                   /* First unused entry. */
696         block_compress = BLOCK_MASK;
697         clear_flg = 0;
698         ratio = 0;
699         checkpoint = CHECK_GAP;
700         in_count = 1;                   /* Length of input. */
701         out_count = 0;                  /* # of codes output (for debugging). */
702         state = S_START;
703         roffset = 0;
704         size = 0;
705
706         /*
707          * Layering compress on top of stdio in order to provide buffering,
708          * and ensure that reads and write work with the data specified.
709          */
710         if ((fp = fopen(fname, mode)) == NULL) {
711                 free(zs);
712                 return (NULL);
713         }
714         switch (*mode) {
715         case 'r':
716                 zmode = 'r';
717                 return (funopen(zs, zread, NULL, NULL, zclose));
718         case 'w':
719                 zmode = 'w';
720                 return (funopen(zs, NULL, zwrite, NULL, zclose));
721         }
722         /* NOTREACHED */
723         return (NULL);
724 }