xref: /freebsd-src/usr.bin/gzip/zuncompress.c (revision 42b388439bd3795e09258c57a74ce9eec3651c7b)
1f13a03d8SXin LI /*	$NetBSD: zuncompress.c,v 1.11 2011/08/16 13:55:02 joerg Exp $ */
29a9ea25fSXin LI 
39a9ea25fSXin LI /*-
48a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
58a16b7a1SPedro F. Giffuni  *
69a9ea25fSXin LI  * Copyright (c) 1985, 1986, 1992, 1993
79a9ea25fSXin LI  *	The Regents of the University of California.  All rights reserved.
89a9ea25fSXin LI  *
99a9ea25fSXin LI  * This code is derived from software contributed to Berkeley by
109a9ea25fSXin LI  * Diomidis Spinellis and James A. Woods, derived from original
119a9ea25fSXin LI  * work by Spencer Thomas and Joseph Orost.
129a9ea25fSXin LI  *
139a9ea25fSXin LI  * Redistribution and use in source and binary forms, with or without
149a9ea25fSXin LI  * modification, are permitted provided that the following conditions
159a9ea25fSXin LI  * are met:
169a9ea25fSXin LI  * 1. Redistributions of source code must retain the above copyright
179a9ea25fSXin LI  *    notice, this list of conditions and the following disclaimer.
189a9ea25fSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
199a9ea25fSXin LI  *    notice, this list of conditions and the following disclaimer in the
209a9ea25fSXin LI  *    documentation and/or other materials provided with the distribution.
219a9ea25fSXin LI  * 3. Neither the name of the University nor the names of its contributors
229a9ea25fSXin LI  *    may be used to endorse or promote products derived from this software
239a9ea25fSXin LI  *    without specific prior written permission.
249a9ea25fSXin LI  *
259a9ea25fSXin LI  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
269a9ea25fSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
279a9ea25fSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
289a9ea25fSXin LI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
299a9ea25fSXin LI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
309a9ea25fSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
319a9ea25fSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
329a9ea25fSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
339a9ea25fSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
349a9ea25fSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
359a9ea25fSXin LI  * SUCH DAMAGE.
369a9ea25fSXin LI  *
379a9ea25fSXin LI  * from: NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp
389a9ea25fSXin LI  */
399a9ea25fSXin LI 
409a9ea25fSXin LI /* This file is #included by gzip.c */
419a9ea25fSXin LI 
429a9ea25fSXin LI static int	zread(void *, char *, int);
439a9ea25fSXin LI 
449a9ea25fSXin LI #define	tab_prefixof(i)	(zs->zs_codetab[i])
459a9ea25fSXin LI #define	tab_suffixof(i)	((char_type *)(zs->zs_htab))[i]
469a9ea25fSXin LI #define	de_stack	((char_type *)&tab_suffixof(1 << BITS))
479a9ea25fSXin LI 
489a9ea25fSXin LI #define BITS		16		/* Default bits. */
499a9ea25fSXin LI #define HSIZE		69001		/* 95% occupancy */ /* XXX may not need HSIZE */
509a9ea25fSXin LI #define BIT_MASK	0x1f		/* Defines for third byte of header. */
519a9ea25fSXin LI #define BLOCK_MASK	0x80
529a9ea25fSXin LI #define CHECK_GAP	10000		/* Ratio check interval. */
539a9ea25fSXin LI #define BUFSIZE		(64 * 1024)
549a9ea25fSXin LI 
559a9ea25fSXin LI /*
569a9ea25fSXin LI  * Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
579a9ea25fSXin LI  * a fourth header byte (for expansion).
589a9ea25fSXin LI  */
599a9ea25fSXin LI #define INIT_BITS	9	/* Initial number of bits/code. */
609a9ea25fSXin LI 
619a9ea25fSXin LI /*
629a9ea25fSXin LI  * the next two codes should not be changed lightly, as they must not
639a9ea25fSXin LI  * lie within the contiguous general code space.
649a9ea25fSXin LI  */
659a9ea25fSXin LI #define	FIRST	257		/* First free entry. */
669a9ea25fSXin LI #define	CLEAR	256		/* Table clear output code. */
679a9ea25fSXin LI 
689a9ea25fSXin LI 
699a9ea25fSXin LI #define MAXCODE(n_bits)	((1 << (n_bits)) - 1)
709a9ea25fSXin LI 
719a9ea25fSXin LI typedef long	code_int;
729a9ea25fSXin LI typedef long	count_int;
739a9ea25fSXin LI typedef u_char	char_type;
749a9ea25fSXin LI 
759a9ea25fSXin LI static char_type magic_header[] =
769a9ea25fSXin LI 	{'\037', '\235'};	/* 1F 9D */
779a9ea25fSXin LI 
789a9ea25fSXin LI static char_type rmask[9] =
799a9ea25fSXin LI 	{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
809a9ea25fSXin LI 
81bf70beceSEd Schouten static off_t total_compressed_bytes;
82bf70beceSEd Schouten static size_t compressed_prelen;
83bf70beceSEd Schouten static char *compressed_pre;
849a9ea25fSXin LI 
859a9ea25fSXin LI struct s_zstate {
869a9ea25fSXin LI 	FILE *zs_fp;			/* File stream for I/O */
879a9ea25fSXin LI 	char zs_mode;			/* r or w */
889a9ea25fSXin LI 	enum {
899a9ea25fSXin LI 		S_START, S_MIDDLE, S_EOF
909a9ea25fSXin LI 	} zs_state;			/* State of computation */
919a9ea25fSXin LI 	int zs_n_bits;			/* Number of bits/code. */
929a9ea25fSXin LI 	int zs_maxbits;			/* User settable max # bits/code. */
939a9ea25fSXin LI 	code_int zs_maxcode;		/* Maximum code, given n_bits. */
949a9ea25fSXin LI 	code_int zs_maxmaxcode;		/* Should NEVER generate this code. */
959a9ea25fSXin LI 	count_int zs_htab [HSIZE];
969a9ea25fSXin LI 	u_short zs_codetab [HSIZE];
979a9ea25fSXin LI 	code_int zs_hsize;		/* For dynamic table sizing. */
989a9ea25fSXin LI 	code_int zs_free_ent;		/* First unused entry. */
999a9ea25fSXin LI 	/*
1009a9ea25fSXin LI 	 * Block compression parameters -- after all codes are used up,
1019a9ea25fSXin LI 	 * and compression rate changes, start over.
1029a9ea25fSXin LI 	 */
1039a9ea25fSXin LI 	int zs_block_compress;
1049a9ea25fSXin LI 	int zs_clear_flg;
1059a9ea25fSXin LI 	long zs_ratio;
1069a9ea25fSXin LI 	count_int zs_checkpoint;
1079a9ea25fSXin LI 	int zs_offset;
1089a9ea25fSXin LI 	long zs_in_count;		/* Length of input. */
1099a9ea25fSXin LI 	long zs_bytes_out;		/* Length of compressed output. */
1109a9ea25fSXin LI 	long zs_out_count;		/* # of codes output (for debugging). */
1119a9ea25fSXin LI 	char_type zs_buf[BITS];
1129a9ea25fSXin LI 	union {
1139a9ea25fSXin LI 		struct {
1149a9ea25fSXin LI 			long zs_fcode;
1159a9ea25fSXin LI 			code_int zs_ent;
1169a9ea25fSXin LI 			code_int zs_hsize_reg;
1179a9ea25fSXin LI 			int zs_hshift;
118c4fadc2bSBenedict Reuschling 		} w;			/* Write parameters */
1199a9ea25fSXin LI 		struct {
1209a9ea25fSXin LI 			char_type *zs_stackp;
1219a9ea25fSXin LI 			int zs_finchar;
1229a9ea25fSXin LI 			code_int zs_code, zs_oldcode, zs_incode;
1239a9ea25fSXin LI 			int zs_roffset, zs_size;
1249a9ea25fSXin LI 			char_type zs_gbuf[BITS];
1259a9ea25fSXin LI 		} r;			/* Read parameters */
1269a9ea25fSXin LI 	} u;
1279a9ea25fSXin LI };
1289a9ea25fSXin LI 
1299a9ea25fSXin LI static code_int	getcode(struct s_zstate *zs);
1309a9ea25fSXin LI 
1319a9ea25fSXin LI static off_t
zuncompress(FILE * in,FILE * out,char * pre,size_t prelen,off_t * compressed_bytes)1329a9ea25fSXin LI zuncompress(FILE *in, FILE *out, char *pre, size_t prelen,
1339a9ea25fSXin LI 	    off_t *compressed_bytes)
1349a9ea25fSXin LI {
1359a9ea25fSXin LI 	off_t bin, bout = 0;
1369a9ea25fSXin LI 	char *buf;
1379a9ea25fSXin LI 
1389a9ea25fSXin LI 	buf = malloc(BUFSIZE);
1399a9ea25fSXin LI 	if (buf == NULL)
1409a9ea25fSXin LI 		return -1;
1419a9ea25fSXin LI 
1429a9ea25fSXin LI 	/* XXX */
1439a9ea25fSXin LI 	compressed_prelen = prelen;
1449a9ea25fSXin LI 	if (prelen != 0)
1459a9ea25fSXin LI 		compressed_pre = pre;
1469a9ea25fSXin LI 	else
1479a9ea25fSXin LI 		compressed_pre = NULL;
1489a9ea25fSXin LI 
14960e56555SXin LI 	while ((bin = fread(buf, 1, BUFSIZE, in)) != 0) {
150b47ed83dSXin LI 		if (tflag == 0 && (off_t)fwrite(buf, 1, bin, out) != bin) {
1519a9ea25fSXin LI 			free(buf);
1529a9ea25fSXin LI 			return -1;
1539a9ea25fSXin LI 		}
1549a9ea25fSXin LI 		bout += bin;
1559a9ea25fSXin LI 	}
1569a9ea25fSXin LI 
1579a9ea25fSXin LI 	if (compressed_bytes)
1589a9ea25fSXin LI 		*compressed_bytes = total_compressed_bytes;
1599a9ea25fSXin LI 
1609a9ea25fSXin LI 	free(buf);
1619a9ea25fSXin LI 	return bout;
1629a9ea25fSXin LI }
1639a9ea25fSXin LI 
1649a9ea25fSXin LI static int
zclose(void * zs)1659a9ea25fSXin LI zclose(void *zs)
1669a9ea25fSXin LI {
1679a9ea25fSXin LI 	free(zs);
1689a9ea25fSXin LI 	/* We leave the caller to close the fd passed to zdopen() */
1699a9ea25fSXin LI 	return 0;
1709a9ea25fSXin LI }
1719a9ea25fSXin LI 
1729a9ea25fSXin LI FILE *
zdopen(int fd)1739a9ea25fSXin LI zdopen(int fd)
1749a9ea25fSXin LI {
1759a9ea25fSXin LI 	struct s_zstate *zs;
1769a9ea25fSXin LI 
1779a9ea25fSXin LI 	if ((zs = calloc(1, sizeof(struct s_zstate))) == NULL)
1789a9ea25fSXin LI 		return (NULL);
1799a9ea25fSXin LI 
1809a9ea25fSXin LI 	zs->zs_state = S_START;
1819a9ea25fSXin LI 
1829a9ea25fSXin LI 	/* XXX we can get rid of some of these */
1839a9ea25fSXin LI 	zs->zs_hsize = HSIZE;			/* For dynamic table sizing. */
1849a9ea25fSXin LI 	zs->zs_free_ent = 0;			/* First unused entry. */
1859a9ea25fSXin LI 	zs->zs_block_compress = BLOCK_MASK;
1869a9ea25fSXin LI 	zs->zs_clear_flg = 0;			/* XXX we calloc()'d this structure why = 0? */
1879a9ea25fSXin LI 	zs->zs_ratio = 0;
1889a9ea25fSXin LI 	zs->zs_checkpoint = CHECK_GAP;
1899a9ea25fSXin LI 	zs->zs_in_count = 1;			/* Length of input. */
1909a9ea25fSXin LI 	zs->zs_out_count = 0;			/* # of codes output (for debugging). */
1919a9ea25fSXin LI 	zs->u.r.zs_roffset = 0;
1929a9ea25fSXin LI 	zs->u.r.zs_size = 0;
1939a9ea25fSXin LI 
1949a9ea25fSXin LI 	/*
1959a9ea25fSXin LI 	 * Layering compress on top of stdio in order to provide buffering,
1969a9ea25fSXin LI 	 * and ensure that reads and write work with the data specified.
1979a9ea25fSXin LI 	 */
1989a9ea25fSXin LI 	if ((zs->zs_fp = fdopen(fd, "r")) == NULL) {
1999a9ea25fSXin LI 		free(zs);
2009a9ea25fSXin LI 		return NULL;
2019a9ea25fSXin LI 	}
2029a9ea25fSXin LI 
2039a9ea25fSXin LI 	return funopen(zs, zread, NULL, NULL, zclose);
2049a9ea25fSXin LI }
2059a9ea25fSXin LI 
2069a9ea25fSXin LI /*
2079a9ea25fSXin LI  * Decompress read.  This routine adapts to the codes in the file building
2089a9ea25fSXin LI  * the "string" table on-the-fly; requiring no table to be stored in the
2099a9ea25fSXin LI  * compressed file.  The tables used herein are shared with those of the
2109a9ea25fSXin LI  * compress() routine.  See the definitions above.
2119a9ea25fSXin LI  */
2129a9ea25fSXin LI static int
zread(void * cookie,char * rbp,int num)2139a9ea25fSXin LI zread(void *cookie, char *rbp, int num)
2149a9ea25fSXin LI {
2159a9ea25fSXin LI 	u_int count, i;
2169a9ea25fSXin LI 	struct s_zstate *zs;
2179a9ea25fSXin LI 	u_char *bp, header[3];
2189a9ea25fSXin LI 
2199a9ea25fSXin LI 	if (num == 0)
2209a9ea25fSXin LI 		return (0);
2219a9ea25fSXin LI 
2229a9ea25fSXin LI 	zs = cookie;
2239a9ea25fSXin LI 	count = num;
2249a9ea25fSXin LI 	bp = (u_char *)rbp;
2259a9ea25fSXin LI 	switch (zs->zs_state) {
2269a9ea25fSXin LI 	case S_START:
2279a9ea25fSXin LI 		zs->zs_state = S_MIDDLE;
2289a9ea25fSXin LI 		break;
2299a9ea25fSXin LI 	case S_MIDDLE:
2309a9ea25fSXin LI 		goto middle;
2319a9ea25fSXin LI 	case S_EOF:
2329a9ea25fSXin LI 		goto eof;
2339a9ea25fSXin LI 	}
2349a9ea25fSXin LI 
2359a9ea25fSXin LI 	/* Check the magic number */
2369a9ea25fSXin LI 	for (i = 0; i < 3 && compressed_prelen; i++, compressed_prelen--)
2379a9ea25fSXin LI 		header[i] = *compressed_pre++;
2389a9ea25fSXin LI 
2399a9ea25fSXin LI 	if (fread(header + i, 1, sizeof(header) - i, zs->zs_fp) !=
2409a9ea25fSXin LI 		  sizeof(header) - i ||
2419a9ea25fSXin LI 	    memcmp(header, magic_header, sizeof(magic_header)) != 0) {
2429a9ea25fSXin LI 		errno = EFTYPE;
2439a9ea25fSXin LI 		return (-1);
2449a9ea25fSXin LI 	}
2459a9ea25fSXin LI 	total_compressed_bytes = 0;
2469a9ea25fSXin LI 	zs->zs_maxbits = header[2];	/* Set -b from file. */
2479a9ea25fSXin LI 	zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK;
2489a9ea25fSXin LI 	zs->zs_maxbits &= BIT_MASK;
2499a9ea25fSXin LI 	zs->zs_maxmaxcode = 1L << zs->zs_maxbits;
250a06534c3SBjoern A. Zeeb 	if (zs->zs_maxbits > BITS || zs->zs_maxbits < 12) {
2519a9ea25fSXin LI 		errno = EFTYPE;
2529a9ea25fSXin LI 		return (-1);
2539a9ea25fSXin LI 	}
2549a9ea25fSXin LI 	/* As above, initialize the first 256 entries in the table. */
2559a9ea25fSXin LI 	zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS);
2569a9ea25fSXin LI 	for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; zs->u.r.zs_code--) {
2579a9ea25fSXin LI 		tab_prefixof(zs->u.r.zs_code) = 0;
2589a9ea25fSXin LI 		tab_suffixof(zs->u.r.zs_code) = (char_type) zs->u.r.zs_code;
2599a9ea25fSXin LI 	}
2609a9ea25fSXin LI 	zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256;
2619a9ea25fSXin LI 
262a06534c3SBjoern A. Zeeb 	zs->u.r.zs_oldcode = -1;
2639a9ea25fSXin LI 	zs->u.r.zs_stackp = de_stack;
2649a9ea25fSXin LI 
2659a9ea25fSXin LI 	while ((zs->u.r.zs_code = getcode(zs)) > -1) {
2669a9ea25fSXin LI 
2679a9ea25fSXin LI 		if ((zs->u.r.zs_code == CLEAR) && zs->zs_block_compress) {
2689a9ea25fSXin LI 			for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0;
2699a9ea25fSXin LI 			    zs->u.r.zs_code--)
2709a9ea25fSXin LI 				tab_prefixof(zs->u.r.zs_code) = 0;
2719a9ea25fSXin LI 			zs->zs_clear_flg = 1;
272a06534c3SBjoern A. Zeeb 			zs->zs_free_ent = FIRST;
273a06534c3SBjoern A. Zeeb 			zs->u.r.zs_oldcode = -1;
274a06534c3SBjoern A. Zeeb 			continue;
2759a9ea25fSXin LI 		}
2769a9ea25fSXin LI 		zs->u.r.zs_incode = zs->u.r.zs_code;
2779a9ea25fSXin LI 
2789a9ea25fSXin LI 		/* Special case for KwKwK string. */
2799a9ea25fSXin LI 		if (zs->u.r.zs_code >= zs->zs_free_ent) {
280a06534c3SBjoern A. Zeeb 			if (zs->u.r.zs_code > zs->zs_free_ent ||
281a06534c3SBjoern A. Zeeb 			    zs->u.r.zs_oldcode == -1) {
282a06534c3SBjoern A. Zeeb 				/* Bad stream. */
283*216f72f1SXin LI 				errno = EFTYPE;
284a06534c3SBjoern A. Zeeb 				return (-1);
285a06534c3SBjoern A. Zeeb 			}
2869a9ea25fSXin LI 			*zs->u.r.zs_stackp++ = zs->u.r.zs_finchar;
2879a9ea25fSXin LI 			zs->u.r.zs_code = zs->u.r.zs_oldcode;
2889a9ea25fSXin LI 		}
289a06534c3SBjoern A. Zeeb 		/*
290a06534c3SBjoern A. Zeeb 		 * The above condition ensures that code < free_ent.
291a06534c3SBjoern A. Zeeb 		 * The construction of tab_prefixof in turn guarantees that
292a06534c3SBjoern A. Zeeb 		 * each iteration decreases code and therefore stack usage is
293a06534c3SBjoern A. Zeeb 		 * bound by 1 << BITS - 256.
294a06534c3SBjoern A. Zeeb 		 */
2959a9ea25fSXin LI 
2969a9ea25fSXin LI 		/* Generate output characters in reverse order. */
2979a9ea25fSXin LI 		while (zs->u.r.zs_code >= 256) {
2989a9ea25fSXin LI 			*zs->u.r.zs_stackp++ = tab_suffixof(zs->u.r.zs_code);
2999a9ea25fSXin LI 			zs->u.r.zs_code = tab_prefixof(zs->u.r.zs_code);
3009a9ea25fSXin LI 		}
3019a9ea25fSXin LI 		*zs->u.r.zs_stackp++ = zs->u.r.zs_finchar = tab_suffixof(zs->u.r.zs_code);
3029a9ea25fSXin LI 
3039a9ea25fSXin LI 		/* And put them out in forward order.  */
3049a9ea25fSXin LI middle:		do {
3059a9ea25fSXin LI 			if (count-- == 0)
3069a9ea25fSXin LI 				return (num);
3079a9ea25fSXin LI 			*bp++ = *--zs->u.r.zs_stackp;
3089a9ea25fSXin LI 		} while (zs->u.r.zs_stackp > de_stack);
3099a9ea25fSXin LI 
3109a9ea25fSXin LI 		/* Generate the new entry. */
311a06534c3SBjoern A. Zeeb 		if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode &&
312a06534c3SBjoern A. Zeeb 		    zs->u.r.zs_oldcode != -1) {
3139a9ea25fSXin LI 			tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode;
3149a9ea25fSXin LI 			tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar;
3159a9ea25fSXin LI 			zs->zs_free_ent = zs->u.r.zs_code + 1;
3169a9ea25fSXin LI 		}
3179a9ea25fSXin LI 
3189a9ea25fSXin LI 		/* Remember previous code. */
3199a9ea25fSXin LI 		zs->u.r.zs_oldcode = zs->u.r.zs_incode;
3209a9ea25fSXin LI 	}
3219a9ea25fSXin LI 	zs->zs_state = S_EOF;
3229a9ea25fSXin LI eof:	return (num - count);
3239a9ea25fSXin LI }
3249a9ea25fSXin LI 
3259a9ea25fSXin LI /*-
3269a9ea25fSXin LI  * Read one code from the standard input.  If EOF, return -1.
3279a9ea25fSXin LI  * Inputs:
3289a9ea25fSXin LI  * 	stdin
3299a9ea25fSXin LI  * Outputs:
3309a9ea25fSXin LI  * 	code or -1 is returned.
3319a9ea25fSXin LI  */
3329a9ea25fSXin LI static code_int
getcode(struct s_zstate * zs)3339a9ea25fSXin LI getcode(struct s_zstate *zs)
3349a9ea25fSXin LI {
3359a9ea25fSXin LI 	code_int gcode;
3369a9ea25fSXin LI 	int r_off, bits, i;
3379a9ea25fSXin LI 	char_type *bp;
3389a9ea25fSXin LI 
3399a9ea25fSXin LI 	bp = zs->u.r.zs_gbuf;
3409a9ea25fSXin LI 	if (zs->zs_clear_flg > 0 || zs->u.r.zs_roffset >= zs->u.r.zs_size ||
3419a9ea25fSXin LI 	    zs->zs_free_ent > zs->zs_maxcode) {
3429a9ea25fSXin LI 		/*
3439a9ea25fSXin LI 		 * If the next entry will be too big for the current gcode
3449a9ea25fSXin LI 		 * size, then we must increase the size.  This implies reading
3459a9ea25fSXin LI 		 * a new buffer full, too.
3469a9ea25fSXin LI 		 */
3479a9ea25fSXin LI 		if (zs->zs_free_ent > zs->zs_maxcode) {
3489a9ea25fSXin LI 			zs->zs_n_bits++;
3499a9ea25fSXin LI 			if (zs->zs_n_bits == zs->zs_maxbits)	/* Won't get any bigger now. */
3509a9ea25fSXin LI 				zs->zs_maxcode = zs->zs_maxmaxcode;
3519a9ea25fSXin LI 			else
3529a9ea25fSXin LI 				zs->zs_maxcode = MAXCODE(zs->zs_n_bits);
3539a9ea25fSXin LI 		}
3549a9ea25fSXin LI 		if (zs->zs_clear_flg > 0) {
3559a9ea25fSXin LI 			zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS);
3569a9ea25fSXin LI 			zs->zs_clear_flg = 0;
3579a9ea25fSXin LI 		}
3589a9ea25fSXin LI 		/* XXX */
3599a9ea25fSXin LI 		for (i = 0; i < zs->zs_n_bits && compressed_prelen; i++, compressed_prelen--)
3609a9ea25fSXin LI 			zs->u.r.zs_gbuf[i] = *compressed_pre++;
3619a9ea25fSXin LI 		zs->u.r.zs_size = fread(zs->u.r.zs_gbuf + i, 1, zs->zs_n_bits - i, zs->zs_fp);
3629a9ea25fSXin LI 		zs->u.r.zs_size += i;
3639a9ea25fSXin LI 		if (zs->u.r.zs_size <= 0)			/* End of file. */
3649a9ea25fSXin LI 			return (-1);
3659a9ea25fSXin LI 		zs->u.r.zs_roffset = 0;
3669a9ea25fSXin LI 
3679a9ea25fSXin LI 		total_compressed_bytes += zs->u.r.zs_size;
3689a9ea25fSXin LI 
3699a9ea25fSXin LI 		/* Round size down to integral number of codes. */
3709a9ea25fSXin LI 		zs->u.r.zs_size = (zs->u.r.zs_size << 3) - (zs->zs_n_bits - 1);
3719a9ea25fSXin LI 	}
3729a9ea25fSXin LI 	r_off = zs->u.r.zs_roffset;
3739a9ea25fSXin LI 	bits = zs->zs_n_bits;
3749a9ea25fSXin LI 
3759a9ea25fSXin LI 	/* Get to the first byte. */
3769a9ea25fSXin LI 	bp += (r_off >> 3);
3779a9ea25fSXin LI 	r_off &= 7;
3789a9ea25fSXin LI 
3799a9ea25fSXin LI 	/* Get first part (low order bits). */
3809a9ea25fSXin LI 	gcode = (*bp++ >> r_off);
3819a9ea25fSXin LI 	bits -= (8 - r_off);
3829a9ea25fSXin LI 	r_off = 8 - r_off;	/* Now, roffset into gcode word. */
3839a9ea25fSXin LI 
3849a9ea25fSXin LI 	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
3859a9ea25fSXin LI 	if (bits >= 8) {
3869a9ea25fSXin LI 		gcode |= *bp++ << r_off;
3879a9ea25fSXin LI 		r_off += 8;
3889a9ea25fSXin LI 		bits -= 8;
3899a9ea25fSXin LI 	}
3909a9ea25fSXin LI 
3919a9ea25fSXin LI 	/* High order bits. */
3929a9ea25fSXin LI 	gcode |= (*bp & rmask[bits]) << r_off;
3939a9ea25fSXin LI 	zs->u.r.zs_roffset += zs->zs_n_bits;
3949a9ea25fSXin LI 
3959a9ea25fSXin LI 	return (gcode);
3969a9ea25fSXin LI }
3979a9ea25fSXin LI 
398