xref: /illumos-gate/usr/src/uts/common/io/ppp/spppcomp/zlib.c (revision 7c478bd95313f5f23a4c958a745db2134aa0324)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*
7*7c478bd9Sstevel@tonic-gate  * Updated from zlib-1.0.4 to zlib-1.1.3 by James Carlson.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * This file is derived from various .h and .c files from the zlib-1.0.4
10*7c478bd9Sstevel@tonic-gate  * distribution by Jean-loup Gailly and Mark Adler, with some additions
11*7c478bd9Sstevel@tonic-gate  * by Paul Mackerras to aid in implementing Deflate compression and
12*7c478bd9Sstevel@tonic-gate  * decompression for PPP packets.  See zlib.h for conditions of
13*7c478bd9Sstevel@tonic-gate  * distribution and use.
14*7c478bd9Sstevel@tonic-gate  *
15*7c478bd9Sstevel@tonic-gate  * Changes that have been made include:
16*7c478bd9Sstevel@tonic-gate  * - added Z_PACKET_FLUSH (see zlib.h for details)
17*7c478bd9Sstevel@tonic-gate  * - added inflateIncomp and deflateOutputPending
18*7c478bd9Sstevel@tonic-gate  * - allow strm->next_out to be NULL, meaning discard the output
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * $Id: zlib.c,v 1.11 1998/09/13 23:37:12 paulus Exp $
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate /*
26*7c478bd9Sstevel@tonic-gate  *  ==FILEVERSION 971210==
27*7c478bd9Sstevel@tonic-gate  *
28*7c478bd9Sstevel@tonic-gate  * This marker is used by the Linux installation script to determine
29*7c478bd9Sstevel@tonic-gate  * whether an up-to-date version of this file is already installed.
30*7c478bd9Sstevel@tonic-gate  */
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #define	NO_DUMMY_DECL
33*7c478bd9Sstevel@tonic-gate #define	NO_ZCFUNCS
34*7c478bd9Sstevel@tonic-gate #define	MY_ZCALLOC
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
37*7c478bd9Sstevel@tonic-gate #define	inflate	inflate_ppp	/* FreeBSD already has an inflate :-( */
38*7c478bd9Sstevel@tonic-gate #endif
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate /* +++ zutil.h */
42*7c478bd9Sstevel@tonic-gate /*
43*7c478bd9Sstevel@tonic-gate  *
44*7c478bd9Sstevel@tonic-gate  * zutil.h -- internal interface and configuration of the compression library
45*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Jean-loup Gailly.
46*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
47*7c478bd9Sstevel@tonic-gate  */
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate /*
50*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
51*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
52*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate /* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate #ifndef _Z_UTIL_H
58*7c478bd9Sstevel@tonic-gate #define	_Z_UTIL_H
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate #include "zlib.h"
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL)
63*7c478bd9Sstevel@tonic-gate /* Assume this is a *BSD or SVR4 kernel */
64*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
65*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
66*7c478bd9Sstevel@tonic-gate #include <sys/systm.h>
67*7c478bd9Sstevel@tonic-gate #ifdef SOL2
68*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
69*7c478bd9Sstevel@tonic-gate #endif
70*7c478bd9Sstevel@tonic-gate #undef u
71*7c478bd9Sstevel@tonic-gate #define	HAVE_MEMCPY
72*7c478bd9Sstevel@tonic-gate #define	memcmp		bcmp
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #else
75*7c478bd9Sstevel@tonic-gate #if defined(__KERNEL__)
76*7c478bd9Sstevel@tonic-gate /* Assume this is a Linux kernel */
77*7c478bd9Sstevel@tonic-gate #include <linux/string.h>
78*7c478bd9Sstevel@tonic-gate #define	HAVE_MEMCPY
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate #else /* not kernel */
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate #include <stddef.h>
83*7c478bd9Sstevel@tonic-gate #ifdef NO_ERRNO_H
84*7c478bd9Sstevel@tonic-gate extern int errno;
85*7c478bd9Sstevel@tonic-gate #else
86*7c478bd9Sstevel@tonic-gate #include <errno.h>
87*7c478bd9Sstevel@tonic-gate #endif
88*7c478bd9Sstevel@tonic-gate #ifdef STDC
89*7c478bd9Sstevel@tonic-gate #include <string.h>
90*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
91*7c478bd9Sstevel@tonic-gate #endif
92*7c478bd9Sstevel@tonic-gate #endif /* __KERNEL__ */
93*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL || KERNEL */
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate #ifndef local
96*7c478bd9Sstevel@tonic-gate #define	local static
97*7c478bd9Sstevel@tonic-gate #endif
98*7c478bd9Sstevel@tonic-gate /* compile with -Dlocal if your debugger can't find static symbols */
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate typedef unsigned char  uch;
101*7c478bd9Sstevel@tonic-gate typedef uch FAR uchf;
102*7c478bd9Sstevel@tonic-gate typedef unsigned short ush;
103*7c478bd9Sstevel@tonic-gate typedef ush FAR ushf;
104*7c478bd9Sstevel@tonic-gate typedef unsigned long  ulg;
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
107*7c478bd9Sstevel@tonic-gate /* (size given to avoid silly warnings with Visual C++) */
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate #define	ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate #define	ERR_RETURN(strm, err) \
112*7c478bd9Sstevel@tonic-gate 	return (strm->msg = ERR_MSG(err), (err))
113*7c478bd9Sstevel@tonic-gate /* To be used only when the state is known to be valid */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	/* common constants */
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate #ifndef DEF_WBITS
118*7c478bd9Sstevel@tonic-gate #define	DEF_WBITS MAX_WBITS
119*7c478bd9Sstevel@tonic-gate #endif
120*7c478bd9Sstevel@tonic-gate /* default windowBits for decompression. MAX_WBITS is for compression only */
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate #if MAX_MEM_LEVEL >= 8
123*7c478bd9Sstevel@tonic-gate #define	DEF_MEM_LEVEL 8
124*7c478bd9Sstevel@tonic-gate #else
125*7c478bd9Sstevel@tonic-gate #define	DEF_MEM_LEVEL  MAX_MEM_LEVEL
126*7c478bd9Sstevel@tonic-gate #endif
127*7c478bd9Sstevel@tonic-gate /* default memLevel */
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate #define	STORED_BLOCK 0
130*7c478bd9Sstevel@tonic-gate #define	STATIC_TREES 1
131*7c478bd9Sstevel@tonic-gate #define	DYN_TREES    2
132*7c478bd9Sstevel@tonic-gate /* The three kinds of block type */
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate #define	MIN_MATCH  3
135*7c478bd9Sstevel@tonic-gate #define	MAX_MATCH  258
136*7c478bd9Sstevel@tonic-gate /* The minimum and maximum match lengths */
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate #define	PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 	/* target dependencies */
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate #ifdef MSDOS
143*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x00
144*7c478bd9Sstevel@tonic-gate #ifdef __TURBOC__
145*7c478bd9Sstevel@tonic-gate #include <alloc.h>
146*7c478bd9Sstevel@tonic-gate #else /* MSC or DJGPP */
147*7c478bd9Sstevel@tonic-gate #include <malloc.h>
148*7c478bd9Sstevel@tonic-gate #endif
149*7c478bd9Sstevel@tonic-gate #endif
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate #ifdef OS2
152*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x06
153*7c478bd9Sstevel@tonic-gate #endif
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate #ifdef WIN32 /* Window 95 & Windows NT */
156*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x0b
157*7c478bd9Sstevel@tonic-gate #endif
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate #if defined(VAXC) || defined(VMS)
160*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x02
161*7c478bd9Sstevel@tonic-gate #define	F_OPEN(name, mode) \
162*7c478bd9Sstevel@tonic-gate 	fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
163*7c478bd9Sstevel@tonic-gate #endif
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate #ifdef AMIGA
166*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x01
167*7c478bd9Sstevel@tonic-gate #endif
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate #if defined(ATARI) || defined(atarist)
170*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x05
171*7c478bd9Sstevel@tonic-gate #endif
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate #ifdef MACOS
174*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x07
175*7c478bd9Sstevel@tonic-gate #endif
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate #ifdef __50SERIES /* Prime/PRIMOS */
178*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x0F
179*7c478bd9Sstevel@tonic-gate #endif
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate #ifdef TOPS20
182*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x0a
183*7c478bd9Sstevel@tonic-gate #endif
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate #if defined(_BEOS_) || defined(RISCOS)
186*7c478bd9Sstevel@tonic-gate #define	fdopen(fd, mode) NULL /* No fdopen() */
187*7c478bd9Sstevel@tonic-gate #endif
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 	/* Common defaults */
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate #ifndef OS_CODE
192*7c478bd9Sstevel@tonic-gate #define	OS_CODE  0x03  /* assume Unix */
193*7c478bd9Sstevel@tonic-gate #endif
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate #ifndef F_OPEN
196*7c478bd9Sstevel@tonic-gate #define	F_OPEN(name, mode) fopen((name), (mode))
197*7c478bd9Sstevel@tonic-gate #endif
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	/* functions */
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate #ifdef HAVE_STRERROR
202*7c478bd9Sstevel@tonic-gate extern char *strerror OF((int));
203*7c478bd9Sstevel@tonic-gate #define	zstrerror(errnum) strerror(errnum)
204*7c478bd9Sstevel@tonic-gate #else
205*7c478bd9Sstevel@tonic-gate #define	zstrerror(errnum) ""
206*7c478bd9Sstevel@tonic-gate #endif
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate #if defined(pyr)
209*7c478bd9Sstevel@tonic-gate #define	NO_MEMCPY
210*7c478bd9Sstevel@tonic-gate #endif
211*7c478bd9Sstevel@tonic-gate #if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER)
212*7c478bd9Sstevel@tonic-gate /*
213*7c478bd9Sstevel@tonic-gate  * Use our own functions for small and medium model with MSC <= 5.0.
214*7c478bd9Sstevel@tonic-gate  * You may have to use the same strategy for Borland C (untested).
215*7c478bd9Sstevel@tonic-gate  */
216*7c478bd9Sstevel@tonic-gate #define	NO_MEMCPY
217*7c478bd9Sstevel@tonic-gate #endif
218*7c478bd9Sstevel@tonic-gate #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
219*7c478bd9Sstevel@tonic-gate #define	HAVE_MEMCPY
220*7c478bd9Sstevel@tonic-gate #endif
221*7c478bd9Sstevel@tonic-gate #ifdef HAVE_MEMCPY
222*7c478bd9Sstevel@tonic-gate #ifdef SMALL_MEDIUM /* MSDOS small or medium model */
223*7c478bd9Sstevel@tonic-gate #define	zmemcpy _fmemcpy
224*7c478bd9Sstevel@tonic-gate #define	zmemcmp _fmemcmp
225*7c478bd9Sstevel@tonic-gate #define	zmemzero(dest, len) _fmemset(dest, 0, len)
226*7c478bd9Sstevel@tonic-gate #else
227*7c478bd9Sstevel@tonic-gate #define	zmemcpy (void) memcpy
228*7c478bd9Sstevel@tonic-gate #define	zmemcmp memcmp
229*7c478bd9Sstevel@tonic-gate #define	zmemzero(dest, len) (void) memset(dest, 0, len)
230*7c478bd9Sstevel@tonic-gate #endif
231*7c478bd9Sstevel@tonic-gate #else
232*7c478bd9Sstevel@tonic-gate extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
233*7c478bd9Sstevel@tonic-gate extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
234*7c478bd9Sstevel@tonic-gate extern void zmemzero OF((Bytef* dest, uInt len));
235*7c478bd9Sstevel@tonic-gate #endif
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate /* Diagnostic functions */
238*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
239*7c478bd9Sstevel@tonic-gate #include <stdio.h>
240*7c478bd9Sstevel@tonic-gate #ifndef verbose
241*7c478bd9Sstevel@tonic-gate #define	verbose 0
242*7c478bd9Sstevel@tonic-gate #endif
243*7c478bd9Sstevel@tonic-gate extern void z_error    OF((char *m));
244*7c478bd9Sstevel@tonic-gate #define	Assert(cond, msg) { if (!(cond)) z_error(msg); }
245*7c478bd9Sstevel@tonic-gate #define	Trace(x) {if (z_verbose >= 0) fprintf x; }
246*7c478bd9Sstevel@tonic-gate #define	Tracev(x) {if (z_verbose > 0) fprintf x; }
247*7c478bd9Sstevel@tonic-gate #define	Tracevv(x) {if (z_verbose > 1) fprintf x; }
248*7c478bd9Sstevel@tonic-gate #define	Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x; }
249*7c478bd9Sstevel@tonic-gate #define	Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x; }
250*7c478bd9Sstevel@tonic-gate #else
251*7c478bd9Sstevel@tonic-gate #if defined(SOL2) && defined(DEBUG)
252*7c478bd9Sstevel@tonic-gate #define	Assert(cond, msg)	((cond) ? ((void)0) : panic(msg))
253*7c478bd9Sstevel@tonic-gate #else
254*7c478bd9Sstevel@tonic-gate #define	Assert(cond, msg)	((void)0)
255*7c478bd9Sstevel@tonic-gate #endif
256*7c478bd9Sstevel@tonic-gate #define	Trace(x)	((void)0)
257*7c478bd9Sstevel@tonic-gate #define	Tracev(x)	((void)0)
258*7c478bd9Sstevel@tonic-gate #define	Tracevv(x)	((void)0)
259*7c478bd9Sstevel@tonic-gate #define	Tracec(c, x)	((void)0)
260*7c478bd9Sstevel@tonic-gate #define	Tracecv(c, x)	((void)0)
261*7c478bd9Sstevel@tonic-gate #endif
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate /* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
267*7c478bd9Sstevel@tonic-gate /* void   zcfree  OF((voidpf opaque, voidpf ptr)); */
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate #define	ZALLOC(strm, items, size) \
270*7c478bd9Sstevel@tonic-gate 	(*((strm)->zalloc))((strm)->opaque, (items), (size))
271*7c478bd9Sstevel@tonic-gate #define	ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
272*7c478bd9Sstevel@tonic-gate #define	TRY_FREE(s, p) {if (p) ZFREE(s, p); }
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate #endif /* _Z_UTIL_H */
275*7c478bd9Sstevel@tonic-gate /* --- zutil.h */
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate /* +++ deflate.h */
278*7c478bd9Sstevel@tonic-gate /*
279*7c478bd9Sstevel@tonic-gate  * deflate.h -- internal compression state
280*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Jean-loup Gailly
281*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
282*7c478bd9Sstevel@tonic-gate  */
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate /*
285*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
286*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
287*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
288*7c478bd9Sstevel@tonic-gate  */
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate /* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate #ifndef _DEFLATE_H
293*7c478bd9Sstevel@tonic-gate #define	_DEFLATE_H
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate /*
298*7c478bd9Sstevel@tonic-gate  * ===========================================================================
299*7c478bd9Sstevel@tonic-gate  * Internal compression state.
300*7c478bd9Sstevel@tonic-gate  */
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate #define	LENGTH_CODES 29
303*7c478bd9Sstevel@tonic-gate /* number of length codes, not counting the special END_BLOCK code */
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate #define	LITERALS  256
306*7c478bd9Sstevel@tonic-gate /* number of literal bytes 0..255 */
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate #define	L_CODES (LITERALS+1+LENGTH_CODES)
309*7c478bd9Sstevel@tonic-gate /* number of Literal or Length codes, including the END_BLOCK code */
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate #define	D_CODES   30
312*7c478bd9Sstevel@tonic-gate /* number of distance codes */
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate #define	BL_CODES  19
315*7c478bd9Sstevel@tonic-gate /* number of codes used to transfer the bit lengths */
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate #define	HEAP_SIZE (2*L_CODES+1)
318*7c478bd9Sstevel@tonic-gate /* maximum heap size */
319*7c478bd9Sstevel@tonic-gate 
320*7c478bd9Sstevel@tonic-gate #define	MAX_BITS 15
321*7c478bd9Sstevel@tonic-gate /* All codes must not exceed MAX_BITS bits */
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate #define	INIT_STATE    42
324*7c478bd9Sstevel@tonic-gate #define	BUSY_STATE   113
325*7c478bd9Sstevel@tonic-gate #define	FINISH_STATE 666
326*7c478bd9Sstevel@tonic-gate /* Stream status */
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate /* Data structure describing a single value and its code string. */
330*7c478bd9Sstevel@tonic-gate typedef struct ct_data_s {
331*7c478bd9Sstevel@tonic-gate 	union {
332*7c478bd9Sstevel@tonic-gate 		ush freq;	/* frequency count */
333*7c478bd9Sstevel@tonic-gate 		ush code;	/* bit string */
334*7c478bd9Sstevel@tonic-gate 	} fc;
335*7c478bd9Sstevel@tonic-gate 	union {
336*7c478bd9Sstevel@tonic-gate 		ush dad;	/* father node in Huffman tree */
337*7c478bd9Sstevel@tonic-gate 		ush len;	/* length of bit string */
338*7c478bd9Sstevel@tonic-gate 	} dl;
339*7c478bd9Sstevel@tonic-gate } FAR ct_data;
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate #define	Freq fc.freq
342*7c478bd9Sstevel@tonic-gate #define	Code fc.code
343*7c478bd9Sstevel@tonic-gate #define	Dad  dl.dad
344*7c478bd9Sstevel@tonic-gate #define	Len  dl.len
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate typedef struct static_tree_desc_s  static_tree_desc;
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate typedef struct tree_desc_s {
349*7c478bd9Sstevel@tonic-gate 	ct_data *dyn_tree;	/* the dynamic tree */
350*7c478bd9Sstevel@tonic-gate 	int	max_code;	/* largest code with non zero frequency */
351*7c478bd9Sstevel@tonic-gate 	static_tree_desc *stat_desc;	/* the corresponding static tree */
352*7c478bd9Sstevel@tonic-gate } FAR tree_desc;
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate typedef ush Pos;
355*7c478bd9Sstevel@tonic-gate typedef Pos FAR Posf;
356*7c478bd9Sstevel@tonic-gate typedef unsigned IPos;
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate /*
359*7c478bd9Sstevel@tonic-gate  * A Pos is an index in the character window. We use short instead of
360*7c478bd9Sstevel@tonic-gate  * int to save space in the various tables. IPos is used only for
361*7c478bd9Sstevel@tonic-gate  * parameter passing.
362*7c478bd9Sstevel@tonic-gate  */
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate typedef struct deflate_state {
365*7c478bd9Sstevel@tonic-gate 	z_streamp strm;	/* pointer back to this zlib stream */
366*7c478bd9Sstevel@tonic-gate 	int   status;	/* as the name implies */
367*7c478bd9Sstevel@tonic-gate 	Bytef *pending_buf;	/* output still pending */
368*7c478bd9Sstevel@tonic-gate 	ulg   pending_buf_size;	/* size of pending_buf */
369*7c478bd9Sstevel@tonic-gate 	Bytef *pending_out;	/* next pending byte to output to the stream */
370*7c478bd9Sstevel@tonic-gate 	int   pending;	/* nb of bytes in the pending buffer */
371*7c478bd9Sstevel@tonic-gate 	int   noheader;	/* suppress zlib header and adler32 */
372*7c478bd9Sstevel@tonic-gate 	Byte  data_type;	/* UNKNOWN, BINARY or ASCII */
373*7c478bd9Sstevel@tonic-gate 	Byte  method;	/* STORED (for zip only) or DEFLATED */
374*7c478bd9Sstevel@tonic-gate 	/* value of flush param for previous deflate call */
375*7c478bd9Sstevel@tonic-gate 	int   last_flush;
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 	/* used by deflate.c: */
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 	uInt  w_size;	/* LZ77 window size (32K by default) */
380*7c478bd9Sstevel@tonic-gate 	uInt  w_bits;	/* log2(w_size)  (8..16) */
381*7c478bd9Sstevel@tonic-gate 	uInt  w_mask;	/* w_size - 1 */
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 	Bytef *window;
384*7c478bd9Sstevel@tonic-gate 	/*
385*7c478bd9Sstevel@tonic-gate 	 * Sliding window. Input bytes are read into the second half
386*7c478bd9Sstevel@tonic-gate 	 * of the window, and move to the first half later to keep a
387*7c478bd9Sstevel@tonic-gate 	 * dictionary of at least wSize bytes. With this organization,
388*7c478bd9Sstevel@tonic-gate 	 * matches are limited to a distance of wSize-MAX_MATCH bytes,
389*7c478bd9Sstevel@tonic-gate 	 * but this ensures that IO is always performed with a length
390*7c478bd9Sstevel@tonic-gate 	 * multiple of the block size. Also, it limits the window size
391*7c478bd9Sstevel@tonic-gate 	 * to 64K, which is quite useful on MSDOS.  To do: use the
392*7c478bd9Sstevel@tonic-gate 	 * user input buffer as sliding window.
393*7c478bd9Sstevel@tonic-gate 	 */
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate 	ulg window_size;
396*7c478bd9Sstevel@tonic-gate 	/*
397*7c478bd9Sstevel@tonic-gate 	 * Actual size of window: 2*wSize, except when the user input
398*7c478bd9Sstevel@tonic-gate 	 * buffer is directly used as sliding window.
399*7c478bd9Sstevel@tonic-gate 	 */
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 	Posf *prev;
402*7c478bd9Sstevel@tonic-gate 	/*
403*7c478bd9Sstevel@tonic-gate 	 * Link to older string with same hash index. To limit the
404*7c478bd9Sstevel@tonic-gate 	 * size of this array to 64K, this link is maintained only for
405*7c478bd9Sstevel@tonic-gate 	 * the last 32K strings.  An index in this array is thus a
406*7c478bd9Sstevel@tonic-gate 	 * window index modulo 32K.
407*7c478bd9Sstevel@tonic-gate 	 */
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 	Posf *head;	/* Heads of the hash chains or NIL. */
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 	uInt  ins_h;	/* hash index of string to be inserted */
412*7c478bd9Sstevel@tonic-gate 	uInt  hash_size;	/* number of elements in hash table */
413*7c478bd9Sstevel@tonic-gate 	uInt  hash_bits;	/* log2(hash_size) */
414*7c478bd9Sstevel@tonic-gate 	uInt  hash_mask;	/* hash_size-1 */
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate 	uInt  hash_shift;
417*7c478bd9Sstevel@tonic-gate 	/*
418*7c478bd9Sstevel@tonic-gate 	 * Number of bits by which ins_h must be shifted at each input
419*7c478bd9Sstevel@tonic-gate 	 * step. It must be such that after MIN_MATCH steps, the
420*7c478bd9Sstevel@tonic-gate 	 * oldest byte no longer takes part in the hash key, that is:
421*7c478bd9Sstevel@tonic-gate 	 * hash_shift * MIN_MATCH >= hash_bits
422*7c478bd9Sstevel@tonic-gate 	 */
423*7c478bd9Sstevel@tonic-gate 
424*7c478bd9Sstevel@tonic-gate 	long block_start;
425*7c478bd9Sstevel@tonic-gate 	/*
426*7c478bd9Sstevel@tonic-gate 	 * Window position at the beginning of the current output
427*7c478bd9Sstevel@tonic-gate 	 * block. Gets negative when the window is moved backwards.
428*7c478bd9Sstevel@tonic-gate 	 */
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate 	uInt match_length;	/* length of best match */
431*7c478bd9Sstevel@tonic-gate 	IPos prev_match;	/* previous match */
432*7c478bd9Sstevel@tonic-gate 	int match_available;	/* set if previous match exists */
433*7c478bd9Sstevel@tonic-gate 	uInt strstart;	/* start of string to insert */
434*7c478bd9Sstevel@tonic-gate 	uInt match_start;	/* start of matching string */
435*7c478bd9Sstevel@tonic-gate 	uInt lookahead;	/* number of valid bytes ahead in window */
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	uInt prev_length;
438*7c478bd9Sstevel@tonic-gate 	/*
439*7c478bd9Sstevel@tonic-gate 	 * Length of the best match at previous step. Matches not
440*7c478bd9Sstevel@tonic-gate 	 * greater than this are discarded. This is used in the lazy
441*7c478bd9Sstevel@tonic-gate 	 * match evaluation.
442*7c478bd9Sstevel@tonic-gate 	 */
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 	uInt max_chain_length;
445*7c478bd9Sstevel@tonic-gate 	/*
446*7c478bd9Sstevel@tonic-gate 	 * To speed up deflation, hash chains are never searched
447*7c478bd9Sstevel@tonic-gate 	 * beyond *this length.  A higher limit improves compression
448*7c478bd9Sstevel@tonic-gate 	 * ratio but *degrades the speed.
449*7c478bd9Sstevel@tonic-gate 	 */
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 	uInt max_lazy_match;
452*7c478bd9Sstevel@tonic-gate 	/*
453*7c478bd9Sstevel@tonic-gate 	 * Attempt to find a better match only when the current match
454*7c478bd9Sstevel@tonic-gate 	 * is strictly smaller than this value. This mechanism is used
455*7c478bd9Sstevel@tonic-gate 	 * only for compression levels >= 4.
456*7c478bd9Sstevel@tonic-gate 	 */
457*7c478bd9Sstevel@tonic-gate #define	max_insert_length  max_lazy_match
458*7c478bd9Sstevel@tonic-gate 	/*
459*7c478bd9Sstevel@tonic-gate 	 * Insert new strings in the hash table only if the match
460*7c478bd9Sstevel@tonic-gate 	 * length is not greater than this length. This saves time but
461*7c478bd9Sstevel@tonic-gate 	 * degrades compression.  max_insert_length is used only for
462*7c478bd9Sstevel@tonic-gate 	 * compression levels <= 3.
463*7c478bd9Sstevel@tonic-gate 	 */
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 	int level;	/* compression level (1..9) */
466*7c478bd9Sstevel@tonic-gate 	int strategy;	/* favor or force Huffman coding */
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate 	uInt good_match;
469*7c478bd9Sstevel@tonic-gate 	/* Use a faster search when the previous match is longer than this */
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate 	int nice_match;	/* Stop searching when current match exceeds this */
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate 	/* used by trees.c: */
474*7c478bd9Sstevel@tonic-gate 	/* Didn't use ct_data typedef below to supress compiler warning */
475*7c478bd9Sstevel@tonic-gate 	struct ct_data_s dyn_ltree[HEAP_SIZE];	/* literal and length tree */
476*7c478bd9Sstevel@tonic-gate 	struct ct_data_s dyn_dtree[2*D_CODES+1];	/* distance tree */
477*7c478bd9Sstevel@tonic-gate 	/* Huffman tree for bit lengths */
478*7c478bd9Sstevel@tonic-gate 	struct ct_data_s bl_tree[2*BL_CODES+1];
479*7c478bd9Sstevel@tonic-gate 
480*7c478bd9Sstevel@tonic-gate 	struct tree_desc_s l_desc;	/* desc. for literal tree */
481*7c478bd9Sstevel@tonic-gate 	struct tree_desc_s d_desc;	/* desc. for distance tree */
482*7c478bd9Sstevel@tonic-gate 	struct tree_desc_s bl_desc;	/* desc. for bit length tree */
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 	ush bl_count[MAX_BITS+1];
485*7c478bd9Sstevel@tonic-gate 	/* number of codes at each bit length for an optimal tree */
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	int heap[2*L_CODES+1];	/* heap used to build the Huffman trees */
488*7c478bd9Sstevel@tonic-gate 	int heap_len;	/* number of elements in the heap */
489*7c478bd9Sstevel@tonic-gate 	int heap_max;	/* element of largest frequency */
490*7c478bd9Sstevel@tonic-gate 	/*
491*7c478bd9Sstevel@tonic-gate 	 * The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0]
492*7c478bd9Sstevel@tonic-gate 	 * is not used.  The same heap array is used to build all
493*7c478bd9Sstevel@tonic-gate 	 * trees.
494*7c478bd9Sstevel@tonic-gate 	 */
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	uch depth[2*L_CODES+1];
497*7c478bd9Sstevel@tonic-gate 	/*
498*7c478bd9Sstevel@tonic-gate 	 * Depth of each subtree used as tie breaker for trees of
499*7c478bd9Sstevel@tonic-gate 	 * equal frequency
500*7c478bd9Sstevel@tonic-gate 	 */
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate 	uchf *l_buf;	/* buffer for literals or lengths */
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	uInt lit_bufsize;
505*7c478bd9Sstevel@tonic-gate 	/*
506*7c478bd9Sstevel@tonic-gate 	 * Size of match buffer for literals/lengths.  There are 4
507*7c478bd9Sstevel@tonic-gate 	 * reasons for limiting lit_bufsize to 64K:
508*7c478bd9Sstevel@tonic-gate 	 *
509*7c478bd9Sstevel@tonic-gate 	 *   - frequencies can be kept in 16 bit counters
510*7c478bd9Sstevel@tonic-gate 	 *
511*7c478bd9Sstevel@tonic-gate 	 *   - if compression is not successful for the first block,
512*7c478bd9Sstevel@tonic-gate 	 *   all input data is still in the window so we can still
513*7c478bd9Sstevel@tonic-gate 	 *   emit a stored block even when input comes from standard
514*7c478bd9Sstevel@tonic-gate 	 *   input.  (This can also be done for all blocks if
515*7c478bd9Sstevel@tonic-gate 	 *   lit_bufsize is not greater than 32K.)
516*7c478bd9Sstevel@tonic-gate 	 *
517*7c478bd9Sstevel@tonic-gate 	 *   - if compression is not successful for a file smaller
518*7c478bd9Sstevel@tonic-gate 	 *   than 64K, we can even emit a stored file instead of a
519*7c478bd9Sstevel@tonic-gate 	 *   stored block (saving 5 bytes).  This is applicable only
520*7c478bd9Sstevel@tonic-gate 	 *   for zip (not gzip or zlib).
521*7c478bd9Sstevel@tonic-gate 	 *
522*7c478bd9Sstevel@tonic-gate 	 *   - creating new Huffman trees less frequently may not
523*7c478bd9Sstevel@tonic-gate 	 *   provide fast adaptation to changes in the input data
524*7c478bd9Sstevel@tonic-gate 	 *   statistics. (Take for example a binary file with poorly
525*7c478bd9Sstevel@tonic-gate 	 *   compressible code followed by a highly compressible
526*7c478bd9Sstevel@tonic-gate 	 *   string table.) Smaller buffer sizes give fast adaptation
527*7c478bd9Sstevel@tonic-gate 	 *   but have of course the overhead of transmitting trees
528*7c478bd9Sstevel@tonic-gate 	 *   more frequently.
529*7c478bd9Sstevel@tonic-gate 	 *
530*7c478bd9Sstevel@tonic-gate 	 *   - I can't count above 4
531*7c478bd9Sstevel@tonic-gate 	 */
532*7c478bd9Sstevel@tonic-gate 
533*7c478bd9Sstevel@tonic-gate 	uInt last_lit;	/* running index in l_buf */
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate 	ushf *d_buf;
536*7c478bd9Sstevel@tonic-gate 	/*
537*7c478bd9Sstevel@tonic-gate 	 * Buffer for distances. To simplify the code, d_buf and l_buf
538*7c478bd9Sstevel@tonic-gate 	 * have the same number of elements. To use different lengths,
539*7c478bd9Sstevel@tonic-gate 	 * an extra flag array would be necessary.
540*7c478bd9Sstevel@tonic-gate 	 */
541*7c478bd9Sstevel@tonic-gate 
542*7c478bd9Sstevel@tonic-gate 	ulg opt_len;	/* bit length of current block with optimal trees */
543*7c478bd9Sstevel@tonic-gate 	ulg static_len;	/* bit length of current block with static trees */
544*7c478bd9Sstevel@tonic-gate 	uInt matches;	/* number of string matches in current block */
545*7c478bd9Sstevel@tonic-gate 	int last_eob_len;	/* bit length of EOB code for last block */
546*7c478bd9Sstevel@tonic-gate 
547*7c478bd9Sstevel@tonic-gate 	ulg compressed_len;	/* total bit length of compressed file PPP */
548*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
549*7c478bd9Sstevel@tonic-gate 	ulg bits_sent;	/* bit length of the compressed data */
550*7c478bd9Sstevel@tonic-gate #endif
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate 	ush bi_buf;
553*7c478bd9Sstevel@tonic-gate 	/*
554*7c478bd9Sstevel@tonic-gate 	 * Output buffer. bits are inserted starting at the bottom
555*7c478bd9Sstevel@tonic-gate 	 * (least significant bits).
556*7c478bd9Sstevel@tonic-gate 	 */
557*7c478bd9Sstevel@tonic-gate 	int bi_valid;
558*7c478bd9Sstevel@tonic-gate 	/*
559*7c478bd9Sstevel@tonic-gate 	 * Number of valid bits in bi_buf.  All bits above the last
560*7c478bd9Sstevel@tonic-gate 	 * valid bit are always zero.
561*7c478bd9Sstevel@tonic-gate 	 */
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate } FAR deflate_state;
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate /*
566*7c478bd9Sstevel@tonic-gate  * Output a byte on the stream.  IN assertion: there is enough room in
567*7c478bd9Sstevel@tonic-gate  * pending_buf.
568*7c478bd9Sstevel@tonic-gate  */
569*7c478bd9Sstevel@tonic-gate #define	put_byte(s, c) {s->pending_buf[s->pending++] = (c); }
570*7c478bd9Sstevel@tonic-gate 
571*7c478bd9Sstevel@tonic-gate 
572*7c478bd9Sstevel@tonic-gate #define	MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
573*7c478bd9Sstevel@tonic-gate /*
574*7c478bd9Sstevel@tonic-gate  * Minimum amount of lookahead, except at the end of the input file.
575*7c478bd9Sstevel@tonic-gate  * See deflate.c for comments about the MIN_MATCH+1.
576*7c478bd9Sstevel@tonic-gate  */
577*7c478bd9Sstevel@tonic-gate 
578*7c478bd9Sstevel@tonic-gate #define	MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
579*7c478bd9Sstevel@tonic-gate /*
580*7c478bd9Sstevel@tonic-gate  * In order to simplify the code, particularly on 16 bit machines,
581*7c478bd9Sstevel@tonic-gate  * match distances are limited to MAX_DIST instead of WSIZE.
582*7c478bd9Sstevel@tonic-gate  */
583*7c478bd9Sstevel@tonic-gate 
584*7c478bd9Sstevel@tonic-gate 	/* in trees.c */
585*7c478bd9Sstevel@tonic-gate void _tr_init		OF((deflate_state *s));
586*7c478bd9Sstevel@tonic-gate int  _tr_tally		OF((deflate_state *s, unsigned dist, unsigned lc));
587*7c478bd9Sstevel@tonic-gate void  _tr_flush_block	OF((deflate_state *s, charf *buf, ulg stored_len,
588*7c478bd9Sstevel@tonic-gate     int eof));
589*7c478bd9Sstevel@tonic-gate void _tr_align		OF((deflate_state *s));
590*7c478bd9Sstevel@tonic-gate void _tr_stored_block	OF((deflate_state *s, charf *buf, ulg stored_len,
591*7c478bd9Sstevel@tonic-gate     int eof));
592*7c478bd9Sstevel@tonic-gate void _tr_stored_type_only OF((deflate_state *));	/* PPP */
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate #define	d_code(dist) \
595*7c478bd9Sstevel@tonic-gate 	((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
596*7c478bd9Sstevel@tonic-gate /*
597*7c478bd9Sstevel@tonic-gate  * Mapping from a distance to a distance code. dist is the distance - 1 and
598*7c478bd9Sstevel@tonic-gate  * must not have side effects. _dist_code[256] and _dist_code[257] are never
599*7c478bd9Sstevel@tonic-gate  * used.
600*7c478bd9Sstevel@tonic-gate  */
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate #ifndef DEBUG_ZLIB
603*7c478bd9Sstevel@tonic-gate /* Inline versions of _tr_tally for speed: */
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate local uch _length_code[];
606*7c478bd9Sstevel@tonic-gate local uch _dist_code[];
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate #define	_tr_tally_lit(s, c, flush) \
609*7c478bd9Sstevel@tonic-gate 	{	uch cc = (c); \
610*7c478bd9Sstevel@tonic-gate 		s->d_buf[s->last_lit] = 0; \
611*7c478bd9Sstevel@tonic-gate 		s->l_buf[s->last_lit++] = cc; \
612*7c478bd9Sstevel@tonic-gate 		s->dyn_ltree[cc].Freq++; \
613*7c478bd9Sstevel@tonic-gate 		flush = (s->last_lit == s->lit_bufsize-1); \
614*7c478bd9Sstevel@tonic-gate 	}
615*7c478bd9Sstevel@tonic-gate #define	_tr_tally_dist(s, distance, length, flush) \
616*7c478bd9Sstevel@tonic-gate 	{	uch len = (length); \
617*7c478bd9Sstevel@tonic-gate 		ush dist = (distance); \
618*7c478bd9Sstevel@tonic-gate 		s->d_buf[s->last_lit] = dist; \
619*7c478bd9Sstevel@tonic-gate 		s->l_buf[s->last_lit++] = len; \
620*7c478bd9Sstevel@tonic-gate 		dist--; \
621*7c478bd9Sstevel@tonic-gate 		s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
622*7c478bd9Sstevel@tonic-gate 		s->dyn_dtree[d_code(dist)].Freq++; \
623*7c478bd9Sstevel@tonic-gate 		flush = (s->last_lit == s->lit_bufsize-1); \
624*7c478bd9Sstevel@tonic-gate 	}
625*7c478bd9Sstevel@tonic-gate #else
626*7c478bd9Sstevel@tonic-gate #define	_tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
627*7c478bd9Sstevel@tonic-gate #define	_tr_tally_dist(s, distance, length, flush) \
628*7c478bd9Sstevel@tonic-gate 		flush = _tr_tally(s, distance, length)
629*7c478bd9Sstevel@tonic-gate #endif
630*7c478bd9Sstevel@tonic-gate 
631*7c478bd9Sstevel@tonic-gate #endif
632*7c478bd9Sstevel@tonic-gate /* --- deflate.h */
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate /* +++ deflate.c */
635*7c478bd9Sstevel@tonic-gate /*
636*7c478bd9Sstevel@tonic-gate  * deflate.c -- compress data using the deflation algorithm
637*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Jean-loup Gailly.
638*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
639*7c478bd9Sstevel@tonic-gate  */
640*7c478bd9Sstevel@tonic-gate 
641*7c478bd9Sstevel@tonic-gate /*
642*7c478bd9Sstevel@tonic-gate  *  ALGORITHM
643*7c478bd9Sstevel@tonic-gate  *
644*7c478bd9Sstevel@tonic-gate  *      The "deflation" process depends on being able to identify portions
645*7c478bd9Sstevel@tonic-gate  *      of the input text which are identical to earlier input (within a
646*7c478bd9Sstevel@tonic-gate  *      sliding window trailing behind the input currently being processed).
647*7c478bd9Sstevel@tonic-gate  *
648*7c478bd9Sstevel@tonic-gate  *      The most straightforward technique turns out to be the fastest for
649*7c478bd9Sstevel@tonic-gate  *      most input files: try all possible matches and select the longest.
650*7c478bd9Sstevel@tonic-gate  *      The key feature of this algorithm is that insertions into the string
651*7c478bd9Sstevel@tonic-gate  *      dictionary are very simple and thus fast, and deletions are avoided
652*7c478bd9Sstevel@tonic-gate  *      completely. Insertions are performed at each input character, whereas
653*7c478bd9Sstevel@tonic-gate  *      string matches are performed only when the previous match ends. So it
654*7c478bd9Sstevel@tonic-gate  *      is preferable to spend more time in matches to allow very fast string
655*7c478bd9Sstevel@tonic-gate  *      insertions and avoid deletions. The matching algorithm for small
656*7c478bd9Sstevel@tonic-gate  *      strings is inspired from that of Rabin & Karp. A brute force approach
657*7c478bd9Sstevel@tonic-gate  *      is used to find longer strings when a small match has been found.
658*7c478bd9Sstevel@tonic-gate  *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
659*7c478bd9Sstevel@tonic-gate  *      (by Leonid Broukhis).
660*7c478bd9Sstevel@tonic-gate  *         A previous version of this file used a more sophisticated algorithm
661*7c478bd9Sstevel@tonic-gate  *      (by Fiala and Greene) which is guaranteed to run in linear amortized
662*7c478bd9Sstevel@tonic-gate  *      time, but has a larger average cost, uses more memory and is patented.
663*7c478bd9Sstevel@tonic-gate  *      However the F&G algorithm may be faster for some highly redundant
664*7c478bd9Sstevel@tonic-gate  *      files if the parameter max_chain_length (described below) is too large.
665*7c478bd9Sstevel@tonic-gate  *
666*7c478bd9Sstevel@tonic-gate  *  ACKNOWLEDGEMENTS
667*7c478bd9Sstevel@tonic-gate  *
668*7c478bd9Sstevel@tonic-gate  *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
669*7c478bd9Sstevel@tonic-gate  *      I found it in 'freeze' written by Leonid Broukhis.
670*7c478bd9Sstevel@tonic-gate  *      Thanks to many people for bug reports and testing.
671*7c478bd9Sstevel@tonic-gate  *
672*7c478bd9Sstevel@tonic-gate  *  REFERENCES
673*7c478bd9Sstevel@tonic-gate  *
674*7c478bd9Sstevel@tonic-gate  *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
675*7c478bd9Sstevel@tonic-gate  *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
676*7c478bd9Sstevel@tonic-gate  *
677*7c478bd9Sstevel@tonic-gate  *      A description of the Rabin and Karp algorithm is given in the book
678*7c478bd9Sstevel@tonic-gate  *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
679*7c478bd9Sstevel@tonic-gate  *
680*7c478bd9Sstevel@tonic-gate  *      Fiala,E.R., and Greene,D.H.
681*7c478bd9Sstevel@tonic-gate  *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
682*7c478bd9Sstevel@tonic-gate  *
683*7c478bd9Sstevel@tonic-gate  */
684*7c478bd9Sstevel@tonic-gate 
685*7c478bd9Sstevel@tonic-gate /* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate /* #include "deflate.h" */
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate const char deflate_copyright[] =
690*7c478bd9Sstevel@tonic-gate " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
691*7c478bd9Sstevel@tonic-gate /*
692*7c478bd9Sstevel@tonic-gate  * If you use the zlib library in a product, an acknowledgment is
693*7c478bd9Sstevel@tonic-gate  * welcome in the documentation of your product. If for some reason
694*7c478bd9Sstevel@tonic-gate  * you cannot include such an acknowledgment, I would appreciate that
695*7c478bd9Sstevel@tonic-gate  * you keep this copyright string in the executable of your product.
696*7c478bd9Sstevel@tonic-gate  */
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate /*
699*7c478bd9Sstevel@tonic-gate  * ===========================================================================
700*7c478bd9Sstevel@tonic-gate  *  Function prototypes.
701*7c478bd9Sstevel@tonic-gate  */
702*7c478bd9Sstevel@tonic-gate typedef enum {
703*7c478bd9Sstevel@tonic-gate 	/* block not completed, need more input or more output */
704*7c478bd9Sstevel@tonic-gate 	need_more,
705*7c478bd9Sstevel@tonic-gate 	block_done,	/* block flush performed */
706*7c478bd9Sstevel@tonic-gate 	/* finish started, need only more output at next deflate */
707*7c478bd9Sstevel@tonic-gate 	finish_started,
708*7c478bd9Sstevel@tonic-gate 	finish_done	/* finish done, accept no more input or output */
709*7c478bd9Sstevel@tonic-gate } block_state;
710*7c478bd9Sstevel@tonic-gate 
711*7c478bd9Sstevel@tonic-gate typedef block_state (*compress_func) OF((deflate_state *s, int flush));
712*7c478bd9Sstevel@tonic-gate /* Compression function. Returns the block state after the call. */
713*7c478bd9Sstevel@tonic-gate 
714*7c478bd9Sstevel@tonic-gate local void fill_window	OF((deflate_state *s));
715*7c478bd9Sstevel@tonic-gate local block_state deflate_stored OF((deflate_state *s, int flush));
716*7c478bd9Sstevel@tonic-gate local block_state deflate_fast	OF((deflate_state *s, int flush));
717*7c478bd9Sstevel@tonic-gate local block_state deflate_slow	OF((deflate_state *s, int flush));
718*7c478bd9Sstevel@tonic-gate local void lm_init	OF((deflate_state *s));
719*7c478bd9Sstevel@tonic-gate local void putShortMSB	OF((deflate_state *s, uInt b));
720*7c478bd9Sstevel@tonic-gate local void flush_pending	OF((z_streamp strm));
721*7c478bd9Sstevel@tonic-gate local int read_buf	OF((z_streamp strm, Bytef *buf, unsigned size));
722*7c478bd9Sstevel@tonic-gate #ifdef ASMV
723*7c478bd9Sstevel@tonic-gate void match_init	OF((void));	/* asm code initialization */
724*7c478bd9Sstevel@tonic-gate uInt longest_match	OF((deflate_state *s, IPos cur_match));
725*7c478bd9Sstevel@tonic-gate #else
726*7c478bd9Sstevel@tonic-gate local uInt longest_match	OF((deflate_state *s, IPos cur_match));
727*7c478bd9Sstevel@tonic-gate #endif
728*7c478bd9Sstevel@tonic-gate 
729*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
730*7c478bd9Sstevel@tonic-gate local void check_match OF((deflate_state *s, IPos start, IPos match,
731*7c478bd9Sstevel@tonic-gate     int length));
732*7c478bd9Sstevel@tonic-gate #endif
733*7c478bd9Sstevel@tonic-gate 
734*7c478bd9Sstevel@tonic-gate /*
735*7c478bd9Sstevel@tonic-gate  * ===========================================================================
736*7c478bd9Sstevel@tonic-gate  * Local data
737*7c478bd9Sstevel@tonic-gate  */
738*7c478bd9Sstevel@tonic-gate 
739*7c478bd9Sstevel@tonic-gate #define	NIL 0
740*7c478bd9Sstevel@tonic-gate /* Tail of hash chains */
741*7c478bd9Sstevel@tonic-gate 
742*7c478bd9Sstevel@tonic-gate #ifndef TOO_FAR
743*7c478bd9Sstevel@tonic-gate #define	TOO_FAR 4096
744*7c478bd9Sstevel@tonic-gate #endif
745*7c478bd9Sstevel@tonic-gate /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
746*7c478bd9Sstevel@tonic-gate 
747*7c478bd9Sstevel@tonic-gate #define	MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
748*7c478bd9Sstevel@tonic-gate /*
749*7c478bd9Sstevel@tonic-gate  * Minimum amount of lookahead, except at the end of the input file.
750*7c478bd9Sstevel@tonic-gate  * See deflate.c for comments about the MIN_MATCH+1.
751*7c478bd9Sstevel@tonic-gate  */
752*7c478bd9Sstevel@tonic-gate 
753*7c478bd9Sstevel@tonic-gate /*
754*7c478bd9Sstevel@tonic-gate  * Values for max_lazy_match, good_match and max_chain_length,
755*7c478bd9Sstevel@tonic-gate  * depending on the desired pack level (0..9). The values given below
756*7c478bd9Sstevel@tonic-gate  * have been tuned to exclude worst case performance for pathological
757*7c478bd9Sstevel@tonic-gate  * files. Better values may be found for specific files.
758*7c478bd9Sstevel@tonic-gate  */
759*7c478bd9Sstevel@tonic-gate typedef struct config_s {
760*7c478bd9Sstevel@tonic-gate 	ush good_length;	/* reduce lazy search above this match length */
761*7c478bd9Sstevel@tonic-gate 	ush max_lazy;	/* do not perform lazy search above this match length */
762*7c478bd9Sstevel@tonic-gate 	ush nice_length;	/* quit search above this match length */
763*7c478bd9Sstevel@tonic-gate 	ush max_chain;
764*7c478bd9Sstevel@tonic-gate 	compress_func func;
765*7c478bd9Sstevel@tonic-gate } config;
766*7c478bd9Sstevel@tonic-gate 
767*7c478bd9Sstevel@tonic-gate local const config configuration_table[10] = {
768*7c478bd9Sstevel@tonic-gate /*	good lazy nice chain */
769*7c478bd9Sstevel@tonic-gate /* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
770*7c478bd9Sstevel@tonic-gate /* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
771*7c478bd9Sstevel@tonic-gate /* 2 */ {4,    5, 16,    8, deflate_fast},
772*7c478bd9Sstevel@tonic-gate /* 3 */ {4,    6, 32,   32, deflate_fast},
773*7c478bd9Sstevel@tonic-gate 
774*7c478bd9Sstevel@tonic-gate /* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
775*7c478bd9Sstevel@tonic-gate /* 5 */ {8,   16, 32,   32, deflate_slow},
776*7c478bd9Sstevel@tonic-gate /* 6 */ {8,   16, 128, 128, deflate_slow},
777*7c478bd9Sstevel@tonic-gate /* 7 */ {8,   32, 128, 256, deflate_slow},
778*7c478bd9Sstevel@tonic-gate /* 8 */ {32, 128, 258, 1024, deflate_slow},
779*7c478bd9Sstevel@tonic-gate /* 9 */ {32, 258, 258, 4096, deflate_slow}};	/* maximum compression */
780*7c478bd9Sstevel@tonic-gate 
781*7c478bd9Sstevel@tonic-gate /*
782*7c478bd9Sstevel@tonic-gate  * Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
783*7c478bd9Sstevel@tonic-gate  * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
784*7c478bd9Sstevel@tonic-gate  * meaning.
785*7c478bd9Sstevel@tonic-gate  */
786*7c478bd9Sstevel@tonic-gate 
787*7c478bd9Sstevel@tonic-gate #define	EQUAL 0
788*7c478bd9Sstevel@tonic-gate /* result of memcmp for equal strings */
789*7c478bd9Sstevel@tonic-gate 
790*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
791*7c478bd9Sstevel@tonic-gate struct static_tree_desc_s {int dummy; };	/* for buggy compilers */
792*7c478bd9Sstevel@tonic-gate #endif
793*7c478bd9Sstevel@tonic-gate 
794*7c478bd9Sstevel@tonic-gate /*
795*7c478bd9Sstevel@tonic-gate  * ===========================================================================
796*7c478bd9Sstevel@tonic-gate  * Update a hash value with the given input byte
797*7c478bd9Sstevel@tonic-gate  * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
798*7c478bd9Sstevel@tonic-gate  *    input characters, so that a running hash key can be computed from the
799*7c478bd9Sstevel@tonic-gate  *    previous key instead of complete recalculation each time.
800*7c478bd9Sstevel@tonic-gate  */
801*7c478bd9Sstevel@tonic-gate #define	UPDATE_HASH(s, h, c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
802*7c478bd9Sstevel@tonic-gate 
803*7c478bd9Sstevel@tonic-gate 
804*7c478bd9Sstevel@tonic-gate /*
805*7c478bd9Sstevel@tonic-gate  * ===========================================================================
806*7c478bd9Sstevel@tonic-gate  * Insert string str in the dictionary and set match_head to the previous head
807*7c478bd9Sstevel@tonic-gate  * of the hash chain (the most recent string with same hash key). Return
808*7c478bd9Sstevel@tonic-gate  * the previous length of the hash chain.
809*7c478bd9Sstevel@tonic-gate  * If this file is compiled with -DFASTEST, the compression level is forced
810*7c478bd9Sstevel@tonic-gate  * to 1, and no hash chains are maintained.
811*7c478bd9Sstevel@tonic-gate  * IN  assertion: all calls to to INSERT_STRING are made with consecutive
812*7c478bd9Sstevel@tonic-gate  *    input characters and the first MIN_MATCH bytes of str are valid
813*7c478bd9Sstevel@tonic-gate  *    (except for the last MIN_MATCH-1 bytes of the input file).
814*7c478bd9Sstevel@tonic-gate  */
815*7c478bd9Sstevel@tonic-gate #ifdef FASTEST
816*7c478bd9Sstevel@tonic-gate #define	INSERT_STRING(s, str, match_head) \
817*7c478bd9Sstevel@tonic-gate 	(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
818*7c478bd9Sstevel@tonic-gate 	match_head = s->head[s->ins_h], \
819*7c478bd9Sstevel@tonic-gate 	s->head[s->ins_h] = (Pos)(str))
820*7c478bd9Sstevel@tonic-gate #else
821*7c478bd9Sstevel@tonic-gate #define	INSERT_STRING(s, str, match_head) \
822*7c478bd9Sstevel@tonic-gate 	(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
823*7c478bd9Sstevel@tonic-gate 	s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
824*7c478bd9Sstevel@tonic-gate 	s->head[s->ins_h] = (Pos)(str))
825*7c478bd9Sstevel@tonic-gate #endif
826*7c478bd9Sstevel@tonic-gate 
827*7c478bd9Sstevel@tonic-gate /*
828*7c478bd9Sstevel@tonic-gate  * ===========================================================================
829*7c478bd9Sstevel@tonic-gate  * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
830*7c478bd9Sstevel@tonic-gate  * prev[] will be initialized on the fly.
831*7c478bd9Sstevel@tonic-gate  */
832*7c478bd9Sstevel@tonic-gate #define	CLEAR_HASH(s) \
833*7c478bd9Sstevel@tonic-gate     s->head[s->hash_size-1] = NIL; \
834*7c478bd9Sstevel@tonic-gate     zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof (*s->head));
835*7c478bd9Sstevel@tonic-gate 
836*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
837*7c478bd9Sstevel@tonic-gate int
838*7c478bd9Sstevel@tonic-gate deflateInit_(strm, level, version, stream_size)
839*7c478bd9Sstevel@tonic-gate     z_streamp strm;
840*7c478bd9Sstevel@tonic-gate     int level;
841*7c478bd9Sstevel@tonic-gate     const char *version;
842*7c478bd9Sstevel@tonic-gate     int stream_size;
843*7c478bd9Sstevel@tonic-gate {
844*7c478bd9Sstevel@tonic-gate 	(void) deflate_copyright;
845*7c478bd9Sstevel@tonic-gate 	return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
846*7c478bd9Sstevel@tonic-gate 	    Z_DEFAULT_STRATEGY, version, stream_size);
847*7c478bd9Sstevel@tonic-gate 	/* To do: ignore strm->next_in if we use it as window */
848*7c478bd9Sstevel@tonic-gate }
849*7c478bd9Sstevel@tonic-gate 
850*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
851*7c478bd9Sstevel@tonic-gate int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
852*7c478bd9Sstevel@tonic-gate     version, stream_size)
853*7c478bd9Sstevel@tonic-gate     z_streamp strm;
854*7c478bd9Sstevel@tonic-gate     int  level;
855*7c478bd9Sstevel@tonic-gate     int  method;
856*7c478bd9Sstevel@tonic-gate     int  windowBits;
857*7c478bd9Sstevel@tonic-gate     int  memLevel;
858*7c478bd9Sstevel@tonic-gate     int  strategy;
859*7c478bd9Sstevel@tonic-gate     const char *version;
860*7c478bd9Sstevel@tonic-gate     int stream_size;
861*7c478bd9Sstevel@tonic-gate {
862*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
863*7c478bd9Sstevel@tonic-gate 	int noheader = 0;
864*7c478bd9Sstevel@tonic-gate 	static const char *my_version = ZLIB_VERSION;
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate 	ushf *overlay;
867*7c478bd9Sstevel@tonic-gate 	/*
868*7c478bd9Sstevel@tonic-gate 	 * We overlay pending_buf and d_buf+l_buf. This works since
869*7c478bd9Sstevel@tonic-gate 	 * the average output size for (length, distance) codes is <=
870*7c478bd9Sstevel@tonic-gate 	 * 24 bits.
871*7c478bd9Sstevel@tonic-gate 	 */
872*7c478bd9Sstevel@tonic-gate 
873*7c478bd9Sstevel@tonic-gate 	if (version == Z_NULL || version[0] != my_version[0] ||
874*7c478bd9Sstevel@tonic-gate 	    stream_size != sizeof (z_stream)) {
875*7c478bd9Sstevel@tonic-gate 		return (Z_VERSION_ERROR);
876*7c478bd9Sstevel@tonic-gate 	}
877*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL)
878*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
879*7c478bd9Sstevel@tonic-gate 
880*7c478bd9Sstevel@tonic-gate 	strm->msg = Z_NULL;
881*7c478bd9Sstevel@tonic-gate #ifndef NO_ZCFUNCS
882*7c478bd9Sstevel@tonic-gate 	if (strm->zalloc == Z_NULL) {
883*7c478bd9Sstevel@tonic-gate 		strm->zalloc = zcalloc;
884*7c478bd9Sstevel@tonic-gate 		strm->opaque = (voidpf)0;
885*7c478bd9Sstevel@tonic-gate 	}
886*7c478bd9Sstevel@tonic-gate 	if (strm->zfree == Z_NULL) strm->zfree = zcfree;
887*7c478bd9Sstevel@tonic-gate #endif
888*7c478bd9Sstevel@tonic-gate 
889*7c478bd9Sstevel@tonic-gate 	if (level == Z_DEFAULT_COMPRESSION) level = 6;
890*7c478bd9Sstevel@tonic-gate #ifdef FASTEST
891*7c478bd9Sstevel@tonic-gate 	level = 1;
892*7c478bd9Sstevel@tonic-gate #endif
893*7c478bd9Sstevel@tonic-gate 
894*7c478bd9Sstevel@tonic-gate 	if (windowBits < 0) { /* undocumented feature: suppress zlib header */
895*7c478bd9Sstevel@tonic-gate 		noheader = 1;
896*7c478bd9Sstevel@tonic-gate 		windowBits = -windowBits;
897*7c478bd9Sstevel@tonic-gate 	}
898*7c478bd9Sstevel@tonic-gate 	if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
899*7c478bd9Sstevel@tonic-gate 	    windowBits <= 8 || windowBits > 15 || level < 0 || level > 9 ||
900*7c478bd9Sstevel@tonic-gate 	    strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
901*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
902*7c478bd9Sstevel@tonic-gate 	}
903*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *) ZALLOC(strm, 1, sizeof (deflate_state));
904*7c478bd9Sstevel@tonic-gate 	if (s == Z_NULL)
905*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
906*7c478bd9Sstevel@tonic-gate 	strm->state = (struct internal_state FAR *)s;
907*7c478bd9Sstevel@tonic-gate 	s->strm = strm;
908*7c478bd9Sstevel@tonic-gate 
909*7c478bd9Sstevel@tonic-gate 	s->noheader = noheader;
910*7c478bd9Sstevel@tonic-gate 	s->w_bits = windowBits;
911*7c478bd9Sstevel@tonic-gate 	s->w_size = 1 << s->w_bits;
912*7c478bd9Sstevel@tonic-gate 	s->w_mask = s->w_size - 1;
913*7c478bd9Sstevel@tonic-gate 
914*7c478bd9Sstevel@tonic-gate 	s->hash_bits = memLevel + 7;
915*7c478bd9Sstevel@tonic-gate 	s->hash_size = 1 << s->hash_bits;
916*7c478bd9Sstevel@tonic-gate 	s->hash_mask = s->hash_size - 1;
917*7c478bd9Sstevel@tonic-gate 	s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
918*7c478bd9Sstevel@tonic-gate 
919*7c478bd9Sstevel@tonic-gate 	s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof (Byte));
920*7c478bd9Sstevel@tonic-gate 	s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof (Pos));
921*7c478bd9Sstevel@tonic-gate 	s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof (Pos));
922*7c478bd9Sstevel@tonic-gate 
923*7c478bd9Sstevel@tonic-gate 	s->lit_bufsize = 1 << (memLevel + 6);	/* 16K elements by default */
924*7c478bd9Sstevel@tonic-gate 
925*7c478bd9Sstevel@tonic-gate 	overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof (ush)+2);
926*7c478bd9Sstevel@tonic-gate 	s->pending_buf = (uchf *) overlay;
927*7c478bd9Sstevel@tonic-gate 	s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof (ush)+2L);
928*7c478bd9Sstevel@tonic-gate 
929*7c478bd9Sstevel@tonic-gate 	if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
930*7c478bd9Sstevel@tonic-gate 	    s->pending_buf == Z_NULL) {
931*7c478bd9Sstevel@tonic-gate 		strm->msg = ERR_MSG(Z_MEM_ERROR);
932*7c478bd9Sstevel@tonic-gate 		s->status = INIT_STATE;
933*7c478bd9Sstevel@tonic-gate 		(void) deflateEnd(strm);
934*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
935*7c478bd9Sstevel@tonic-gate 	}
936*7c478bd9Sstevel@tonic-gate 	s->d_buf = overlay + s->lit_bufsize/sizeof (ush);
937*7c478bd9Sstevel@tonic-gate 	s->l_buf = s->pending_buf + (1+sizeof (ush))*s->lit_bufsize;
938*7c478bd9Sstevel@tonic-gate 
939*7c478bd9Sstevel@tonic-gate 	s->level = level;
940*7c478bd9Sstevel@tonic-gate 	s->strategy = strategy;
941*7c478bd9Sstevel@tonic-gate 	s->method = (Byte)method;
942*7c478bd9Sstevel@tonic-gate 
943*7c478bd9Sstevel@tonic-gate 	return (deflateReset(strm));
944*7c478bd9Sstevel@tonic-gate }
945*7c478bd9Sstevel@tonic-gate 
946*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
947*7c478bd9Sstevel@tonic-gate int
948*7c478bd9Sstevel@tonic-gate deflateSetDictionary(strm, dictionary, dictLength)
949*7c478bd9Sstevel@tonic-gate     z_streamp strm;
950*7c478bd9Sstevel@tonic-gate     const Bytef *dictionary;
951*7c478bd9Sstevel@tonic-gate     uInt  dictLength;
952*7c478bd9Sstevel@tonic-gate {
953*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
954*7c478bd9Sstevel@tonic-gate 	uInt length = dictLength;
955*7c478bd9Sstevel@tonic-gate 	uInt n;
956*7c478bd9Sstevel@tonic-gate 	IPos hash_head = 0;
957*7c478bd9Sstevel@tonic-gate 
958*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
959*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
960*7c478bd9Sstevel@tonic-gate 
961*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *) strm->state;
962*7c478bd9Sstevel@tonic-gate 	if (s->status != INIT_STATE)
963*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
964*7c478bd9Sstevel@tonic-gate 
965*7c478bd9Sstevel@tonic-gate 	strm->adler = adler32(strm->adler, dictionary, dictLength);
966*7c478bd9Sstevel@tonic-gate 
967*7c478bd9Sstevel@tonic-gate 	if (length < MIN_MATCH)
968*7c478bd9Sstevel@tonic-gate 		return (Z_OK);
969*7c478bd9Sstevel@tonic-gate 	if (length > MAX_DIST(s)) {
970*7c478bd9Sstevel@tonic-gate 		length = MAX_DIST(s);
971*7c478bd9Sstevel@tonic-gate #ifndef USE_DICT_HEAD
972*7c478bd9Sstevel@tonic-gate 		/* use the tail of the dictionary */
973*7c478bd9Sstevel@tonic-gate 		dictionary += dictLength - length;
974*7c478bd9Sstevel@tonic-gate #endif
975*7c478bd9Sstevel@tonic-gate 	}
976*7c478bd9Sstevel@tonic-gate 	Assert(length <= s->window_size, "dict copy");
977*7c478bd9Sstevel@tonic-gate 	zmemcpy(s->window, dictionary, length);
978*7c478bd9Sstevel@tonic-gate 	s->strstart = length;
979*7c478bd9Sstevel@tonic-gate 	s->block_start = (long)length;
980*7c478bd9Sstevel@tonic-gate 
981*7c478bd9Sstevel@tonic-gate 	/*
982*7c478bd9Sstevel@tonic-gate 	 * Insert all strings in the hash table (except for the last
983*7c478bd9Sstevel@tonic-gate 	 * two bytes).  s->lookahead stays null, so s->ins_h will be
984*7c478bd9Sstevel@tonic-gate 	 * recomputed at the next call of fill_window.
985*7c478bd9Sstevel@tonic-gate 	 */
986*7c478bd9Sstevel@tonic-gate 	s->ins_h = s->window[0];
987*7c478bd9Sstevel@tonic-gate 	UPDATE_HASH(s, s->ins_h, s->window[1]);
988*7c478bd9Sstevel@tonic-gate 	for (n = 0; n <= length - MIN_MATCH; n++) {
989*7c478bd9Sstevel@tonic-gate 		INSERT_STRING(s, n, hash_head);
990*7c478bd9Sstevel@tonic-gate 	}
991*7c478bd9Sstevel@tonic-gate 	if (hash_head) hash_head = 0;	/* to make compiler happy */
992*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
993*7c478bd9Sstevel@tonic-gate }
994*7c478bd9Sstevel@tonic-gate 
995*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
996*7c478bd9Sstevel@tonic-gate int
997*7c478bd9Sstevel@tonic-gate deflateReset(strm)
998*7c478bd9Sstevel@tonic-gate     z_streamp strm;
999*7c478bd9Sstevel@tonic-gate {
1000*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
1001*7c478bd9Sstevel@tonic-gate 
1002*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL ||
1003*7c478bd9Sstevel@tonic-gate 	    strm->zalloc == Z_NULL || strm->zfree == Z_NULL)
1004*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1005*7c478bd9Sstevel@tonic-gate 
1006*7c478bd9Sstevel@tonic-gate 	strm->total_in = strm->total_out = 0;
1007*7c478bd9Sstevel@tonic-gate 	/* use zfree if we ever allocate msg dynamically */
1008*7c478bd9Sstevel@tonic-gate 	strm->msg = Z_NULL;
1009*7c478bd9Sstevel@tonic-gate 	strm->data_type = Z_UNKNOWN;
1010*7c478bd9Sstevel@tonic-gate 
1011*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *)strm->state;
1012*7c478bd9Sstevel@tonic-gate 	s->pending = 0;
1013*7c478bd9Sstevel@tonic-gate 	s->pending_out = s->pending_buf;
1014*7c478bd9Sstevel@tonic-gate 
1015*7c478bd9Sstevel@tonic-gate 	if (s->noheader < 0) {
1016*7c478bd9Sstevel@tonic-gate 		/* was set to -1 by deflate(..., Z_FINISH); */
1017*7c478bd9Sstevel@tonic-gate 		s->noheader = 0;
1018*7c478bd9Sstevel@tonic-gate 	}
1019*7c478bd9Sstevel@tonic-gate 	s->status = s->noheader ? BUSY_STATE : INIT_STATE;
1020*7c478bd9Sstevel@tonic-gate 	strm->adler = 1;
1021*7c478bd9Sstevel@tonic-gate 	s->last_flush = Z_NO_FLUSH;
1022*7c478bd9Sstevel@tonic-gate 
1023*7c478bd9Sstevel@tonic-gate 	_tr_init(s);
1024*7c478bd9Sstevel@tonic-gate 	lm_init(s);
1025*7c478bd9Sstevel@tonic-gate 
1026*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
1027*7c478bd9Sstevel@tonic-gate }
1028*7c478bd9Sstevel@tonic-gate 
1029*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
1030*7c478bd9Sstevel@tonic-gate int
1031*7c478bd9Sstevel@tonic-gate deflateParams(strm, level, strategy)
1032*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1033*7c478bd9Sstevel@tonic-gate     int level;
1034*7c478bd9Sstevel@tonic-gate     int strategy;
1035*7c478bd9Sstevel@tonic-gate {
1036*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
1037*7c478bd9Sstevel@tonic-gate 	compress_func func;
1038*7c478bd9Sstevel@tonic-gate 	int err = Z_OK;
1039*7c478bd9Sstevel@tonic-gate 
1040*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL)
1041*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1042*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *) strm->state;
1043*7c478bd9Sstevel@tonic-gate 
1044*7c478bd9Sstevel@tonic-gate 	if (level == Z_DEFAULT_COMPRESSION) {
1045*7c478bd9Sstevel@tonic-gate 		level = 6;
1046*7c478bd9Sstevel@tonic-gate 	}
1047*7c478bd9Sstevel@tonic-gate 	if (level < 0 || level > 9 || strategy < 0 ||
1048*7c478bd9Sstevel@tonic-gate 	    strategy > Z_HUFFMAN_ONLY) {
1049*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1050*7c478bd9Sstevel@tonic-gate 	}
1051*7c478bd9Sstevel@tonic-gate 	func = configuration_table[s->level].func;
1052*7c478bd9Sstevel@tonic-gate 
1053*7c478bd9Sstevel@tonic-gate 	if (func != configuration_table[level].func && strm->total_in != 0) {
1054*7c478bd9Sstevel@tonic-gate 		/* Flush the last buffer: */
1055*7c478bd9Sstevel@tonic-gate 		err = deflate(strm, Z_PARTIAL_FLUSH);
1056*7c478bd9Sstevel@tonic-gate 	}
1057*7c478bd9Sstevel@tonic-gate 	if (s->level != level) {
1058*7c478bd9Sstevel@tonic-gate 		s->level = level;
1059*7c478bd9Sstevel@tonic-gate 		s->max_lazy_match   = configuration_table[level].max_lazy;
1060*7c478bd9Sstevel@tonic-gate 		s->good_match	= configuration_table[level].good_length;
1061*7c478bd9Sstevel@tonic-gate 		s->nice_match	= configuration_table[level].nice_length;
1062*7c478bd9Sstevel@tonic-gate 		s->max_chain_length = configuration_table[level].max_chain;
1063*7c478bd9Sstevel@tonic-gate 	}
1064*7c478bd9Sstevel@tonic-gate 	s->strategy = strategy;
1065*7c478bd9Sstevel@tonic-gate 	return (err);
1066*7c478bd9Sstevel@tonic-gate }
1067*7c478bd9Sstevel@tonic-gate 
1068*7c478bd9Sstevel@tonic-gate /*
1069*7c478bd9Sstevel@tonic-gate  * =========================================================================
1070*7c478bd9Sstevel@tonic-gate  * Put a short in the pending buffer. The 16-bit value is put in MSB order.
1071*7c478bd9Sstevel@tonic-gate  * IN assertion: the stream state is correct and there is enough room in
1072*7c478bd9Sstevel@tonic-gate  * pending_buf.
1073*7c478bd9Sstevel@tonic-gate  */
1074*7c478bd9Sstevel@tonic-gate local void
1075*7c478bd9Sstevel@tonic-gate putShortMSB(s, b)
1076*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1077*7c478bd9Sstevel@tonic-gate     uInt b;
1078*7c478bd9Sstevel@tonic-gate {
1079*7c478bd9Sstevel@tonic-gate 	put_byte(s, (Byte)(b >> 8));
1080*7c478bd9Sstevel@tonic-gate 	put_byte(s, (Byte)(b & 0xff));
1081*7c478bd9Sstevel@tonic-gate }
1082*7c478bd9Sstevel@tonic-gate 
1083*7c478bd9Sstevel@tonic-gate /*
1084*7c478bd9Sstevel@tonic-gate  * =========================================================================
1085*7c478bd9Sstevel@tonic-gate  * Flush as much pending output as possible. All deflate() output goes
1086*7c478bd9Sstevel@tonic-gate  * through this function so some applications may wish to modify it
1087*7c478bd9Sstevel@tonic-gate  * to avoid allocating a large strm->next_out buffer and copying into it.
1088*7c478bd9Sstevel@tonic-gate  * (See also read_buf()).
1089*7c478bd9Sstevel@tonic-gate  */
1090*7c478bd9Sstevel@tonic-gate local void
1091*7c478bd9Sstevel@tonic-gate flush_pending(strm)
1092*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1093*7c478bd9Sstevel@tonic-gate {
1094*7c478bd9Sstevel@tonic-gate 	deflate_state *s = (deflate_state *) strm->state;
1095*7c478bd9Sstevel@tonic-gate 	unsigned len = s->pending;
1096*7c478bd9Sstevel@tonic-gate 
1097*7c478bd9Sstevel@tonic-gate 	if (len > strm->avail_out) len = strm->avail_out;
1098*7c478bd9Sstevel@tonic-gate 	if (len == 0)
1099*7c478bd9Sstevel@tonic-gate 		return;
1100*7c478bd9Sstevel@tonic-gate 
1101*7c478bd9Sstevel@tonic-gate 	if (strm->next_out != Z_NULL) {		/* PPP */
1102*7c478bd9Sstevel@tonic-gate 		zmemcpy(strm->next_out, s->pending_out, len);
1103*7c478bd9Sstevel@tonic-gate 		strm->next_out += len;
1104*7c478bd9Sstevel@tonic-gate 	}					/* PPP */
1105*7c478bd9Sstevel@tonic-gate 	s->pending_out += len;
1106*7c478bd9Sstevel@tonic-gate 	strm->total_out += len;
1107*7c478bd9Sstevel@tonic-gate 	strm->avail_out  -= len;
1108*7c478bd9Sstevel@tonic-gate 	s->pending -= len;
1109*7c478bd9Sstevel@tonic-gate 	if (s->pending == 0) {
1110*7c478bd9Sstevel@tonic-gate 		s->pending_out = s->pending_buf;
1111*7c478bd9Sstevel@tonic-gate 	}
1112*7c478bd9Sstevel@tonic-gate }
1113*7c478bd9Sstevel@tonic-gate 
1114*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
1115*7c478bd9Sstevel@tonic-gate int
1116*7c478bd9Sstevel@tonic-gate deflate(strm, flush)
1117*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1118*7c478bd9Sstevel@tonic-gate     int flush;
1119*7c478bd9Sstevel@tonic-gate {
1120*7c478bd9Sstevel@tonic-gate 	int old_flush;	/* value of flush param for previous deflate call */
1121*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
1122*7c478bd9Sstevel@tonic-gate 
1123*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL ||
1124*7c478bd9Sstevel@tonic-gate 	    flush > Z_FINISH || flush < 0) {
1125*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1126*7c478bd9Sstevel@tonic-gate 	}
1127*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *) strm->state;
1128*7c478bd9Sstevel@tonic-gate 
1129*7c478bd9Sstevel@tonic-gate 	if (/* strm->next_out == Z_NULL || --- we allow null --- PPP */
1130*7c478bd9Sstevel@tonic-gate 		(strm->next_in == Z_NULL && strm->avail_in != 0) ||
1131*7c478bd9Sstevel@tonic-gate 	    (s->status == FINISH_STATE && flush != Z_FINISH)) {
1132*7c478bd9Sstevel@tonic-gate 		ERR_RETURN(strm, Z_STREAM_ERROR);
1133*7c478bd9Sstevel@tonic-gate 	}
1134*7c478bd9Sstevel@tonic-gate 	if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
1135*7c478bd9Sstevel@tonic-gate 
1136*7c478bd9Sstevel@tonic-gate 	s->strm = strm;	/* just in case */
1137*7c478bd9Sstevel@tonic-gate 	old_flush = s->last_flush;
1138*7c478bd9Sstevel@tonic-gate 	s->last_flush = flush;
1139*7c478bd9Sstevel@tonic-gate 
1140*7c478bd9Sstevel@tonic-gate 	/* Write the zlib header */
1141*7c478bd9Sstevel@tonic-gate 	if (s->status == INIT_STATE) {
1142*7c478bd9Sstevel@tonic-gate 
1143*7c478bd9Sstevel@tonic-gate 		uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
1144*7c478bd9Sstevel@tonic-gate 		uInt level_flags = (s->level-1) >> 1;
1145*7c478bd9Sstevel@tonic-gate 
1146*7c478bd9Sstevel@tonic-gate 		if (level_flags > 3) level_flags = 3;
1147*7c478bd9Sstevel@tonic-gate 		header |= (level_flags << 6);
1148*7c478bd9Sstevel@tonic-gate 		if (s->strstart != 0) header |= PRESET_DICT;
1149*7c478bd9Sstevel@tonic-gate 		header += 31 - (header % 31);
1150*7c478bd9Sstevel@tonic-gate 
1151*7c478bd9Sstevel@tonic-gate 		s->status = BUSY_STATE;
1152*7c478bd9Sstevel@tonic-gate 		putShortMSB(s, header);
1153*7c478bd9Sstevel@tonic-gate 
1154*7c478bd9Sstevel@tonic-gate 		/* Save the adler32 of the preset dictionary: */
1155*7c478bd9Sstevel@tonic-gate 		if (s->strstart != 0) {
1156*7c478bd9Sstevel@tonic-gate 			putShortMSB(s, (uInt)(strm->adler >> 16));
1157*7c478bd9Sstevel@tonic-gate 			putShortMSB(s, (uInt)(strm->adler & 0xffff));
1158*7c478bd9Sstevel@tonic-gate 		}
1159*7c478bd9Sstevel@tonic-gate 		strm->adler = 1L;
1160*7c478bd9Sstevel@tonic-gate 	}
1161*7c478bd9Sstevel@tonic-gate 
1162*7c478bd9Sstevel@tonic-gate 	/* Flush as much pending output as possible */
1163*7c478bd9Sstevel@tonic-gate 	if (s->pending != 0) {
1164*7c478bd9Sstevel@tonic-gate 		flush_pending(strm);
1165*7c478bd9Sstevel@tonic-gate 		if (strm->avail_out == 0) {
1166*7c478bd9Sstevel@tonic-gate 			/*
1167*7c478bd9Sstevel@tonic-gate 			 * Since avail_out is 0, deflate will be
1168*7c478bd9Sstevel@tonic-gate 			 * called again with more output space, but
1169*7c478bd9Sstevel@tonic-gate 			 * possibly with both pending and avail_in
1170*7c478bd9Sstevel@tonic-gate 			 * equal to zero. There won't be anything to
1171*7c478bd9Sstevel@tonic-gate 			 * do, but this is not an error situation so
1172*7c478bd9Sstevel@tonic-gate 			 * make sure we return OK instead of BUF_ERROR
1173*7c478bd9Sstevel@tonic-gate 			 * at next call of deflate:
1174*7c478bd9Sstevel@tonic-gate 			 */
1175*7c478bd9Sstevel@tonic-gate 			s->last_flush = -1;
1176*7c478bd9Sstevel@tonic-gate 			return (Z_OK);
1177*7c478bd9Sstevel@tonic-gate 		}
1178*7c478bd9Sstevel@tonic-gate 
1179*7c478bd9Sstevel@tonic-gate 		/*
1180*7c478bd9Sstevel@tonic-gate 		 * Make sure there is something to do and avoid
1181*7c478bd9Sstevel@tonic-gate 		 * duplicate consecutive flushes. For repeated and
1182*7c478bd9Sstevel@tonic-gate 		 * useless calls with Z_FINISH, we keep returning
1183*7c478bd9Sstevel@tonic-gate 		 * Z_STREAM_END instead of Z_BUFF_ERROR.
1184*7c478bd9Sstevel@tonic-gate 		 */
1185*7c478bd9Sstevel@tonic-gate 	} else if (strm->avail_in == 0 && flush <= old_flush &&
1186*7c478bd9Sstevel@tonic-gate 	    flush != Z_FINISH) {
1187*7c478bd9Sstevel@tonic-gate 		ERR_RETURN(strm, Z_BUF_ERROR);
1188*7c478bd9Sstevel@tonic-gate 	}
1189*7c478bd9Sstevel@tonic-gate 
1190*7c478bd9Sstevel@tonic-gate 	/* User must not provide more input after the first FINISH: */
1191*7c478bd9Sstevel@tonic-gate 	if (s->status == FINISH_STATE && strm->avail_in != 0) {
1192*7c478bd9Sstevel@tonic-gate 		ERR_RETURN(strm, Z_BUF_ERROR);
1193*7c478bd9Sstevel@tonic-gate 	}
1194*7c478bd9Sstevel@tonic-gate 
1195*7c478bd9Sstevel@tonic-gate 	/* Start a new block or continue the current one. */
1196*7c478bd9Sstevel@tonic-gate 	if (strm->avail_in != 0 || s->lookahead != 0 ||
1197*7c478bd9Sstevel@tonic-gate 	    (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
1198*7c478bd9Sstevel@tonic-gate 		block_state bstate;
1199*7c478bd9Sstevel@tonic-gate 
1200*7c478bd9Sstevel@tonic-gate 		bstate = (*(configuration_table[s->level].func))(s, flush);
1201*7c478bd9Sstevel@tonic-gate 
1202*7c478bd9Sstevel@tonic-gate 		if (bstate == finish_started || bstate == finish_done) {
1203*7c478bd9Sstevel@tonic-gate 			s->status = FINISH_STATE;
1204*7c478bd9Sstevel@tonic-gate 		}
1205*7c478bd9Sstevel@tonic-gate 		if (bstate == need_more || bstate == finish_started) {
1206*7c478bd9Sstevel@tonic-gate 			if (strm->avail_out == 0) {
1207*7c478bd9Sstevel@tonic-gate 				/* avoid BUF_ERROR next call, see above */
1208*7c478bd9Sstevel@tonic-gate 				s->last_flush = -1;
1209*7c478bd9Sstevel@tonic-gate 			}
1210*7c478bd9Sstevel@tonic-gate 			return (Z_OK);
1211*7c478bd9Sstevel@tonic-gate 			/*
1212*7c478bd9Sstevel@tonic-gate 			 * If flush != Z_NO_FLUSH && avail_out == 0,
1213*7c478bd9Sstevel@tonic-gate 			 * the next call of deflate should use the
1214*7c478bd9Sstevel@tonic-gate 			 * same flush parameter to make sure that the
1215*7c478bd9Sstevel@tonic-gate 			 * flush is complete. So we don't have to
1216*7c478bd9Sstevel@tonic-gate 			 * output an empty block here, this will be
1217*7c478bd9Sstevel@tonic-gate 			 * done at next call. This also ensures that
1218*7c478bd9Sstevel@tonic-gate 			 * for a very small output buffer, we emit at
1219*7c478bd9Sstevel@tonic-gate 			 * most one empty block.
1220*7c478bd9Sstevel@tonic-gate 			 */
1221*7c478bd9Sstevel@tonic-gate 		}
1222*7c478bd9Sstevel@tonic-gate 		if (bstate == block_done) {
1223*7c478bd9Sstevel@tonic-gate 			if (flush == Z_PARTIAL_FLUSH) {
1224*7c478bd9Sstevel@tonic-gate 				_tr_align(s);
1225*7c478bd9Sstevel@tonic-gate 			} else if (flush == Z_PACKET_FLUSH) {	/* PPP */
1226*7c478bd9Sstevel@tonic-gate 				/*
1227*7c478bd9Sstevel@tonic-gate 				 * Output just the 3-bit `stored'
1228*7c478bd9Sstevel@tonic-gate 				 * block type value, but not a zero
1229*7c478bd9Sstevel@tonic-gate 				 * length.  Added for PPP.
1230*7c478bd9Sstevel@tonic-gate 				 */
1231*7c478bd9Sstevel@tonic-gate 				_tr_stored_type_only(s);	/* PPP */
1232*7c478bd9Sstevel@tonic-gate 			} else { /* FULL_FLUSH or SYNC_FLUSH */
1233*7c478bd9Sstevel@tonic-gate 				_tr_stored_block(s, (char *)0, 0L, 0);
1234*7c478bd9Sstevel@tonic-gate 				/*
1235*7c478bd9Sstevel@tonic-gate 				 * For a full flush, this empty block
1236*7c478bd9Sstevel@tonic-gate 				 * will be recognized as a special
1237*7c478bd9Sstevel@tonic-gate 				 * marker by inflate_sync().
1238*7c478bd9Sstevel@tonic-gate 				 */
1239*7c478bd9Sstevel@tonic-gate 				if (flush == Z_FULL_FLUSH) {
1240*7c478bd9Sstevel@tonic-gate 					CLEAR_HASH(s);	/* forget history */
1241*7c478bd9Sstevel@tonic-gate 				}
1242*7c478bd9Sstevel@tonic-gate 			}
1243*7c478bd9Sstevel@tonic-gate 			flush_pending(strm);
1244*7c478bd9Sstevel@tonic-gate 			if (strm->avail_out == 0) {
1245*7c478bd9Sstevel@tonic-gate 				/* avoid BUF_ERROR at next call, see above */
1246*7c478bd9Sstevel@tonic-gate 				s->last_flush = -1;
1247*7c478bd9Sstevel@tonic-gate 				return (Z_OK);
1248*7c478bd9Sstevel@tonic-gate 			}
1249*7c478bd9Sstevel@tonic-gate 		}
1250*7c478bd9Sstevel@tonic-gate 	}
1251*7c478bd9Sstevel@tonic-gate 	Assert(strm->avail_out > 0, "bug2");
1252*7c478bd9Sstevel@tonic-gate 
1253*7c478bd9Sstevel@tonic-gate 	if (flush != Z_FINISH)
1254*7c478bd9Sstevel@tonic-gate 		return (Z_OK);
1255*7c478bd9Sstevel@tonic-gate 	if (s->noheader)
1256*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_END);
1257*7c478bd9Sstevel@tonic-gate 
1258*7c478bd9Sstevel@tonic-gate 	/* Write the zlib trailer (adler32) */
1259*7c478bd9Sstevel@tonic-gate 	putShortMSB(s, (uInt)(strm->adler >> 16));
1260*7c478bd9Sstevel@tonic-gate 	putShortMSB(s, (uInt)(strm->adler & 0xffff));
1261*7c478bd9Sstevel@tonic-gate 	flush_pending(strm);
1262*7c478bd9Sstevel@tonic-gate 	/*
1263*7c478bd9Sstevel@tonic-gate 	 * If avail_out is zero, the application will call deflate
1264*7c478bd9Sstevel@tonic-gate 	 * again to flush the rest.
1265*7c478bd9Sstevel@tonic-gate 	 */
1266*7c478bd9Sstevel@tonic-gate 	s->noheader = -1;	/* write the trailer only once! */
1267*7c478bd9Sstevel@tonic-gate 	return (s->pending != 0 ? Z_OK : Z_STREAM_END);
1268*7c478bd9Sstevel@tonic-gate }
1269*7c478bd9Sstevel@tonic-gate 
1270*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
1271*7c478bd9Sstevel@tonic-gate int
1272*7c478bd9Sstevel@tonic-gate deflateEnd(strm)
1273*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1274*7c478bd9Sstevel@tonic-gate {
1275*7c478bd9Sstevel@tonic-gate 	int status;
1276*7c478bd9Sstevel@tonic-gate 	deflate_state *s;
1277*7c478bd9Sstevel@tonic-gate 
1278*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL)
1279*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1280*7c478bd9Sstevel@tonic-gate 	s = (deflate_state *) strm->state;
1281*7c478bd9Sstevel@tonic-gate 
1282*7c478bd9Sstevel@tonic-gate 	status = s->status;
1283*7c478bd9Sstevel@tonic-gate 	if (status != INIT_STATE && status != BUSY_STATE &&
1284*7c478bd9Sstevel@tonic-gate 	    status != FINISH_STATE) {
1285*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1286*7c478bd9Sstevel@tonic-gate 	}
1287*7c478bd9Sstevel@tonic-gate 
1288*7c478bd9Sstevel@tonic-gate 	/* Deallocate in reverse order of allocations: */
1289*7c478bd9Sstevel@tonic-gate 	TRY_FREE(strm, s->pending_buf);
1290*7c478bd9Sstevel@tonic-gate 	TRY_FREE(strm, s->head);
1291*7c478bd9Sstevel@tonic-gate 	TRY_FREE(strm, s->prev);
1292*7c478bd9Sstevel@tonic-gate 	TRY_FREE(strm, s->window);
1293*7c478bd9Sstevel@tonic-gate 
1294*7c478bd9Sstevel@tonic-gate 	ZFREE(strm, s);
1295*7c478bd9Sstevel@tonic-gate 	strm->state = Z_NULL;
1296*7c478bd9Sstevel@tonic-gate 
1297*7c478bd9Sstevel@tonic-gate 	return (status == BUSY_STATE ? Z_DATA_ERROR : Z_OK);
1298*7c478bd9Sstevel@tonic-gate }
1299*7c478bd9Sstevel@tonic-gate 
1300*7c478bd9Sstevel@tonic-gate /*
1301*7c478bd9Sstevel@tonic-gate  * =========================================================================
1302*7c478bd9Sstevel@tonic-gate  * Copy the source state to the destination state.
1303*7c478bd9Sstevel@tonic-gate  * To simplify the source, this is not supported for 16-bit MSDOS (which
1304*7c478bd9Sstevel@tonic-gate  * doesn't have enough memory anyway to duplicate compression states).
1305*7c478bd9Sstevel@tonic-gate  */
1306*7c478bd9Sstevel@tonic-gate int
1307*7c478bd9Sstevel@tonic-gate deflateCopy(dest, source)
1308*7c478bd9Sstevel@tonic-gate     z_streamp dest;
1309*7c478bd9Sstevel@tonic-gate     z_streamp source;
1310*7c478bd9Sstevel@tonic-gate {
1311*7c478bd9Sstevel@tonic-gate #ifdef MAXSEG_64K
1312*7c478bd9Sstevel@tonic-gate 	return (Z_STREAM_ERROR);
1313*7c478bd9Sstevel@tonic-gate #else
1314*7c478bd9Sstevel@tonic-gate 	deflate_state *ds;
1315*7c478bd9Sstevel@tonic-gate 	deflate_state *ss;
1316*7c478bd9Sstevel@tonic-gate 	ushf *overlay;
1317*7c478bd9Sstevel@tonic-gate 
1318*7c478bd9Sstevel@tonic-gate 	if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL)
1319*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
1320*7c478bd9Sstevel@tonic-gate 	ss = (deflate_state *) source->state;
1321*7c478bd9Sstevel@tonic-gate 
1322*7c478bd9Sstevel@tonic-gate 	zmemcpy(dest, source, sizeof (*dest));
1323*7c478bd9Sstevel@tonic-gate 
1324*7c478bd9Sstevel@tonic-gate 	ds = (deflate_state *) ZALLOC(dest, 1, sizeof (deflate_state));
1325*7c478bd9Sstevel@tonic-gate 	if (ds == Z_NULL)
1326*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
1327*7c478bd9Sstevel@tonic-gate 	dest->state = (struct internal_state FAR *) ds;
1328*7c478bd9Sstevel@tonic-gate 	zmemcpy(ds, ss, sizeof (*ds));
1329*7c478bd9Sstevel@tonic-gate 	ds->strm = dest;
1330*7c478bd9Sstevel@tonic-gate 
1331*7c478bd9Sstevel@tonic-gate 	ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof (Byte));
1332*7c478bd9Sstevel@tonic-gate 	ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof (Pos));
1333*7c478bd9Sstevel@tonic-gate 	ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof (Pos));
1334*7c478bd9Sstevel@tonic-gate 	overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof (ush)+2);
1335*7c478bd9Sstevel@tonic-gate 	ds->pending_buf = (uchf *) overlay;
1336*7c478bd9Sstevel@tonic-gate 
1337*7c478bd9Sstevel@tonic-gate 	if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
1338*7c478bd9Sstevel@tonic-gate 	    ds->pending_buf == Z_NULL) {
1339*7c478bd9Sstevel@tonic-gate 		ds->status = INIT_STATE;
1340*7c478bd9Sstevel@tonic-gate 		(void) deflateEnd(dest);
1341*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
1342*7c478bd9Sstevel@tonic-gate 	}
1343*7c478bd9Sstevel@tonic-gate 	/* following zmemcpy doesn't work for 16-bit MSDOS */
1344*7c478bd9Sstevel@tonic-gate 	zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof (Byte));
1345*7c478bd9Sstevel@tonic-gate 	zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof (Pos));
1346*7c478bd9Sstevel@tonic-gate 	zmemcpy(ds->head, ss->head, ds->hash_size * sizeof (Pos));
1347*7c478bd9Sstevel@tonic-gate 	zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
1348*7c478bd9Sstevel@tonic-gate 
1349*7c478bd9Sstevel@tonic-gate 	ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
1350*7c478bd9Sstevel@tonic-gate 	ds->d_buf = overlay + ds->lit_bufsize/sizeof (ush);
1351*7c478bd9Sstevel@tonic-gate 	ds->l_buf = ds->pending_buf + (1+sizeof (ush))*ds->lit_bufsize;
1352*7c478bd9Sstevel@tonic-gate 
1353*7c478bd9Sstevel@tonic-gate 	ds->l_desc.dyn_tree = ds->dyn_ltree;
1354*7c478bd9Sstevel@tonic-gate 	ds->d_desc.dyn_tree = ds->dyn_dtree;
1355*7c478bd9Sstevel@tonic-gate 	ds->bl_desc.dyn_tree = ds->bl_tree;
1356*7c478bd9Sstevel@tonic-gate 
1357*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
1358*7c478bd9Sstevel@tonic-gate #endif
1359*7c478bd9Sstevel@tonic-gate }
1360*7c478bd9Sstevel@tonic-gate 
1361*7c478bd9Sstevel@tonic-gate /*
1362*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1363*7c478bd9Sstevel@tonic-gate  * Return the number of bytes of output which are immediately available
1364*7c478bd9Sstevel@tonic-gate  * for output from the decompressor.		---PPP---
1365*7c478bd9Sstevel@tonic-gate  */
1366*7c478bd9Sstevel@tonic-gate int
1367*7c478bd9Sstevel@tonic-gate deflateOutputPending(strm)
1368*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1369*7c478bd9Sstevel@tonic-gate {
1370*7c478bd9Sstevel@tonic-gate 	if (strm == Z_NULL || strm->state == Z_NULL)
1371*7c478bd9Sstevel@tonic-gate 		return (0);
1372*7c478bd9Sstevel@tonic-gate 
1373*7c478bd9Sstevel@tonic-gate 	return (((deflate_state *)(strm->state))->pending);
1374*7c478bd9Sstevel@tonic-gate }
1375*7c478bd9Sstevel@tonic-gate 
1376*7c478bd9Sstevel@tonic-gate /*
1377*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1378*7c478bd9Sstevel@tonic-gate  * Read a new buffer from the current input stream, update the adler32
1379*7c478bd9Sstevel@tonic-gate  * and total number of bytes read.  All deflate() input goes through
1380*7c478bd9Sstevel@tonic-gate  * this function so some applications may wish to modify it to avoid
1381*7c478bd9Sstevel@tonic-gate  * allocating a large strm->next_in buffer and copying from it.
1382*7c478bd9Sstevel@tonic-gate  * (See also flush_pending()).
1383*7c478bd9Sstevel@tonic-gate  */
1384*7c478bd9Sstevel@tonic-gate local int
1385*7c478bd9Sstevel@tonic-gate read_buf(strm, buf, size)
1386*7c478bd9Sstevel@tonic-gate     z_streamp strm;
1387*7c478bd9Sstevel@tonic-gate     Bytef *buf;
1388*7c478bd9Sstevel@tonic-gate     unsigned size;
1389*7c478bd9Sstevel@tonic-gate {
1390*7c478bd9Sstevel@tonic-gate 	unsigned len = strm->avail_in;
1391*7c478bd9Sstevel@tonic-gate 
1392*7c478bd9Sstevel@tonic-gate 	if (len > size) len = size;
1393*7c478bd9Sstevel@tonic-gate 	if (len == 0)
1394*7c478bd9Sstevel@tonic-gate 		return (0);
1395*7c478bd9Sstevel@tonic-gate 
1396*7c478bd9Sstevel@tonic-gate 	strm->avail_in  -= len;
1397*7c478bd9Sstevel@tonic-gate 
1398*7c478bd9Sstevel@tonic-gate 	if (!((deflate_state *)(strm->state))->noheader) {
1399*7c478bd9Sstevel@tonic-gate 		strm->adler = adler32(strm->adler, strm->next_in, len);
1400*7c478bd9Sstevel@tonic-gate 	}
1401*7c478bd9Sstevel@tonic-gate 	zmemcpy(buf, strm->next_in, len);
1402*7c478bd9Sstevel@tonic-gate 	strm->next_in  += len;
1403*7c478bd9Sstevel@tonic-gate 	strm->total_in += len;
1404*7c478bd9Sstevel@tonic-gate 
1405*7c478bd9Sstevel@tonic-gate 	return ((int)len);
1406*7c478bd9Sstevel@tonic-gate }
1407*7c478bd9Sstevel@tonic-gate 
1408*7c478bd9Sstevel@tonic-gate /*
1409*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1410*7c478bd9Sstevel@tonic-gate  * Initialize the "longest match" routines for a new zlib stream
1411*7c478bd9Sstevel@tonic-gate  */
1412*7c478bd9Sstevel@tonic-gate local void
1413*7c478bd9Sstevel@tonic-gate lm_init(s)
1414*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1415*7c478bd9Sstevel@tonic-gate {
1416*7c478bd9Sstevel@tonic-gate 	s->window_size = (ulg)2L*s->w_size;
1417*7c478bd9Sstevel@tonic-gate 
1418*7c478bd9Sstevel@tonic-gate 	CLEAR_HASH(s);
1419*7c478bd9Sstevel@tonic-gate 
1420*7c478bd9Sstevel@tonic-gate 	/* Set the default configuration parameters: */
1421*7c478bd9Sstevel@tonic-gate 	s->max_lazy_match   = configuration_table[s->level].max_lazy;
1422*7c478bd9Sstevel@tonic-gate 	s->good_match	= configuration_table[s->level].good_length;
1423*7c478bd9Sstevel@tonic-gate 	s->nice_match	= configuration_table[s->level].nice_length;
1424*7c478bd9Sstevel@tonic-gate 	s->max_chain_length = configuration_table[s->level].max_chain;
1425*7c478bd9Sstevel@tonic-gate 
1426*7c478bd9Sstevel@tonic-gate 	s->strstart = 0;
1427*7c478bd9Sstevel@tonic-gate 	s->block_start = 0L;
1428*7c478bd9Sstevel@tonic-gate 	s->lookahead = 0;
1429*7c478bd9Sstevel@tonic-gate 	s->match_length = s->prev_length = MIN_MATCH-1;
1430*7c478bd9Sstevel@tonic-gate 	s->match_available = 0;
1431*7c478bd9Sstevel@tonic-gate 	s->ins_h = 0;
1432*7c478bd9Sstevel@tonic-gate #ifdef ASMV
1433*7c478bd9Sstevel@tonic-gate 	match_init();	/* initialize the asm code */
1434*7c478bd9Sstevel@tonic-gate #endif
1435*7c478bd9Sstevel@tonic-gate }
1436*7c478bd9Sstevel@tonic-gate 
1437*7c478bd9Sstevel@tonic-gate /*
1438*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1439*7c478bd9Sstevel@tonic-gate  * Set match_start to the longest match starting at the given string and
1440*7c478bd9Sstevel@tonic-gate  * return its length. Matches shorter or equal to prev_length are discarded,
1441*7c478bd9Sstevel@tonic-gate  * in which case the result is equal to prev_length and match_start is
1442*7c478bd9Sstevel@tonic-gate  * garbage.
1443*7c478bd9Sstevel@tonic-gate  * IN assertions: cur_match is the head of the hash chain for the current
1444*7c478bd9Sstevel@tonic-gate  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
1445*7c478bd9Sstevel@tonic-gate  * OUT assertion: the match length is not greater than s->lookahead.
1446*7c478bd9Sstevel@tonic-gate  */
1447*7c478bd9Sstevel@tonic-gate #ifndef ASMV
1448*7c478bd9Sstevel@tonic-gate /*
1449*7c478bd9Sstevel@tonic-gate  * For 80x86 and 680x0, an optimized version will be provided in
1450*7c478bd9Sstevel@tonic-gate  * match.asm or match.S. The code will be functionally equivalent.
1451*7c478bd9Sstevel@tonic-gate  */
1452*7c478bd9Sstevel@tonic-gate #ifndef FASTEST
1453*7c478bd9Sstevel@tonic-gate local uInt
1454*7c478bd9Sstevel@tonic-gate longest_match(s, cur_match)
1455*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1456*7c478bd9Sstevel@tonic-gate     IPos cur_match;	/* current match */
1457*7c478bd9Sstevel@tonic-gate {
1458*7c478bd9Sstevel@tonic-gate 	/* max hash chain length */
1459*7c478bd9Sstevel@tonic-gate 	unsigned chain_length = s->max_chain_length;
1460*7c478bd9Sstevel@tonic-gate 	register Bytef *scan = s->window + s->strstart;	/* current string */
1461*7c478bd9Sstevel@tonic-gate 	register Bytef *match;	/* matched string */
1462*7c478bd9Sstevel@tonic-gate 	register int len;	/* length of current match */
1463*7c478bd9Sstevel@tonic-gate 	int best_len = s->prev_length;	/* best match length so far */
1464*7c478bd9Sstevel@tonic-gate 	int nice_match = s->nice_match;	/* stop if match long enough */
1465*7c478bd9Sstevel@tonic-gate 	IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
1466*7c478bd9Sstevel@tonic-gate 	    s->strstart - (IPos)MAX_DIST(s) : NIL;
1467*7c478bd9Sstevel@tonic-gate 	/*
1468*7c478bd9Sstevel@tonic-gate 	 * Stop when cur_match becomes <= limit. To simplify the code,
1469*7c478bd9Sstevel@tonic-gate 	 * we prevent matches with the string of window index 0.
1470*7c478bd9Sstevel@tonic-gate 	 */
1471*7c478bd9Sstevel@tonic-gate 	Posf *prev = s->prev;
1472*7c478bd9Sstevel@tonic-gate 	uInt wmask = s->w_mask;
1473*7c478bd9Sstevel@tonic-gate 
1474*7c478bd9Sstevel@tonic-gate #ifdef UNALIGNED_OK
1475*7c478bd9Sstevel@tonic-gate 	/*
1476*7c478bd9Sstevel@tonic-gate 	 * Compare two bytes at a time. Note: this is not always
1477*7c478bd9Sstevel@tonic-gate 	 * beneficial.  Try with and without -DUNALIGNED_OK to check.
1478*7c478bd9Sstevel@tonic-gate 	 */
1479*7c478bd9Sstevel@tonic-gate 	register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
1480*7c478bd9Sstevel@tonic-gate 	register ush scan_start = *(ushf*)scan;
1481*7c478bd9Sstevel@tonic-gate 	register ush scan_end   = *(ushf*)(scan+best_len-1);
1482*7c478bd9Sstevel@tonic-gate #else
1483*7c478bd9Sstevel@tonic-gate 	register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1484*7c478bd9Sstevel@tonic-gate 	register Byte scan_end1  = scan[best_len-1];
1485*7c478bd9Sstevel@tonic-gate 	register Byte scan_end   = scan[best_len];
1486*7c478bd9Sstevel@tonic-gate #endif
1487*7c478bd9Sstevel@tonic-gate 
1488*7c478bd9Sstevel@tonic-gate 	/*
1489*7c478bd9Sstevel@tonic-gate 	 * The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2
1490*7c478bd9Sstevel@tonic-gate 	 * multiple of 16.  It is easy to get rid of this optimization
1491*7c478bd9Sstevel@tonic-gate 	 * if necessary.
1492*7c478bd9Sstevel@tonic-gate 	 */
1493*7c478bd9Sstevel@tonic-gate 	Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1494*7c478bd9Sstevel@tonic-gate 
1495*7c478bd9Sstevel@tonic-gate 	/* Do not waste too much time if we already have a good match: */
1496*7c478bd9Sstevel@tonic-gate 	if (s->prev_length >= s->good_match) {
1497*7c478bd9Sstevel@tonic-gate 		chain_length >>= 2;
1498*7c478bd9Sstevel@tonic-gate 	}
1499*7c478bd9Sstevel@tonic-gate 	/*
1500*7c478bd9Sstevel@tonic-gate 	 * Do not look for matches beyond the end of the input. This
1501*7c478bd9Sstevel@tonic-gate 	 * is necessary to make deflate deterministic.
1502*7c478bd9Sstevel@tonic-gate 	 */
1503*7c478bd9Sstevel@tonic-gate 	if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
1504*7c478bd9Sstevel@tonic-gate 
1505*7c478bd9Sstevel@tonic-gate 	Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD,
1506*7c478bd9Sstevel@tonic-gate 	    "need lookahead");
1507*7c478bd9Sstevel@tonic-gate 
1508*7c478bd9Sstevel@tonic-gate 	do {
1509*7c478bd9Sstevel@tonic-gate 		Assert(cur_match <= s->strstart, "no future");
1510*7c478bd9Sstevel@tonic-gate 		match = s->window + cur_match;
1511*7c478bd9Sstevel@tonic-gate 
1512*7c478bd9Sstevel@tonic-gate 		/*
1513*7c478bd9Sstevel@tonic-gate 		 * Skip to next match if the match length cannot
1514*7c478bd9Sstevel@tonic-gate 		 * increase or if the match length is less than 2:
1515*7c478bd9Sstevel@tonic-gate 		 */
1516*7c478bd9Sstevel@tonic-gate #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
1517*7c478bd9Sstevel@tonic-gate 		/*
1518*7c478bd9Sstevel@tonic-gate 		 * This code assumes sizeof (unsigned short) == 2. Do
1519*7c478bd9Sstevel@tonic-gate 		 * not use UNALIGNED_OK if your compiler uses a
1520*7c478bd9Sstevel@tonic-gate 		 * different size.
1521*7c478bd9Sstevel@tonic-gate 		 */
1522*7c478bd9Sstevel@tonic-gate 		if (*(ushf*)(match+best_len-1) != scan_end ||
1523*7c478bd9Sstevel@tonic-gate 		    *(ushf*)match != scan_start) continue;
1524*7c478bd9Sstevel@tonic-gate 
1525*7c478bd9Sstevel@tonic-gate 		/*
1526*7c478bd9Sstevel@tonic-gate 		 * It is not necessary to compare scan[2] and match[2]
1527*7c478bd9Sstevel@tonic-gate 		 * since they are always equal when the other bytes
1528*7c478bd9Sstevel@tonic-gate 		 * match, given that the hash keys are equal and that
1529*7c478bd9Sstevel@tonic-gate 		 * HASH_BITS >= 8. Compare 2 bytes at a time at
1530*7c478bd9Sstevel@tonic-gate 		 * strstart+3, +5, ... up to strstart+257. We check
1531*7c478bd9Sstevel@tonic-gate 		 * for insufficient lookahead only every 4th
1532*7c478bd9Sstevel@tonic-gate 		 * comparison; the 128th check will be made at
1533*7c478bd9Sstevel@tonic-gate 		 * strstart+257. If MAX_MATCH-2 is not a multiple of
1534*7c478bd9Sstevel@tonic-gate 		 * 8, it is necessary to put more guard bytes at the
1535*7c478bd9Sstevel@tonic-gate 		 * end of the window, or to check more often for
1536*7c478bd9Sstevel@tonic-gate 		 * insufficient lookahead.
1537*7c478bd9Sstevel@tonic-gate 		 */
1538*7c478bd9Sstevel@tonic-gate 		Assert(scan[2] == match[2], "scan[2]?");
1539*7c478bd9Sstevel@tonic-gate 		scan++, match++;
1540*7c478bd9Sstevel@tonic-gate 		do {
1541*7c478bd9Sstevel@tonic-gate 		} while (*(ushf *)(scan += 2) == *(ushf *)(match += 2) &&
1542*7c478bd9Sstevel@tonic-gate 		    *(ushf *)(scan += 2) == *(ushf *)(match += 2) &&
1543*7c478bd9Sstevel@tonic-gate 		    *(ushf *)(scan += 2) == *(ushf *)(match += 2) &&
1544*7c478bd9Sstevel@tonic-gate 		    *(ushf *)(scan += 2) == *(ushf *)(match += 2) &&
1545*7c478bd9Sstevel@tonic-gate 		    scan < strend);
1546*7c478bd9Sstevel@tonic-gate 		/* The funny "do {}" generates better code on most compilers */
1547*7c478bd9Sstevel@tonic-gate 
1548*7c478bd9Sstevel@tonic-gate 		/* Here, scan <= window+strstart+257 */
1549*7c478bd9Sstevel@tonic-gate 		Assert(scan <= s->window+(unsigned)(s->window_size-1),
1550*7c478bd9Sstevel@tonic-gate 		    "wild scan");
1551*7c478bd9Sstevel@tonic-gate 		if (*scan == *match) scan++;
1552*7c478bd9Sstevel@tonic-gate 
1553*7c478bd9Sstevel@tonic-gate 		len = (MAX_MATCH - 1) - (int)(strend-scan);
1554*7c478bd9Sstevel@tonic-gate 		scan = strend - (MAX_MATCH-1);
1555*7c478bd9Sstevel@tonic-gate 
1556*7c478bd9Sstevel@tonic-gate #else /* UNALIGNED_OK */
1557*7c478bd9Sstevel@tonic-gate 
1558*7c478bd9Sstevel@tonic-gate 		if (match[best_len]	!= scan_end	||
1559*7c478bd9Sstevel@tonic-gate 		    match[best_len-1]	!= scan_end1	||
1560*7c478bd9Sstevel@tonic-gate 		    *match		!= *scan	||
1561*7c478bd9Sstevel@tonic-gate 		    *++match		!= scan[1])
1562*7c478bd9Sstevel@tonic-gate 			continue;
1563*7c478bd9Sstevel@tonic-gate 
1564*7c478bd9Sstevel@tonic-gate 		/*
1565*7c478bd9Sstevel@tonic-gate 		 * The check at best_len-1 can be removed because it
1566*7c478bd9Sstevel@tonic-gate 		 * will be made again later. (This heuristic is not
1567*7c478bd9Sstevel@tonic-gate 		 * always a win.)  It is not necessary to compare
1568*7c478bd9Sstevel@tonic-gate 		 * scan[2] and match[2] since they are always equal
1569*7c478bd9Sstevel@tonic-gate 		 * when the other bytes match, given that the hash
1570*7c478bd9Sstevel@tonic-gate 		 * keys are equal and that HASH_BITS >= 8.
1571*7c478bd9Sstevel@tonic-gate 		 */
1572*7c478bd9Sstevel@tonic-gate 		scan += 2, match++;
1573*7c478bd9Sstevel@tonic-gate 		Assert(*scan == *match, "match[2]?");
1574*7c478bd9Sstevel@tonic-gate 
1575*7c478bd9Sstevel@tonic-gate 		/*
1576*7c478bd9Sstevel@tonic-gate 		 * We check for insufficient lookahead only every 8th
1577*7c478bd9Sstevel@tonic-gate 		 * comparison; the 256th check will be made at
1578*7c478bd9Sstevel@tonic-gate 		 * strstart+258.
1579*7c478bd9Sstevel@tonic-gate 		 */
1580*7c478bd9Sstevel@tonic-gate 		do {
1581*7c478bd9Sstevel@tonic-gate 		} while (*++scan == *++match && *++scan == *++match &&
1582*7c478bd9Sstevel@tonic-gate 		    *++scan == *++match && *++scan == *++match &&
1583*7c478bd9Sstevel@tonic-gate 		    *++scan == *++match && *++scan == *++match &&
1584*7c478bd9Sstevel@tonic-gate 		    *++scan == *++match && *++scan == *++match &&
1585*7c478bd9Sstevel@tonic-gate 		    scan < strend);
1586*7c478bd9Sstevel@tonic-gate 
1587*7c478bd9Sstevel@tonic-gate 		Assert(scan <= s->window+(unsigned)(s->window_size-1),
1588*7c478bd9Sstevel@tonic-gate 		    "wild scan");
1589*7c478bd9Sstevel@tonic-gate 
1590*7c478bd9Sstevel@tonic-gate 		len = MAX_MATCH - (int)(strend - scan);
1591*7c478bd9Sstevel@tonic-gate 		scan = strend - MAX_MATCH;
1592*7c478bd9Sstevel@tonic-gate 
1593*7c478bd9Sstevel@tonic-gate #endif /* UNALIGNED_OK */
1594*7c478bd9Sstevel@tonic-gate 
1595*7c478bd9Sstevel@tonic-gate 		if (len > best_len) {
1596*7c478bd9Sstevel@tonic-gate 			s->match_start = cur_match;
1597*7c478bd9Sstevel@tonic-gate 			best_len = len;
1598*7c478bd9Sstevel@tonic-gate 			if (len >= nice_match) break;
1599*7c478bd9Sstevel@tonic-gate #ifdef UNALIGNED_OK
1600*7c478bd9Sstevel@tonic-gate 			scan_end = *(ushf*)(scan+best_len-1);
1601*7c478bd9Sstevel@tonic-gate #else
1602*7c478bd9Sstevel@tonic-gate 			scan_end1  = scan[best_len-1];
1603*7c478bd9Sstevel@tonic-gate 			scan_end   = scan[best_len];
1604*7c478bd9Sstevel@tonic-gate #endif
1605*7c478bd9Sstevel@tonic-gate 		}
1606*7c478bd9Sstevel@tonic-gate 	} while ((cur_match = prev[cur_match & wmask]) > limit &&
1607*7c478bd9Sstevel@tonic-gate 	    --chain_length != 0);
1608*7c478bd9Sstevel@tonic-gate 
1609*7c478bd9Sstevel@tonic-gate 	if ((uInt)best_len <= s->lookahead)
1610*7c478bd9Sstevel@tonic-gate 		return (best_len);
1611*7c478bd9Sstevel@tonic-gate 	return (s->lookahead);
1612*7c478bd9Sstevel@tonic-gate }
1613*7c478bd9Sstevel@tonic-gate #else /* FASTEST */
1614*7c478bd9Sstevel@tonic-gate /*
1615*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------------
1616*7c478bd9Sstevel@tonic-gate  * Optimized version for level == 1 only
1617*7c478bd9Sstevel@tonic-gate  */
1618*7c478bd9Sstevel@tonic-gate local uInt
1619*7c478bd9Sstevel@tonic-gate longest_match(s, cur_match)
1620*7c478bd9Sstevel@tonic-gate deflate_state *s;
1621*7c478bd9Sstevel@tonic-gate IPos cur_match;		/* current match */
1622*7c478bd9Sstevel@tonic-gate {
1623*7c478bd9Sstevel@tonic-gate 	register Bytef *scan = s->window + s->strstart; /* current string */
1624*7c478bd9Sstevel@tonic-gate 	register Bytef *match;		/* matched string */
1625*7c478bd9Sstevel@tonic-gate 	register int len;			/* length of current match */
1626*7c478bd9Sstevel@tonic-gate 	register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1627*7c478bd9Sstevel@tonic-gate 
1628*7c478bd9Sstevel@tonic-gate 	/*
1629*7c478bd9Sstevel@tonic-gate 	 * The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2
1630*7c478bd9Sstevel@tonic-gate 	 * multiple of 16.  It is easy to get rid of this optimization
1631*7c478bd9Sstevel@tonic-gate 	 * if necessary.
1632*7c478bd9Sstevel@tonic-gate 	 */
1633*7c478bd9Sstevel@tonic-gate 	Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1634*7c478bd9Sstevel@tonic-gate 
1635*7c478bd9Sstevel@tonic-gate 	Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD,
1636*7c478bd9Sstevel@tonic-gate 	    "need lookahead");
1637*7c478bd9Sstevel@tonic-gate 
1638*7c478bd9Sstevel@tonic-gate 	Assert(cur_match <= s->strstart, "no future");
1639*7c478bd9Sstevel@tonic-gate 
1640*7c478bd9Sstevel@tonic-gate 	match = s->window + cur_match;
1641*7c478bd9Sstevel@tonic-gate 
1642*7c478bd9Sstevel@tonic-gate 	/* Return failure if the match length is less than 2: */
1643*7c478bd9Sstevel@tonic-gate 	if (match[0] != scan[0] || match[1] != scan[1])
1644*7c478bd9Sstevel@tonic-gate 		return (MIN_MATCH-1);
1645*7c478bd9Sstevel@tonic-gate 
1646*7c478bd9Sstevel@tonic-gate 	/*
1647*7c478bd9Sstevel@tonic-gate 	 * The check at best_len-1 can be removed because it will be
1648*7c478bd9Sstevel@tonic-gate 	 * made again later. (This heuristic is not always a win.)  It
1649*7c478bd9Sstevel@tonic-gate 	 * is not necessary to compare scan[2] and match[2] since they
1650*7c478bd9Sstevel@tonic-gate 	 * are always equal when the other bytes match, given that the
1651*7c478bd9Sstevel@tonic-gate 	 * hash keys are equal and that HASH_BITS >= 8.
1652*7c478bd9Sstevel@tonic-gate 	 */
1653*7c478bd9Sstevel@tonic-gate 	scan += 2, match += 2;
1654*7c478bd9Sstevel@tonic-gate 	Assert(*scan == *match, "match[2]?");
1655*7c478bd9Sstevel@tonic-gate 
1656*7c478bd9Sstevel@tonic-gate 	/*
1657*7c478bd9Sstevel@tonic-gate 	 * We check for insufficient lookahead only every 8th comparison;
1658*7c478bd9Sstevel@tonic-gate 	 * the 256th check will be made at strstart+258.
1659*7c478bd9Sstevel@tonic-gate 	 */
1660*7c478bd9Sstevel@tonic-gate 	do {
1661*7c478bd9Sstevel@tonic-gate 	} while (*++scan == *++match && *++scan == *++match &&
1662*7c478bd9Sstevel@tonic-gate 	    *++scan == *++match && *++scan == *++match &&
1663*7c478bd9Sstevel@tonic-gate 	    *++scan == *++match && *++scan == *++match &&
1664*7c478bd9Sstevel@tonic-gate 	    *++scan == *++match && *++scan == *++match &&
1665*7c478bd9Sstevel@tonic-gate 	    scan < strend);
1666*7c478bd9Sstevel@tonic-gate 
1667*7c478bd9Sstevel@tonic-gate 	Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1668*7c478bd9Sstevel@tonic-gate 
1669*7c478bd9Sstevel@tonic-gate 	len = MAX_MATCH - (int)(strend - scan);
1670*7c478bd9Sstevel@tonic-gate 
1671*7c478bd9Sstevel@tonic-gate 	if (len < MIN_MATCH)
1672*7c478bd9Sstevel@tonic-gate 		return (MIN_MATCH - 1);
1673*7c478bd9Sstevel@tonic-gate 
1674*7c478bd9Sstevel@tonic-gate 	s->match_start = cur_match;
1675*7c478bd9Sstevel@tonic-gate 	return (len <= s->lookahead ? len : s->lookahead);
1676*7c478bd9Sstevel@tonic-gate }
1677*7c478bd9Sstevel@tonic-gate #endif /* FASTEST */
1678*7c478bd9Sstevel@tonic-gate #endif /* ASMV */
1679*7c478bd9Sstevel@tonic-gate 
1680*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
1681*7c478bd9Sstevel@tonic-gate /*
1682*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1683*7c478bd9Sstevel@tonic-gate  * Check that the match at match_start is indeed a match.
1684*7c478bd9Sstevel@tonic-gate  */
1685*7c478bd9Sstevel@tonic-gate local void
1686*7c478bd9Sstevel@tonic-gate check_match(s, start, match, length)
1687*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1688*7c478bd9Sstevel@tonic-gate     IPos start, match;
1689*7c478bd9Sstevel@tonic-gate     int length;
1690*7c478bd9Sstevel@tonic-gate {
1691*7c478bd9Sstevel@tonic-gate 	/* check that the match is indeed a match */
1692*7c478bd9Sstevel@tonic-gate 	if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) {
1693*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, " start %u, match %u, length %d\n",
1694*7c478bd9Sstevel@tonic-gate 		    start, match, length);
1695*7c478bd9Sstevel@tonic-gate 		do {
1696*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%c%c", s->window[match++],
1697*7c478bd9Sstevel@tonic-gate 			    s->window[start++]);
1698*7c478bd9Sstevel@tonic-gate 		} while (--length != 0);
1699*7c478bd9Sstevel@tonic-gate 		z_error("invalid match");
1700*7c478bd9Sstevel@tonic-gate 	}
1701*7c478bd9Sstevel@tonic-gate 	if (z_verbose > 1) {
1702*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "\\[%d,%d]", start-match, length);
1703*7c478bd9Sstevel@tonic-gate 		do { putc(s->window[start++], stderr); } while (--length != 0);
1704*7c478bd9Sstevel@tonic-gate 	}
1705*7c478bd9Sstevel@tonic-gate }
1706*7c478bd9Sstevel@tonic-gate #else
1707*7c478bd9Sstevel@tonic-gate #define	check_match(s, start, match, length)
1708*7c478bd9Sstevel@tonic-gate #endif
1709*7c478bd9Sstevel@tonic-gate 
1710*7c478bd9Sstevel@tonic-gate /*
1711*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1712*7c478bd9Sstevel@tonic-gate  * Fill the window when the lookahead becomes insufficient.
1713*7c478bd9Sstevel@tonic-gate  * Updates strstart and lookahead.
1714*7c478bd9Sstevel@tonic-gate  *
1715*7c478bd9Sstevel@tonic-gate  * IN assertion: lookahead < MIN_LOOKAHEAD
1716*7c478bd9Sstevel@tonic-gate  * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
1717*7c478bd9Sstevel@tonic-gate  *    At least one byte has been read, or avail_in == 0; reads are
1718*7c478bd9Sstevel@tonic-gate  *    performed for at least two bytes (required for the zip translate_eol
1719*7c478bd9Sstevel@tonic-gate  *    option -- not supported here).
1720*7c478bd9Sstevel@tonic-gate  */
1721*7c478bd9Sstevel@tonic-gate local void
1722*7c478bd9Sstevel@tonic-gate fill_window(s)
1723*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1724*7c478bd9Sstevel@tonic-gate {
1725*7c478bd9Sstevel@tonic-gate 	register unsigned n, m;
1726*7c478bd9Sstevel@tonic-gate 	register Posf *p;
1727*7c478bd9Sstevel@tonic-gate 	unsigned more;	/* Amount of free space at the end of the window. */
1728*7c478bd9Sstevel@tonic-gate 	uInt wsize = s->w_size;
1729*7c478bd9Sstevel@tonic-gate 
1730*7c478bd9Sstevel@tonic-gate 	do {
1731*7c478bd9Sstevel@tonic-gate 		more = (unsigned)(s->window_size -(ulg)s->lookahead -
1732*7c478bd9Sstevel@tonic-gate 		    (ulg)s->strstart);
1733*7c478bd9Sstevel@tonic-gate 
1734*7c478bd9Sstevel@tonic-gate 		/* Deal with !@#$% 64K limit: */
1735*7c478bd9Sstevel@tonic-gate 		if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
1736*7c478bd9Sstevel@tonic-gate 			more = wsize;
1737*7c478bd9Sstevel@tonic-gate 
1738*7c478bd9Sstevel@tonic-gate 		} else if (more == (unsigned)(-1)) {
1739*7c478bd9Sstevel@tonic-gate 			/*
1740*7c478bd9Sstevel@tonic-gate 			 * Very unlikely, but possible on 16 bit
1741*7c478bd9Sstevel@tonic-gate 			 * machine if strstart == 0 and lookahead == 1
1742*7c478bd9Sstevel@tonic-gate 			 * (input done one byte at time)
1743*7c478bd9Sstevel@tonic-gate 			 */
1744*7c478bd9Sstevel@tonic-gate 			more--;
1745*7c478bd9Sstevel@tonic-gate 
1746*7c478bd9Sstevel@tonic-gate 			/*
1747*7c478bd9Sstevel@tonic-gate 			 * If the window is almost full and there is
1748*7c478bd9Sstevel@tonic-gate 			 * insufficient lookahead, move the upper half
1749*7c478bd9Sstevel@tonic-gate 			 * to the lower one to make room in the upper
1750*7c478bd9Sstevel@tonic-gate 			 * half.
1751*7c478bd9Sstevel@tonic-gate 			 */
1752*7c478bd9Sstevel@tonic-gate 		} else if (s->strstart >= wsize+MAX_DIST(s)) {
1753*7c478bd9Sstevel@tonic-gate 
1754*7c478bd9Sstevel@tonic-gate 			Assert(wsize+wsize <= s->window_size, "wsize*2");
1755*7c478bd9Sstevel@tonic-gate 			zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
1756*7c478bd9Sstevel@tonic-gate 			s->match_start -= wsize;
1757*7c478bd9Sstevel@tonic-gate 			/* we now have strstart >= MAX_DIST */
1758*7c478bd9Sstevel@tonic-gate 			s->strstart    -= wsize;
1759*7c478bd9Sstevel@tonic-gate 			s->block_start -= (long)wsize;
1760*7c478bd9Sstevel@tonic-gate 
1761*7c478bd9Sstevel@tonic-gate 			/*
1762*7c478bd9Sstevel@tonic-gate 			 * Slide the hash table (could be avoided with
1763*7c478bd9Sstevel@tonic-gate 			 * 32 bit values at the expense of memory
1764*7c478bd9Sstevel@tonic-gate 			 * usage). We slide even when level == 0 to
1765*7c478bd9Sstevel@tonic-gate 			 * keep the hash table consistent if we switch
1766*7c478bd9Sstevel@tonic-gate 			 * back to level > 0 later. (Using level 0
1767*7c478bd9Sstevel@tonic-gate 			 * permanently is not an optimal usage of
1768*7c478bd9Sstevel@tonic-gate 			 * zlib, so we don't care about this
1769*7c478bd9Sstevel@tonic-gate 			 * pathological case.)
1770*7c478bd9Sstevel@tonic-gate 			 */
1771*7c478bd9Sstevel@tonic-gate 			n = s->hash_size;
1772*7c478bd9Sstevel@tonic-gate 			p = &s->head[n];
1773*7c478bd9Sstevel@tonic-gate 			do {
1774*7c478bd9Sstevel@tonic-gate 				m = *--p;
1775*7c478bd9Sstevel@tonic-gate 				*p = (Pos)(m >= wsize ? m-wsize : NIL);
1776*7c478bd9Sstevel@tonic-gate 			} while (--n);
1777*7c478bd9Sstevel@tonic-gate 
1778*7c478bd9Sstevel@tonic-gate 			n = wsize;
1779*7c478bd9Sstevel@tonic-gate #ifndef FASTEST
1780*7c478bd9Sstevel@tonic-gate 			p = &s->prev[n];
1781*7c478bd9Sstevel@tonic-gate 			do {
1782*7c478bd9Sstevel@tonic-gate 				m = *--p;
1783*7c478bd9Sstevel@tonic-gate 				*p = (Pos)(m >= wsize ? m-wsize : NIL);
1784*7c478bd9Sstevel@tonic-gate 				/*
1785*7c478bd9Sstevel@tonic-gate 				 * If n is not on any hash chain,
1786*7c478bd9Sstevel@tonic-gate 				 * prev[n] is garbage but its value
1787*7c478bd9Sstevel@tonic-gate 				 * will never be used.
1788*7c478bd9Sstevel@tonic-gate 				 */
1789*7c478bd9Sstevel@tonic-gate 			} while (--n);
1790*7c478bd9Sstevel@tonic-gate #endif
1791*7c478bd9Sstevel@tonic-gate 			more += wsize;
1792*7c478bd9Sstevel@tonic-gate 		}
1793*7c478bd9Sstevel@tonic-gate 		if (s->strm->avail_in == 0)
1794*7c478bd9Sstevel@tonic-gate 			return;
1795*7c478bd9Sstevel@tonic-gate 
1796*7c478bd9Sstevel@tonic-gate 		/*
1797*7c478bd9Sstevel@tonic-gate 		 * If there was no sliding:
1798*7c478bd9Sstevel@tonic-gate 		 *    strstart <= WSIZE+MAX_DIST-1 &&
1799*7c478bd9Sstevel@tonic-gate 		 *	lookahead <= MIN_LOOKAHEAD - 1 &&
1800*7c478bd9Sstevel@tonic-gate 		 *    more == window_size - lookahead - strstart
1801*7c478bd9Sstevel@tonic-gate 		 * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE +
1802*7c478bd9Sstevel@tonic-gate 		 *	MAX_DIST-1)
1803*7c478bd9Sstevel@tonic-gate 		 * => more >= window_size - 2*WSIZE + 2
1804*7c478bd9Sstevel@tonic-gate 		 * In the BIG_MEM or MMAP case (not yet supported),
1805*7c478bd9Sstevel@tonic-gate 		 *   window_size == input_size + MIN_LOOKAHEAD  &&
1806*7c478bd9Sstevel@tonic-gate 		 *   strstart + s->lookahead <= input_size =>
1807*7c478bd9Sstevel@tonic-gate 		 *	more >= MIN_LOOKAHEAD.
1808*7c478bd9Sstevel@tonic-gate 		 * Otherwise, window_size == 2*WSIZE so more >= 2.
1809*7c478bd9Sstevel@tonic-gate 		 * If there was sliding, more >= WSIZE. So in all cases,
1810*7c478bd9Sstevel@tonic-gate 		 * more >= 2.
1811*7c478bd9Sstevel@tonic-gate 		 */
1812*7c478bd9Sstevel@tonic-gate 		Assert(more >= 2, "more < 2");
1813*7c478bd9Sstevel@tonic-gate 		Assert(s->strstart + s->lookahead + more <= s->window_size,
1814*7c478bd9Sstevel@tonic-gate 		    "read too much");
1815*7c478bd9Sstevel@tonic-gate 
1816*7c478bd9Sstevel@tonic-gate 		n = read_buf(s->strm, s->window + s->strstart + s->lookahead,
1817*7c478bd9Sstevel@tonic-gate 		    more);
1818*7c478bd9Sstevel@tonic-gate 		s->lookahead += n;
1819*7c478bd9Sstevel@tonic-gate 
1820*7c478bd9Sstevel@tonic-gate 		/* Initialize the hash value now that we have some input: */
1821*7c478bd9Sstevel@tonic-gate 		if (s->lookahead >= MIN_MATCH) {
1822*7c478bd9Sstevel@tonic-gate 			s->ins_h = s->window[s->strstart];
1823*7c478bd9Sstevel@tonic-gate 			UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1824*7c478bd9Sstevel@tonic-gate #if MIN_MATCH != 3
1825*7c478bd9Sstevel@tonic-gate 			Call UPDATE_HASH() MIN_MATCH-3 more times
1826*7c478bd9Sstevel@tonic-gate #endif
1827*7c478bd9Sstevel@tonic-gate 			    }
1828*7c478bd9Sstevel@tonic-gate 		/*
1829*7c478bd9Sstevel@tonic-gate 		 * If the whole input has less than MIN_MATCH bytes,
1830*7c478bd9Sstevel@tonic-gate 		 * ins_h is garbage, but this is not important since
1831*7c478bd9Sstevel@tonic-gate 		 * only literal bytes will be emitted.
1832*7c478bd9Sstevel@tonic-gate 		 */
1833*7c478bd9Sstevel@tonic-gate 
1834*7c478bd9Sstevel@tonic-gate 	} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1835*7c478bd9Sstevel@tonic-gate }
1836*7c478bd9Sstevel@tonic-gate 
1837*7c478bd9Sstevel@tonic-gate /*
1838*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1839*7c478bd9Sstevel@tonic-gate  * Flush the current block, with given end-of-file flag.
1840*7c478bd9Sstevel@tonic-gate  * IN assertion: strstart is set to the end of the current match.
1841*7c478bd9Sstevel@tonic-gate  */
1842*7c478bd9Sstevel@tonic-gate #define	FLUSH_BLOCK_ONLY(s, eof) { \
1843*7c478bd9Sstevel@tonic-gate 	_tr_flush_block(s, (s->block_start >= 0L ? \
1844*7c478bd9Sstevel@tonic-gate 		(charf *)&s->window[(unsigned)s->block_start] : \
1845*7c478bd9Sstevel@tonic-gate 		(charf *)Z_NULL), \
1846*7c478bd9Sstevel@tonic-gate 		(ulg)((long)s->strstart - s->block_start), \
1847*7c478bd9Sstevel@tonic-gate 		(eof)); \
1848*7c478bd9Sstevel@tonic-gate 	s->block_start = s->strstart; \
1849*7c478bd9Sstevel@tonic-gate 	flush_pending(s->strm); \
1850*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "[FLUSH]")); \
1851*7c478bd9Sstevel@tonic-gate }
1852*7c478bd9Sstevel@tonic-gate 
1853*7c478bd9Sstevel@tonic-gate /* Same but force premature exit if necessary. */
1854*7c478bd9Sstevel@tonic-gate #define	FLUSH_BLOCK(s, eof) { \
1855*7c478bd9Sstevel@tonic-gate 	FLUSH_BLOCK_ONLY(s, eof); \
1856*7c478bd9Sstevel@tonic-gate 	if (s->strm->avail_out == 0) \
1857*7c478bd9Sstevel@tonic-gate 		return ((eof) ? finish_started : need_more); \
1858*7c478bd9Sstevel@tonic-gate }
1859*7c478bd9Sstevel@tonic-gate 
1860*7c478bd9Sstevel@tonic-gate /*
1861*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1862*7c478bd9Sstevel@tonic-gate  * Copy without compression as much as possible from the input stream, return
1863*7c478bd9Sstevel@tonic-gate  * the current block state.
1864*7c478bd9Sstevel@tonic-gate  * This function does not insert new strings in the dictionary since
1865*7c478bd9Sstevel@tonic-gate  * uncompressible data is probably not useful. This function is used
1866*7c478bd9Sstevel@tonic-gate  * only for the level=0 compression option.
1867*7c478bd9Sstevel@tonic-gate  * NOTE: this function should be optimized to avoid extra copying from
1868*7c478bd9Sstevel@tonic-gate  * window to pending_buf.
1869*7c478bd9Sstevel@tonic-gate  */
1870*7c478bd9Sstevel@tonic-gate local block_state
1871*7c478bd9Sstevel@tonic-gate deflate_stored(s, flush)
1872*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1873*7c478bd9Sstevel@tonic-gate     int flush;
1874*7c478bd9Sstevel@tonic-gate {
1875*7c478bd9Sstevel@tonic-gate 	/*
1876*7c478bd9Sstevel@tonic-gate 	 * Stored blocks are limited to 0xffff bytes, pending_buf is
1877*7c478bd9Sstevel@tonic-gate 	 * limited to pending_buf_size, and each stored block has a 5
1878*7c478bd9Sstevel@tonic-gate 	 * byte header:
1879*7c478bd9Sstevel@tonic-gate 	 */
1880*7c478bd9Sstevel@tonic-gate 	ulg max_block_size = 0xffff;
1881*7c478bd9Sstevel@tonic-gate 	ulg max_start;
1882*7c478bd9Sstevel@tonic-gate 
1883*7c478bd9Sstevel@tonic-gate 	if (max_block_size > s->pending_buf_size - 5) {
1884*7c478bd9Sstevel@tonic-gate 		max_block_size = s->pending_buf_size - 5;
1885*7c478bd9Sstevel@tonic-gate 	}
1886*7c478bd9Sstevel@tonic-gate 
1887*7c478bd9Sstevel@tonic-gate 	/* Copy as much as possible from input to output: */
1888*7c478bd9Sstevel@tonic-gate 	for (;;) {
1889*7c478bd9Sstevel@tonic-gate 		/* Fill the window as much as possible: */
1890*7c478bd9Sstevel@tonic-gate 		if (s->lookahead <= 1) {
1891*7c478bd9Sstevel@tonic-gate 
1892*7c478bd9Sstevel@tonic-gate 			Assert(s->strstart < s->w_size+MAX_DIST(s) ||
1893*7c478bd9Sstevel@tonic-gate 			    s->block_start >= (long)s->w_size,
1894*7c478bd9Sstevel@tonic-gate 			    "slide too late");
1895*7c478bd9Sstevel@tonic-gate 
1896*7c478bd9Sstevel@tonic-gate 			fill_window(s);
1897*7c478bd9Sstevel@tonic-gate 			if (s->lookahead == 0 && flush == Z_NO_FLUSH)
1898*7c478bd9Sstevel@tonic-gate 				return (need_more);
1899*7c478bd9Sstevel@tonic-gate 
1900*7c478bd9Sstevel@tonic-gate 			if (s->lookahead == 0)
1901*7c478bd9Sstevel@tonic-gate 				break;	/* flush the current block */
1902*7c478bd9Sstevel@tonic-gate 		}
1903*7c478bd9Sstevel@tonic-gate 		Assert(s->block_start >= 0L, "block gone");
1904*7c478bd9Sstevel@tonic-gate 
1905*7c478bd9Sstevel@tonic-gate 		s->strstart += s->lookahead;
1906*7c478bd9Sstevel@tonic-gate 		s->lookahead = 0;
1907*7c478bd9Sstevel@tonic-gate 
1908*7c478bd9Sstevel@tonic-gate 		/* Emit a stored block if pending_buf will be full: */
1909*7c478bd9Sstevel@tonic-gate 		max_start = s->block_start + max_block_size;
1910*7c478bd9Sstevel@tonic-gate 		if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
1911*7c478bd9Sstevel@tonic-gate 			/*
1912*7c478bd9Sstevel@tonic-gate 			 * strstart == 0 is possible when wraparound
1913*7c478bd9Sstevel@tonic-gate 			 * on 16-bit machine
1914*7c478bd9Sstevel@tonic-gate 			 */
1915*7c478bd9Sstevel@tonic-gate 			s->lookahead = (uInt)(s->strstart - max_start);
1916*7c478bd9Sstevel@tonic-gate 			s->strstart = (uInt)max_start;
1917*7c478bd9Sstevel@tonic-gate 			FLUSH_BLOCK(s, 0);
1918*7c478bd9Sstevel@tonic-gate 		}
1919*7c478bd9Sstevel@tonic-gate 		/*
1920*7c478bd9Sstevel@tonic-gate 		 * Flush if we may have to slide, otherwise
1921*7c478bd9Sstevel@tonic-gate 		 * block_start may become negative and the data will
1922*7c478bd9Sstevel@tonic-gate 		 * be gone:
1923*7c478bd9Sstevel@tonic-gate 		 */
1924*7c478bd9Sstevel@tonic-gate 		if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
1925*7c478bd9Sstevel@tonic-gate 			FLUSH_BLOCK(s, 0);
1926*7c478bd9Sstevel@tonic-gate 		}
1927*7c478bd9Sstevel@tonic-gate 	}
1928*7c478bd9Sstevel@tonic-gate 	FLUSH_BLOCK(s, flush == Z_FINISH);
1929*7c478bd9Sstevel@tonic-gate 	return (flush == Z_FINISH ? finish_done : block_done);
1930*7c478bd9Sstevel@tonic-gate }
1931*7c478bd9Sstevel@tonic-gate 
1932*7c478bd9Sstevel@tonic-gate /*
1933*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1934*7c478bd9Sstevel@tonic-gate  * Compress as much as possible from the input stream, return the current
1935*7c478bd9Sstevel@tonic-gate  * block state.
1936*7c478bd9Sstevel@tonic-gate  * This function does not perform lazy evaluation of matches and inserts
1937*7c478bd9Sstevel@tonic-gate  * new strings in the dictionary only for unmatched strings or for short
1938*7c478bd9Sstevel@tonic-gate  * matches. It is used only for the fast compression options.
1939*7c478bd9Sstevel@tonic-gate  */
1940*7c478bd9Sstevel@tonic-gate local block_state
1941*7c478bd9Sstevel@tonic-gate deflate_fast(s, flush)
1942*7c478bd9Sstevel@tonic-gate     deflate_state *s;
1943*7c478bd9Sstevel@tonic-gate     int flush;
1944*7c478bd9Sstevel@tonic-gate {
1945*7c478bd9Sstevel@tonic-gate 	IPos hash_head = NIL;	/* head of the hash chain */
1946*7c478bd9Sstevel@tonic-gate 	int bflush;	/* set if current block must be flushed */
1947*7c478bd9Sstevel@tonic-gate 
1948*7c478bd9Sstevel@tonic-gate 	for (;;) {
1949*7c478bd9Sstevel@tonic-gate 		/*
1950*7c478bd9Sstevel@tonic-gate 		 * Make sure that we always have enough lookahead,
1951*7c478bd9Sstevel@tonic-gate 		 * except at the end of the input file. We need
1952*7c478bd9Sstevel@tonic-gate 		 * MAX_MATCH bytes for the next match, plus MIN_MATCH
1953*7c478bd9Sstevel@tonic-gate 		 * bytes to insert the string following the next
1954*7c478bd9Sstevel@tonic-gate 		 * match.
1955*7c478bd9Sstevel@tonic-gate 		 */
1956*7c478bd9Sstevel@tonic-gate 		if (s->lookahead < MIN_LOOKAHEAD) {
1957*7c478bd9Sstevel@tonic-gate 			fill_window(s);
1958*7c478bd9Sstevel@tonic-gate 			if (s->lookahead < MIN_LOOKAHEAD &&
1959*7c478bd9Sstevel@tonic-gate 			    flush == Z_NO_FLUSH) {
1960*7c478bd9Sstevel@tonic-gate 				return (need_more);
1961*7c478bd9Sstevel@tonic-gate 			}
1962*7c478bd9Sstevel@tonic-gate 			if (s->lookahead == 0)
1963*7c478bd9Sstevel@tonic-gate 				break;	/* flush the current block */
1964*7c478bd9Sstevel@tonic-gate 		}
1965*7c478bd9Sstevel@tonic-gate 
1966*7c478bd9Sstevel@tonic-gate 		/*
1967*7c478bd9Sstevel@tonic-gate 		 * Insert the string window[strstart .. strstart+2] in
1968*7c478bd9Sstevel@tonic-gate 		 * the dictionary, and set hash_head to the head of
1969*7c478bd9Sstevel@tonic-gate 		 * the hash chain:
1970*7c478bd9Sstevel@tonic-gate 		 */
1971*7c478bd9Sstevel@tonic-gate 		if (s->lookahead >= MIN_MATCH) {
1972*7c478bd9Sstevel@tonic-gate 			INSERT_STRING(s, s->strstart, hash_head);
1973*7c478bd9Sstevel@tonic-gate 		}
1974*7c478bd9Sstevel@tonic-gate 
1975*7c478bd9Sstevel@tonic-gate 		/*
1976*7c478bd9Sstevel@tonic-gate 		 * Find the longest match, discarding those <=
1977*7c478bd9Sstevel@tonic-gate 		 * prev_length.  At this point we have always
1978*7c478bd9Sstevel@tonic-gate 		 * match_length < MIN_MATCH
1979*7c478bd9Sstevel@tonic-gate 		 */
1980*7c478bd9Sstevel@tonic-gate 		if (hash_head != NIL && s->strstart - hash_head <=
1981*7c478bd9Sstevel@tonic-gate 		    MAX_DIST(s)) {
1982*7c478bd9Sstevel@tonic-gate 			/*
1983*7c478bd9Sstevel@tonic-gate 			 * To simplify the code, we prevent matches
1984*7c478bd9Sstevel@tonic-gate 			 * with the string of window index 0 (in
1985*7c478bd9Sstevel@tonic-gate 			 * particular we have to avoid a match of the
1986*7c478bd9Sstevel@tonic-gate 			 * string with itself at the start of the
1987*7c478bd9Sstevel@tonic-gate 			 * input file).
1988*7c478bd9Sstevel@tonic-gate 			 */
1989*7c478bd9Sstevel@tonic-gate 			if (s->strategy != Z_HUFFMAN_ONLY) {
1990*7c478bd9Sstevel@tonic-gate 				s->match_length = longest_match(s, hash_head);
1991*7c478bd9Sstevel@tonic-gate 			}
1992*7c478bd9Sstevel@tonic-gate 			/* longest_match() sets match_start */
1993*7c478bd9Sstevel@tonic-gate 		}
1994*7c478bd9Sstevel@tonic-gate 		if (s->match_length >= MIN_MATCH) {
1995*7c478bd9Sstevel@tonic-gate 			check_match(s, s->strstart, s->match_start,
1996*7c478bd9Sstevel@tonic-gate 			    s->match_length);
1997*7c478bd9Sstevel@tonic-gate 
1998*7c478bd9Sstevel@tonic-gate 			_tr_tally_dist(s, s->strstart - s->match_start,
1999*7c478bd9Sstevel@tonic-gate 			    s->match_length - MIN_MATCH, bflush);
2000*7c478bd9Sstevel@tonic-gate 
2001*7c478bd9Sstevel@tonic-gate 			s->lookahead -= s->match_length;
2002*7c478bd9Sstevel@tonic-gate 
2003*7c478bd9Sstevel@tonic-gate 			/*
2004*7c478bd9Sstevel@tonic-gate 			 * Insert new strings in the hash table only
2005*7c478bd9Sstevel@tonic-gate 			 * if the match length is not too large. This
2006*7c478bd9Sstevel@tonic-gate 			 * saves time but degrades compression.
2007*7c478bd9Sstevel@tonic-gate 			 */
2008*7c478bd9Sstevel@tonic-gate #ifndef FASTEST
2009*7c478bd9Sstevel@tonic-gate 			if (s->match_length <= s->max_insert_length &&
2010*7c478bd9Sstevel@tonic-gate 			    s->lookahead >= MIN_MATCH) {
2011*7c478bd9Sstevel@tonic-gate 				/* string at strstart already in hash table */
2012*7c478bd9Sstevel@tonic-gate 				s->match_length--;
2013*7c478bd9Sstevel@tonic-gate 				do {
2014*7c478bd9Sstevel@tonic-gate 					s->strstart++;
2015*7c478bd9Sstevel@tonic-gate 					INSERT_STRING(s, s->strstart,
2016*7c478bd9Sstevel@tonic-gate 					    hash_head);
2017*7c478bd9Sstevel@tonic-gate 					/*
2018*7c478bd9Sstevel@tonic-gate 					 * strstart never exceeds
2019*7c478bd9Sstevel@tonic-gate 					 * WSIZE-MAX_MATCH, so there
2020*7c478bd9Sstevel@tonic-gate 					 * are always MIN_MATCH bytes
2021*7c478bd9Sstevel@tonic-gate 					 * ahead.
2022*7c478bd9Sstevel@tonic-gate 					 */
2023*7c478bd9Sstevel@tonic-gate 				} while (--s->match_length != 0);
2024*7c478bd9Sstevel@tonic-gate 				s->strstart++;
2025*7c478bd9Sstevel@tonic-gate 			} else
2026*7c478bd9Sstevel@tonic-gate #endif
2027*7c478bd9Sstevel@tonic-gate 			{
2028*7c478bd9Sstevel@tonic-gate 				s->strstart += s->match_length;
2029*7c478bd9Sstevel@tonic-gate 				s->match_length = 0;
2030*7c478bd9Sstevel@tonic-gate 				s->ins_h = s->window[s->strstart];
2031*7c478bd9Sstevel@tonic-gate 				UPDATE_HASH(s, s->ins_h,
2032*7c478bd9Sstevel@tonic-gate 				    s->window[s->strstart+1]);
2033*7c478bd9Sstevel@tonic-gate #if MIN_MATCH != 3
2034*7c478bd9Sstevel@tonic-gate 				Call UPDATE_HASH() MIN_MATCH-3 more times
2035*7c478bd9Sstevel@tonic-gate #endif
2036*7c478bd9Sstevel@tonic-gate 				/*
2037*7c478bd9Sstevel@tonic-gate 				 * If lookahead < MIN_MATCH, ins_h is
2038*7c478bd9Sstevel@tonic-gate 				 * garbage, but it does not matter
2039*7c478bd9Sstevel@tonic-gate 				 * since it will be recomputed at next
2040*7c478bd9Sstevel@tonic-gate 				 * deflate call.
2041*7c478bd9Sstevel@tonic-gate 				 */
2042*7c478bd9Sstevel@tonic-gate 			}
2043*7c478bd9Sstevel@tonic-gate 		} else {
2044*7c478bd9Sstevel@tonic-gate 			/* No match, output a literal byte */
2045*7c478bd9Sstevel@tonic-gate 			Tracevv((stderr, "%c", s->window[s->strstart]));
2046*7c478bd9Sstevel@tonic-gate 			_tr_tally_lit(s, s->window[s->strstart], bflush);
2047*7c478bd9Sstevel@tonic-gate 			s->lookahead--;
2048*7c478bd9Sstevel@tonic-gate 			s->strstart++;
2049*7c478bd9Sstevel@tonic-gate 		}
2050*7c478bd9Sstevel@tonic-gate 		if (bflush) FLUSH_BLOCK(s, 0);
2051*7c478bd9Sstevel@tonic-gate 	}
2052*7c478bd9Sstevel@tonic-gate 	FLUSH_BLOCK(s, flush == Z_FINISH);
2053*7c478bd9Sstevel@tonic-gate 	return (flush == Z_FINISH ? finish_done : block_done);
2054*7c478bd9Sstevel@tonic-gate }
2055*7c478bd9Sstevel@tonic-gate 
2056*7c478bd9Sstevel@tonic-gate /*
2057*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2058*7c478bd9Sstevel@tonic-gate  * Same as above, but achieves better compression. We use a lazy
2059*7c478bd9Sstevel@tonic-gate  * evaluation for matches: a match is finally adopted only if there is
2060*7c478bd9Sstevel@tonic-gate  * no better match at the next window position.
2061*7c478bd9Sstevel@tonic-gate  */
2062*7c478bd9Sstevel@tonic-gate local block_state
2063*7c478bd9Sstevel@tonic-gate deflate_slow(s, flush)
2064*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2065*7c478bd9Sstevel@tonic-gate     int flush;
2066*7c478bd9Sstevel@tonic-gate {
2067*7c478bd9Sstevel@tonic-gate 	IPos hash_head = NIL;	/* head of hash chain */
2068*7c478bd9Sstevel@tonic-gate 	int bflush;	/* set if current block must be flushed */
2069*7c478bd9Sstevel@tonic-gate 
2070*7c478bd9Sstevel@tonic-gate 	/* Process the input block. */
2071*7c478bd9Sstevel@tonic-gate 	for (;;) {
2072*7c478bd9Sstevel@tonic-gate 		/*
2073*7c478bd9Sstevel@tonic-gate 		 * Make sure that we always have enough lookahead,
2074*7c478bd9Sstevel@tonic-gate 		 * except at the end of the input file. We need
2075*7c478bd9Sstevel@tonic-gate 		 * MAX_MATCH bytes for the next match, plus MIN_MATCH
2076*7c478bd9Sstevel@tonic-gate 		 * bytes to insert the string following the next
2077*7c478bd9Sstevel@tonic-gate 		 * match.
2078*7c478bd9Sstevel@tonic-gate 		 */
2079*7c478bd9Sstevel@tonic-gate 		if (s->lookahead < MIN_LOOKAHEAD) {
2080*7c478bd9Sstevel@tonic-gate 			fill_window(s);
2081*7c478bd9Sstevel@tonic-gate 			if (s->lookahead < MIN_LOOKAHEAD &&
2082*7c478bd9Sstevel@tonic-gate 			    flush == Z_NO_FLUSH) {
2083*7c478bd9Sstevel@tonic-gate 				return (need_more);
2084*7c478bd9Sstevel@tonic-gate 			}
2085*7c478bd9Sstevel@tonic-gate 			/* flush the current block */
2086*7c478bd9Sstevel@tonic-gate 			if (s->lookahead == 0)
2087*7c478bd9Sstevel@tonic-gate 				break;
2088*7c478bd9Sstevel@tonic-gate 		}
2089*7c478bd9Sstevel@tonic-gate 
2090*7c478bd9Sstevel@tonic-gate 		/*
2091*7c478bd9Sstevel@tonic-gate 		 * Insert the string window[strstart .. strstart+2] in
2092*7c478bd9Sstevel@tonic-gate 		 * the dictionary, and set hash_head to the head of
2093*7c478bd9Sstevel@tonic-gate 		 * the hash chain:
2094*7c478bd9Sstevel@tonic-gate 		 */
2095*7c478bd9Sstevel@tonic-gate 		if (s->lookahead >= MIN_MATCH) {
2096*7c478bd9Sstevel@tonic-gate 			INSERT_STRING(s, s->strstart, hash_head);
2097*7c478bd9Sstevel@tonic-gate 		}
2098*7c478bd9Sstevel@tonic-gate 
2099*7c478bd9Sstevel@tonic-gate 		/*
2100*7c478bd9Sstevel@tonic-gate 		 * Find the longest match, discarding those <=
2101*7c478bd9Sstevel@tonic-gate 		 * prev_length.
2102*7c478bd9Sstevel@tonic-gate 		 */
2103*7c478bd9Sstevel@tonic-gate 		s->prev_length = s->match_length;
2104*7c478bd9Sstevel@tonic-gate 		s->prev_match = s->match_start;
2105*7c478bd9Sstevel@tonic-gate 		s->match_length = MIN_MATCH-1;
2106*7c478bd9Sstevel@tonic-gate 
2107*7c478bd9Sstevel@tonic-gate 		if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
2108*7c478bd9Sstevel@tonic-gate 		    s->strstart - hash_head <= MAX_DIST(s)) {
2109*7c478bd9Sstevel@tonic-gate 			/*
2110*7c478bd9Sstevel@tonic-gate 			 * To simplify the code, we prevent matches
2111*7c478bd9Sstevel@tonic-gate 			 * with the string of window index 0 (in
2112*7c478bd9Sstevel@tonic-gate 			 * particular we have to avoid a match of the
2113*7c478bd9Sstevel@tonic-gate 			 * string with itself at the start of the
2114*7c478bd9Sstevel@tonic-gate 			 * input file).
2115*7c478bd9Sstevel@tonic-gate 			 */
2116*7c478bd9Sstevel@tonic-gate 			if (s->strategy != Z_HUFFMAN_ONLY) {
2117*7c478bd9Sstevel@tonic-gate 				s->match_length = longest_match(s, hash_head);
2118*7c478bd9Sstevel@tonic-gate 			}
2119*7c478bd9Sstevel@tonic-gate 			/* longest_match() sets match_start */
2120*7c478bd9Sstevel@tonic-gate 
2121*7c478bd9Sstevel@tonic-gate 			if (s->match_length <= 5 &&
2122*7c478bd9Sstevel@tonic-gate 			    (s->strategy == Z_FILTERED ||
2123*7c478bd9Sstevel@tonic-gate 				(s->match_length == MIN_MATCH &&
2124*7c478bd9Sstevel@tonic-gate 				    s->strstart - s->match_start > TOO_FAR))) {
2125*7c478bd9Sstevel@tonic-gate 
2126*7c478bd9Sstevel@tonic-gate 				/*
2127*7c478bd9Sstevel@tonic-gate 				 * If prev_match is also MIN_MATCH,
2128*7c478bd9Sstevel@tonic-gate 				 * match_start is garbage but we will
2129*7c478bd9Sstevel@tonic-gate 				 * ignore the current match anyway.
2130*7c478bd9Sstevel@tonic-gate 				 */
2131*7c478bd9Sstevel@tonic-gate 				s->match_length = MIN_MATCH-1;
2132*7c478bd9Sstevel@tonic-gate 			}
2133*7c478bd9Sstevel@tonic-gate 		}
2134*7c478bd9Sstevel@tonic-gate 		/*
2135*7c478bd9Sstevel@tonic-gate 		 * If there was a match at the previous step and the
2136*7c478bd9Sstevel@tonic-gate 		 * current match is not better, output the previous
2137*7c478bd9Sstevel@tonic-gate 		 * match:
2138*7c478bd9Sstevel@tonic-gate 		 */
2139*7c478bd9Sstevel@tonic-gate 		if (s->prev_length >= MIN_MATCH &&
2140*7c478bd9Sstevel@tonic-gate 		    s->match_length <= s->prev_length) {
2141*7c478bd9Sstevel@tonic-gate 			uInt max_insert = s->strstart + s->lookahead -
2142*7c478bd9Sstevel@tonic-gate 			    MIN_MATCH;
2143*7c478bd9Sstevel@tonic-gate 			/* Do not insert strings in hash table beyond this. */
2144*7c478bd9Sstevel@tonic-gate 
2145*7c478bd9Sstevel@tonic-gate 			check_match(s, s->strstart-1, s->prev_match,
2146*7c478bd9Sstevel@tonic-gate 			    s->prev_length);
2147*7c478bd9Sstevel@tonic-gate 
2148*7c478bd9Sstevel@tonic-gate 			_tr_tally_dist(s, s->strstart -1 - s->prev_match,
2149*7c478bd9Sstevel@tonic-gate 			    s->prev_length - MIN_MATCH, bflush);
2150*7c478bd9Sstevel@tonic-gate 
2151*7c478bd9Sstevel@tonic-gate 			/*
2152*7c478bd9Sstevel@tonic-gate 			 * Insert in hash table all strings up to the
2153*7c478bd9Sstevel@tonic-gate 			 * end of the match.  strstart-1 and strstart
2154*7c478bd9Sstevel@tonic-gate 			 * are already inserted. If there is not
2155*7c478bd9Sstevel@tonic-gate 			 * enough lookahead, the last two strings are
2156*7c478bd9Sstevel@tonic-gate 			 * not inserted in the hash table.
2157*7c478bd9Sstevel@tonic-gate 			 */
2158*7c478bd9Sstevel@tonic-gate 			s->lookahead -= s->prev_length-1;
2159*7c478bd9Sstevel@tonic-gate 			s->prev_length -= 2;
2160*7c478bd9Sstevel@tonic-gate 			do {
2161*7c478bd9Sstevel@tonic-gate 				if (++s->strstart <= max_insert) {
2162*7c478bd9Sstevel@tonic-gate 					INSERT_STRING(s, s->strstart,
2163*7c478bd9Sstevel@tonic-gate 					    hash_head);
2164*7c478bd9Sstevel@tonic-gate 				}
2165*7c478bd9Sstevel@tonic-gate 			} while (--s->prev_length != 0);
2166*7c478bd9Sstevel@tonic-gate 			s->match_available = 0;
2167*7c478bd9Sstevel@tonic-gate 			s->match_length = MIN_MATCH-1;
2168*7c478bd9Sstevel@tonic-gate 			s->strstart++;
2169*7c478bd9Sstevel@tonic-gate 
2170*7c478bd9Sstevel@tonic-gate 			if (bflush) FLUSH_BLOCK(s, 0);
2171*7c478bd9Sstevel@tonic-gate 
2172*7c478bd9Sstevel@tonic-gate 		} else if (s->match_available) {
2173*7c478bd9Sstevel@tonic-gate 			/*
2174*7c478bd9Sstevel@tonic-gate 			 * If there was no match at the previous
2175*7c478bd9Sstevel@tonic-gate 			 * position, output a single literal. If there
2176*7c478bd9Sstevel@tonic-gate 			 * was a match but the current match is
2177*7c478bd9Sstevel@tonic-gate 			 * longer, truncate the previous match to a
2178*7c478bd9Sstevel@tonic-gate 			 * single literal.
2179*7c478bd9Sstevel@tonic-gate 			 */
2180*7c478bd9Sstevel@tonic-gate 			Tracevv((stderr, "%c", s->window[s->strstart-1]));
2181*7c478bd9Sstevel@tonic-gate 			_tr_tally_lit(s, s->window[s->strstart-1], bflush);
2182*7c478bd9Sstevel@tonic-gate 			if (bflush) {
2183*7c478bd9Sstevel@tonic-gate 				FLUSH_BLOCK_ONLY(s, 0);
2184*7c478bd9Sstevel@tonic-gate 			}
2185*7c478bd9Sstevel@tonic-gate 			s->strstart++;
2186*7c478bd9Sstevel@tonic-gate 			s->lookahead--;
2187*7c478bd9Sstevel@tonic-gate 			if (s->strm->avail_out == 0)
2188*7c478bd9Sstevel@tonic-gate 				return (need_more);
2189*7c478bd9Sstevel@tonic-gate 		} else {
2190*7c478bd9Sstevel@tonic-gate 			/*
2191*7c478bd9Sstevel@tonic-gate 			 * There is no previous match to compare with,
2192*7c478bd9Sstevel@tonic-gate 			 * wait for the next step to decide.
2193*7c478bd9Sstevel@tonic-gate 			 */
2194*7c478bd9Sstevel@tonic-gate 			s->match_available = 1;
2195*7c478bd9Sstevel@tonic-gate 			s->strstart++;
2196*7c478bd9Sstevel@tonic-gate 			s->lookahead--;
2197*7c478bd9Sstevel@tonic-gate 		}
2198*7c478bd9Sstevel@tonic-gate 	}
2199*7c478bd9Sstevel@tonic-gate 	Assert(flush != Z_NO_FLUSH, "no flush?");
2200*7c478bd9Sstevel@tonic-gate 	if (s->match_available) {
2201*7c478bd9Sstevel@tonic-gate 		Tracevv((stderr, "%c", s->window[s->strstart-1]));
2202*7c478bd9Sstevel@tonic-gate 		_tr_tally_lit(s, s->window[s->strstart-1], bflush);
2203*7c478bd9Sstevel@tonic-gate 		s->match_available = 0;
2204*7c478bd9Sstevel@tonic-gate 	}
2205*7c478bd9Sstevel@tonic-gate 	FLUSH_BLOCK(s, flush == Z_FINISH);
2206*7c478bd9Sstevel@tonic-gate 	return (flush == Z_FINISH ? finish_done : block_done);
2207*7c478bd9Sstevel@tonic-gate }
2208*7c478bd9Sstevel@tonic-gate /* --- deflate.c */
2209*7c478bd9Sstevel@tonic-gate 
2210*7c478bd9Sstevel@tonic-gate /* +++ trees.c */
2211*7c478bd9Sstevel@tonic-gate /*
2212*7c478bd9Sstevel@tonic-gate  * trees.c -- output deflated data using Huffman coding
2213*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Jean-loup Gailly
2214*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
2215*7c478bd9Sstevel@tonic-gate  */
2216*7c478bd9Sstevel@tonic-gate 
2217*7c478bd9Sstevel@tonic-gate /*
2218*7c478bd9Sstevel@tonic-gate  *  ALGORITHM
2219*7c478bd9Sstevel@tonic-gate  *
2220*7c478bd9Sstevel@tonic-gate  *      The "deflation" process uses several Huffman trees. The more
2221*7c478bd9Sstevel@tonic-gate  *      common source values are represented by shorter bit sequences.
2222*7c478bd9Sstevel@tonic-gate  *
2223*7c478bd9Sstevel@tonic-gate  *      Each code tree is stored in a compressed form which is itself
2224*7c478bd9Sstevel@tonic-gate  * a Huffman encoding of the lengths of all the code strings (in
2225*7c478bd9Sstevel@tonic-gate  * ascending order by source values).  The actual code strings are
2226*7c478bd9Sstevel@tonic-gate  * reconstructed from the lengths in the inflate process, as described
2227*7c478bd9Sstevel@tonic-gate  * in the deflate specification.
2228*7c478bd9Sstevel@tonic-gate  *
2229*7c478bd9Sstevel@tonic-gate  *  REFERENCES
2230*7c478bd9Sstevel@tonic-gate  *
2231*7c478bd9Sstevel@tonic-gate  *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
2232*7c478bd9Sstevel@tonic-gate  *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
2233*7c478bd9Sstevel@tonic-gate  *
2234*7c478bd9Sstevel@tonic-gate  *      Storer, James A.
2235*7c478bd9Sstevel@tonic-gate  *          Data Compression:  Methods and Theory, pp. 49-50.
2236*7c478bd9Sstevel@tonic-gate  *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
2237*7c478bd9Sstevel@tonic-gate  *
2238*7c478bd9Sstevel@tonic-gate  *      Sedgewick, R.
2239*7c478bd9Sstevel@tonic-gate  *          Algorithms, p290.
2240*7c478bd9Sstevel@tonic-gate  *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
2241*7c478bd9Sstevel@tonic-gate  */
2242*7c478bd9Sstevel@tonic-gate 
2243*7c478bd9Sstevel@tonic-gate /* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
2244*7c478bd9Sstevel@tonic-gate 
2245*7c478bd9Sstevel@tonic-gate /* #include "deflate.h" */
2246*7c478bd9Sstevel@tonic-gate 
2247*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
2248*7c478bd9Sstevel@tonic-gate #include <ctype.h>
2249*7c478bd9Sstevel@tonic-gate #endif
2250*7c478bd9Sstevel@tonic-gate 
2251*7c478bd9Sstevel@tonic-gate /*
2252*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2253*7c478bd9Sstevel@tonic-gate  * Constants
2254*7c478bd9Sstevel@tonic-gate  */
2255*7c478bd9Sstevel@tonic-gate 
2256*7c478bd9Sstevel@tonic-gate #define	MAX_BL_BITS 7
2257*7c478bd9Sstevel@tonic-gate /* Bit length codes must not exceed MAX_BL_BITS bits */
2258*7c478bd9Sstevel@tonic-gate 
2259*7c478bd9Sstevel@tonic-gate #define	END_BLOCK 256
2260*7c478bd9Sstevel@tonic-gate /* end of block literal code */
2261*7c478bd9Sstevel@tonic-gate 
2262*7c478bd9Sstevel@tonic-gate #define	REP_3_6		16
2263*7c478bd9Sstevel@tonic-gate /* repeat previous bit length 3-6 times (2 bits of repeat count) */
2264*7c478bd9Sstevel@tonic-gate 
2265*7c478bd9Sstevel@tonic-gate #define	REPZ_3_10	17
2266*7c478bd9Sstevel@tonic-gate /* repeat a zero length 3-10 times  (3 bits of repeat count) */
2267*7c478bd9Sstevel@tonic-gate 
2268*7c478bd9Sstevel@tonic-gate #define	REPZ_11_138	18
2269*7c478bd9Sstevel@tonic-gate /* repeat a zero length 11-138 times  (7 bits of repeat count) */
2270*7c478bd9Sstevel@tonic-gate 
2271*7c478bd9Sstevel@tonic-gate /* extra bits for each length code */
2272*7c478bd9Sstevel@tonic-gate local const int extra_lbits[LENGTH_CODES] = {
2273*7c478bd9Sstevel@tonic-gate 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4,
2274*7c478bd9Sstevel@tonic-gate 	4, 4, 4, 5, 5, 5, 5, 0};
2275*7c478bd9Sstevel@tonic-gate 
2276*7c478bd9Sstevel@tonic-gate /* extra bits for each distance code */
2277*7c478bd9Sstevel@tonic-gate local const int extra_dbits[D_CODES] = {
2278*7c478bd9Sstevel@tonic-gate 	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
2279*7c478bd9Sstevel@tonic-gate 	9, 10, 10, 11, 11, 12, 12, 13, 13};
2280*7c478bd9Sstevel@tonic-gate 
2281*7c478bd9Sstevel@tonic-gate /* extra bits for each bit length code */
2282*7c478bd9Sstevel@tonic-gate local const int extra_blbits[BL_CODES] = {
2283*7c478bd9Sstevel@tonic-gate 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
2284*7c478bd9Sstevel@tonic-gate 
2285*7c478bd9Sstevel@tonic-gate local const uch bl_order[BL_CODES] = {
2286*7c478bd9Sstevel@tonic-gate 	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
2287*7c478bd9Sstevel@tonic-gate 
2288*7c478bd9Sstevel@tonic-gate /*
2289*7c478bd9Sstevel@tonic-gate  * The lengths of the bit length codes are sent in order of decreasing
2290*7c478bd9Sstevel@tonic-gate  * probability, to avoid transmitting the lengths for unused bit
2291*7c478bd9Sstevel@tonic-gate  * length codes.
2292*7c478bd9Sstevel@tonic-gate  */
2293*7c478bd9Sstevel@tonic-gate 
2294*7c478bd9Sstevel@tonic-gate #define	Buf_size (8 * 2*sizeof (char))
2295*7c478bd9Sstevel@tonic-gate /*
2296*7c478bd9Sstevel@tonic-gate  * Number of bits used within bi_buf. (bi_buf might be implemented on
2297*7c478bd9Sstevel@tonic-gate  * more than 16 bits on some systems.)
2298*7c478bd9Sstevel@tonic-gate  */
2299*7c478bd9Sstevel@tonic-gate 
2300*7c478bd9Sstevel@tonic-gate /*
2301*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2302*7c478bd9Sstevel@tonic-gate  * Local data. These are initialized only once.
2303*7c478bd9Sstevel@tonic-gate  */
2304*7c478bd9Sstevel@tonic-gate #define	DIST_CODE_LEN  512 /* see definition of array dist_code below */
2305*7c478bd9Sstevel@tonic-gate 
2306*7c478bd9Sstevel@tonic-gate local ct_data static_ltree[L_CODES+2];
2307*7c478bd9Sstevel@tonic-gate /*
2308*7c478bd9Sstevel@tonic-gate  * The static literal tree. Since the bit lengths are imposed, there
2309*7c478bd9Sstevel@tonic-gate  * is no need for the L_CODES extra codes used during heap
2310*7c478bd9Sstevel@tonic-gate  * construction. However The codes 286 and 287 are needed to build a
2311*7c478bd9Sstevel@tonic-gate  * canonical tree (see _tr_init below).
2312*7c478bd9Sstevel@tonic-gate  */
2313*7c478bd9Sstevel@tonic-gate 
2314*7c478bd9Sstevel@tonic-gate local ct_data static_dtree[D_CODES];
2315*7c478bd9Sstevel@tonic-gate /*
2316*7c478bd9Sstevel@tonic-gate  * The static distance tree. (Actually a trivial tree since all codes
2317*7c478bd9Sstevel@tonic-gate  * use 5 bits.)
2318*7c478bd9Sstevel@tonic-gate  */
2319*7c478bd9Sstevel@tonic-gate 
2320*7c478bd9Sstevel@tonic-gate local uch _dist_code[512];
2321*7c478bd9Sstevel@tonic-gate /*
2322*7c478bd9Sstevel@tonic-gate  * distance codes. The first 256 values correspond to the distances 3
2323*7c478bd9Sstevel@tonic-gate  * .. 258, the last 256 values correspond to the top 8 bits of the 15
2324*7c478bd9Sstevel@tonic-gate  * bit distances.
2325*7c478bd9Sstevel@tonic-gate  */
2326*7c478bd9Sstevel@tonic-gate 
2327*7c478bd9Sstevel@tonic-gate local uch _length_code[MAX_MATCH-MIN_MATCH+1];
2328*7c478bd9Sstevel@tonic-gate /* length code for each normalized match length (0 == MIN_MATCH) */
2329*7c478bd9Sstevel@tonic-gate 
2330*7c478bd9Sstevel@tonic-gate local int base_length[LENGTH_CODES];
2331*7c478bd9Sstevel@tonic-gate /* First normalized length for each code (0 = MIN_MATCH) */
2332*7c478bd9Sstevel@tonic-gate 
2333*7c478bd9Sstevel@tonic-gate local int base_dist[D_CODES];
2334*7c478bd9Sstevel@tonic-gate /* First normalized distance for each code (0 = distance of 1) */
2335*7c478bd9Sstevel@tonic-gate 
2336*7c478bd9Sstevel@tonic-gate struct static_tree_desc_s {
2337*7c478bd9Sstevel@tonic-gate 	const ct_data *static_tree;	/* static tree or NULL */
2338*7c478bd9Sstevel@tonic-gate 	const intf    *extra_bits;	/* extra bits for each code or NULL */
2339*7c478bd9Sstevel@tonic-gate 	int	extra_base;	/* base index for extra_bits */
2340*7c478bd9Sstevel@tonic-gate 	int	elems;	/* max number of elements in the tree */
2341*7c478bd9Sstevel@tonic-gate 	int	max_length;	/* max bit length for the codes */
2342*7c478bd9Sstevel@tonic-gate };
2343*7c478bd9Sstevel@tonic-gate 
2344*7c478bd9Sstevel@tonic-gate local static_tree_desc  static_l_desc = {
2345*7c478bd9Sstevel@tonic-gate 	static_ltree, extra_lbits, LITERALS+1,	L_CODES, MAX_BITS};
2346*7c478bd9Sstevel@tonic-gate 
2347*7c478bd9Sstevel@tonic-gate local static_tree_desc  static_d_desc = {
2348*7c478bd9Sstevel@tonic-gate 	static_dtree, extra_dbits, 0,		D_CODES, MAX_BITS};
2349*7c478bd9Sstevel@tonic-gate 
2350*7c478bd9Sstevel@tonic-gate local static_tree_desc  static_bl_desc = {
2351*7c478bd9Sstevel@tonic-gate 	(const ct_data *)0, extra_blbits, 0,		BL_CODES, MAX_BL_BITS};
2352*7c478bd9Sstevel@tonic-gate 
2353*7c478bd9Sstevel@tonic-gate /*
2354*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2355*7c478bd9Sstevel@tonic-gate  * Local (static) routines in this file.
2356*7c478bd9Sstevel@tonic-gate  */
2357*7c478bd9Sstevel@tonic-gate 
2358*7c478bd9Sstevel@tonic-gate local void tr_static_init OF((void));
2359*7c478bd9Sstevel@tonic-gate local void init_block	OF((deflate_state *s));
2360*7c478bd9Sstevel@tonic-gate local void pqdownheap	OF((deflate_state *s, ct_data *tree, int k));
2361*7c478bd9Sstevel@tonic-gate local void gen_bitlen	OF((deflate_state *s, tree_desc *desc));
2362*7c478bd9Sstevel@tonic-gate local void gen_codes	OF((ct_data *tree, int max_code, ushf *bl_count));
2363*7c478bd9Sstevel@tonic-gate local void build_tree	OF((deflate_state *s, tree_desc *desc));
2364*7c478bd9Sstevel@tonic-gate local void scan_tree	OF((deflate_state *s, ct_data *tree, int max_code));
2365*7c478bd9Sstevel@tonic-gate local void send_tree	OF((deflate_state *s, ct_data *tree, int max_code));
2366*7c478bd9Sstevel@tonic-gate local int  build_bl_tree	OF((deflate_state *s));
2367*7c478bd9Sstevel@tonic-gate local void send_all_trees	OF((deflate_state *s, int lcodes, int dcodes,
2368*7c478bd9Sstevel@tonic-gate     int blcodes));
2369*7c478bd9Sstevel@tonic-gate local void compress_block OF((deflate_state *s, ct_data *ltree,
2370*7c478bd9Sstevel@tonic-gate     ct_data *dtree));
2371*7c478bd9Sstevel@tonic-gate local void set_data_type	OF((deflate_state *s));
2372*7c478bd9Sstevel@tonic-gate local unsigned bi_reverse	OF((unsigned value, int length));
2373*7c478bd9Sstevel@tonic-gate local void bi_windup	OF((deflate_state *s));
2374*7c478bd9Sstevel@tonic-gate local void bi_flush	OF((deflate_state *s));
2375*7c478bd9Sstevel@tonic-gate local void copy_block	OF((deflate_state *s, charf *buf, unsigned len,
2376*7c478bd9Sstevel@tonic-gate     int header));
2377*7c478bd9Sstevel@tonic-gate 
2378*7c478bd9Sstevel@tonic-gate #ifndef DEBUG_ZLIB
2379*7c478bd9Sstevel@tonic-gate #define	send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
2380*7c478bd9Sstevel@tonic-gate /* Send a code of the given tree. c and tree must not have side effects */
2381*7c478bd9Sstevel@tonic-gate 
2382*7c478bd9Sstevel@tonic-gate #else /* DEBUG_ZLIB */
2383*7c478bd9Sstevel@tonic-gate #define	send_code(s, c, tree) \
2384*7c478bd9Sstevel@tonic-gate 	{ if (z_verbose > 2) fprintf(stderr, "\ncd %3d ", (c)); \
2385*7c478bd9Sstevel@tonic-gate 	send_bits(s, tree[c].Code, tree[c].Len); }
2386*7c478bd9Sstevel@tonic-gate #endif
2387*7c478bd9Sstevel@tonic-gate 
2388*7c478bd9Sstevel@tonic-gate /*
2389*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2390*7c478bd9Sstevel@tonic-gate  * Output a short LSB first on the stream.
2391*7c478bd9Sstevel@tonic-gate  * IN assertion: there is enough room in pendingBuf.
2392*7c478bd9Sstevel@tonic-gate  */
2393*7c478bd9Sstevel@tonic-gate #define	put_short(s, w) { \
2394*7c478bd9Sstevel@tonic-gate 	put_byte(s, (uch)((w) & 0xff)); \
2395*7c478bd9Sstevel@tonic-gate 	put_byte(s, (uch)((ush)(w) >> 8)); \
2396*7c478bd9Sstevel@tonic-gate }
2397*7c478bd9Sstevel@tonic-gate 
2398*7c478bd9Sstevel@tonic-gate /*
2399*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2400*7c478bd9Sstevel@tonic-gate  * Send a value on a given number of bits.
2401*7c478bd9Sstevel@tonic-gate  * IN assertion: length <= 16 and value fits in length bits.
2402*7c478bd9Sstevel@tonic-gate  */
2403*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
2404*7c478bd9Sstevel@tonic-gate local void send_bits	OF((deflate_state *s, int value, int length));
2405*7c478bd9Sstevel@tonic-gate 
2406*7c478bd9Sstevel@tonic-gate local void
2407*7c478bd9Sstevel@tonic-gate send_bits(s, value, length)
2408*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2409*7c478bd9Sstevel@tonic-gate     int value;	/* value to send */
2410*7c478bd9Sstevel@tonic-gate     int length;	/* number of bits */
2411*7c478bd9Sstevel@tonic-gate {
2412*7c478bd9Sstevel@tonic-gate 	Tracevv((stderr, " l %2d v %4x ", length, value));
2413*7c478bd9Sstevel@tonic-gate 	Assert(length > 0 && length <= 15, "invalid length");
2414*7c478bd9Sstevel@tonic-gate 	s->bits_sent += (ulg)length;
2415*7c478bd9Sstevel@tonic-gate 
2416*7c478bd9Sstevel@tonic-gate 	/*
2417*7c478bd9Sstevel@tonic-gate 	 * If not enough room in bi_buf, use (valid) bits from bi_buf
2418*7c478bd9Sstevel@tonic-gate 	 * and (16 - bi_valid) bits from value, leaving (width -
2419*7c478bd9Sstevel@tonic-gate 	 * (16-bi_valid)) unused bits in value.
2420*7c478bd9Sstevel@tonic-gate 	 */
2421*7c478bd9Sstevel@tonic-gate 	if (s->bi_valid > (int)Buf_size - length) {
2422*7c478bd9Sstevel@tonic-gate 		s->bi_buf |= (value << s->bi_valid);
2423*7c478bd9Sstevel@tonic-gate 		put_short(s, s->bi_buf);
2424*7c478bd9Sstevel@tonic-gate 		s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
2425*7c478bd9Sstevel@tonic-gate 		s->bi_valid += length - Buf_size;
2426*7c478bd9Sstevel@tonic-gate 	} else {
2427*7c478bd9Sstevel@tonic-gate 		s->bi_buf |= value << s->bi_valid;
2428*7c478bd9Sstevel@tonic-gate 		s->bi_valid += length;
2429*7c478bd9Sstevel@tonic-gate 	}
2430*7c478bd9Sstevel@tonic-gate }
2431*7c478bd9Sstevel@tonic-gate #else /* !DEBUG_ZLIB */
2432*7c478bd9Sstevel@tonic-gate 
2433*7c478bd9Sstevel@tonic-gate #define	send_bits(s, value, length) \
2434*7c478bd9Sstevel@tonic-gate {	int len = length; \
2435*7c478bd9Sstevel@tonic-gate 	if (s->bi_valid > (int)Buf_size - len) {\
2436*7c478bd9Sstevel@tonic-gate 		int val = value; \
2437*7c478bd9Sstevel@tonic-gate 		s->bi_buf |= (val << s->bi_valid); \
2438*7c478bd9Sstevel@tonic-gate 		put_short(s, s->bi_buf); \
2439*7c478bd9Sstevel@tonic-gate 		s->bi_buf = (ush)val >> (Buf_size - s->bi_valid); \
2440*7c478bd9Sstevel@tonic-gate 		s->bi_valid += len - Buf_size; \
2441*7c478bd9Sstevel@tonic-gate 	} else {\
2442*7c478bd9Sstevel@tonic-gate 		s->bi_buf |= (value) << s->bi_valid; \
2443*7c478bd9Sstevel@tonic-gate 		s->bi_valid += len; \
2444*7c478bd9Sstevel@tonic-gate 	}\
2445*7c478bd9Sstevel@tonic-gate }
2446*7c478bd9Sstevel@tonic-gate #endif /* DEBUG_ZLIB */
2447*7c478bd9Sstevel@tonic-gate 
2448*7c478bd9Sstevel@tonic-gate 
2449*7c478bd9Sstevel@tonic-gate #define	MAX(a, b) (a >= b ? a : b)
2450*7c478bd9Sstevel@tonic-gate /* the arguments must not have side effects */
2451*7c478bd9Sstevel@tonic-gate 
2452*7c478bd9Sstevel@tonic-gate /*
2453*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2454*7c478bd9Sstevel@tonic-gate  * Initialize the various 'constant' tables. In a multi-threaded environment,
2455*7c478bd9Sstevel@tonic-gate  * this function may be called by two threads concurrently, but this is
2456*7c478bd9Sstevel@tonic-gate  * harmless since both invocations do exactly the same thing.
2457*7c478bd9Sstevel@tonic-gate  */
2458*7c478bd9Sstevel@tonic-gate local void
2459*7c478bd9Sstevel@tonic-gate tr_static_init()
2460*7c478bd9Sstevel@tonic-gate {
2461*7c478bd9Sstevel@tonic-gate 	static int static_init_done = 0;
2462*7c478bd9Sstevel@tonic-gate 	int n;	/* iterates over tree elements */
2463*7c478bd9Sstevel@tonic-gate 	int bits;	/* bit counter */
2464*7c478bd9Sstevel@tonic-gate 	int length;	/* length value */
2465*7c478bd9Sstevel@tonic-gate 	int code;	/* code value */
2466*7c478bd9Sstevel@tonic-gate 	int dist;	/* distance index */
2467*7c478bd9Sstevel@tonic-gate 	ush bl_count[MAX_BITS+1];
2468*7c478bd9Sstevel@tonic-gate 	/* number of codes at each bit length for an optimal tree */
2469*7c478bd9Sstevel@tonic-gate 
2470*7c478bd9Sstevel@tonic-gate 	if (static_init_done)
2471*7c478bd9Sstevel@tonic-gate 		return;
2472*7c478bd9Sstevel@tonic-gate 
2473*7c478bd9Sstevel@tonic-gate 	/* For some embedded targets, global variables are not initialized: */
2474*7c478bd9Sstevel@tonic-gate 	static_l_desc.static_tree = static_ltree;
2475*7c478bd9Sstevel@tonic-gate 	static_l_desc.extra_bits = extra_lbits;
2476*7c478bd9Sstevel@tonic-gate 	static_d_desc.static_tree = static_dtree;
2477*7c478bd9Sstevel@tonic-gate 	static_d_desc.extra_bits = extra_dbits;
2478*7c478bd9Sstevel@tonic-gate 	static_bl_desc.extra_bits = extra_blbits;
2479*7c478bd9Sstevel@tonic-gate 
2480*7c478bd9Sstevel@tonic-gate 	/* Initialize the mapping length (0..255) -> length code (0..28) */
2481*7c478bd9Sstevel@tonic-gate 	length = 0;
2482*7c478bd9Sstevel@tonic-gate 	for (code = 0; code < LENGTH_CODES-1; code++) {
2483*7c478bd9Sstevel@tonic-gate 		base_length[code] = length;
2484*7c478bd9Sstevel@tonic-gate 		for (n = 0; n < (1<<extra_lbits[code]); n++) {
2485*7c478bd9Sstevel@tonic-gate 			_length_code[length++] = (uch)code;
2486*7c478bd9Sstevel@tonic-gate 		}
2487*7c478bd9Sstevel@tonic-gate 	}
2488*7c478bd9Sstevel@tonic-gate 	Assert(length == 256, "tr_static_init: length != 256");
2489*7c478bd9Sstevel@tonic-gate 	/*
2490*7c478bd9Sstevel@tonic-gate 	 * Note that the length 255 (match length 258) can be
2491*7c478bd9Sstevel@tonic-gate 	 * represented in two different ways: code 284 + 5 bits or
2492*7c478bd9Sstevel@tonic-gate 	 * code 285, so we overwrite _length_code[255] to use the best
2493*7c478bd9Sstevel@tonic-gate 	 * encoding:
2494*7c478bd9Sstevel@tonic-gate 	 */
2495*7c478bd9Sstevel@tonic-gate 	_length_code[length-1] = (uch)code;
2496*7c478bd9Sstevel@tonic-gate 
2497*7c478bd9Sstevel@tonic-gate 	/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
2498*7c478bd9Sstevel@tonic-gate 	dist = 0;
2499*7c478bd9Sstevel@tonic-gate 	for (code = 0; code < 16; code++) {
2500*7c478bd9Sstevel@tonic-gate 		base_dist[code] = dist;
2501*7c478bd9Sstevel@tonic-gate 		for (n = 0; n < (1<<extra_dbits[code]); n++) {
2502*7c478bd9Sstevel@tonic-gate 			_dist_code[dist++] = (uch)code;
2503*7c478bd9Sstevel@tonic-gate 		}
2504*7c478bd9Sstevel@tonic-gate 	}
2505*7c478bd9Sstevel@tonic-gate 	Assert(dist == 256, "tr_static_init: dist != 256");
2506*7c478bd9Sstevel@tonic-gate 	dist >>= 7;	/* from now on, all distances are divided by 128 */
2507*7c478bd9Sstevel@tonic-gate 	for (; code < D_CODES; code++) {
2508*7c478bd9Sstevel@tonic-gate 		base_dist[code] = dist << 7;
2509*7c478bd9Sstevel@tonic-gate 		for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
2510*7c478bd9Sstevel@tonic-gate 			_dist_code[256 + dist++] = (uch)code;
2511*7c478bd9Sstevel@tonic-gate 		}
2512*7c478bd9Sstevel@tonic-gate 	}
2513*7c478bd9Sstevel@tonic-gate 	Assert(dist == 256, "tr_static_init: 256+dist != 512");
2514*7c478bd9Sstevel@tonic-gate 
2515*7c478bd9Sstevel@tonic-gate 	/* Construct the codes of the static literal tree */
2516*7c478bd9Sstevel@tonic-gate 	for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
2517*7c478bd9Sstevel@tonic-gate 	n = 0;
2518*7c478bd9Sstevel@tonic-gate 	while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
2519*7c478bd9Sstevel@tonic-gate 	while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
2520*7c478bd9Sstevel@tonic-gate 	while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
2521*7c478bd9Sstevel@tonic-gate 	while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
2522*7c478bd9Sstevel@tonic-gate 	/*
2523*7c478bd9Sstevel@tonic-gate 	 * Codes 286 and 287 do not exist, but we must include them in the
2524*7c478bd9Sstevel@tonic-gate 	 * tree construction to get a canonical Huffman tree (longest code
2525*7c478bd9Sstevel@tonic-gate 	 * all ones)
2526*7c478bd9Sstevel@tonic-gate 	 */
2527*7c478bd9Sstevel@tonic-gate 	gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
2528*7c478bd9Sstevel@tonic-gate 
2529*7c478bd9Sstevel@tonic-gate 	/* The static distance tree is trivial: */
2530*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < D_CODES; n++) {
2531*7c478bd9Sstevel@tonic-gate 		static_dtree[n].Len = 5;
2532*7c478bd9Sstevel@tonic-gate 		static_dtree[n].Code = bi_reverse((unsigned)n, 5);
2533*7c478bd9Sstevel@tonic-gate 	}
2534*7c478bd9Sstevel@tonic-gate 	static_init_done = 1;
2535*7c478bd9Sstevel@tonic-gate }
2536*7c478bd9Sstevel@tonic-gate 
2537*7c478bd9Sstevel@tonic-gate /*
2538*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2539*7c478bd9Sstevel@tonic-gate  * Initialize the tree data structures for a new zlib stream.
2540*7c478bd9Sstevel@tonic-gate  */
2541*7c478bd9Sstevel@tonic-gate void
2542*7c478bd9Sstevel@tonic-gate _tr_init(s)
2543*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2544*7c478bd9Sstevel@tonic-gate {
2545*7c478bd9Sstevel@tonic-gate 	tr_static_init();
2546*7c478bd9Sstevel@tonic-gate 
2547*7c478bd9Sstevel@tonic-gate 	s->l_desc.dyn_tree = s->dyn_ltree;
2548*7c478bd9Sstevel@tonic-gate 	s->l_desc.stat_desc = &static_l_desc;
2549*7c478bd9Sstevel@tonic-gate 
2550*7c478bd9Sstevel@tonic-gate 	s->d_desc.dyn_tree = s->dyn_dtree;
2551*7c478bd9Sstevel@tonic-gate 	s->d_desc.stat_desc = &static_d_desc;
2552*7c478bd9Sstevel@tonic-gate 
2553*7c478bd9Sstevel@tonic-gate 	s->bl_desc.dyn_tree = s->bl_tree;
2554*7c478bd9Sstevel@tonic-gate 	s->bl_desc.stat_desc = &static_bl_desc;
2555*7c478bd9Sstevel@tonic-gate 
2556*7c478bd9Sstevel@tonic-gate 	s->bi_buf = 0;
2557*7c478bd9Sstevel@tonic-gate 	s->bi_valid = 0;
2558*7c478bd9Sstevel@tonic-gate 	s->last_eob_len = 8;	/* enough lookahead for inflate */
2559*7c478bd9Sstevel@tonic-gate 	s->compressed_len = 0L;		/* PPP */
2560*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
2561*7c478bd9Sstevel@tonic-gate 	s->bits_sent = 0L;
2562*7c478bd9Sstevel@tonic-gate #endif
2563*7c478bd9Sstevel@tonic-gate 
2564*7c478bd9Sstevel@tonic-gate 	/* Initialize the first block of the first file: */
2565*7c478bd9Sstevel@tonic-gate 	init_block(s);
2566*7c478bd9Sstevel@tonic-gate }
2567*7c478bd9Sstevel@tonic-gate 
2568*7c478bd9Sstevel@tonic-gate /*
2569*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2570*7c478bd9Sstevel@tonic-gate  * Initialize a new block.
2571*7c478bd9Sstevel@tonic-gate  */
2572*7c478bd9Sstevel@tonic-gate local void
2573*7c478bd9Sstevel@tonic-gate init_block(s)
2574*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2575*7c478bd9Sstevel@tonic-gate {
2576*7c478bd9Sstevel@tonic-gate 	int n;	/* iterates over tree elements */
2577*7c478bd9Sstevel@tonic-gate 
2578*7c478bd9Sstevel@tonic-gate 	/* Initialize the trees. */
2579*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
2580*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
2581*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
2582*7c478bd9Sstevel@tonic-gate 
2583*7c478bd9Sstevel@tonic-gate 	s->dyn_ltree[END_BLOCK].Freq = 1;
2584*7c478bd9Sstevel@tonic-gate 	s->opt_len = s->static_len = 0L;
2585*7c478bd9Sstevel@tonic-gate 	s->last_lit = s->matches = 0;
2586*7c478bd9Sstevel@tonic-gate }
2587*7c478bd9Sstevel@tonic-gate 
2588*7c478bd9Sstevel@tonic-gate #define	SMALLEST 1
2589*7c478bd9Sstevel@tonic-gate /* Index within the heap array of least frequent node in the Huffman tree */
2590*7c478bd9Sstevel@tonic-gate 
2591*7c478bd9Sstevel@tonic-gate 
2592*7c478bd9Sstevel@tonic-gate /*
2593*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2594*7c478bd9Sstevel@tonic-gate  * Remove the smallest element from the heap and recreate the heap with
2595*7c478bd9Sstevel@tonic-gate  * one less element. Updates heap and heap_len.
2596*7c478bd9Sstevel@tonic-gate  */
2597*7c478bd9Sstevel@tonic-gate #define	pqremove(s, tree, top) \
2598*7c478bd9Sstevel@tonic-gate {\
2599*7c478bd9Sstevel@tonic-gate 	top = s->heap[SMALLEST]; \
2600*7c478bd9Sstevel@tonic-gate 	s->heap[SMALLEST] = s->heap[s->heap_len--]; \
2601*7c478bd9Sstevel@tonic-gate 	pqdownheap(s, tree, SMALLEST); \
2602*7c478bd9Sstevel@tonic-gate }
2603*7c478bd9Sstevel@tonic-gate 
2604*7c478bd9Sstevel@tonic-gate /*
2605*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2606*7c478bd9Sstevel@tonic-gate  * Compares to subtrees, using the tree depth as tie breaker when
2607*7c478bd9Sstevel@tonic-gate  * the subtrees have equal frequency. This minimizes the worst case length.
2608*7c478bd9Sstevel@tonic-gate  */
2609*7c478bd9Sstevel@tonic-gate #define	smaller(tree, n, m, depth) \
2610*7c478bd9Sstevel@tonic-gate 	(tree[n].Freq < tree[m].Freq || \
2611*7c478bd9Sstevel@tonic-gate 	(tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
2612*7c478bd9Sstevel@tonic-gate /*
2613*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2614*7c478bd9Sstevel@tonic-gate  * Restore the heap property by moving down the tree starting at node k,
2615*7c478bd9Sstevel@tonic-gate  * exchanging a node with the smallest of its two sons if necessary, stopping
2616*7c478bd9Sstevel@tonic-gate  * when the heap property is re-established (each father smaller than its
2617*7c478bd9Sstevel@tonic-gate  * two sons).
2618*7c478bd9Sstevel@tonic-gate  */
2619*7c478bd9Sstevel@tonic-gate local void
2620*7c478bd9Sstevel@tonic-gate pqdownheap(s, tree, k)
2621*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2622*7c478bd9Sstevel@tonic-gate     ct_data *tree;	/* the tree to restore */
2623*7c478bd9Sstevel@tonic-gate     int k;	/* node to move down */
2624*7c478bd9Sstevel@tonic-gate {
2625*7c478bd9Sstevel@tonic-gate 	int v = s->heap[k];
2626*7c478bd9Sstevel@tonic-gate 	int j = k << 1;	/* left son of k */
2627*7c478bd9Sstevel@tonic-gate 	while (j <= s->heap_len) {
2628*7c478bd9Sstevel@tonic-gate 		/* Set j to the smallest of the two sons: */
2629*7c478bd9Sstevel@tonic-gate 		if (j < s->heap_len &&
2630*7c478bd9Sstevel@tonic-gate 		    smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
2631*7c478bd9Sstevel@tonic-gate 			j++;
2632*7c478bd9Sstevel@tonic-gate 		}
2633*7c478bd9Sstevel@tonic-gate 		/* Exit if v is smaller than both sons */
2634*7c478bd9Sstevel@tonic-gate 		if (smaller(tree, v, s->heap[j], s->depth)) break;
2635*7c478bd9Sstevel@tonic-gate 
2636*7c478bd9Sstevel@tonic-gate 		/* Exchange v with the smallest son */
2637*7c478bd9Sstevel@tonic-gate 		s->heap[k] = s->heap[j];  k = j;
2638*7c478bd9Sstevel@tonic-gate 
2639*7c478bd9Sstevel@tonic-gate 		/* And continue down the tree, setting j to the left son of k */
2640*7c478bd9Sstevel@tonic-gate 		j <<= 1;
2641*7c478bd9Sstevel@tonic-gate 	}
2642*7c478bd9Sstevel@tonic-gate 	s->heap[k] = v;
2643*7c478bd9Sstevel@tonic-gate }
2644*7c478bd9Sstevel@tonic-gate 
2645*7c478bd9Sstevel@tonic-gate /*
2646*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2647*7c478bd9Sstevel@tonic-gate  * Compute the optimal bit lengths for a tree and update the total bit length
2648*7c478bd9Sstevel@tonic-gate  * for the current block.
2649*7c478bd9Sstevel@tonic-gate  * IN assertion: the fields freq and dad are set, heap[heap_max] and
2650*7c478bd9Sstevel@tonic-gate  *    above are the tree nodes sorted by increasing frequency.
2651*7c478bd9Sstevel@tonic-gate  * OUT assertions: the field len is set to the optimal bit length, the
2652*7c478bd9Sstevel@tonic-gate  *     array bl_count contains the frequencies for each bit length.
2653*7c478bd9Sstevel@tonic-gate  *     The length opt_len is updated; static_len is also updated if stree is
2654*7c478bd9Sstevel@tonic-gate  *     not null.
2655*7c478bd9Sstevel@tonic-gate  */
2656*7c478bd9Sstevel@tonic-gate local void
2657*7c478bd9Sstevel@tonic-gate gen_bitlen(s, desc)
2658*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2659*7c478bd9Sstevel@tonic-gate     tree_desc *desc;	/* the tree descriptor */
2660*7c478bd9Sstevel@tonic-gate {
2661*7c478bd9Sstevel@tonic-gate 	ct_data *tree  = desc->dyn_tree;
2662*7c478bd9Sstevel@tonic-gate 	int max_code   = desc->max_code;
2663*7c478bd9Sstevel@tonic-gate 	const ct_data *stree = desc->stat_desc->static_tree;
2664*7c478bd9Sstevel@tonic-gate 	const intf *extra    = desc->stat_desc->extra_bits;
2665*7c478bd9Sstevel@tonic-gate 	int base	= desc->stat_desc->extra_base;
2666*7c478bd9Sstevel@tonic-gate 	int max_length = desc->stat_desc->max_length;
2667*7c478bd9Sstevel@tonic-gate 	int h;	/* heap index */
2668*7c478bd9Sstevel@tonic-gate 	int n, m;	/* iterate over the tree elements */
2669*7c478bd9Sstevel@tonic-gate 	int bits;	/* bit length */
2670*7c478bd9Sstevel@tonic-gate 	int xbits;	/* extra bits */
2671*7c478bd9Sstevel@tonic-gate 	ush f;	/* frequency */
2672*7c478bd9Sstevel@tonic-gate 	/* number of elements with bit length too large */
2673*7c478bd9Sstevel@tonic-gate 	int overflow = 0;
2674*7c478bd9Sstevel@tonic-gate 
2675*7c478bd9Sstevel@tonic-gate 	for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
2676*7c478bd9Sstevel@tonic-gate 
2677*7c478bd9Sstevel@tonic-gate 	/*
2678*7c478bd9Sstevel@tonic-gate 	 * In a first pass, compute the optimal bit lengths (which may
2679*7c478bd9Sstevel@tonic-gate 	 * overflow in the case of the bit length tree).
2680*7c478bd9Sstevel@tonic-gate 	 */
2681*7c478bd9Sstevel@tonic-gate 	tree[s->heap[s->heap_max]].Len = 0;	/* root of the heap */
2682*7c478bd9Sstevel@tonic-gate 
2683*7c478bd9Sstevel@tonic-gate 	for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
2684*7c478bd9Sstevel@tonic-gate 		n = s->heap[h];
2685*7c478bd9Sstevel@tonic-gate 		bits = tree[tree[n].Dad].Len + 1;
2686*7c478bd9Sstevel@tonic-gate 		if (bits > max_length) bits = max_length, overflow++;
2687*7c478bd9Sstevel@tonic-gate 		tree[n].Len = (ush)bits;
2688*7c478bd9Sstevel@tonic-gate 		/* We overwrite tree[n].Dad which is no longer needed */
2689*7c478bd9Sstevel@tonic-gate 
2690*7c478bd9Sstevel@tonic-gate 		if (n > max_code) continue;	/* not a leaf node */
2691*7c478bd9Sstevel@tonic-gate 
2692*7c478bd9Sstevel@tonic-gate 		s->bl_count[bits]++;
2693*7c478bd9Sstevel@tonic-gate 		xbits = 0;
2694*7c478bd9Sstevel@tonic-gate 		if (n >= base) xbits = extra[n-base];
2695*7c478bd9Sstevel@tonic-gate 		f = tree[n].Freq;
2696*7c478bd9Sstevel@tonic-gate 		s->opt_len += (ulg)f * (bits + xbits);
2697*7c478bd9Sstevel@tonic-gate 		if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
2698*7c478bd9Sstevel@tonic-gate 	}
2699*7c478bd9Sstevel@tonic-gate 	if (overflow == 0)
2700*7c478bd9Sstevel@tonic-gate 		return;
2701*7c478bd9Sstevel@tonic-gate 
2702*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "\nbit length overflow\n"));
2703*7c478bd9Sstevel@tonic-gate 	/* This happens for example on obj2 and pic of the Calgary corpus */
2704*7c478bd9Sstevel@tonic-gate 
2705*7c478bd9Sstevel@tonic-gate 	/* Find the first bit length which could increase: */
2706*7c478bd9Sstevel@tonic-gate 	do {
2707*7c478bd9Sstevel@tonic-gate 		bits = max_length-1;
2708*7c478bd9Sstevel@tonic-gate 		while (s->bl_count[bits] == 0) bits--;
2709*7c478bd9Sstevel@tonic-gate 		s->bl_count[bits]--;	/* move one leaf down the tree */
2710*7c478bd9Sstevel@tonic-gate 		/* move one overflow item as its brother */
2711*7c478bd9Sstevel@tonic-gate 		s->bl_count[bits+1] += 2;
2712*7c478bd9Sstevel@tonic-gate 		s->bl_count[max_length]--;
2713*7c478bd9Sstevel@tonic-gate 		/*
2714*7c478bd9Sstevel@tonic-gate 		 * The brother of the overflow item also moves one
2715*7c478bd9Sstevel@tonic-gate 		 * step up, but this does not affect
2716*7c478bd9Sstevel@tonic-gate 		 * bl_count[max_length]
2717*7c478bd9Sstevel@tonic-gate 		 */
2718*7c478bd9Sstevel@tonic-gate 		overflow -= 2;
2719*7c478bd9Sstevel@tonic-gate 	} while (overflow > 0);
2720*7c478bd9Sstevel@tonic-gate 
2721*7c478bd9Sstevel@tonic-gate 	/*
2722*7c478bd9Sstevel@tonic-gate 	 * Now recompute all bit lengths, scanning in increasing
2723*7c478bd9Sstevel@tonic-gate 	 * frequency.  h is still equal to HEAP_SIZE. (It is simpler
2724*7c478bd9Sstevel@tonic-gate 	 * to reconstruct all lengths instead of fixing only the wrong
2725*7c478bd9Sstevel@tonic-gate 	 * ones. This idea is taken from 'ar' written by Haruhiko
2726*7c478bd9Sstevel@tonic-gate 	 * Okumura.)
2727*7c478bd9Sstevel@tonic-gate 	 */
2728*7c478bd9Sstevel@tonic-gate 	for (bits = max_length; bits != 0; bits--) {
2729*7c478bd9Sstevel@tonic-gate 		n = s->bl_count[bits];
2730*7c478bd9Sstevel@tonic-gate 		while (n != 0) {
2731*7c478bd9Sstevel@tonic-gate 			m = s->heap[--h];
2732*7c478bd9Sstevel@tonic-gate 			if (m > max_code) continue;
2733*7c478bd9Sstevel@tonic-gate 			if (tree[m].Len != (unsigned)bits) {
2734*7c478bd9Sstevel@tonic-gate 				Trace((stderr, "code %d bits %d->%d\n", m,
2735*7c478bd9Sstevel@tonic-gate 				    tree[m].Len, bits));
2736*7c478bd9Sstevel@tonic-gate 				s->opt_len += ((long)bits - (long)tree[m].Len)
2737*7c478bd9Sstevel@tonic-gate 				    *(long)tree[m].Freq;
2738*7c478bd9Sstevel@tonic-gate 				tree[m].Len = (ush)bits;
2739*7c478bd9Sstevel@tonic-gate 			}
2740*7c478bd9Sstevel@tonic-gate 			n--;
2741*7c478bd9Sstevel@tonic-gate 		}
2742*7c478bd9Sstevel@tonic-gate 	}
2743*7c478bd9Sstevel@tonic-gate }
2744*7c478bd9Sstevel@tonic-gate 
2745*7c478bd9Sstevel@tonic-gate /*
2746*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2747*7c478bd9Sstevel@tonic-gate  * Generate the codes for a given tree and bit counts (which need not be
2748*7c478bd9Sstevel@tonic-gate  * optimal).
2749*7c478bd9Sstevel@tonic-gate  * IN assertion: the array bl_count contains the bit length statistics for
2750*7c478bd9Sstevel@tonic-gate  * the given tree and the field len is set for all tree elements.
2751*7c478bd9Sstevel@tonic-gate  * OUT assertion: the field code is set for all tree elements of non
2752*7c478bd9Sstevel@tonic-gate  *     zero code length.
2753*7c478bd9Sstevel@tonic-gate  */
2754*7c478bd9Sstevel@tonic-gate local void
2755*7c478bd9Sstevel@tonic-gate gen_codes(tree, max_code, bl_count)
2756*7c478bd9Sstevel@tonic-gate     ct_data *tree;	/* the tree to decorate */
2757*7c478bd9Sstevel@tonic-gate     int max_code;	/* largest code with non zero frequency */
2758*7c478bd9Sstevel@tonic-gate     ushf *bl_count;	/* number of codes at each bit length */
2759*7c478bd9Sstevel@tonic-gate {
2760*7c478bd9Sstevel@tonic-gate 	/* next code value for each bit length */
2761*7c478bd9Sstevel@tonic-gate 	ush next_code[MAX_BITS+1];
2762*7c478bd9Sstevel@tonic-gate 	ush code = 0;	/* running code value */
2763*7c478bd9Sstevel@tonic-gate 	int bits;	/* bit index */
2764*7c478bd9Sstevel@tonic-gate 	int n;	/* code index */
2765*7c478bd9Sstevel@tonic-gate 
2766*7c478bd9Sstevel@tonic-gate 	/*
2767*7c478bd9Sstevel@tonic-gate 	 * The distribution counts are first used to generate the code
2768*7c478bd9Sstevel@tonic-gate 	 * values without bit reversal.
2769*7c478bd9Sstevel@tonic-gate 	 */
2770*7c478bd9Sstevel@tonic-gate 	for (bits = 1; bits <= MAX_BITS; bits++) {
2771*7c478bd9Sstevel@tonic-gate 		next_code[bits] = code = (code + bl_count[bits-1]) << 1;
2772*7c478bd9Sstevel@tonic-gate 	}
2773*7c478bd9Sstevel@tonic-gate 	/*
2774*7c478bd9Sstevel@tonic-gate 	 * Check that the bit counts in bl_count are consistent. The
2775*7c478bd9Sstevel@tonic-gate 	 * last code must be all ones.
2776*7c478bd9Sstevel@tonic-gate 	 */
2777*7c478bd9Sstevel@tonic-gate 	Assert(code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
2778*7c478bd9Sstevel@tonic-gate 	    "inconsistent bit counts");
2779*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
2780*7c478bd9Sstevel@tonic-gate 
2781*7c478bd9Sstevel@tonic-gate 	for (n = 0;  n <= max_code; n++) {
2782*7c478bd9Sstevel@tonic-gate 		int len = tree[n].Len;
2783*7c478bd9Sstevel@tonic-gate 		if (len == 0) continue;
2784*7c478bd9Sstevel@tonic-gate 		/* Now reverse the bits */
2785*7c478bd9Sstevel@tonic-gate 		tree[n].Code = bi_reverse(next_code[len]++, len);
2786*7c478bd9Sstevel@tonic-gate 
2787*7c478bd9Sstevel@tonic-gate 		Tracecv(tree != static_ltree,
2788*7c478bd9Sstevel@tonic-gate 		    (stderr, "\nn %3d %c l %2d c %4x (%x) ",
2789*7c478bd9Sstevel@tonic-gate 		    n, (isgraph(n) ? n : ' '), len, tree[n].Code,
2790*7c478bd9Sstevel@tonic-gate 			next_code[len]-1));
2791*7c478bd9Sstevel@tonic-gate 	}
2792*7c478bd9Sstevel@tonic-gate }
2793*7c478bd9Sstevel@tonic-gate 
2794*7c478bd9Sstevel@tonic-gate /*
2795*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2796*7c478bd9Sstevel@tonic-gate  * Construct one Huffman tree and assigns the code bit strings and lengths.
2797*7c478bd9Sstevel@tonic-gate  * Update the total bit length for the current block.
2798*7c478bd9Sstevel@tonic-gate  * IN assertion: the field freq is set for all tree elements.
2799*7c478bd9Sstevel@tonic-gate  * OUT assertions: the fields len and code are set to the optimal bit length
2800*7c478bd9Sstevel@tonic-gate  *     and corresponding code. The length opt_len is updated; static_len is
2801*7c478bd9Sstevel@tonic-gate  *     also updated if stree is not null. The field max_code is set.
2802*7c478bd9Sstevel@tonic-gate  */
2803*7c478bd9Sstevel@tonic-gate local void
2804*7c478bd9Sstevel@tonic-gate build_tree(s, desc)
2805*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2806*7c478bd9Sstevel@tonic-gate     tree_desc *desc;	/* the tree descriptor */
2807*7c478bd9Sstevel@tonic-gate {
2808*7c478bd9Sstevel@tonic-gate 	ct_data *tree   = desc->dyn_tree;
2809*7c478bd9Sstevel@tonic-gate 	const ct_data *stree  = desc->stat_desc->static_tree;
2810*7c478bd9Sstevel@tonic-gate 	int elems	= desc->stat_desc->elems;
2811*7c478bd9Sstevel@tonic-gate 	int n, m;	/* iterate over heap elements */
2812*7c478bd9Sstevel@tonic-gate 	int max_code = -1;	/* largest code with non zero frequency */
2813*7c478bd9Sstevel@tonic-gate 	int node;	/* new node being created */
2814*7c478bd9Sstevel@tonic-gate 
2815*7c478bd9Sstevel@tonic-gate 	/*
2816*7c478bd9Sstevel@tonic-gate 	 * Construct the initial heap, with least frequent element in
2817*7c478bd9Sstevel@tonic-gate 	 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and
2818*7c478bd9Sstevel@tonic-gate 	 * heap[2*n+1].  heap[0] is not used.
2819*7c478bd9Sstevel@tonic-gate 	 */
2820*7c478bd9Sstevel@tonic-gate 	s->heap_len = 0, s->heap_max = HEAP_SIZE;
2821*7c478bd9Sstevel@tonic-gate 
2822*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < elems; n++) {
2823*7c478bd9Sstevel@tonic-gate 		if (tree[n].Freq != 0) {
2824*7c478bd9Sstevel@tonic-gate 			s->heap[++(s->heap_len)] = max_code = n;
2825*7c478bd9Sstevel@tonic-gate 			s->depth[n] = 0;
2826*7c478bd9Sstevel@tonic-gate 		} else {
2827*7c478bd9Sstevel@tonic-gate 			tree[n].Len = 0;
2828*7c478bd9Sstevel@tonic-gate 		}
2829*7c478bd9Sstevel@tonic-gate 	}
2830*7c478bd9Sstevel@tonic-gate 
2831*7c478bd9Sstevel@tonic-gate 	/*
2832*7c478bd9Sstevel@tonic-gate 	 * The pkzip format requires that at least one distance code
2833*7c478bd9Sstevel@tonic-gate 	 * exists, and that at least one bit should be sent even if
2834*7c478bd9Sstevel@tonic-gate 	 * there is only one possible code. So to avoid special checks
2835*7c478bd9Sstevel@tonic-gate 	 * later on we force at least two codes of non zero frequency.
2836*7c478bd9Sstevel@tonic-gate 	 */
2837*7c478bd9Sstevel@tonic-gate 	while (s->heap_len < 2) {
2838*7c478bd9Sstevel@tonic-gate 		node = s->heap[++(s->heap_len)] = (max_code < 2 ?
2839*7c478bd9Sstevel@tonic-gate 		    ++max_code : 0);
2840*7c478bd9Sstevel@tonic-gate 		tree[node].Freq = 1;
2841*7c478bd9Sstevel@tonic-gate 		s->depth[node] = 0;
2842*7c478bd9Sstevel@tonic-gate 		s->opt_len--; if (stree) s->static_len -= stree[node].Len;
2843*7c478bd9Sstevel@tonic-gate 		/* node is 0 or 1 so it does not have extra bits */
2844*7c478bd9Sstevel@tonic-gate 	}
2845*7c478bd9Sstevel@tonic-gate 	desc->max_code = max_code;
2846*7c478bd9Sstevel@tonic-gate 
2847*7c478bd9Sstevel@tonic-gate 	/*
2848*7c478bd9Sstevel@tonic-gate 	 * The elements heap[heap_len/2+1 .. heap_len] are leaves of
2849*7c478bd9Sstevel@tonic-gate 	 * the tree, establish sub-heaps of increasing lengths:
2850*7c478bd9Sstevel@tonic-gate 	 */
2851*7c478bd9Sstevel@tonic-gate 	for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
2852*7c478bd9Sstevel@tonic-gate 
2853*7c478bd9Sstevel@tonic-gate 	/*
2854*7c478bd9Sstevel@tonic-gate 	 * Construct the Huffman tree by repeatedly combining the
2855*7c478bd9Sstevel@tonic-gate 	 * least two frequent nodes.
2856*7c478bd9Sstevel@tonic-gate 	 */
2857*7c478bd9Sstevel@tonic-gate 	node = elems;	/* next internal node of the tree */
2858*7c478bd9Sstevel@tonic-gate 	do {
2859*7c478bd9Sstevel@tonic-gate 		pqremove(s, tree, n);	/* n = node of least frequency */
2860*7c478bd9Sstevel@tonic-gate 		m = s->heap[SMALLEST];	/* m = node of next least frequency */
2861*7c478bd9Sstevel@tonic-gate 
2862*7c478bd9Sstevel@tonic-gate 		/* keep the nodes sorted by frequency */
2863*7c478bd9Sstevel@tonic-gate 		s->heap[--(s->heap_max)] = n;
2864*7c478bd9Sstevel@tonic-gate 		s->heap[--(s->heap_max)] = m;
2865*7c478bd9Sstevel@tonic-gate 
2866*7c478bd9Sstevel@tonic-gate 		/* Create a new node father of n and m */
2867*7c478bd9Sstevel@tonic-gate 		tree[node].Freq = tree[n].Freq + tree[m].Freq;
2868*7c478bd9Sstevel@tonic-gate 		s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
2869*7c478bd9Sstevel@tonic-gate 		tree[n].Dad = tree[m].Dad = (ush)node;
2870*7c478bd9Sstevel@tonic-gate #ifdef DUMP_BL_TREE
2871*7c478bd9Sstevel@tonic-gate 		if (tree == s->bl_tree) {
2872*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)",
2873*7c478bd9Sstevel@tonic-gate 			    node, tree[node].Freq, n, tree[n].Freq, m,
2874*7c478bd9Sstevel@tonic-gate 			    tree[m].Freq);
2875*7c478bd9Sstevel@tonic-gate 		}
2876*7c478bd9Sstevel@tonic-gate #endif
2877*7c478bd9Sstevel@tonic-gate 		/* and insert the new node in the heap */
2878*7c478bd9Sstevel@tonic-gate 		s->heap[SMALLEST] = node++;
2879*7c478bd9Sstevel@tonic-gate 		pqdownheap(s, tree, SMALLEST);
2880*7c478bd9Sstevel@tonic-gate 
2881*7c478bd9Sstevel@tonic-gate 	} while (s->heap_len >= 2);
2882*7c478bd9Sstevel@tonic-gate 
2883*7c478bd9Sstevel@tonic-gate 	s->heap[--(s->heap_max)] = s->heap[SMALLEST];
2884*7c478bd9Sstevel@tonic-gate 
2885*7c478bd9Sstevel@tonic-gate 	/*
2886*7c478bd9Sstevel@tonic-gate 	 * At this point, the fields freq and dad are set. We can now
2887*7c478bd9Sstevel@tonic-gate 	 * generate the bit lengths.
2888*7c478bd9Sstevel@tonic-gate 	 */
2889*7c478bd9Sstevel@tonic-gate 	gen_bitlen(s, (tree_desc *)desc);
2890*7c478bd9Sstevel@tonic-gate 
2891*7c478bd9Sstevel@tonic-gate 	/* The field len is now set, we can generate the bit codes */
2892*7c478bd9Sstevel@tonic-gate 	gen_codes((ct_data *)tree, max_code, s->bl_count);
2893*7c478bd9Sstevel@tonic-gate }
2894*7c478bd9Sstevel@tonic-gate 
2895*7c478bd9Sstevel@tonic-gate /*
2896*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2897*7c478bd9Sstevel@tonic-gate  * Scan a literal or distance tree to determine the frequencies of the codes
2898*7c478bd9Sstevel@tonic-gate  * in the bit length tree.
2899*7c478bd9Sstevel@tonic-gate  */
2900*7c478bd9Sstevel@tonic-gate local void
2901*7c478bd9Sstevel@tonic-gate scan_tree(s, tree, max_code)
2902*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2903*7c478bd9Sstevel@tonic-gate     ct_data *tree;	/* the tree to be scanned */
2904*7c478bd9Sstevel@tonic-gate     int max_code;	/* and its largest code of non zero frequency */
2905*7c478bd9Sstevel@tonic-gate {
2906*7c478bd9Sstevel@tonic-gate 	int n;	/* iterates over all tree elements */
2907*7c478bd9Sstevel@tonic-gate 	int prevlen = -1;	/* last emitted length */
2908*7c478bd9Sstevel@tonic-gate 	int curlen;	/* length of current code */
2909*7c478bd9Sstevel@tonic-gate 	int nextlen = tree[0].Len;	/* length of next code */
2910*7c478bd9Sstevel@tonic-gate 	int count = 0;	/* repeat count of the current code */
2911*7c478bd9Sstevel@tonic-gate 	int max_count = 7;	/* max repeat count */
2912*7c478bd9Sstevel@tonic-gate 	int min_count = 4;	/* min repeat count */
2913*7c478bd9Sstevel@tonic-gate 
2914*7c478bd9Sstevel@tonic-gate 	if (nextlen == 0) max_count = 138, min_count = 3;
2915*7c478bd9Sstevel@tonic-gate 	tree[max_code+1].Len = (ush)0xffff;	/* guard */
2916*7c478bd9Sstevel@tonic-gate 
2917*7c478bd9Sstevel@tonic-gate 	for (n = 0; n <= max_code; n++) {
2918*7c478bd9Sstevel@tonic-gate 		curlen = nextlen; nextlen = tree[n+1].Len;
2919*7c478bd9Sstevel@tonic-gate 		if (++count < max_count && curlen == nextlen) {
2920*7c478bd9Sstevel@tonic-gate 			continue;
2921*7c478bd9Sstevel@tonic-gate 		} else if (count < min_count) {
2922*7c478bd9Sstevel@tonic-gate 			s->bl_tree[curlen].Freq += count;
2923*7c478bd9Sstevel@tonic-gate 		} else if (curlen != 0) {
2924*7c478bd9Sstevel@tonic-gate 			if (curlen != prevlen) s->bl_tree[curlen].Freq++;
2925*7c478bd9Sstevel@tonic-gate 			s->bl_tree[REP_3_6].Freq++;
2926*7c478bd9Sstevel@tonic-gate 		} else if (count <= 10) {
2927*7c478bd9Sstevel@tonic-gate 			s->bl_tree[REPZ_3_10].Freq++;
2928*7c478bd9Sstevel@tonic-gate 		} else {
2929*7c478bd9Sstevel@tonic-gate 			s->bl_tree[REPZ_11_138].Freq++;
2930*7c478bd9Sstevel@tonic-gate 		}
2931*7c478bd9Sstevel@tonic-gate 		count = 0; prevlen = curlen;
2932*7c478bd9Sstevel@tonic-gate 		if (nextlen == 0) {
2933*7c478bd9Sstevel@tonic-gate 			max_count = 138, min_count = 3;
2934*7c478bd9Sstevel@tonic-gate 		} else if (curlen == nextlen) {
2935*7c478bd9Sstevel@tonic-gate 			max_count = 6, min_count = 3;
2936*7c478bd9Sstevel@tonic-gate 		} else {
2937*7c478bd9Sstevel@tonic-gate 			max_count = 7, min_count = 4;
2938*7c478bd9Sstevel@tonic-gate 		}
2939*7c478bd9Sstevel@tonic-gate 	}
2940*7c478bd9Sstevel@tonic-gate }
2941*7c478bd9Sstevel@tonic-gate 
2942*7c478bd9Sstevel@tonic-gate /*
2943*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2944*7c478bd9Sstevel@tonic-gate  * Send a literal or distance tree in compressed form, using the codes in
2945*7c478bd9Sstevel@tonic-gate  * bl_tree.
2946*7c478bd9Sstevel@tonic-gate  */
2947*7c478bd9Sstevel@tonic-gate local void
2948*7c478bd9Sstevel@tonic-gate send_tree(s, tree, max_code)
2949*7c478bd9Sstevel@tonic-gate     deflate_state *s;
2950*7c478bd9Sstevel@tonic-gate     ct_data *tree;	/* the tree to be scanned */
2951*7c478bd9Sstevel@tonic-gate     int max_code;	/* and its largest code of non zero frequency */
2952*7c478bd9Sstevel@tonic-gate {
2953*7c478bd9Sstevel@tonic-gate 	int n;	/* iterates over all tree elements */
2954*7c478bd9Sstevel@tonic-gate 	int prevlen = -1;	/* last emitted length */
2955*7c478bd9Sstevel@tonic-gate 	int curlen;	/* length of current code */
2956*7c478bd9Sstevel@tonic-gate 	int nextlen = tree[0].Len;	/* length of next code */
2957*7c478bd9Sstevel@tonic-gate 	int count = 0;	/* repeat count of the current code */
2958*7c478bd9Sstevel@tonic-gate 	int max_count = 7;	/* max repeat count */
2959*7c478bd9Sstevel@tonic-gate 	int min_count = 4;	/* min repeat count */
2960*7c478bd9Sstevel@tonic-gate 
2961*7c478bd9Sstevel@tonic-gate 	/* tree[max_code+1].Len = -1; */  /* guard already set */
2962*7c478bd9Sstevel@tonic-gate 	if (nextlen == 0) max_count = 138, min_count = 3;
2963*7c478bd9Sstevel@tonic-gate 
2964*7c478bd9Sstevel@tonic-gate 	for (n = 0; n <= max_code; n++) {
2965*7c478bd9Sstevel@tonic-gate 		curlen = nextlen; nextlen = tree[n+1].Len;
2966*7c478bd9Sstevel@tonic-gate 		if (++count < max_count && curlen == nextlen) {
2967*7c478bd9Sstevel@tonic-gate 			continue;
2968*7c478bd9Sstevel@tonic-gate 		} else if (count < min_count) {
2969*7c478bd9Sstevel@tonic-gate 			do { send_code(s, curlen, s->bl_tree); }
2970*7c478bd9Sstevel@tonic-gate 			while (--count != 0);
2971*7c478bd9Sstevel@tonic-gate 
2972*7c478bd9Sstevel@tonic-gate 		} else if (curlen != 0) {
2973*7c478bd9Sstevel@tonic-gate 			if (curlen != prevlen) {
2974*7c478bd9Sstevel@tonic-gate 				send_code(s, curlen, s->bl_tree); count--;
2975*7c478bd9Sstevel@tonic-gate 			}
2976*7c478bd9Sstevel@tonic-gate 			Assert(count >= 3 && count <= 6, " 3_6?");
2977*7c478bd9Sstevel@tonic-gate 			send_code(s, REP_3_6, s->bl_tree);
2978*7c478bd9Sstevel@tonic-gate 			send_bits(s, count-3, 2);
2979*7c478bd9Sstevel@tonic-gate 
2980*7c478bd9Sstevel@tonic-gate 		} else if (count <= 10) {
2981*7c478bd9Sstevel@tonic-gate 			send_code(s, REPZ_3_10, s->bl_tree);
2982*7c478bd9Sstevel@tonic-gate 			send_bits(s, count-3, 3);
2983*7c478bd9Sstevel@tonic-gate 
2984*7c478bd9Sstevel@tonic-gate 		} else {
2985*7c478bd9Sstevel@tonic-gate 			send_code(s, REPZ_11_138, s->bl_tree);
2986*7c478bd9Sstevel@tonic-gate 			send_bits(s, count-11, 7);
2987*7c478bd9Sstevel@tonic-gate 		}
2988*7c478bd9Sstevel@tonic-gate 		count = 0; prevlen = curlen;
2989*7c478bd9Sstevel@tonic-gate 		if (nextlen == 0) {
2990*7c478bd9Sstevel@tonic-gate 			max_count = 138, min_count = 3;
2991*7c478bd9Sstevel@tonic-gate 		} else if (curlen == nextlen) {
2992*7c478bd9Sstevel@tonic-gate 			max_count = 6, min_count = 3;
2993*7c478bd9Sstevel@tonic-gate 		} else {
2994*7c478bd9Sstevel@tonic-gate 			max_count = 7, min_count = 4;
2995*7c478bd9Sstevel@tonic-gate 		}
2996*7c478bd9Sstevel@tonic-gate 	}
2997*7c478bd9Sstevel@tonic-gate }
2998*7c478bd9Sstevel@tonic-gate 
2999*7c478bd9Sstevel@tonic-gate /*
3000*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3001*7c478bd9Sstevel@tonic-gate  * Construct the Huffman tree for the bit lengths and return the index in
3002*7c478bd9Sstevel@tonic-gate  * bl_order of the last bit length code to send.
3003*7c478bd9Sstevel@tonic-gate  */
3004*7c478bd9Sstevel@tonic-gate local int
3005*7c478bd9Sstevel@tonic-gate build_bl_tree(s)
3006*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3007*7c478bd9Sstevel@tonic-gate {
3008*7c478bd9Sstevel@tonic-gate 	/* index of last bit length code of non zero freq */
3009*7c478bd9Sstevel@tonic-gate 	int max_blindex;
3010*7c478bd9Sstevel@tonic-gate 
3011*7c478bd9Sstevel@tonic-gate 	/*
3012*7c478bd9Sstevel@tonic-gate 	 * Determine the bit length frequencies for literal and
3013*7c478bd9Sstevel@tonic-gate 	 * distance trees
3014*7c478bd9Sstevel@tonic-gate 	 */
3015*7c478bd9Sstevel@tonic-gate 	scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
3016*7c478bd9Sstevel@tonic-gate 	scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
3017*7c478bd9Sstevel@tonic-gate 
3018*7c478bd9Sstevel@tonic-gate 	/* Build the bit length tree: */
3019*7c478bd9Sstevel@tonic-gate 	build_tree(s, (tree_desc *)(&(s->bl_desc)));
3020*7c478bd9Sstevel@tonic-gate 	/*
3021*7c478bd9Sstevel@tonic-gate 	 * opt_len now includes the length of the tree
3022*7c478bd9Sstevel@tonic-gate 	 * representations, except the lengths of the bit lengths
3023*7c478bd9Sstevel@tonic-gate 	 * codes and the 5+5+4 bits for the counts.
3024*7c478bd9Sstevel@tonic-gate 	 */
3025*7c478bd9Sstevel@tonic-gate 
3026*7c478bd9Sstevel@tonic-gate 	/*
3027*7c478bd9Sstevel@tonic-gate 	 * Determine the number of bit length codes to send. The pkzip
3028*7c478bd9Sstevel@tonic-gate 	 * format requires that at least 4 bit length codes be
3029*7c478bd9Sstevel@tonic-gate 	 * sent. (appnote.txt says 3 but the actual value used is 4.)
3030*7c478bd9Sstevel@tonic-gate 	 */
3031*7c478bd9Sstevel@tonic-gate 	for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
3032*7c478bd9Sstevel@tonic-gate 		if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
3033*7c478bd9Sstevel@tonic-gate 	}
3034*7c478bd9Sstevel@tonic-gate 	/* Update opt_len to include the bit length tree and counts */
3035*7c478bd9Sstevel@tonic-gate 	s->opt_len += 3*(max_blindex+1) + 5+5+4;
3036*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
3037*7c478bd9Sstevel@tonic-gate 	    s->opt_len, s->static_len));
3038*7c478bd9Sstevel@tonic-gate 
3039*7c478bd9Sstevel@tonic-gate 	return (max_blindex);
3040*7c478bd9Sstevel@tonic-gate }
3041*7c478bd9Sstevel@tonic-gate 
3042*7c478bd9Sstevel@tonic-gate /*
3043*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3044*7c478bd9Sstevel@tonic-gate  * Send the header for a block using dynamic Huffman trees: the counts, the
3045*7c478bd9Sstevel@tonic-gate  * lengths of the bit length codes, the literal tree and the distance tree.
3046*7c478bd9Sstevel@tonic-gate  * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
3047*7c478bd9Sstevel@tonic-gate  */
3048*7c478bd9Sstevel@tonic-gate local void
3049*7c478bd9Sstevel@tonic-gate send_all_trees(s, lcodes, dcodes, blcodes)
3050*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3051*7c478bd9Sstevel@tonic-gate     int lcodes, dcodes, blcodes;	/* number of codes for each tree */
3052*7c478bd9Sstevel@tonic-gate {
3053*7c478bd9Sstevel@tonic-gate 	int rank;	/* index in bl_order */
3054*7c478bd9Sstevel@tonic-gate 
3055*7c478bd9Sstevel@tonic-gate 	Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4,
3056*7c478bd9Sstevel@tonic-gate 	    "not enough codes");
3057*7c478bd9Sstevel@tonic-gate 	Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
3058*7c478bd9Sstevel@tonic-gate 	    "too many codes");
3059*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\nbl counts: "));
3060*7c478bd9Sstevel@tonic-gate 	send_bits(s, lcodes-257, 5);	/* not +255 as stated in appnote.txt */
3061*7c478bd9Sstevel@tonic-gate 	send_bits(s, dcodes-1,   5);
3062*7c478bd9Sstevel@tonic-gate 	send_bits(s, blcodes-4,  4);	/* not -3 as stated in appnote.txt */
3063*7c478bd9Sstevel@tonic-gate 	for (rank = 0; rank < blcodes; rank++) {
3064*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
3065*7c478bd9Sstevel@tonic-gate 		send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
3066*7c478bd9Sstevel@tonic-gate 	}
3067*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3068*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
3069*7c478bd9Sstevel@tonic-gate #endif
3070*7c478bd9Sstevel@tonic-gate 
3071*7c478bd9Sstevel@tonic-gate 	/* literal tree */
3072*7c478bd9Sstevel@tonic-gate 	send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1);
3073*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3074*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
3075*7c478bd9Sstevel@tonic-gate #endif
3076*7c478bd9Sstevel@tonic-gate 
3077*7c478bd9Sstevel@tonic-gate 	/* distance tree */
3078*7c478bd9Sstevel@tonic-gate 	send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1);
3079*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3080*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
3081*7c478bd9Sstevel@tonic-gate #endif
3082*7c478bd9Sstevel@tonic-gate }
3083*7c478bd9Sstevel@tonic-gate 
3084*7c478bd9Sstevel@tonic-gate /*
3085*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3086*7c478bd9Sstevel@tonic-gate  * Send a stored block
3087*7c478bd9Sstevel@tonic-gate  */
3088*7c478bd9Sstevel@tonic-gate void
3089*7c478bd9Sstevel@tonic-gate _tr_stored_block(s, buf, stored_len, eof)
3090*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3091*7c478bd9Sstevel@tonic-gate     charf *buf;	/* input block */
3092*7c478bd9Sstevel@tonic-gate     ulg stored_len;	/* length of input block */
3093*7c478bd9Sstevel@tonic-gate     int eof;	/* true if this is the last block for a file */
3094*7c478bd9Sstevel@tonic-gate {
3095*7c478bd9Sstevel@tonic-gate 	send_bits(s, (STORED_BLOCK<<1)+eof, 3);	/* send block type */
3096*7c478bd9Sstevel@tonic-gate 	s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; /* PPP */
3097*7c478bd9Sstevel@tonic-gate 	s->compressed_len += (stored_len + 4) << 3;	/* PPP */
3098*7c478bd9Sstevel@tonic-gate 
3099*7c478bd9Sstevel@tonic-gate 	copy_block(s, buf, (unsigned)stored_len, 1);	/* with header */
3100*7c478bd9Sstevel@tonic-gate }
3101*7c478bd9Sstevel@tonic-gate 
3102*7c478bd9Sstevel@tonic-gate /*
3103*7c478bd9Sstevel@tonic-gate  * Send just the `stored block' type code without any length bytes or data.
3104*7c478bd9Sstevel@tonic-gate  * ---PPP---
3105*7c478bd9Sstevel@tonic-gate  */
3106*7c478bd9Sstevel@tonic-gate void
3107*7c478bd9Sstevel@tonic-gate _tr_stored_type_only(s)
3108*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3109*7c478bd9Sstevel@tonic-gate {
3110*7c478bd9Sstevel@tonic-gate 	send_bits(s, (STORED_BLOCK << 1), 3);
3111*7c478bd9Sstevel@tonic-gate 	bi_windup(s);
3112*7c478bd9Sstevel@tonic-gate 	s->compressed_len = (s->compressed_len + 3) & ~7L;	/* PPP */
3113*7c478bd9Sstevel@tonic-gate }
3114*7c478bd9Sstevel@tonic-gate 
3115*7c478bd9Sstevel@tonic-gate 
3116*7c478bd9Sstevel@tonic-gate /*
3117*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3118*7c478bd9Sstevel@tonic-gate  * Send one empty static block to give enough lookahead for inflate.
3119*7c478bd9Sstevel@tonic-gate  * This takes 10 bits, of which 7 may remain in the bit buffer.
3120*7c478bd9Sstevel@tonic-gate  * The current inflate code requires 9 bits of lookahead. If the
3121*7c478bd9Sstevel@tonic-gate  * last two codes for the previous block (real code plus EOB) were coded
3122*7c478bd9Sstevel@tonic-gate  * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
3123*7c478bd9Sstevel@tonic-gate  * the last real code. In this case we send two empty static blocks instead
3124*7c478bd9Sstevel@tonic-gate  * of one. (There are no problems if the previous block is stored or fixed.)
3125*7c478bd9Sstevel@tonic-gate  * To simplify the code, we assume the worst case of last real code encoded
3126*7c478bd9Sstevel@tonic-gate  * on one bit only.
3127*7c478bd9Sstevel@tonic-gate  */
3128*7c478bd9Sstevel@tonic-gate void
3129*7c478bd9Sstevel@tonic-gate _tr_align(s)
3130*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3131*7c478bd9Sstevel@tonic-gate {
3132*7c478bd9Sstevel@tonic-gate 	send_bits(s, STATIC_TREES<<1, 3);
3133*7c478bd9Sstevel@tonic-gate 	send_code(s, END_BLOCK, static_ltree);
3134*7c478bd9Sstevel@tonic-gate 	s->compressed_len += 10L;	/* 3 for block type, 7 for EOB */
3135*7c478bd9Sstevel@tonic-gate 	bi_flush(s);
3136*7c478bd9Sstevel@tonic-gate 	/*
3137*7c478bd9Sstevel@tonic-gate 	 * Of the 10 bits for the empty block, we have already sent
3138*7c478bd9Sstevel@tonic-gate 	 * (10 - bi_valid) bits. The lookahead for the last real code
3139*7c478bd9Sstevel@tonic-gate 	 * (before the EOB of the previous block) was thus at least
3140*7c478bd9Sstevel@tonic-gate 	 * one plus the length of the EOB plus what we have just sent
3141*7c478bd9Sstevel@tonic-gate 	 * of the empty static block.
3142*7c478bd9Sstevel@tonic-gate 	 */
3143*7c478bd9Sstevel@tonic-gate 	if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
3144*7c478bd9Sstevel@tonic-gate 		send_bits(s, STATIC_TREES<<1, 3);
3145*7c478bd9Sstevel@tonic-gate 		send_code(s, END_BLOCK, static_ltree);
3146*7c478bd9Sstevel@tonic-gate 		s->compressed_len += 10L;
3147*7c478bd9Sstevel@tonic-gate 		bi_flush(s);
3148*7c478bd9Sstevel@tonic-gate 	}
3149*7c478bd9Sstevel@tonic-gate 	s->last_eob_len = 7;
3150*7c478bd9Sstevel@tonic-gate }
3151*7c478bd9Sstevel@tonic-gate 
3152*7c478bd9Sstevel@tonic-gate /*
3153*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3154*7c478bd9Sstevel@tonic-gate  * Determine the best encoding for the current block: dynamic trees, static
3155*7c478bd9Sstevel@tonic-gate  * trees or store, and output the encoded block to the zip file.
3156*7c478bd9Sstevel@tonic-gate  */
3157*7c478bd9Sstevel@tonic-gate void
3158*7c478bd9Sstevel@tonic-gate _tr_flush_block(s, buf, stored_len, eof)
3159*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3160*7c478bd9Sstevel@tonic-gate     charf *buf;	/* input block, or NULL if too old */
3161*7c478bd9Sstevel@tonic-gate     ulg stored_len;	/* length of input block */
3162*7c478bd9Sstevel@tonic-gate     int eof;	/* true if this is the last block for a file */
3163*7c478bd9Sstevel@tonic-gate {
3164*7c478bd9Sstevel@tonic-gate 	ulg opt_lenb, static_lenb;	/* opt_len and static_len in bytes */
3165*7c478bd9Sstevel@tonic-gate 	/* index of last bit length code of non zero freq */
3166*7c478bd9Sstevel@tonic-gate 	int max_blindex = 0;
3167*7c478bd9Sstevel@tonic-gate 
3168*7c478bd9Sstevel@tonic-gate 	/* Build the Huffman trees unless a stored block is forced */
3169*7c478bd9Sstevel@tonic-gate 	if (s->level > 0) {
3170*7c478bd9Sstevel@tonic-gate 
3171*7c478bd9Sstevel@tonic-gate 		/* Check if the file is ascii or binary */
3172*7c478bd9Sstevel@tonic-gate 		if (s->data_type == Z_UNKNOWN) set_data_type(s);
3173*7c478bd9Sstevel@tonic-gate 
3174*7c478bd9Sstevel@tonic-gate 		/* Construct the literal and distance trees */
3175*7c478bd9Sstevel@tonic-gate 		build_tree(s, (tree_desc *)(&(s->l_desc)));
3176*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
3177*7c478bd9Sstevel@tonic-gate 		    s->static_len));
3178*7c478bd9Sstevel@tonic-gate 
3179*7c478bd9Sstevel@tonic-gate 		build_tree(s, (tree_desc *)(&(s->d_desc)));
3180*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
3181*7c478bd9Sstevel@tonic-gate 		    s->static_len));
3182*7c478bd9Sstevel@tonic-gate 		/*
3183*7c478bd9Sstevel@tonic-gate 		 * At this point, opt_len and static_len are the total
3184*7c478bd9Sstevel@tonic-gate 		 * bit lengths of the compressed block data, excluding
3185*7c478bd9Sstevel@tonic-gate 		 * the tree representations.
3186*7c478bd9Sstevel@tonic-gate 		 */
3187*7c478bd9Sstevel@tonic-gate 
3188*7c478bd9Sstevel@tonic-gate 		/*
3189*7c478bd9Sstevel@tonic-gate 		 * Build the bit length tree for the above two trees,
3190*7c478bd9Sstevel@tonic-gate 		 * and get the index in bl_order of the last bit
3191*7c478bd9Sstevel@tonic-gate 		 * length code to send.
3192*7c478bd9Sstevel@tonic-gate 		 */
3193*7c478bd9Sstevel@tonic-gate 		max_blindex = build_bl_tree(s);
3194*7c478bd9Sstevel@tonic-gate 
3195*7c478bd9Sstevel@tonic-gate 		/*
3196*7c478bd9Sstevel@tonic-gate 		 * Determine the best encoding. Compute first the
3197*7c478bd9Sstevel@tonic-gate 		 * block length in bytes
3198*7c478bd9Sstevel@tonic-gate 		 */
3199*7c478bd9Sstevel@tonic-gate 		opt_lenb = (s->opt_len+3+7)>>3;
3200*7c478bd9Sstevel@tonic-gate 		static_lenb = (s->static_len+3+7)>>3;
3201*7c478bd9Sstevel@tonic-gate 
3202*7c478bd9Sstevel@tonic-gate 		Tracev((stderr,
3203*7c478bd9Sstevel@tonic-gate 		    "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
3204*7c478bd9Sstevel@tonic-gate 		    opt_lenb, s->opt_len, static_lenb, s->static_len,
3205*7c478bd9Sstevel@tonic-gate 		    stored_len, s->last_lit));
3206*7c478bd9Sstevel@tonic-gate 
3207*7c478bd9Sstevel@tonic-gate 		if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
3208*7c478bd9Sstevel@tonic-gate 
3209*7c478bd9Sstevel@tonic-gate 	} else {
3210*7c478bd9Sstevel@tonic-gate 		Assert(buf != (char *)0, "lost buf");
3211*7c478bd9Sstevel@tonic-gate 		/* force a stored block */
3212*7c478bd9Sstevel@tonic-gate 		opt_lenb = static_lenb = stored_len + 5;
3213*7c478bd9Sstevel@tonic-gate 	}
3214*7c478bd9Sstevel@tonic-gate 
3215*7c478bd9Sstevel@tonic-gate 	/*
3216*7c478bd9Sstevel@tonic-gate 	 * If compression failed and this is the first and last block,
3217*7c478bd9Sstevel@tonic-gate 	 * and if the .zip file can be seeked (to rewrite the local
3218*7c478bd9Sstevel@tonic-gate 	 * header), the whole file is transformed into a stored file:
3219*7c478bd9Sstevel@tonic-gate 	 */
3220*7c478bd9Sstevel@tonic-gate #ifdef STORED_FILE_OK
3221*7c478bd9Sstevel@tonic-gate #ifdef FORCE_STORED_FILE
3222*7c478bd9Sstevel@tonic-gate #define	FRC_STR_COND	eof && s->compressed_len == 0L /* force stored file */
3223*7c478bd9Sstevel@tonic-gate #else
3224*7c478bd9Sstevel@tonic-gate #define	FRC_STR_COND	stored_len <= opt_lenb && eof && \
3225*7c478bd9Sstevel@tonic-gate 			s->compressed_len == 0L && seekable()
3226*7c478bd9Sstevel@tonic-gate #endif
3227*7c478bd9Sstevel@tonic-gate 	if (FRC_STR_COND) {
3228*7c478bd9Sstevel@tonic-gate #undef FRC_STR_COND
3229*7c478bd9Sstevel@tonic-gate 		/*
3230*7c478bd9Sstevel@tonic-gate 		 * Since LIT_BUFSIZE <= 2*WSIZE, the input data must
3231*7c478bd9Sstevel@tonic-gate 		 * be there:
3232*7c478bd9Sstevel@tonic-gate 		 */
3233*7c478bd9Sstevel@tonic-gate 		if (buf == (charf*)0) error("block vanished");
3234*7c478bd9Sstevel@tonic-gate 
3235*7c478bd9Sstevel@tonic-gate 		/* without header */
3236*7c478bd9Sstevel@tonic-gate 		copy_block(s, buf, (unsigned)stored_len, 0);
3237*7c478bd9Sstevel@tonic-gate 		s->compressed_len = stored_len << 3;
3238*7c478bd9Sstevel@tonic-gate 		s->method = STORED;
3239*7c478bd9Sstevel@tonic-gate 	} else
3240*7c478bd9Sstevel@tonic-gate #endif /* STORED_FILE_OK */
3241*7c478bd9Sstevel@tonic-gate 
3242*7c478bd9Sstevel@tonic-gate #ifdef FORCE_STORED
3243*7c478bd9Sstevel@tonic-gate #define	FRC_STR_COND	buf != (char *)0	/* force stored block */
3244*7c478bd9Sstevel@tonic-gate #else
3245*7c478bd9Sstevel@tonic-gate 			/* 4: two words for the lengths */
3246*7c478bd9Sstevel@tonic-gate #define	FRC_STR_COND	stored_len+4 <= opt_lenb && buf != (char *)0
3247*7c478bd9Sstevel@tonic-gate #endif
3248*7c478bd9Sstevel@tonic-gate 		if (FRC_STR_COND) {
3249*7c478bd9Sstevel@tonic-gate #undef FRC_STR_COND
3250*7c478bd9Sstevel@tonic-gate 			/*
3251*7c478bd9Sstevel@tonic-gate 			 * The test buf != NULL is only necessary if
3252*7c478bd9Sstevel@tonic-gate 			 * LIT_BUFSIZE > WSIZE.  Otherwise we can't
3253*7c478bd9Sstevel@tonic-gate 			 * have processed more than WSIZE input bytes
3254*7c478bd9Sstevel@tonic-gate 			 * since the last block flush, because
3255*7c478bd9Sstevel@tonic-gate 			 * compression would have been successful. If
3256*7c478bd9Sstevel@tonic-gate 			 * LIT_BUFSIZE <= WSIZE, it is never too late
3257*7c478bd9Sstevel@tonic-gate 			 * to transform a block into a stored block.
3258*7c478bd9Sstevel@tonic-gate 			 */
3259*7c478bd9Sstevel@tonic-gate 			_tr_stored_block(s, buf, stored_len, eof);
3260*7c478bd9Sstevel@tonic-gate #ifdef FORCE_STATIC
3261*7c478bd9Sstevel@tonic-gate #define	FRC_STAT_COND	static_lenb >= 0 /* force static trees */
3262*7c478bd9Sstevel@tonic-gate #else
3263*7c478bd9Sstevel@tonic-gate #define	FRC_STAT_COND	static_lenb == opt_lenb
3264*7c478bd9Sstevel@tonic-gate #endif
3265*7c478bd9Sstevel@tonic-gate 		} else if (FRC_STAT_COND) {
3266*7c478bd9Sstevel@tonic-gate #undef FRC_STAT_COND
3267*7c478bd9Sstevel@tonic-gate 			send_bits(s, (STATIC_TREES<<1)+eof, 3);
3268*7c478bd9Sstevel@tonic-gate 			compress_block(s, (ct_data *)static_ltree,
3269*7c478bd9Sstevel@tonic-gate 			    (ct_data *)static_dtree);
3270*7c478bd9Sstevel@tonic-gate 			s->compressed_len += 3 + s->static_len;	/* PPP */
3271*7c478bd9Sstevel@tonic-gate 		} else {
3272*7c478bd9Sstevel@tonic-gate 			send_bits(s, (DYN_TREES<<1)+eof, 3);
3273*7c478bd9Sstevel@tonic-gate 			send_all_trees(s, s->l_desc.max_code+1,
3274*7c478bd9Sstevel@tonic-gate 			    s->d_desc.max_code+1,
3275*7c478bd9Sstevel@tonic-gate 			    max_blindex+1);
3276*7c478bd9Sstevel@tonic-gate 			compress_block(s, (ct_data *)s->dyn_ltree,
3277*7c478bd9Sstevel@tonic-gate 			    (ct_data *)s->dyn_dtree);
3278*7c478bd9Sstevel@tonic-gate 			s->compressed_len += 3 + s->opt_len;	/* PPP */
3279*7c478bd9Sstevel@tonic-gate 		}
3280*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3281*7c478bd9Sstevel@tonic-gate 	Assert(s->compressed_len == s->bits_sent, "bad compressed size");
3282*7c478bd9Sstevel@tonic-gate #endif
3283*7c478bd9Sstevel@tonic-gate 	/*
3284*7c478bd9Sstevel@tonic-gate 	 * The above check is made mod 2^32, for files larger than 512
3285*7c478bd9Sstevel@tonic-gate 	 * MB and uLong implemented on 32 bits.
3286*7c478bd9Sstevel@tonic-gate 	 */
3287*7c478bd9Sstevel@tonic-gate 	init_block(s);
3288*7c478bd9Sstevel@tonic-gate 
3289*7c478bd9Sstevel@tonic-gate 	if (eof) {
3290*7c478bd9Sstevel@tonic-gate 		bi_windup(s);
3291*7c478bd9Sstevel@tonic-gate 		s->compressed_len += 7;	/* align on byte boundary PPP */
3292*7c478bd9Sstevel@tonic-gate 	}
3293*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3,
3294*7c478bd9Sstevel@tonic-gate 	    s->compressed_len-7*eof));
3295*7c478bd9Sstevel@tonic-gate 
3296*7c478bd9Sstevel@tonic-gate 	/* return (s->compressed_len >> 3); */
3297*7c478bd9Sstevel@tonic-gate }
3298*7c478bd9Sstevel@tonic-gate 
3299*7c478bd9Sstevel@tonic-gate /*
3300*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3301*7c478bd9Sstevel@tonic-gate  * Save the match info and tally the frequency counts. Return true if
3302*7c478bd9Sstevel@tonic-gate  * the current block must be flushed.
3303*7c478bd9Sstevel@tonic-gate  */
3304*7c478bd9Sstevel@tonic-gate int
3305*7c478bd9Sstevel@tonic-gate _tr_tally(s, dist, lc)
3306*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3307*7c478bd9Sstevel@tonic-gate     unsigned dist;	/* distance of matched string */
3308*7c478bd9Sstevel@tonic-gate 	/* match length-MIN_MATCH or unmatched char (if dist==0) */
3309*7c478bd9Sstevel@tonic-gate     unsigned lc;
3310*7c478bd9Sstevel@tonic-gate {
3311*7c478bd9Sstevel@tonic-gate 	s->d_buf[s->last_lit] = (ush)dist;
3312*7c478bd9Sstevel@tonic-gate 	s->l_buf[s->last_lit++] = (uch)lc;
3313*7c478bd9Sstevel@tonic-gate 	if (dist == 0) {
3314*7c478bd9Sstevel@tonic-gate 		/* lc is the unmatched char */
3315*7c478bd9Sstevel@tonic-gate 		s->dyn_ltree[lc].Freq++;
3316*7c478bd9Sstevel@tonic-gate 	} else {
3317*7c478bd9Sstevel@tonic-gate 		s->matches++;
3318*7c478bd9Sstevel@tonic-gate 		/* Here, lc is the match length - MIN_MATCH */
3319*7c478bd9Sstevel@tonic-gate 		dist--;	/* dist = match distance - 1 */
3320*7c478bd9Sstevel@tonic-gate 		Assert((ush)dist < (ush)MAX_DIST(s) &&
3321*7c478bd9Sstevel@tonic-gate 		    (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
3322*7c478bd9Sstevel@tonic-gate 		    (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
3323*7c478bd9Sstevel@tonic-gate 
3324*7c478bd9Sstevel@tonic-gate 		s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
3325*7c478bd9Sstevel@tonic-gate 		s->dyn_dtree[d_code(dist)].Freq++;
3326*7c478bd9Sstevel@tonic-gate 	}
3327*7c478bd9Sstevel@tonic-gate 
3328*7c478bd9Sstevel@tonic-gate #ifdef TRUNCATE_BLOCK
3329*7c478bd9Sstevel@tonic-gate 	/* Try to guess if it is profitable to stop the current block here */
3330*7c478bd9Sstevel@tonic-gate 	if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
3331*7c478bd9Sstevel@tonic-gate 		/* Compute an upper bound for the compressed length */
3332*7c478bd9Sstevel@tonic-gate 		ulg out_length = (ulg)s->last_lit*8L;
3333*7c478bd9Sstevel@tonic-gate 		ulg in_length = (ulg)((long)s->strstart - s->block_start);
3334*7c478bd9Sstevel@tonic-gate 		int dcode;
3335*7c478bd9Sstevel@tonic-gate 		for (dcode = 0; dcode < D_CODES; dcode++) {
3336*7c478bd9Sstevel@tonic-gate 			out_length += (ulg)s->dyn_dtree[dcode].Freq *
3337*7c478bd9Sstevel@tonic-gate 			    (5L+extra_dbits[dcode]);
3338*7c478bd9Sstevel@tonic-gate 		}
3339*7c478bd9Sstevel@tonic-gate 		out_length >>= 3;
3340*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
3341*7c478bd9Sstevel@tonic-gate 		    s->last_lit, in_length, out_length,
3342*7c478bd9Sstevel@tonic-gate 		    100L - out_length*100L/in_length));
3343*7c478bd9Sstevel@tonic-gate 		if (s->matches < s->last_lit/2 && out_length < in_length/2)
3344*7c478bd9Sstevel@tonic-gate 			return (1);
3345*7c478bd9Sstevel@tonic-gate 	}
3346*7c478bd9Sstevel@tonic-gate #endif
3347*7c478bd9Sstevel@tonic-gate 	return (s->last_lit == s->lit_bufsize-1);
3348*7c478bd9Sstevel@tonic-gate 	/*
3349*7c478bd9Sstevel@tonic-gate 	 * We avoid equality with lit_bufsize because of wraparound at 64K
3350*7c478bd9Sstevel@tonic-gate 	 * on 16 bit machines and because stored blocks are restricted to
3351*7c478bd9Sstevel@tonic-gate 	 * 64K-1 bytes.
3352*7c478bd9Sstevel@tonic-gate 	 */
3353*7c478bd9Sstevel@tonic-gate }
3354*7c478bd9Sstevel@tonic-gate 
3355*7c478bd9Sstevel@tonic-gate /*
3356*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3357*7c478bd9Sstevel@tonic-gate  * Send the block data compressed using the given Huffman trees
3358*7c478bd9Sstevel@tonic-gate  */
3359*7c478bd9Sstevel@tonic-gate local void
3360*7c478bd9Sstevel@tonic-gate compress_block(s, ltree, dtree)
3361*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3362*7c478bd9Sstevel@tonic-gate     ct_data *ltree;	/* literal tree */
3363*7c478bd9Sstevel@tonic-gate     ct_data *dtree;	/* distance tree */
3364*7c478bd9Sstevel@tonic-gate {
3365*7c478bd9Sstevel@tonic-gate 	unsigned dist;	/* distance of matched string */
3366*7c478bd9Sstevel@tonic-gate 	int lc;	/* match length or unmatched char (if dist == 0) */
3367*7c478bd9Sstevel@tonic-gate 	unsigned lx = 0;	/* running index in l_buf */
3368*7c478bd9Sstevel@tonic-gate 	unsigned code;	/* the code to send */
3369*7c478bd9Sstevel@tonic-gate 	int extra;	/* number of extra bits to send */
3370*7c478bd9Sstevel@tonic-gate 
3371*7c478bd9Sstevel@tonic-gate 	if (s->last_lit != 0) do {
3372*7c478bd9Sstevel@tonic-gate 		dist = s->d_buf[lx];
3373*7c478bd9Sstevel@tonic-gate 		lc = s->l_buf[lx++];
3374*7c478bd9Sstevel@tonic-gate 		if (dist == 0) {
3375*7c478bd9Sstevel@tonic-gate 			/* send a literal byte */
3376*7c478bd9Sstevel@tonic-gate 			send_code(s, lc, ltree);
3377*7c478bd9Sstevel@tonic-gate 			Tracecv(isgraph(lc), (stderr, " '%c' ", lc));
3378*7c478bd9Sstevel@tonic-gate 		} else {
3379*7c478bd9Sstevel@tonic-gate 			/* Here, lc is the match length - MIN_MATCH */
3380*7c478bd9Sstevel@tonic-gate 			code = _length_code[lc];
3381*7c478bd9Sstevel@tonic-gate 			/* send the length code */
3382*7c478bd9Sstevel@tonic-gate 			send_code(s, code+LITERALS+1, ltree);
3383*7c478bd9Sstevel@tonic-gate 			extra = extra_lbits[code];
3384*7c478bd9Sstevel@tonic-gate 			if (extra != 0) {
3385*7c478bd9Sstevel@tonic-gate 				lc -= base_length[code];
3386*7c478bd9Sstevel@tonic-gate 				/* send the extra length bits */
3387*7c478bd9Sstevel@tonic-gate 				send_bits(s, lc, extra);
3388*7c478bd9Sstevel@tonic-gate 			}
3389*7c478bd9Sstevel@tonic-gate 			/* dist is now the match distance - 1 */
3390*7c478bd9Sstevel@tonic-gate 			dist--;
3391*7c478bd9Sstevel@tonic-gate 			code = d_code(dist);
3392*7c478bd9Sstevel@tonic-gate 			Assert(code < D_CODES, "bad d_code");
3393*7c478bd9Sstevel@tonic-gate 
3394*7c478bd9Sstevel@tonic-gate 			/* send the distance code */
3395*7c478bd9Sstevel@tonic-gate 			send_code(s, code, dtree);
3396*7c478bd9Sstevel@tonic-gate 			extra = extra_dbits[code];
3397*7c478bd9Sstevel@tonic-gate 			if (extra != 0) {
3398*7c478bd9Sstevel@tonic-gate 				dist -= base_dist[code];
3399*7c478bd9Sstevel@tonic-gate 				/* send the extra distance bits */
3400*7c478bd9Sstevel@tonic-gate 				send_bits(s, dist, extra);
3401*7c478bd9Sstevel@tonic-gate 			}
3402*7c478bd9Sstevel@tonic-gate 		} /* literal or match pair ? */
3403*7c478bd9Sstevel@tonic-gate 
3404*7c478bd9Sstevel@tonic-gate 		/*
3405*7c478bd9Sstevel@tonic-gate 		 * Check that the overlay between pending_buf and
3406*7c478bd9Sstevel@tonic-gate 		 * d_buf+l_buf is ok:
3407*7c478bd9Sstevel@tonic-gate 		 */
3408*7c478bd9Sstevel@tonic-gate 		Assert(s->pending < s->lit_bufsize + 2*lx,
3409*7c478bd9Sstevel@tonic-gate 		    "pendingBuf overflow");
3410*7c478bd9Sstevel@tonic-gate 
3411*7c478bd9Sstevel@tonic-gate 	} while (lx < s->last_lit);
3412*7c478bd9Sstevel@tonic-gate 
3413*7c478bd9Sstevel@tonic-gate 	send_code(s, END_BLOCK, ltree);
3414*7c478bd9Sstevel@tonic-gate 	s->last_eob_len = ltree[END_BLOCK].Len;
3415*7c478bd9Sstevel@tonic-gate }
3416*7c478bd9Sstevel@tonic-gate 
3417*7c478bd9Sstevel@tonic-gate /*
3418*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3419*7c478bd9Sstevel@tonic-gate  * Set the data type to ASCII or BINARY, using a crude approximation:
3420*7c478bd9Sstevel@tonic-gate  * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
3421*7c478bd9Sstevel@tonic-gate  * IN assertion: the fields freq of dyn_ltree are set and the total of all
3422*7c478bd9Sstevel@tonic-gate  * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
3423*7c478bd9Sstevel@tonic-gate  */
3424*7c478bd9Sstevel@tonic-gate local void
3425*7c478bd9Sstevel@tonic-gate set_data_type(s)
3426*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3427*7c478bd9Sstevel@tonic-gate {
3428*7c478bd9Sstevel@tonic-gate 	int n = 0;
3429*7c478bd9Sstevel@tonic-gate 	unsigned ascii_freq = 0;
3430*7c478bd9Sstevel@tonic-gate 	unsigned bin_freq = 0;
3431*7c478bd9Sstevel@tonic-gate 	while (n < 7)	bin_freq	+= s->dyn_ltree[n++].Freq;
3432*7c478bd9Sstevel@tonic-gate 	while (n < 128)	ascii_freq	+= s->dyn_ltree[n++].Freq;
3433*7c478bd9Sstevel@tonic-gate 	while (n < LITERALS) bin_freq	+= s->dyn_ltree[n++].Freq;
3434*7c478bd9Sstevel@tonic-gate 	s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ?
3435*7c478bd9Sstevel@tonic-gate 	    Z_BINARY : Z_ASCII);
3436*7c478bd9Sstevel@tonic-gate }
3437*7c478bd9Sstevel@tonic-gate 
3438*7c478bd9Sstevel@tonic-gate /*
3439*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3440*7c478bd9Sstevel@tonic-gate  * Reverse the first len bits of a code, using straightforward code (a faster
3441*7c478bd9Sstevel@tonic-gate  * method would use a table)
3442*7c478bd9Sstevel@tonic-gate  * IN assertion: 1 <= len <= 15
3443*7c478bd9Sstevel@tonic-gate  */
3444*7c478bd9Sstevel@tonic-gate local unsigned
3445*7c478bd9Sstevel@tonic-gate bi_reverse(code, len)
3446*7c478bd9Sstevel@tonic-gate     unsigned code;	/* the value to invert */
3447*7c478bd9Sstevel@tonic-gate     int len;	/* its bit length */
3448*7c478bd9Sstevel@tonic-gate {
3449*7c478bd9Sstevel@tonic-gate 	register unsigned res = 0;
3450*7c478bd9Sstevel@tonic-gate 	do {
3451*7c478bd9Sstevel@tonic-gate 		res |= code & 1;
3452*7c478bd9Sstevel@tonic-gate 		code >>= 1, res <<= 1;
3453*7c478bd9Sstevel@tonic-gate 	} while (--len > 0);
3454*7c478bd9Sstevel@tonic-gate 	return (res >> 1);
3455*7c478bd9Sstevel@tonic-gate }
3456*7c478bd9Sstevel@tonic-gate 
3457*7c478bd9Sstevel@tonic-gate /*
3458*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3459*7c478bd9Sstevel@tonic-gate  * Flush the bit buffer, keeping at most 7 bits in it.
3460*7c478bd9Sstevel@tonic-gate  */
3461*7c478bd9Sstevel@tonic-gate local void
3462*7c478bd9Sstevel@tonic-gate bi_flush(s)
3463*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3464*7c478bd9Sstevel@tonic-gate {
3465*7c478bd9Sstevel@tonic-gate 	if (s->bi_valid == 16) {
3466*7c478bd9Sstevel@tonic-gate 		put_short(s, s->bi_buf);
3467*7c478bd9Sstevel@tonic-gate 		s->bi_buf = 0;
3468*7c478bd9Sstevel@tonic-gate 		s->bi_valid = 0;
3469*7c478bd9Sstevel@tonic-gate 	} else if (s->bi_valid >= 8) {
3470*7c478bd9Sstevel@tonic-gate 		put_byte(s, (Byte)s->bi_buf);
3471*7c478bd9Sstevel@tonic-gate 		s->bi_buf >>= 8;
3472*7c478bd9Sstevel@tonic-gate 		s->bi_valid -= 8;
3473*7c478bd9Sstevel@tonic-gate 	}
3474*7c478bd9Sstevel@tonic-gate }
3475*7c478bd9Sstevel@tonic-gate 
3476*7c478bd9Sstevel@tonic-gate /*
3477*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3478*7c478bd9Sstevel@tonic-gate  * Flush the bit buffer and align the output on a byte boundary
3479*7c478bd9Sstevel@tonic-gate  */
3480*7c478bd9Sstevel@tonic-gate local void
3481*7c478bd9Sstevel@tonic-gate bi_windup(s)
3482*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3483*7c478bd9Sstevel@tonic-gate {
3484*7c478bd9Sstevel@tonic-gate 	if (s->bi_valid > 8) {
3485*7c478bd9Sstevel@tonic-gate 		put_short(s, s->bi_buf);
3486*7c478bd9Sstevel@tonic-gate 	} else if (s->bi_valid > 0) {
3487*7c478bd9Sstevel@tonic-gate 		put_byte(s, (Byte)s->bi_buf);
3488*7c478bd9Sstevel@tonic-gate 	}
3489*7c478bd9Sstevel@tonic-gate 	s->bi_buf = 0;
3490*7c478bd9Sstevel@tonic-gate 	s->bi_valid = 0;
3491*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3492*7c478bd9Sstevel@tonic-gate 	s->bits_sent = (s->bits_sent+7) & ~7;
3493*7c478bd9Sstevel@tonic-gate #endif
3494*7c478bd9Sstevel@tonic-gate }
3495*7c478bd9Sstevel@tonic-gate 
3496*7c478bd9Sstevel@tonic-gate /*
3497*7c478bd9Sstevel@tonic-gate  * ===========================================================================
3498*7c478bd9Sstevel@tonic-gate  * Copy a stored block, storing first the length and its
3499*7c478bd9Sstevel@tonic-gate  * one's complement if requested.
3500*7c478bd9Sstevel@tonic-gate  */
3501*7c478bd9Sstevel@tonic-gate local void
3502*7c478bd9Sstevel@tonic-gate copy_block(s, buf, len, header)
3503*7c478bd9Sstevel@tonic-gate     deflate_state *s;
3504*7c478bd9Sstevel@tonic-gate     charf    *buf;	/* the input data */
3505*7c478bd9Sstevel@tonic-gate     unsigned len;	/* its length */
3506*7c478bd9Sstevel@tonic-gate     int	header;	/* true if block header must be written */
3507*7c478bd9Sstevel@tonic-gate {
3508*7c478bd9Sstevel@tonic-gate 	bi_windup(s);	/* align on byte boundary */
3509*7c478bd9Sstevel@tonic-gate 	s->last_eob_len = 8;	/* enough lookahead for inflate */
3510*7c478bd9Sstevel@tonic-gate 
3511*7c478bd9Sstevel@tonic-gate 	if (header) {
3512*7c478bd9Sstevel@tonic-gate 		put_short(s, (ush)len);
3513*7c478bd9Sstevel@tonic-gate 		put_short(s, (ush)~len);
3514*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3515*7c478bd9Sstevel@tonic-gate 		s->bits_sent += 2*16;
3516*7c478bd9Sstevel@tonic-gate #endif
3517*7c478bd9Sstevel@tonic-gate 	}
3518*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
3519*7c478bd9Sstevel@tonic-gate 	s->bits_sent += (ulg)len<<3;
3520*7c478bd9Sstevel@tonic-gate #endif
3521*7c478bd9Sstevel@tonic-gate 	/* bundle up the put_byte(s, *buf++) calls PPP */
3522*7c478bd9Sstevel@tonic-gate 	Assert(s->pending + len < s->pending_buf_size, "pending_buf overrun");
3523*7c478bd9Sstevel@tonic-gate 	zmemcpy(&s->pending_buf[s->pending], buf, len);	/* PPP */
3524*7c478bd9Sstevel@tonic-gate 	s->pending += len;				/* PPP */
3525*7c478bd9Sstevel@tonic-gate }
3526*7c478bd9Sstevel@tonic-gate /* --- trees.c */
3527*7c478bd9Sstevel@tonic-gate 
3528*7c478bd9Sstevel@tonic-gate /* +++ inflate.c */
3529*7c478bd9Sstevel@tonic-gate /*
3530*7c478bd9Sstevel@tonic-gate  * inflate.c -- zlib interface to inflate modules
3531*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
3532*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
3533*7c478bd9Sstevel@tonic-gate  */
3534*7c478bd9Sstevel@tonic-gate 
3535*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
3536*7c478bd9Sstevel@tonic-gate 
3537*7c478bd9Sstevel@tonic-gate /* +++ infblock.h */
3538*7c478bd9Sstevel@tonic-gate /*
3539*7c478bd9Sstevel@tonic-gate  * infblock.h -- header to use infblock.c
3540*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
3541*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
3542*7c478bd9Sstevel@tonic-gate  */
3543*7c478bd9Sstevel@tonic-gate 
3544*7c478bd9Sstevel@tonic-gate /*
3545*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
3546*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
3547*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
3548*7c478bd9Sstevel@tonic-gate  */
3549*7c478bd9Sstevel@tonic-gate 
3550*7c478bd9Sstevel@tonic-gate struct inflate_blocks_state;
3551*7c478bd9Sstevel@tonic-gate typedef struct inflate_blocks_state FAR inflate_blocks_statef;
3552*7c478bd9Sstevel@tonic-gate 
3553*7c478bd9Sstevel@tonic-gate extern inflate_blocks_statef * inflate_blocks_new OF((
3554*7c478bd9Sstevel@tonic-gate     z_streamp z,
3555*7c478bd9Sstevel@tonic-gate     check_func c,	/* check function */
3556*7c478bd9Sstevel@tonic-gate     uInt w));	/* window size */
3557*7c478bd9Sstevel@tonic-gate 
3558*7c478bd9Sstevel@tonic-gate extern int inflate_blocks OF((
3559*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
3560*7c478bd9Sstevel@tonic-gate     z_streamp,
3561*7c478bd9Sstevel@tonic-gate     int));	/* initial return code */
3562*7c478bd9Sstevel@tonic-gate 
3563*7c478bd9Sstevel@tonic-gate extern void inflate_blocks_reset OF((
3564*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
3565*7c478bd9Sstevel@tonic-gate     z_streamp,
3566*7c478bd9Sstevel@tonic-gate     uLongf *));	/* check value on output */
3567*7c478bd9Sstevel@tonic-gate 
3568*7c478bd9Sstevel@tonic-gate extern int inflate_blocks_free OF((
3569*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
3570*7c478bd9Sstevel@tonic-gate     z_streamp));
3571*7c478bd9Sstevel@tonic-gate 
3572*7c478bd9Sstevel@tonic-gate extern void inflate_set_dictionary OF((
3573*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *s,
3574*7c478bd9Sstevel@tonic-gate     const Bytef *d,  /* dictionary */
3575*7c478bd9Sstevel@tonic-gate     uInt  n));	/* dictionary length */
3576*7c478bd9Sstevel@tonic-gate 
3577*7c478bd9Sstevel@tonic-gate extern int inflate_blocks_sync_point OF((
3578*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *s));
3579*7c478bd9Sstevel@tonic-gate 
3580*7c478bd9Sstevel@tonic-gate /* PPP -- added function */
3581*7c478bd9Sstevel@tonic-gate extern int inflate_addhistory OF((
3582*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
3583*7c478bd9Sstevel@tonic-gate     z_streamp));
3584*7c478bd9Sstevel@tonic-gate 
3585*7c478bd9Sstevel@tonic-gate /* PPP -- added function */
3586*7c478bd9Sstevel@tonic-gate extern int inflate_packet_flush OF((
3587*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *));
3588*7c478bd9Sstevel@tonic-gate /* --- infblock.h */
3589*7c478bd9Sstevel@tonic-gate 
3590*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
3591*7c478bd9Sstevel@tonic-gate struct inflate_blocks_state {int dummy; };	/* for buggy compilers */
3592*7c478bd9Sstevel@tonic-gate #endif
3593*7c478bd9Sstevel@tonic-gate 
3594*7c478bd9Sstevel@tonic-gate /* inflate private state */
3595*7c478bd9Sstevel@tonic-gate struct internal_state {
3596*7c478bd9Sstevel@tonic-gate 
3597*7c478bd9Sstevel@tonic-gate 	/* mode */
3598*7c478bd9Sstevel@tonic-gate 	enum {
3599*7c478bd9Sstevel@tonic-gate 		METHOD,	/* waiting for method byte */
3600*7c478bd9Sstevel@tonic-gate 		FLAG,	/* waiting for flag byte */
3601*7c478bd9Sstevel@tonic-gate 		DICT4,	/* four dictionary check bytes to go */
3602*7c478bd9Sstevel@tonic-gate 		DICT3,	/* three dictionary check bytes to go */
3603*7c478bd9Sstevel@tonic-gate 		DICT2,	/* two dictionary check bytes to go */
3604*7c478bd9Sstevel@tonic-gate 		DICT1,	/* one dictionary check byte to go */
3605*7c478bd9Sstevel@tonic-gate 		DICT0,	/* waiting for inflateSetDictionary */
3606*7c478bd9Sstevel@tonic-gate 		BLOCKS,	/* decompressing blocks */
3607*7c478bd9Sstevel@tonic-gate 		CHECK4,	/* four check bytes to go */
3608*7c478bd9Sstevel@tonic-gate 		CHECK3,	/* three check bytes to go */
3609*7c478bd9Sstevel@tonic-gate 		CHECK2,	/* two check bytes to go */
3610*7c478bd9Sstevel@tonic-gate 		CHECK1,	/* one check byte to go */
3611*7c478bd9Sstevel@tonic-gate 		DONE,	/* finished check, done */
3612*7c478bd9Sstevel@tonic-gate 		BAD}	/* got an error--stay here */
3613*7c478bd9Sstevel@tonic-gate 	mode;	/* current inflate mode */
3614*7c478bd9Sstevel@tonic-gate 
3615*7c478bd9Sstevel@tonic-gate 	/* mode dependent information */
3616*7c478bd9Sstevel@tonic-gate 	union {
3617*7c478bd9Sstevel@tonic-gate 		uInt method;	/* if FLAGS, method byte */
3618*7c478bd9Sstevel@tonic-gate 		struct {
3619*7c478bd9Sstevel@tonic-gate 			uLong was;	/* computed check value */
3620*7c478bd9Sstevel@tonic-gate 			uLong need;	/* stream check value */
3621*7c478bd9Sstevel@tonic-gate 		} check;	/* if CHECK, check values to compare */
3622*7c478bd9Sstevel@tonic-gate 		uInt marker;	/* if BAD, inflateSync's marker bytes count */
3623*7c478bd9Sstevel@tonic-gate 	} sub;	/* submode */
3624*7c478bd9Sstevel@tonic-gate 
3625*7c478bd9Sstevel@tonic-gate 	/* mode independent information */
3626*7c478bd9Sstevel@tonic-gate 	int  nowrap;	/* flag for no wrapper */
3627*7c478bd9Sstevel@tonic-gate 	uInt wbits;	/* log2(window size)  (8..15, defaults to 15) */
3628*7c478bd9Sstevel@tonic-gate 	/* current inflate_blocks state */
3629*7c478bd9Sstevel@tonic-gate 	inflate_blocks_statef *blocks;
3630*7c478bd9Sstevel@tonic-gate };
3631*7c478bd9Sstevel@tonic-gate 
3632*7c478bd9Sstevel@tonic-gate 
3633*7c478bd9Sstevel@tonic-gate int
3634*7c478bd9Sstevel@tonic-gate inflateReset(z)
3635*7c478bd9Sstevel@tonic-gate z_streamp z;
3636*7c478bd9Sstevel@tonic-gate {
3637*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL)
3638*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3639*7c478bd9Sstevel@tonic-gate 	z->total_in = z->total_out = 0;
3640*7c478bd9Sstevel@tonic-gate 	z->msg = Z_NULL;
3641*7c478bd9Sstevel@tonic-gate 	z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
3642*7c478bd9Sstevel@tonic-gate 	inflate_blocks_reset(z->state->blocks, z, Z_NULL);
3643*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate: reset\n"));
3644*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
3645*7c478bd9Sstevel@tonic-gate }
3646*7c478bd9Sstevel@tonic-gate 
3647*7c478bd9Sstevel@tonic-gate 
3648*7c478bd9Sstevel@tonic-gate int
3649*7c478bd9Sstevel@tonic-gate inflateEnd(z)
3650*7c478bd9Sstevel@tonic-gate z_streamp z;
3651*7c478bd9Sstevel@tonic-gate {
3652*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
3653*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3654*7c478bd9Sstevel@tonic-gate 	if (z->state->blocks != Z_NULL) {
3655*7c478bd9Sstevel@tonic-gate 		(void) inflate_blocks_free(z->state->blocks, z);
3656*7c478bd9Sstevel@tonic-gate 		z->state->blocks = Z_NULL;
3657*7c478bd9Sstevel@tonic-gate 	}
3658*7c478bd9Sstevel@tonic-gate 	ZFREE(z, z->state);
3659*7c478bd9Sstevel@tonic-gate 	z->state = Z_NULL;
3660*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate: end\n"));
3661*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
3662*7c478bd9Sstevel@tonic-gate }
3663*7c478bd9Sstevel@tonic-gate 
3664*7c478bd9Sstevel@tonic-gate 
3665*7c478bd9Sstevel@tonic-gate int
3666*7c478bd9Sstevel@tonic-gate inflateInit2_(z, w, version, stream_size)
3667*7c478bd9Sstevel@tonic-gate z_streamp z;
3668*7c478bd9Sstevel@tonic-gate int w;
3669*7c478bd9Sstevel@tonic-gate const char *version;
3670*7c478bd9Sstevel@tonic-gate int stream_size;
3671*7c478bd9Sstevel@tonic-gate {
3672*7c478bd9Sstevel@tonic-gate 	if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
3673*7c478bd9Sstevel@tonic-gate 	    stream_size != sizeof (z_stream))
3674*7c478bd9Sstevel@tonic-gate 		return (Z_VERSION_ERROR);
3675*7c478bd9Sstevel@tonic-gate 
3676*7c478bd9Sstevel@tonic-gate 	/* initialize state */
3677*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL)
3678*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3679*7c478bd9Sstevel@tonic-gate 	z->msg = Z_NULL;
3680*7c478bd9Sstevel@tonic-gate #ifndef NO_ZCFUNCS
3681*7c478bd9Sstevel@tonic-gate 	if (z->zalloc == Z_NULL)
3682*7c478bd9Sstevel@tonic-gate 	{
3683*7c478bd9Sstevel@tonic-gate 		z->zalloc = zcalloc;
3684*7c478bd9Sstevel@tonic-gate 		z->opaque = (voidpf)0;
3685*7c478bd9Sstevel@tonic-gate 	}
3686*7c478bd9Sstevel@tonic-gate 	if (z->zfree == Z_NULL) z->zfree = zcfree;
3687*7c478bd9Sstevel@tonic-gate #endif
3688*7c478bd9Sstevel@tonic-gate 	if ((z->state = (struct internal_state FAR *)
3689*7c478bd9Sstevel@tonic-gate 	    ZALLOC(z, 1, sizeof (struct internal_state))) == Z_NULL)
3690*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
3691*7c478bd9Sstevel@tonic-gate 	z->state->blocks = Z_NULL;
3692*7c478bd9Sstevel@tonic-gate 
3693*7c478bd9Sstevel@tonic-gate 	/* handle undocumented nowrap option (no zlib header or check) */
3694*7c478bd9Sstevel@tonic-gate 	z->state->nowrap = 0;
3695*7c478bd9Sstevel@tonic-gate 	if (w < 0)
3696*7c478bd9Sstevel@tonic-gate 	{
3697*7c478bd9Sstevel@tonic-gate 		w = - w;
3698*7c478bd9Sstevel@tonic-gate 		z->state->nowrap = 1;
3699*7c478bd9Sstevel@tonic-gate 	}
3700*7c478bd9Sstevel@tonic-gate 
3701*7c478bd9Sstevel@tonic-gate 	/* set window size */
3702*7c478bd9Sstevel@tonic-gate 	if (w < 8 || w > 15)
3703*7c478bd9Sstevel@tonic-gate 	{
3704*7c478bd9Sstevel@tonic-gate 		(void) inflateEnd(z);
3705*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3706*7c478bd9Sstevel@tonic-gate 	}
3707*7c478bd9Sstevel@tonic-gate 	z->state->wbits = (uInt)w;
3708*7c478bd9Sstevel@tonic-gate 
3709*7c478bd9Sstevel@tonic-gate 	/* create inflate_blocks state */
3710*7c478bd9Sstevel@tonic-gate 	if ((z->state->blocks =
3711*7c478bd9Sstevel@tonic-gate 	    inflate_blocks_new(z, z->state->nowrap ?
3712*7c478bd9Sstevel@tonic-gate 		Z_NULL : adler32, (uInt)1 << w))
3713*7c478bd9Sstevel@tonic-gate 	    == Z_NULL)
3714*7c478bd9Sstevel@tonic-gate 	{
3715*7c478bd9Sstevel@tonic-gate 		(void) inflateEnd(z);
3716*7c478bd9Sstevel@tonic-gate 		return (Z_MEM_ERROR);
3717*7c478bd9Sstevel@tonic-gate 	}
3718*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate: allocated\n"));
3719*7c478bd9Sstevel@tonic-gate 
3720*7c478bd9Sstevel@tonic-gate 	/* reset state */
3721*7c478bd9Sstevel@tonic-gate 	(void) inflateReset(z);
3722*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
3723*7c478bd9Sstevel@tonic-gate }
3724*7c478bd9Sstevel@tonic-gate 
3725*7c478bd9Sstevel@tonic-gate 
3726*7c478bd9Sstevel@tonic-gate int
3727*7c478bd9Sstevel@tonic-gate inflateInit_(z, version, stream_size)
3728*7c478bd9Sstevel@tonic-gate z_streamp z;
3729*7c478bd9Sstevel@tonic-gate const char *version;
3730*7c478bd9Sstevel@tonic-gate int stream_size;
3731*7c478bd9Sstevel@tonic-gate {
3732*7c478bd9Sstevel@tonic-gate 	return (inflateInit2_(z, DEF_WBITS, version, stream_size));
3733*7c478bd9Sstevel@tonic-gate }
3734*7c478bd9Sstevel@tonic-gate 
3735*7c478bd9Sstevel@tonic-gate /* PPP -- added "empty" label and changed f to Z_OK */
3736*7c478bd9Sstevel@tonic-gate #define	NEEDBYTE {if (z->avail_in == 0) goto empty; r = Z_OK; } ((void)0)
3737*7c478bd9Sstevel@tonic-gate #define	NEXTBYTE (z->avail_in--, z->total_in++, *z->next_in++)
3738*7c478bd9Sstevel@tonic-gate 
3739*7c478bd9Sstevel@tonic-gate int
3740*7c478bd9Sstevel@tonic-gate inflate(z, f)
3741*7c478bd9Sstevel@tonic-gate z_streamp z;
3742*7c478bd9Sstevel@tonic-gate int f;
3743*7c478bd9Sstevel@tonic-gate {
3744*7c478bd9Sstevel@tonic-gate 	int r;
3745*7c478bd9Sstevel@tonic-gate 	uInt b;
3746*7c478bd9Sstevel@tonic-gate 
3747*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
3748*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3749*7c478bd9Sstevel@tonic-gate 	/* f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; -- PPP; Z_FINISH unused */
3750*7c478bd9Sstevel@tonic-gate 	r = Z_BUF_ERROR;
3751*7c478bd9Sstevel@tonic-gate 	/* CONSTCOND */
3752*7c478bd9Sstevel@tonic-gate 	while (1)
3753*7c478bd9Sstevel@tonic-gate 		switch (z->state->mode)
3754*7c478bd9Sstevel@tonic-gate 	{
3755*7c478bd9Sstevel@tonic-gate 	case METHOD:
3756*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3757*7c478bd9Sstevel@tonic-gate 		if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
3758*7c478bd9Sstevel@tonic-gate 		{
3759*7c478bd9Sstevel@tonic-gate 			z->state->mode = BAD;
3760*7c478bd9Sstevel@tonic-gate 			z->msg = "unknown compression method";
3761*7c478bd9Sstevel@tonic-gate 			/* can't try inflateSync */
3762*7c478bd9Sstevel@tonic-gate 			z->state->sub.marker = 5;
3763*7c478bd9Sstevel@tonic-gate 			break;
3764*7c478bd9Sstevel@tonic-gate 		}
3765*7c478bd9Sstevel@tonic-gate 		if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
3766*7c478bd9Sstevel@tonic-gate 		{
3767*7c478bd9Sstevel@tonic-gate 			z->state->mode = BAD;
3768*7c478bd9Sstevel@tonic-gate 			z->msg = "invalid window size";
3769*7c478bd9Sstevel@tonic-gate 			/* can't try inflateSync */
3770*7c478bd9Sstevel@tonic-gate 			z->state->sub.marker = 5;
3771*7c478bd9Sstevel@tonic-gate 			break;
3772*7c478bd9Sstevel@tonic-gate 		}
3773*7c478bd9Sstevel@tonic-gate 		z->state->mode = FLAG;
3774*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3775*7c478bd9Sstevel@tonic-gate 	case FLAG:
3776*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3777*7c478bd9Sstevel@tonic-gate 		b = NEXTBYTE;
3778*7c478bd9Sstevel@tonic-gate 		if (((z->state->sub.method << 8) + b) % 31)
3779*7c478bd9Sstevel@tonic-gate 		{
3780*7c478bd9Sstevel@tonic-gate 			z->state->mode = BAD;
3781*7c478bd9Sstevel@tonic-gate 			z->msg = "incorrect header check";
3782*7c478bd9Sstevel@tonic-gate 			/* can't try inflateSync */
3783*7c478bd9Sstevel@tonic-gate 			z->state->sub.marker = 5;
3784*7c478bd9Sstevel@tonic-gate 			break;
3785*7c478bd9Sstevel@tonic-gate 		}
3786*7c478bd9Sstevel@tonic-gate 		Trace((stderr, "inflate: zlib header ok\n"));
3787*7c478bd9Sstevel@tonic-gate 		if (!(b & PRESET_DICT))
3788*7c478bd9Sstevel@tonic-gate 		{
3789*7c478bd9Sstevel@tonic-gate 			z->state->mode = BLOCKS;
3790*7c478bd9Sstevel@tonic-gate 			break;
3791*7c478bd9Sstevel@tonic-gate 		}
3792*7c478bd9Sstevel@tonic-gate 		z->state->mode = DICT4;
3793*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3794*7c478bd9Sstevel@tonic-gate 	case DICT4:
3795*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3796*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need = (uLong)NEXTBYTE << 24;
3797*7c478bd9Sstevel@tonic-gate 		z->state->mode = DICT3;
3798*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3799*7c478bd9Sstevel@tonic-gate 	case DICT3:
3800*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3801*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE << 16;
3802*7c478bd9Sstevel@tonic-gate 		z->state->mode = DICT2;
3803*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3804*7c478bd9Sstevel@tonic-gate 	case DICT2:
3805*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3806*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE << 8;
3807*7c478bd9Sstevel@tonic-gate 		z->state->mode = DICT1;
3808*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3809*7c478bd9Sstevel@tonic-gate 	case DICT1:
3810*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3811*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE;
3812*7c478bd9Sstevel@tonic-gate 		z->adler = z->state->sub.check.need;
3813*7c478bd9Sstevel@tonic-gate 		z->state->mode = DICT0;
3814*7c478bd9Sstevel@tonic-gate 		return (Z_NEED_DICT);
3815*7c478bd9Sstevel@tonic-gate 	case DICT0:
3816*7c478bd9Sstevel@tonic-gate 		z->state->mode = BAD;
3817*7c478bd9Sstevel@tonic-gate 		z->msg = "need dictionary";
3818*7c478bd9Sstevel@tonic-gate 		z->state->sub.marker = 0;	/* can try inflateSync */
3819*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3820*7c478bd9Sstevel@tonic-gate 	case BLOCKS:
3821*7c478bd9Sstevel@tonic-gate 		r = inflate_blocks(z->state->blocks, z, r);
3822*7c478bd9Sstevel@tonic-gate 		if (f == Z_PACKET_FLUSH && z->avail_in == 0 &&	/* PPP */
3823*7c478bd9Sstevel@tonic-gate 		    z->avail_out != 0)				/* PPP */
3824*7c478bd9Sstevel@tonic-gate 			r = inflate_packet_flush(z->state->blocks); /* PPP */
3825*7c478bd9Sstevel@tonic-gate 		if (r == Z_DATA_ERROR)
3826*7c478bd9Sstevel@tonic-gate 		{
3827*7c478bd9Sstevel@tonic-gate 			z->state->mode = BAD;
3828*7c478bd9Sstevel@tonic-gate 			/* can try inflateSync */
3829*7c478bd9Sstevel@tonic-gate 			z->state->sub.marker = 0;
3830*7c478bd9Sstevel@tonic-gate 			break;
3831*7c478bd9Sstevel@tonic-gate 		}
3832*7c478bd9Sstevel@tonic-gate 		/* PPP */
3833*7c478bd9Sstevel@tonic-gate 		if (r != Z_STREAM_END)
3834*7c478bd9Sstevel@tonic-gate 			return (r);
3835*7c478bd9Sstevel@tonic-gate 		r = Z_OK;	/* PPP */
3836*7c478bd9Sstevel@tonic-gate 		inflate_blocks_reset(z->state->blocks, z,
3837*7c478bd9Sstevel@tonic-gate 		    &z->state->sub.check.was);
3838*7c478bd9Sstevel@tonic-gate 		if (z->state->nowrap)
3839*7c478bd9Sstevel@tonic-gate 		{
3840*7c478bd9Sstevel@tonic-gate 			z->state->mode = DONE;
3841*7c478bd9Sstevel@tonic-gate 			break;
3842*7c478bd9Sstevel@tonic-gate 		}
3843*7c478bd9Sstevel@tonic-gate 		z->state->mode = CHECK4;
3844*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3845*7c478bd9Sstevel@tonic-gate 	case CHECK4:
3846*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3847*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need = (uLong)NEXTBYTE << 24;
3848*7c478bd9Sstevel@tonic-gate 		z->state->mode = CHECK3;
3849*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3850*7c478bd9Sstevel@tonic-gate 	case CHECK3:
3851*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3852*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE << 16;
3853*7c478bd9Sstevel@tonic-gate 		z->state->mode = CHECK2;
3854*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3855*7c478bd9Sstevel@tonic-gate 	case CHECK2:
3856*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3857*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE << 8;
3858*7c478bd9Sstevel@tonic-gate 		z->state->mode = CHECK1;
3859*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3860*7c478bd9Sstevel@tonic-gate 	case CHECK1:
3861*7c478bd9Sstevel@tonic-gate 		NEEDBYTE;
3862*7c478bd9Sstevel@tonic-gate 		z->state->sub.check.need += (uLong)NEXTBYTE;
3863*7c478bd9Sstevel@tonic-gate 
3864*7c478bd9Sstevel@tonic-gate 		if (z->state->sub.check.was != z->state->sub.check.need)
3865*7c478bd9Sstevel@tonic-gate 		{
3866*7c478bd9Sstevel@tonic-gate 			z->state->mode = BAD;
3867*7c478bd9Sstevel@tonic-gate 			z->msg = "incorrect data check";
3868*7c478bd9Sstevel@tonic-gate 			/* can't try inflateSync */
3869*7c478bd9Sstevel@tonic-gate 			z->state->sub.marker = 5;
3870*7c478bd9Sstevel@tonic-gate 			break;
3871*7c478bd9Sstevel@tonic-gate 		}
3872*7c478bd9Sstevel@tonic-gate 		Trace((stderr, "inflate: zlib check ok\n"));
3873*7c478bd9Sstevel@tonic-gate 		z->state->mode = DONE;
3874*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
3875*7c478bd9Sstevel@tonic-gate 	case DONE:
3876*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_END);
3877*7c478bd9Sstevel@tonic-gate 	case BAD:
3878*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
3879*7c478bd9Sstevel@tonic-gate 	default:
3880*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3881*7c478bd9Sstevel@tonic-gate 	}
3882*7c478bd9Sstevel@tonic-gate 
3883*7c478bd9Sstevel@tonic-gate /* PPP -- packet flush handling */
3884*7c478bd9Sstevel@tonic-gate empty:
3885*7c478bd9Sstevel@tonic-gate 	if (f != Z_PACKET_FLUSH)
3886*7c478bd9Sstevel@tonic-gate 		return (r);
3887*7c478bd9Sstevel@tonic-gate 	z->state->mode = BAD;
3888*7c478bd9Sstevel@tonic-gate 	z->msg = "need more for packet flush";
3889*7c478bd9Sstevel@tonic-gate 	z->state->sub.marker = 0;	/* can try inflateSync */
3890*7c478bd9Sstevel@tonic-gate 	return (Z_DATA_ERROR);
3891*7c478bd9Sstevel@tonic-gate }
3892*7c478bd9Sstevel@tonic-gate 
3893*7c478bd9Sstevel@tonic-gate 
3894*7c478bd9Sstevel@tonic-gate int
3895*7c478bd9Sstevel@tonic-gate inflateSetDictionary(z, dictionary, dictLength)
3896*7c478bd9Sstevel@tonic-gate z_streamp z;
3897*7c478bd9Sstevel@tonic-gate const Bytef *dictionary;
3898*7c478bd9Sstevel@tonic-gate uInt  dictLength;
3899*7c478bd9Sstevel@tonic-gate {
3900*7c478bd9Sstevel@tonic-gate 	uInt length = dictLength;
3901*7c478bd9Sstevel@tonic-gate 
3902*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
3903*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3904*7c478bd9Sstevel@tonic-gate 
3905*7c478bd9Sstevel@tonic-gate 	if (adler32(1L, dictionary, dictLength) != z->adler)
3906*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
3907*7c478bd9Sstevel@tonic-gate 	z->adler = 1L;
3908*7c478bd9Sstevel@tonic-gate 
3909*7c478bd9Sstevel@tonic-gate 	if (length >= ((uInt)1<<z->state->wbits))
3910*7c478bd9Sstevel@tonic-gate 	{
3911*7c478bd9Sstevel@tonic-gate 		length = (1<<z->state->wbits)-1;
3912*7c478bd9Sstevel@tonic-gate 		dictionary += dictLength - length;
3913*7c478bd9Sstevel@tonic-gate 	}
3914*7c478bd9Sstevel@tonic-gate 	inflate_set_dictionary(z->state->blocks, dictionary, length);
3915*7c478bd9Sstevel@tonic-gate 	z->state->mode = BLOCKS;
3916*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
3917*7c478bd9Sstevel@tonic-gate }
3918*7c478bd9Sstevel@tonic-gate 
3919*7c478bd9Sstevel@tonic-gate /*
3920*7c478bd9Sstevel@tonic-gate  * This subroutine adds the data at next_in/avail_in to the output history
3921*7c478bd9Sstevel@tonic-gate  * without performing any output.  The output buffer must be "caught up";
3922*7c478bd9Sstevel@tonic-gate  * i.e. no pending output (hence s->read equals s->write), and the state must
3923*7c478bd9Sstevel@tonic-gate  * be BLOCKS (i.e. we should be willing to see the start of a series of
3924*7c478bd9Sstevel@tonic-gate  * BLOCKS).  On exit, the output will also be caught up, and the checksum
3925*7c478bd9Sstevel@tonic-gate  * will have been updated if need be.
3926*7c478bd9Sstevel@tonic-gate  *
3927*7c478bd9Sstevel@tonic-gate  * Added for PPP.
3928*7c478bd9Sstevel@tonic-gate  */
3929*7c478bd9Sstevel@tonic-gate 
3930*7c478bd9Sstevel@tonic-gate int
3931*7c478bd9Sstevel@tonic-gate inflateIncomp(z)
3932*7c478bd9Sstevel@tonic-gate z_stream *z;
3933*7c478bd9Sstevel@tonic-gate {
3934*7c478bd9Sstevel@tonic-gate 	if (z->state->mode != BLOCKS)
3935*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
3936*7c478bd9Sstevel@tonic-gate 	return (inflate_addhistory(z->state->blocks, z));
3937*7c478bd9Sstevel@tonic-gate }
3938*7c478bd9Sstevel@tonic-gate 
3939*7c478bd9Sstevel@tonic-gate 
3940*7c478bd9Sstevel@tonic-gate int
3941*7c478bd9Sstevel@tonic-gate inflateSync(z)
3942*7c478bd9Sstevel@tonic-gate z_streamp z;
3943*7c478bd9Sstevel@tonic-gate {
3944*7c478bd9Sstevel@tonic-gate 	uInt n;	/* number of bytes to look at */
3945*7c478bd9Sstevel@tonic-gate 	Bytef *p;	/* pointer to bytes */
3946*7c478bd9Sstevel@tonic-gate 	uInt m;	/* number of marker bytes found in a row */
3947*7c478bd9Sstevel@tonic-gate 	uLong r, w;	/* temporaries to save total_in and total_out */
3948*7c478bd9Sstevel@tonic-gate 
3949*7c478bd9Sstevel@tonic-gate 	/* set up */
3950*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL)
3951*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
3952*7c478bd9Sstevel@tonic-gate 	if (z->state->mode != BAD)
3953*7c478bd9Sstevel@tonic-gate 	{
3954*7c478bd9Sstevel@tonic-gate 		z->state->mode = BAD;
3955*7c478bd9Sstevel@tonic-gate 		z->state->sub.marker = 0;
3956*7c478bd9Sstevel@tonic-gate 	}
3957*7c478bd9Sstevel@tonic-gate 	if ((n = z->avail_in) == 0)
3958*7c478bd9Sstevel@tonic-gate 		return (Z_BUF_ERROR);
3959*7c478bd9Sstevel@tonic-gate 	p = z->next_in;
3960*7c478bd9Sstevel@tonic-gate 	m = z->state->sub.marker;
3961*7c478bd9Sstevel@tonic-gate 
3962*7c478bd9Sstevel@tonic-gate 	/* search */
3963*7c478bd9Sstevel@tonic-gate 	while (n && m < 4)
3964*7c478bd9Sstevel@tonic-gate 	{
3965*7c478bd9Sstevel@tonic-gate 		static const Byte mark[4] = { 0, 0, 0xff, 0xff };
3966*7c478bd9Sstevel@tonic-gate 		if (*p == mark[m])
3967*7c478bd9Sstevel@tonic-gate 			m++;
3968*7c478bd9Sstevel@tonic-gate 		else if (*p)
3969*7c478bd9Sstevel@tonic-gate 			m = 0;
3970*7c478bd9Sstevel@tonic-gate 		else
3971*7c478bd9Sstevel@tonic-gate 			/*
3972*7c478bd9Sstevel@tonic-gate 			 * This statement maps 2->2 and 3->1 because a
3973*7c478bd9Sstevel@tonic-gate 			 * mismatch with input byte 0x00 on the first
3974*7c478bd9Sstevel@tonic-gate 			 * 0xFF in the pattern means that we still
3975*7c478bd9Sstevel@tonic-gate 			 * have two contiguous zeros matched (thus
3976*7c478bd9Sstevel@tonic-gate 			 * offset 2 is kept), but a mismatch on the
3977*7c478bd9Sstevel@tonic-gate 			 * second 0xFF means that only one 0x00 byte
3978*7c478bd9Sstevel@tonic-gate 			 * has been matched.  (Boyer-Moore like
3979*7c478bd9Sstevel@tonic-gate 			 * search.)
3980*7c478bd9Sstevel@tonic-gate 			 */
3981*7c478bd9Sstevel@tonic-gate 			m = 4 - m;
3982*7c478bd9Sstevel@tonic-gate 		p++, n--;
3983*7c478bd9Sstevel@tonic-gate 	}
3984*7c478bd9Sstevel@tonic-gate 
3985*7c478bd9Sstevel@tonic-gate 	/* restore */
3986*7c478bd9Sstevel@tonic-gate 	z->total_in += p - z->next_in;
3987*7c478bd9Sstevel@tonic-gate 	z->next_in = p;
3988*7c478bd9Sstevel@tonic-gate 	z->avail_in = n;
3989*7c478bd9Sstevel@tonic-gate 	z->state->sub.marker = m;
3990*7c478bd9Sstevel@tonic-gate 
3991*7c478bd9Sstevel@tonic-gate 	/* return no joy or set up to restart on a new block */
3992*7c478bd9Sstevel@tonic-gate 	if (m != 4)
3993*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
3994*7c478bd9Sstevel@tonic-gate 	r = z->total_in;  w = z->total_out;
3995*7c478bd9Sstevel@tonic-gate 	(void) inflateReset(z);
3996*7c478bd9Sstevel@tonic-gate 	z->total_in = r;  z->total_out = w;
3997*7c478bd9Sstevel@tonic-gate 	z->state->mode = BLOCKS;
3998*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
3999*7c478bd9Sstevel@tonic-gate }
4000*7c478bd9Sstevel@tonic-gate 
4001*7c478bd9Sstevel@tonic-gate /*
4002*7c478bd9Sstevel@tonic-gate  * Returns true if inflate is currently at the end of a block
4003*7c478bd9Sstevel@tonic-gate  * generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by
4004*7c478bd9Sstevel@tonic-gate  * one PPP implementation to provide an additional safety check. PPP
4005*7c478bd9Sstevel@tonic-gate  * uses Z_SYNC_FLUSH but removes the length bytes of the resulting
4006*7c478bd9Sstevel@tonic-gate  * empty stored block. When decompressing, PPP checks that at the end
4007*7c478bd9Sstevel@tonic-gate  * of input packet, inflate is waiting for these length bytes.
4008*7c478bd9Sstevel@tonic-gate  */
4009*7c478bd9Sstevel@tonic-gate int
4010*7c478bd9Sstevel@tonic-gate inflateSyncPoint(z)
4011*7c478bd9Sstevel@tonic-gate z_streamp z;
4012*7c478bd9Sstevel@tonic-gate {
4013*7c478bd9Sstevel@tonic-gate 	if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
4014*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
4015*7c478bd9Sstevel@tonic-gate 	return (inflate_blocks_sync_point(z->state->blocks));
4016*7c478bd9Sstevel@tonic-gate }
4017*7c478bd9Sstevel@tonic-gate 
4018*7c478bd9Sstevel@tonic-gate #undef NEEDBYTE
4019*7c478bd9Sstevel@tonic-gate #undef NEXTBYTE
4020*7c478bd9Sstevel@tonic-gate /* --- inflate.c */
4021*7c478bd9Sstevel@tonic-gate 
4022*7c478bd9Sstevel@tonic-gate /* +++ infblock.c */
4023*7c478bd9Sstevel@tonic-gate /*
4024*7c478bd9Sstevel@tonic-gate  * infblock.c -- interpret and process block types to last block
4025*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
4026*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
4027*7c478bd9Sstevel@tonic-gate  */
4028*7c478bd9Sstevel@tonic-gate 
4029*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
4030*7c478bd9Sstevel@tonic-gate /* #include "infblock.h" */
4031*7c478bd9Sstevel@tonic-gate 
4032*7c478bd9Sstevel@tonic-gate /* +++ inftrees.h */
4033*7c478bd9Sstevel@tonic-gate /*
4034*7c478bd9Sstevel@tonic-gate  * inftrees.h -- header to use inftrees.c
4035*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
4036*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
4037*7c478bd9Sstevel@tonic-gate  */
4038*7c478bd9Sstevel@tonic-gate 
4039*7c478bd9Sstevel@tonic-gate /*
4040*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
4041*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
4042*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
4043*7c478bd9Sstevel@tonic-gate  */
4044*7c478bd9Sstevel@tonic-gate 
4045*7c478bd9Sstevel@tonic-gate /*
4046*7c478bd9Sstevel@tonic-gate  * Huffman code lookup table entry--this entry is four bytes for
4047*7c478bd9Sstevel@tonic-gate  * machines that have 16-bit pointers (e.g. PC's in the small or
4048*7c478bd9Sstevel@tonic-gate  * medium model).
4049*7c478bd9Sstevel@tonic-gate  */
4050*7c478bd9Sstevel@tonic-gate 
4051*7c478bd9Sstevel@tonic-gate typedef struct inflate_huft_s FAR inflate_huft;
4052*7c478bd9Sstevel@tonic-gate 
4053*7c478bd9Sstevel@tonic-gate struct inflate_huft_s {
4054*7c478bd9Sstevel@tonic-gate 	union {
4055*7c478bd9Sstevel@tonic-gate 		struct {
4056*7c478bd9Sstevel@tonic-gate 			Byte Exop;	/* number of extra bits or operation */
4057*7c478bd9Sstevel@tonic-gate 			/* number of bits in this code or subcode */
4058*7c478bd9Sstevel@tonic-gate 			Byte Bits;
4059*7c478bd9Sstevel@tonic-gate 		} what;
4060*7c478bd9Sstevel@tonic-gate 		Bytef *pad;	/* pad structure to a power of 2 (4 bytes for */
4061*7c478bd9Sstevel@tonic-gate 	} word;	/*  16-bit, 8 bytes for 32-bit machines) */
4062*7c478bd9Sstevel@tonic-gate 	/* literal, length base, distance base, or table offset */
4063*7c478bd9Sstevel@tonic-gate 	uInt base;
4064*7c478bd9Sstevel@tonic-gate };
4065*7c478bd9Sstevel@tonic-gate 
4066*7c478bd9Sstevel@tonic-gate /*
4067*7c478bd9Sstevel@tonic-gate  * Maximum size of dynamic tree.  The maximum found in a long but non-
4068*7c478bd9Sstevel@tonic-gate  * exhaustive search was 1004 huft structures (850 for length/literals
4069*7c478bd9Sstevel@tonic-gate  * and 154 for distances, the latter actually the result of an
4070*7c478bd9Sstevel@tonic-gate  * exhaustive search).  The actual maximum is not known, but the value
4071*7c478bd9Sstevel@tonic-gate  * below is more than safe.
4072*7c478bd9Sstevel@tonic-gate  */
4073*7c478bd9Sstevel@tonic-gate #define	MANY 1440
4074*7c478bd9Sstevel@tonic-gate 
4075*7c478bd9Sstevel@tonic-gate extern int inflate_trees_bits OF((
4076*7c478bd9Sstevel@tonic-gate     uIntf *,			/* 19 code lengths */
4077*7c478bd9Sstevel@tonic-gate     uIntf *,			/* bits tree desired/actual depth */
4078*7c478bd9Sstevel@tonic-gate     inflate_huft * FAR *,	/* bits tree result */
4079*7c478bd9Sstevel@tonic-gate     inflate_huft *,		/* space for trees */
4080*7c478bd9Sstevel@tonic-gate     z_streamp));	/* for zalloc, zfree functions */
4081*7c478bd9Sstevel@tonic-gate 
4082*7c478bd9Sstevel@tonic-gate extern int inflate_trees_dynamic OF((
4083*7c478bd9Sstevel@tonic-gate     uInt,	/* number of literal/length codes */
4084*7c478bd9Sstevel@tonic-gate     uInt,	/* number of distance codes */
4085*7c478bd9Sstevel@tonic-gate     uIntf *,	/* that many (total) code lengths */
4086*7c478bd9Sstevel@tonic-gate     uIntf *,	/* literal desired/actual bit depth */
4087*7c478bd9Sstevel@tonic-gate     uIntf *,	/* distance desired/actual bit depth */
4088*7c478bd9Sstevel@tonic-gate     inflate_huft * FAR *,	/* literal/length tree result */
4089*7c478bd9Sstevel@tonic-gate     inflate_huft * FAR *,	/* distance tree result */
4090*7c478bd9Sstevel@tonic-gate     inflate_huft *,		/* space for trees */
4091*7c478bd9Sstevel@tonic-gate     z_streamp));	/* for zalloc, zfree functions */
4092*7c478bd9Sstevel@tonic-gate 
4093*7c478bd9Sstevel@tonic-gate extern int inflate_trees_fixed OF((
4094*7c478bd9Sstevel@tonic-gate     uIntf *,	/* literal desired/actual bit depth */
4095*7c478bd9Sstevel@tonic-gate     uIntf *,	/* distance desired/actual bit depth */
4096*7c478bd9Sstevel@tonic-gate     const inflate_huft * FAR *,	/* literal/length tree result */
4097*7c478bd9Sstevel@tonic-gate     const inflate_huft * FAR *,	/* distance tree result */
4098*7c478bd9Sstevel@tonic-gate     z_streamp));
4099*7c478bd9Sstevel@tonic-gate 
4100*7c478bd9Sstevel@tonic-gate /* --- inftrees.h */
4101*7c478bd9Sstevel@tonic-gate 
4102*7c478bd9Sstevel@tonic-gate /* +++ infcodes.h */
4103*7c478bd9Sstevel@tonic-gate /*
4104*7c478bd9Sstevel@tonic-gate  * infcodes.h -- header to use infcodes.c
4105*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
4106*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
4107*7c478bd9Sstevel@tonic-gate  */
4108*7c478bd9Sstevel@tonic-gate 
4109*7c478bd9Sstevel@tonic-gate /*
4110*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
4111*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
4112*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
4113*7c478bd9Sstevel@tonic-gate  */
4114*7c478bd9Sstevel@tonic-gate 
4115*7c478bd9Sstevel@tonic-gate struct inflate_codes_state;
4116*7c478bd9Sstevel@tonic-gate typedef struct inflate_codes_state FAR inflate_codes_statef;
4117*7c478bd9Sstevel@tonic-gate 
4118*7c478bd9Sstevel@tonic-gate extern inflate_codes_statef *inflate_codes_new OF((
4119*7c478bd9Sstevel@tonic-gate     uInt, uInt,
4120*7c478bd9Sstevel@tonic-gate     const inflate_huft *, const inflate_huft *,
4121*7c478bd9Sstevel@tonic-gate     z_streamp));
4122*7c478bd9Sstevel@tonic-gate 
4123*7c478bd9Sstevel@tonic-gate extern int inflate_codes OF((
4124*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
4125*7c478bd9Sstevel@tonic-gate     z_streamp,
4126*7c478bd9Sstevel@tonic-gate     int));
4127*7c478bd9Sstevel@tonic-gate 
4128*7c478bd9Sstevel@tonic-gate extern void inflate_codes_free OF((
4129*7c478bd9Sstevel@tonic-gate     inflate_codes_statef *,
4130*7c478bd9Sstevel@tonic-gate     z_streamp));
4131*7c478bd9Sstevel@tonic-gate 
4132*7c478bd9Sstevel@tonic-gate /* --- infcodes.h */
4133*7c478bd9Sstevel@tonic-gate 
4134*7c478bd9Sstevel@tonic-gate /* +++ infutil.h */
4135*7c478bd9Sstevel@tonic-gate /*
4136*7c478bd9Sstevel@tonic-gate  * infutil.h -- types and macros common to blocks and codes
4137*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
4138*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
4139*7c478bd9Sstevel@tonic-gate  */
4140*7c478bd9Sstevel@tonic-gate 
4141*7c478bd9Sstevel@tonic-gate /*
4142*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
4143*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
4144*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
4145*7c478bd9Sstevel@tonic-gate  */
4146*7c478bd9Sstevel@tonic-gate 
4147*7c478bd9Sstevel@tonic-gate #ifndef _INFUTIL_H
4148*7c478bd9Sstevel@tonic-gate #define	_INFUTIL_H
4149*7c478bd9Sstevel@tonic-gate 
4150*7c478bd9Sstevel@tonic-gate typedef enum {
4151*7c478bd9Sstevel@tonic-gate 	TYPE,	/* get type bits (3, including end bit) */
4152*7c478bd9Sstevel@tonic-gate 	LENS,	/* get lengths for stored */
4153*7c478bd9Sstevel@tonic-gate 	STORED,	/* processing stored block */
4154*7c478bd9Sstevel@tonic-gate 	TABLE,	/* get table lengths */
4155*7c478bd9Sstevel@tonic-gate 	BTREE,	/* get bit lengths tree for a dynamic block */
4156*7c478bd9Sstevel@tonic-gate 	DTREE,	/* get length, distance trees for a dynamic block */
4157*7c478bd9Sstevel@tonic-gate 	CODES,	/* processing fixed or dynamic block */
4158*7c478bd9Sstevel@tonic-gate 	DRY,	/* output remaining window bytes */
4159*7c478bd9Sstevel@tonic-gate 	DONEB,	/* finished last block, done */
4160*7c478bd9Sstevel@tonic-gate 	BADB}	/* got a data error--stuck here */
4161*7c478bd9Sstevel@tonic-gate inflate_block_mode;
4162*7c478bd9Sstevel@tonic-gate 
4163*7c478bd9Sstevel@tonic-gate /* inflate blocks semi-private state */
4164*7c478bd9Sstevel@tonic-gate struct inflate_blocks_state {
4165*7c478bd9Sstevel@tonic-gate 
4166*7c478bd9Sstevel@tonic-gate 	/* mode */
4167*7c478bd9Sstevel@tonic-gate 	inflate_block_mode  mode;	/* current inflate_block mode */
4168*7c478bd9Sstevel@tonic-gate 
4169*7c478bd9Sstevel@tonic-gate 	/* mode dependent information */
4170*7c478bd9Sstevel@tonic-gate 	union {
4171*7c478bd9Sstevel@tonic-gate 		uInt left;	/* if STORED, bytes left to copy */
4172*7c478bd9Sstevel@tonic-gate 		struct {
4173*7c478bd9Sstevel@tonic-gate 			uInt table;	/* table lengths (14 bits) */
4174*7c478bd9Sstevel@tonic-gate 			uInt index;	/* index into blens (or border) */
4175*7c478bd9Sstevel@tonic-gate 			uIntf *blens;	/* bit lengths of codes */
4176*7c478bd9Sstevel@tonic-gate 			uInt bb;	/* bit length tree depth */
4177*7c478bd9Sstevel@tonic-gate 			inflate_huft *tb;	/* bit length decoding tree */
4178*7c478bd9Sstevel@tonic-gate 		} trees;	/* if DTREE, decoding info for trees */
4179*7c478bd9Sstevel@tonic-gate 		struct {
4180*7c478bd9Sstevel@tonic-gate 			inflate_codes_statef *codes;
4181*7c478bd9Sstevel@tonic-gate 		} decode;	/* if CODES, current state */
4182*7c478bd9Sstevel@tonic-gate 	} sub;	/* submode */
4183*7c478bd9Sstevel@tonic-gate 	uInt last;	/* true if this block is the last block */
4184*7c478bd9Sstevel@tonic-gate 
4185*7c478bd9Sstevel@tonic-gate 	/* mode independent information */
4186*7c478bd9Sstevel@tonic-gate 	uInt bitk;	/* bits in bit buffer */
4187*7c478bd9Sstevel@tonic-gate 	uLong bitb;	/* bit buffer */
4188*7c478bd9Sstevel@tonic-gate 	inflate_huft *hufts;  /* single malloc for tree space */
4189*7c478bd9Sstevel@tonic-gate 	Bytef *window;	/* sliding window */
4190*7c478bd9Sstevel@tonic-gate 	Bytef *end;	/* one byte after sliding window */
4191*7c478bd9Sstevel@tonic-gate 	Bytef *read;	/* window read pointer */
4192*7c478bd9Sstevel@tonic-gate 	Bytef *write;	/* window write pointer */
4193*7c478bd9Sstevel@tonic-gate 	check_func checkfn;	/* check function */
4194*7c478bd9Sstevel@tonic-gate 	uLong check;	/* check on output */
4195*7c478bd9Sstevel@tonic-gate 
4196*7c478bd9Sstevel@tonic-gate };
4197*7c478bd9Sstevel@tonic-gate 
4198*7c478bd9Sstevel@tonic-gate 
4199*7c478bd9Sstevel@tonic-gate /* defines for inflate input/output */
4200*7c478bd9Sstevel@tonic-gate /*   update pointers and return */
4201*7c478bd9Sstevel@tonic-gate #define	UPDBITS {s->bitb = b; s->bitk = k; }
4202*7c478bd9Sstevel@tonic-gate #define	UPDIN {z->avail_in = n; z->total_in += p-z->next_in; z->next_in = p; }
4203*7c478bd9Sstevel@tonic-gate #define	UPDOUT {s->write = q; }
4204*7c478bd9Sstevel@tonic-gate #define	UPDATE {UPDBITS UPDIN UPDOUT}
4205*7c478bd9Sstevel@tonic-gate #define	LEAVE {UPDATE return (inflate_flush(s, z, r)); }
4206*7c478bd9Sstevel@tonic-gate /*   get bytes and bits */
4207*7c478bd9Sstevel@tonic-gate #define	LOADIN {p = z->next_in; n = z->avail_in; b = s->bitb; k = s->bitk; }
4208*7c478bd9Sstevel@tonic-gate #define	NEEDBYTE { if (n) r = Z_OK; else LEAVE }
4209*7c478bd9Sstevel@tonic-gate #define	NEXTBYTE (n--, *p++)
4210*7c478bd9Sstevel@tonic-gate #define	NEEDBITS(j) { while (k < (j)) { NEEDBYTE; b |= ((uLong)NEXTBYTE)<<k; \
4211*7c478bd9Sstevel@tonic-gate 	k += 8; }}
4212*7c478bd9Sstevel@tonic-gate #define	DUMPBITS(j) {b >>= (j); k -= (j); }
4213*7c478bd9Sstevel@tonic-gate /*   output bytes */
4214*7c478bd9Sstevel@tonic-gate #define	WAVAIL (uInt)(q < s->read ? s->read-q-1 : s->end-q)
4215*7c478bd9Sstevel@tonic-gate #define	LOADOUT {q = s->write; m = (uInt)WAVAIL; }
4216*7c478bd9Sstevel@tonic-gate #define	WWRAP {if (q == s->end && s->read != s->window) {q = s->window; \
4217*7c478bd9Sstevel@tonic-gate 	m = (uInt)WAVAIL; }}
4218*7c478bd9Sstevel@tonic-gate #define	FLUSH {UPDOUT r = inflate_flush(s, z, r); LOADOUT}
4219*7c478bd9Sstevel@tonic-gate #define	NEEDOUT {if (m == 0) {WWRAP if (m == 0) { FLUSH WWRAP \
4220*7c478bd9Sstevel@tonic-gate 	if (m == 0) LEAVE }} r = Z_OK; }
4221*7c478bd9Sstevel@tonic-gate #define	OUTBYTE(a) {*q++ = (Byte)(a); m--; }
4222*7c478bd9Sstevel@tonic-gate /*   load local pointers */
4223*7c478bd9Sstevel@tonic-gate #define	LOAD {LOADIN LOADOUT}
4224*7c478bd9Sstevel@tonic-gate 
4225*7c478bd9Sstevel@tonic-gate /* masks for lower bits (size given to avoid silly warnings with Visual C++) */
4226*7c478bd9Sstevel@tonic-gate extern uInt inflate_mask[17];
4227*7c478bd9Sstevel@tonic-gate 
4228*7c478bd9Sstevel@tonic-gate /* copy as much as possible from the sliding window to the output area */
4229*7c478bd9Sstevel@tonic-gate extern int inflate_flush OF((
4230*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
4231*7c478bd9Sstevel@tonic-gate     z_streamp,
4232*7c478bd9Sstevel@tonic-gate     int));
4233*7c478bd9Sstevel@tonic-gate 
4234*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
4235*7c478bd9Sstevel@tonic-gate struct internal_state {int dummy; };	/* for buggy compilers */
4236*7c478bd9Sstevel@tonic-gate #endif
4237*7c478bd9Sstevel@tonic-gate 
4238*7c478bd9Sstevel@tonic-gate #endif
4239*7c478bd9Sstevel@tonic-gate /* --- infutil.h */
4240*7c478bd9Sstevel@tonic-gate 
4241*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
4242*7c478bd9Sstevel@tonic-gate struct inflate_codes_state {int dummy; };	/* for buggy compilers */
4243*7c478bd9Sstevel@tonic-gate #endif
4244*7c478bd9Sstevel@tonic-gate 
4245*7c478bd9Sstevel@tonic-gate /* Table for deflate from PKZIP's appnote.txt. */
4246*7c478bd9Sstevel@tonic-gate local const uInt border[] = { /* Order of the bit length code lengths */
4247*7c478bd9Sstevel@tonic-gate 	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
4248*7c478bd9Sstevel@tonic-gate 
4249*7c478bd9Sstevel@tonic-gate /*
4250*7c478bd9Sstevel@tonic-gate  * Notes beyond the 1.93a appnote.txt:
4251*7c478bd9Sstevel@tonic-gate  *
4252*7c478bd9Sstevel@tonic-gate  *   1. Distance pointers never point before the beginning of the output
4253*7c478bd9Sstevel@tonic-gate  *      stream.
4254*7c478bd9Sstevel@tonic-gate  *   2. Distance pointers can point back across blocks, up to 32k away.
4255*7c478bd9Sstevel@tonic-gate  *   3. There is an implied maximum of 7 bits for the bit length table and
4256*7c478bd9Sstevel@tonic-gate  *      15 bits for the actual data.
4257*7c478bd9Sstevel@tonic-gate  *   4. If only one code exists, then it is encoded using one bit.  (Zero
4258*7c478bd9Sstevel@tonic-gate  *      would be more efficient, but perhaps a little confusing.)  If two
4259*7c478bd9Sstevel@tonic-gate  *      codes exist, they are coded using one bit each (0 and 1).
4260*7c478bd9Sstevel@tonic-gate  *   5. There is no way of sending zero distance codes--a dummy must be
4261*7c478bd9Sstevel@tonic-gate  *      sent if there are none.  (History: a pre 2.0 version of PKZIP would
4262*7c478bd9Sstevel@tonic-gate  *      store blocks with no distance codes, but this was discovered to be
4263*7c478bd9Sstevel@tonic-gate  *      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
4264*7c478bd9Sstevel@tonic-gate  *      zero distance codes, which is sent as one code of zero bits in
4265*7c478bd9Sstevel@tonic-gate  *      length.
4266*7c478bd9Sstevel@tonic-gate  *   6. There are up to 286 literal/length codes.  Code 256 represents the
4267*7c478bd9Sstevel@tonic-gate  *      end-of-block.  Note however that the static length tree defines
4268*7c478bd9Sstevel@tonic-gate  *      288 codes just to fill out the Huffman codes.  Codes 286 and 287
4269*7c478bd9Sstevel@tonic-gate  *      cannot be used though, since there is no length base or extra bits
4270*7c478bd9Sstevel@tonic-gate  *      defined for them.  Similarily, there are up to 30 distance codes.
4271*7c478bd9Sstevel@tonic-gate  *      However, static trees define 32 codes (all 5 bits) to fill out the
4272*7c478bd9Sstevel@tonic-gate  *      Huffman codes, but the last two had better not show up in the data.
4273*7c478bd9Sstevel@tonic-gate  *   7. Unzip can check dynamic Huffman blocks for complete code sets.
4274*7c478bd9Sstevel@tonic-gate  *      The exception is that a single code would not be complete (see #4).
4275*7c478bd9Sstevel@tonic-gate  *   8. The five bits following the block type is really the number of
4276*7c478bd9Sstevel@tonic-gate  *      literal codes sent minus 257.
4277*7c478bd9Sstevel@tonic-gate  *   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
4278*7c478bd9Sstevel@tonic-gate  *      (1+6+6).  Therefore, to output three times the length, you output
4279*7c478bd9Sstevel@tonic-gate  *      three codes (1+1+1), whereas to output four times the same length,
4280*7c478bd9Sstevel@tonic-gate  *      you only need two codes (1+3).  Hmm.
4281*7c478bd9Sstevel@tonic-gate  *  10. In the tree reconstruction algorithm, Code = Code + Increment
4282*7c478bd9Sstevel@tonic-gate  *      only if BitLength(i) is not zero.  (Pretty obvious.)
4283*7c478bd9Sstevel@tonic-gate  *  11. Correction: 4 Bits: #of Bit Length codes - 4     (4 - 19)
4284*7c478bd9Sstevel@tonic-gate  *  12. Note: length code 284 can represent 227-258, but length code 285
4285*7c478bd9Sstevel@tonic-gate  *      really is 258.  The last length deserves its own, short code
4286*7c478bd9Sstevel@tonic-gate  *      since it gets used a lot in very redundant files.  The length
4287*7c478bd9Sstevel@tonic-gate  *      258 is special since 258 - 3 (the min match length) is 255.
4288*7c478bd9Sstevel@tonic-gate  *  13. The literal/length and distance code bit lengths are read as a
4289*7c478bd9Sstevel@tonic-gate  *      single stream of lengths.  It is possible (and advantageous) for
4290*7c478bd9Sstevel@tonic-gate  *      a repeat code (16, 17, or 18) to go across the boundary between
4291*7c478bd9Sstevel@tonic-gate  *      the two sets of lengths.
4292*7c478bd9Sstevel@tonic-gate  */
4293*7c478bd9Sstevel@tonic-gate 
4294*7c478bd9Sstevel@tonic-gate 
4295*7c478bd9Sstevel@tonic-gate void
4296*7c478bd9Sstevel@tonic-gate inflate_blocks_reset(s, z, c)
4297*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4298*7c478bd9Sstevel@tonic-gate z_streamp z;
4299*7c478bd9Sstevel@tonic-gate uLongf *c;
4300*7c478bd9Sstevel@tonic-gate {
4301*7c478bd9Sstevel@tonic-gate 	if (c != Z_NULL)
4302*7c478bd9Sstevel@tonic-gate 		*c = s->check;
4303*7c478bd9Sstevel@tonic-gate 	if ((s->mode == BTREE || s->mode == DTREE) &&
4304*7c478bd9Sstevel@tonic-gate 	    s->sub.trees.blens != Z_NULL) {
4305*7c478bd9Sstevel@tonic-gate 		ZFREE(z, s->sub.trees.blens);
4306*7c478bd9Sstevel@tonic-gate 		s->sub.trees.blens = Z_NULL;
4307*7c478bd9Sstevel@tonic-gate 	}
4308*7c478bd9Sstevel@tonic-gate 	if (s->mode == CODES && s->sub.decode.codes != Z_NULL) {
4309*7c478bd9Sstevel@tonic-gate 		(void) inflate_codes_free(s->sub.decode.codes, z);
4310*7c478bd9Sstevel@tonic-gate 		s->sub.decode.codes = Z_NULL;
4311*7c478bd9Sstevel@tonic-gate 	}
4312*7c478bd9Sstevel@tonic-gate 	s->mode = TYPE;
4313*7c478bd9Sstevel@tonic-gate 	s->bitk = 0;
4314*7c478bd9Sstevel@tonic-gate 	s->bitb = 0;
4315*7c478bd9Sstevel@tonic-gate 	s->read = s->write = s->window;
4316*7c478bd9Sstevel@tonic-gate 	if (s->checkfn != Z_NULL)
4317*7c478bd9Sstevel@tonic-gate 		z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
4318*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate:   blocks reset\n"));
4319*7c478bd9Sstevel@tonic-gate }
4320*7c478bd9Sstevel@tonic-gate 
4321*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *
4322*7c478bd9Sstevel@tonic-gate inflate_blocks_new(z, c, w)
4323*7c478bd9Sstevel@tonic-gate z_streamp z;
4324*7c478bd9Sstevel@tonic-gate check_func c;
4325*7c478bd9Sstevel@tonic-gate uInt w;
4326*7c478bd9Sstevel@tonic-gate {
4327*7c478bd9Sstevel@tonic-gate 	inflate_blocks_statef *s;
4328*7c478bd9Sstevel@tonic-gate 
4329*7c478bd9Sstevel@tonic-gate 	if ((s = (inflate_blocks_statef *)ZALLOC
4330*7c478bd9Sstevel@tonic-gate 	    (z, 1, sizeof (struct inflate_blocks_state))) == Z_NULL)
4331*7c478bd9Sstevel@tonic-gate 		return (s);
4332*7c478bd9Sstevel@tonic-gate 	s->hufts = (inflate_huft *)ZALLOC(z, MANY, sizeof (inflate_huft));
4333*7c478bd9Sstevel@tonic-gate 	if (s->hufts == Z_NULL) {
4334*7c478bd9Sstevel@tonic-gate 		ZFREE(z, s);
4335*7c478bd9Sstevel@tonic-gate 		return (Z_NULL);
4336*7c478bd9Sstevel@tonic-gate 	}
4337*7c478bd9Sstevel@tonic-gate 	if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
4338*7c478bd9Sstevel@tonic-gate 	{
4339*7c478bd9Sstevel@tonic-gate 		ZFREE(z, s->hufts);
4340*7c478bd9Sstevel@tonic-gate 		ZFREE(z, s);
4341*7c478bd9Sstevel@tonic-gate 		return (Z_NULL);
4342*7c478bd9Sstevel@tonic-gate 	}
4343*7c478bd9Sstevel@tonic-gate 	s->end = s->window + w;
4344*7c478bd9Sstevel@tonic-gate 	s->checkfn = c;
4345*7c478bd9Sstevel@tonic-gate 	s->mode = TYPE;
4346*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate:   blocks allocated\n"));
4347*7c478bd9Sstevel@tonic-gate 	inflate_blocks_reset(s, z, Z_NULL);
4348*7c478bd9Sstevel@tonic-gate 	return (s);
4349*7c478bd9Sstevel@tonic-gate }
4350*7c478bd9Sstevel@tonic-gate 
4351*7c478bd9Sstevel@tonic-gate 
4352*7c478bd9Sstevel@tonic-gate int
4353*7c478bd9Sstevel@tonic-gate inflate_blocks(s, z, r)
4354*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4355*7c478bd9Sstevel@tonic-gate z_streamp z;
4356*7c478bd9Sstevel@tonic-gate int r;
4357*7c478bd9Sstevel@tonic-gate {
4358*7c478bd9Sstevel@tonic-gate 	uInt t;	/* temporary storage */
4359*7c478bd9Sstevel@tonic-gate 	uLong b;	/* bit buffer */
4360*7c478bd9Sstevel@tonic-gate 	uInt k;	/* bits in bit buffer */
4361*7c478bd9Sstevel@tonic-gate 	Bytef *p;	/* input data pointer */
4362*7c478bd9Sstevel@tonic-gate 	uInt n;	/* bytes available there */
4363*7c478bd9Sstevel@tonic-gate 	Bytef *q;	/* output window write pointer */
4364*7c478bd9Sstevel@tonic-gate 	uInt m;	/* bytes to end of window or read pointer */
4365*7c478bd9Sstevel@tonic-gate 
4366*7c478bd9Sstevel@tonic-gate 	/* copy input/output information to locals (UPDATE macro restores) */
4367*7c478bd9Sstevel@tonic-gate 	LOAD;
4368*7c478bd9Sstevel@tonic-gate 
4369*7c478bd9Sstevel@tonic-gate 	/* process input based on current state */
4370*7c478bd9Sstevel@tonic-gate 	/* CONSTCOND */
4371*7c478bd9Sstevel@tonic-gate 	while (1)
4372*7c478bd9Sstevel@tonic-gate 		switch (s->mode)
4373*7c478bd9Sstevel@tonic-gate 	{
4374*7c478bd9Sstevel@tonic-gate 	case TYPE:
4375*7c478bd9Sstevel@tonic-gate 		NEEDBITS(3);
4376*7c478bd9Sstevel@tonic-gate 		t = (uInt)b & 7;
4377*7c478bd9Sstevel@tonic-gate 		s->last = t & 1;
4378*7c478bd9Sstevel@tonic-gate 		switch (t >> 1)
4379*7c478bd9Sstevel@tonic-gate 		{
4380*7c478bd9Sstevel@tonic-gate 		case 0:			/* stored */
4381*7c478bd9Sstevel@tonic-gate 			Trace((stderr, "inflate:     stored block%s\n",
4382*7c478bd9Sstevel@tonic-gate 			    s->last ? " (last)" : ""));
4383*7c478bd9Sstevel@tonic-gate 			DUMPBITS(3);
4384*7c478bd9Sstevel@tonic-gate 			t = k & 7;	/* go to byte boundary */
4385*7c478bd9Sstevel@tonic-gate 			DUMPBITS(t);
4386*7c478bd9Sstevel@tonic-gate 			s->mode = LENS;	/* get length of stored block */
4387*7c478bd9Sstevel@tonic-gate 			break;
4388*7c478bd9Sstevel@tonic-gate 		case 1:			/* fixed */
4389*7c478bd9Sstevel@tonic-gate 			Trace((stderr, "inflate:     fixed codes block%s\n",
4390*7c478bd9Sstevel@tonic-gate 			    s->last ? " (last)" : ""));
4391*7c478bd9Sstevel@tonic-gate 			{
4392*7c478bd9Sstevel@tonic-gate 				uInt bl, bd;
4393*7c478bd9Sstevel@tonic-gate 				const inflate_huft *tl, *td;
4394*7c478bd9Sstevel@tonic-gate 
4395*7c478bd9Sstevel@tonic-gate 				(void) inflate_trees_fixed(&bl, &bd, &tl, &td,
4396*7c478bd9Sstevel@tonic-gate 				    z);
4397*7c478bd9Sstevel@tonic-gate 				s->sub.decode.codes = inflate_codes_new(bl,
4398*7c478bd9Sstevel@tonic-gate 				    bd, tl, td, z);
4399*7c478bd9Sstevel@tonic-gate 				if (s->sub.decode.codes == Z_NULL)
4400*7c478bd9Sstevel@tonic-gate 				{
4401*7c478bd9Sstevel@tonic-gate 					r = Z_MEM_ERROR;
4402*7c478bd9Sstevel@tonic-gate 					LEAVE
4403*7c478bd9Sstevel@tonic-gate 				}
4404*7c478bd9Sstevel@tonic-gate 			}
4405*7c478bd9Sstevel@tonic-gate 			DUMPBITS(3);
4406*7c478bd9Sstevel@tonic-gate 			s->mode = CODES;
4407*7c478bd9Sstevel@tonic-gate 			break;
4408*7c478bd9Sstevel@tonic-gate 		case 2:			/* dynamic */
4409*7c478bd9Sstevel@tonic-gate 			Trace((stderr, "inflate:     dynamic codes block%s\n",
4410*7c478bd9Sstevel@tonic-gate 			    s->last ? " (last)" : ""));
4411*7c478bd9Sstevel@tonic-gate 			DUMPBITS(3);
4412*7c478bd9Sstevel@tonic-gate 			s->mode = TABLE;
4413*7c478bd9Sstevel@tonic-gate 			break;
4414*7c478bd9Sstevel@tonic-gate 		case 3:			/* illegal */
4415*7c478bd9Sstevel@tonic-gate 			DUMPBITS(3);
4416*7c478bd9Sstevel@tonic-gate 			s->mode = BADB;
4417*7c478bd9Sstevel@tonic-gate 			z->msg = "invalid block type";
4418*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
4419*7c478bd9Sstevel@tonic-gate 			LEAVE
4420*7c478bd9Sstevel@tonic-gate 		}
4421*7c478bd9Sstevel@tonic-gate 		break;
4422*7c478bd9Sstevel@tonic-gate 	case LENS:
4423*7c478bd9Sstevel@tonic-gate 		NEEDBITS(32);
4424*7c478bd9Sstevel@tonic-gate 		if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
4425*7c478bd9Sstevel@tonic-gate 		{
4426*7c478bd9Sstevel@tonic-gate 			s->mode = BADB;
4427*7c478bd9Sstevel@tonic-gate 			z->msg = "invalid stored block lengths";
4428*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
4429*7c478bd9Sstevel@tonic-gate 			LEAVE
4430*7c478bd9Sstevel@tonic-gate 		}
4431*7c478bd9Sstevel@tonic-gate 		s->sub.left = (uInt)b & 0xffff;
4432*7c478bd9Sstevel@tonic-gate 		b = k = 0;	/* dump bits */
4433*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "inflate:       stored length %u\n",
4434*7c478bd9Sstevel@tonic-gate 		    s->sub.left));
4435*7c478bd9Sstevel@tonic-gate 		s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
4436*7c478bd9Sstevel@tonic-gate 		break;
4437*7c478bd9Sstevel@tonic-gate 	case STORED:
4438*7c478bd9Sstevel@tonic-gate 		if (n == 0)
4439*7c478bd9Sstevel@tonic-gate 			LEAVE
4440*7c478bd9Sstevel@tonic-gate 		NEEDOUT;
4441*7c478bd9Sstevel@tonic-gate 		t = s->sub.left;
4442*7c478bd9Sstevel@tonic-gate 		if (t > n) t = n;
4443*7c478bd9Sstevel@tonic-gate 		if (t > m) t = m;
4444*7c478bd9Sstevel@tonic-gate 		zmemcpy(q, p, t);
4445*7c478bd9Sstevel@tonic-gate 		p += t;  n -= t;
4446*7c478bd9Sstevel@tonic-gate 		q += t;  m -= t;
4447*7c478bd9Sstevel@tonic-gate 		if ((s->sub.left -= t) != 0)
4448*7c478bd9Sstevel@tonic-gate 			break;
4449*7c478bd9Sstevel@tonic-gate 		Tracev((stderr,
4450*7c478bd9Sstevel@tonic-gate 		    "inflate:       stored end, %lu total out\n",
4451*7c478bd9Sstevel@tonic-gate 		    z->total_out + (q >= s->read ? q - s->read :
4452*7c478bd9Sstevel@tonic-gate 			(s->end - s->read) + (q - s->window))));
4453*7c478bd9Sstevel@tonic-gate 		s->mode = s->last ? DRY : TYPE;
4454*7c478bd9Sstevel@tonic-gate 		break;
4455*7c478bd9Sstevel@tonic-gate 	case TABLE:
4456*7c478bd9Sstevel@tonic-gate 		NEEDBITS(14);
4457*7c478bd9Sstevel@tonic-gate 		s->sub.trees.table = t = (uInt)b & 0x3fff;
4458*7c478bd9Sstevel@tonic-gate #ifndef PKZIP_BUG_WORKAROUND
4459*7c478bd9Sstevel@tonic-gate 		if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
4460*7c478bd9Sstevel@tonic-gate 		{
4461*7c478bd9Sstevel@tonic-gate 			s->mode = BADB;
4462*7c478bd9Sstevel@tonic-gate 			z->msg =
4463*7c478bd9Sstevel@tonic-gate 			    (char *)"too many length or distance symbols";
4464*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
4465*7c478bd9Sstevel@tonic-gate 			LEAVE
4466*7c478bd9Sstevel@tonic-gate 		}
4467*7c478bd9Sstevel@tonic-gate #endif
4468*7c478bd9Sstevel@tonic-gate 		t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
4469*7c478bd9Sstevel@tonic-gate 		/* if (t < 19) t = 19; */
4470*7c478bd9Sstevel@tonic-gate 		if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t,
4471*7c478bd9Sstevel@tonic-gate 		    sizeof (uInt))) == Z_NULL)
4472*7c478bd9Sstevel@tonic-gate 		{
4473*7c478bd9Sstevel@tonic-gate 			r = Z_MEM_ERROR;
4474*7c478bd9Sstevel@tonic-gate 			LEAVE
4475*7c478bd9Sstevel@tonic-gate 		}
4476*7c478bd9Sstevel@tonic-gate 		DUMPBITS(14);
4477*7c478bd9Sstevel@tonic-gate 		s->sub.trees.index = 0;
4478*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "inflate:       table sizes ok\n"));
4479*7c478bd9Sstevel@tonic-gate 		s->mode = BTREE;
4480*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
4481*7c478bd9Sstevel@tonic-gate 	case BTREE:
4482*7c478bd9Sstevel@tonic-gate 		while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
4483*7c478bd9Sstevel@tonic-gate 		{
4484*7c478bd9Sstevel@tonic-gate 			NEEDBITS(3);
4485*7c478bd9Sstevel@tonic-gate 			s->sub.trees.blens[border[s->sub.trees.index++]] =
4486*7c478bd9Sstevel@tonic-gate 			    (uInt)b & 7;
4487*7c478bd9Sstevel@tonic-gate 			DUMPBITS(3);
4488*7c478bd9Sstevel@tonic-gate 		}
4489*7c478bd9Sstevel@tonic-gate 		while (s->sub.trees.index < 19)
4490*7c478bd9Sstevel@tonic-gate 			s->sub.trees.blens[border[s->sub.trees.index++]] =
4491*7c478bd9Sstevel@tonic-gate 			    0;
4492*7c478bd9Sstevel@tonic-gate 		s->sub.trees.bb = 7;
4493*7c478bd9Sstevel@tonic-gate 		t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
4494*7c478bd9Sstevel@tonic-gate 		    &s->sub.trees.tb, s->hufts, z);
4495*7c478bd9Sstevel@tonic-gate 		if (t != Z_OK)
4496*7c478bd9Sstevel@tonic-gate 		{
4497*7c478bd9Sstevel@tonic-gate 			ZFREE(z, s->sub.trees.blens);
4498*7c478bd9Sstevel@tonic-gate 			s->sub.trees.blens = Z_NULL;
4499*7c478bd9Sstevel@tonic-gate 			r = t;
4500*7c478bd9Sstevel@tonic-gate 			if (r == Z_DATA_ERROR)
4501*7c478bd9Sstevel@tonic-gate 				s->mode = BADB;
4502*7c478bd9Sstevel@tonic-gate 			LEAVE
4503*7c478bd9Sstevel@tonic-gate 		}
4504*7c478bd9Sstevel@tonic-gate 		s->sub.trees.index = 0;
4505*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "inflate:       bits tree ok\n"));
4506*7c478bd9Sstevel@tonic-gate 		s->mode = DTREE;
4507*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
4508*7c478bd9Sstevel@tonic-gate 	case DTREE:
4509*7c478bd9Sstevel@tonic-gate 		while (t = s->sub.trees.table,
4510*7c478bd9Sstevel@tonic-gate 		    s->sub.trees.index < 258 + (t & 0x1f) +
4511*7c478bd9Sstevel@tonic-gate 		    ((t >> 5) & 0x1f))
4512*7c478bd9Sstevel@tonic-gate 		{
4513*7c478bd9Sstevel@tonic-gate 			inflate_huft *h;
4514*7c478bd9Sstevel@tonic-gate 			uInt i, j, c;
4515*7c478bd9Sstevel@tonic-gate 
4516*7c478bd9Sstevel@tonic-gate 			t = s->sub.trees.bb;
4517*7c478bd9Sstevel@tonic-gate 			NEEDBITS(t);
4518*7c478bd9Sstevel@tonic-gate 			h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
4519*7c478bd9Sstevel@tonic-gate 			t = h->word.what.Bits;
4520*7c478bd9Sstevel@tonic-gate 			c = h->base;
4521*7c478bd9Sstevel@tonic-gate 			if (c < 16)
4522*7c478bd9Sstevel@tonic-gate 			{
4523*7c478bd9Sstevel@tonic-gate 				DUMPBITS(t);
4524*7c478bd9Sstevel@tonic-gate 				s->sub.trees.blens[s->sub.trees.index++] =
4525*7c478bd9Sstevel@tonic-gate 				    c;
4526*7c478bd9Sstevel@tonic-gate 			} else { /* c == 16..18 */
4527*7c478bd9Sstevel@tonic-gate 				i = c == 18 ? 7 : c - 14;
4528*7c478bd9Sstevel@tonic-gate 				j = c == 18 ? 11 : 3;
4529*7c478bd9Sstevel@tonic-gate 				NEEDBITS(t + i);
4530*7c478bd9Sstevel@tonic-gate 				DUMPBITS(t);
4531*7c478bd9Sstevel@tonic-gate 				j += (uInt)b & inflate_mask[i];
4532*7c478bd9Sstevel@tonic-gate 				DUMPBITS(i);
4533*7c478bd9Sstevel@tonic-gate 				i = s->sub.trees.index;
4534*7c478bd9Sstevel@tonic-gate 				t = s->sub.trees.table;
4535*7c478bd9Sstevel@tonic-gate 				if (i + j > 258 + (t & 0x1f) +
4536*7c478bd9Sstevel@tonic-gate 				    ((t >> 5) & 0x1f) ||
4537*7c478bd9Sstevel@tonic-gate 				    (c == 16 && i < 1))
4538*7c478bd9Sstevel@tonic-gate 				{
4539*7c478bd9Sstevel@tonic-gate 					ZFREE(z, s->sub.trees.blens);
4540*7c478bd9Sstevel@tonic-gate 					s->sub.trees.blens = Z_NULL;
4541*7c478bd9Sstevel@tonic-gate 					s->mode = BADB;
4542*7c478bd9Sstevel@tonic-gate 					z->msg = "invalid bit length repeat";
4543*7c478bd9Sstevel@tonic-gate 					r = Z_DATA_ERROR;
4544*7c478bd9Sstevel@tonic-gate 					LEAVE
4545*7c478bd9Sstevel@tonic-gate 				}
4546*7c478bd9Sstevel@tonic-gate 				c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
4547*7c478bd9Sstevel@tonic-gate 				do {
4548*7c478bd9Sstevel@tonic-gate 					s->sub.trees.blens[i++] = c;
4549*7c478bd9Sstevel@tonic-gate 				} while (--j);
4550*7c478bd9Sstevel@tonic-gate 				s->sub.trees.index = i;
4551*7c478bd9Sstevel@tonic-gate 			}
4552*7c478bd9Sstevel@tonic-gate 		}
4553*7c478bd9Sstevel@tonic-gate 		s->sub.trees.tb = Z_NULL;
4554*7c478bd9Sstevel@tonic-gate 		{
4555*7c478bd9Sstevel@tonic-gate 			uInt bl, bd;
4556*7c478bd9Sstevel@tonic-gate 			inflate_huft *tl, *td;
4557*7c478bd9Sstevel@tonic-gate 			inflate_codes_statef *c;
4558*7c478bd9Sstevel@tonic-gate 
4559*7c478bd9Sstevel@tonic-gate 				/* must be <= 9 for lookahead assumptions */
4560*7c478bd9Sstevel@tonic-gate 			bl = 9;
4561*7c478bd9Sstevel@tonic-gate 				/* must be <= 9 for lookahead assumptions */
4562*7c478bd9Sstevel@tonic-gate 			bd = 6;
4563*7c478bd9Sstevel@tonic-gate 			t = s->sub.trees.table;
4564*7c478bd9Sstevel@tonic-gate 			t = inflate_trees_dynamic(257 + (t & 0x1f),
4565*7c478bd9Sstevel@tonic-gate 			    1 + ((t >> 5) & 0x1f),
4566*7c478bd9Sstevel@tonic-gate 			    s->sub.trees.blens, &bl, &bd, &tl, &td,
4567*7c478bd9Sstevel@tonic-gate 			    s->hufts, z);
4568*7c478bd9Sstevel@tonic-gate 			ZFREE(z, s->sub.trees.blens);
4569*7c478bd9Sstevel@tonic-gate 			s->sub.trees.blens = Z_NULL;
4570*7c478bd9Sstevel@tonic-gate 			if (t != Z_OK)
4571*7c478bd9Sstevel@tonic-gate 			{
4572*7c478bd9Sstevel@tonic-gate 				if (t == (uInt)Z_DATA_ERROR)
4573*7c478bd9Sstevel@tonic-gate 					s->mode = BADB;
4574*7c478bd9Sstevel@tonic-gate 				r = t;
4575*7c478bd9Sstevel@tonic-gate 				LEAVE
4576*7c478bd9Sstevel@tonic-gate 			}
4577*7c478bd9Sstevel@tonic-gate 			Tracev((stderr, "inflate:       trees ok\n"));
4578*7c478bd9Sstevel@tonic-gate 			if ((c = inflate_codes_new(bl, bd, tl, td, z)) ==
4579*7c478bd9Sstevel@tonic-gate 			    Z_NULL)
4580*7c478bd9Sstevel@tonic-gate 			{
4581*7c478bd9Sstevel@tonic-gate 				r = Z_MEM_ERROR;
4582*7c478bd9Sstevel@tonic-gate 				LEAVE
4583*7c478bd9Sstevel@tonic-gate 			}
4584*7c478bd9Sstevel@tonic-gate 			s->sub.decode.codes = c;
4585*7c478bd9Sstevel@tonic-gate 		}
4586*7c478bd9Sstevel@tonic-gate 		s->mode = CODES;
4587*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
4588*7c478bd9Sstevel@tonic-gate 	case CODES:
4589*7c478bd9Sstevel@tonic-gate 		UPDATE;
4590*7c478bd9Sstevel@tonic-gate 		if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
4591*7c478bd9Sstevel@tonic-gate 			return (inflate_flush(s, z, r));
4592*7c478bd9Sstevel@tonic-gate 		r = Z_OK;
4593*7c478bd9Sstevel@tonic-gate 		(void) inflate_codes_free(s->sub.decode.codes, z);
4594*7c478bd9Sstevel@tonic-gate 		LOAD;
4595*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "inflate:       codes end, %lu total out\n",
4596*7c478bd9Sstevel@tonic-gate 		    z->total_out + (q >= s->read ? q - s->read :
4597*7c478bd9Sstevel@tonic-gate 			(s->end - s->read) + (q - s->window))));
4598*7c478bd9Sstevel@tonic-gate 		if (!s->last)
4599*7c478bd9Sstevel@tonic-gate 		{
4600*7c478bd9Sstevel@tonic-gate 			s->mode = TYPE;
4601*7c478bd9Sstevel@tonic-gate 			break;
4602*7c478bd9Sstevel@tonic-gate 		}
4603*7c478bd9Sstevel@tonic-gate 		s->mode = DRY;
4604*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
4605*7c478bd9Sstevel@tonic-gate 	case DRY:
4606*7c478bd9Sstevel@tonic-gate 		FLUSH;
4607*7c478bd9Sstevel@tonic-gate 		if (s->read != s->write)
4608*7c478bd9Sstevel@tonic-gate 			LEAVE
4609*7c478bd9Sstevel@tonic-gate 		s->mode = DONEB;
4610*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
4611*7c478bd9Sstevel@tonic-gate 	case DONEB:
4612*7c478bd9Sstevel@tonic-gate 		r = Z_STREAM_END;
4613*7c478bd9Sstevel@tonic-gate 		LEAVE
4614*7c478bd9Sstevel@tonic-gate 	case BADB:
4615*7c478bd9Sstevel@tonic-gate 		r = Z_DATA_ERROR;
4616*7c478bd9Sstevel@tonic-gate 		LEAVE
4617*7c478bd9Sstevel@tonic-gate 	default:
4618*7c478bd9Sstevel@tonic-gate 		r = Z_STREAM_ERROR;
4619*7c478bd9Sstevel@tonic-gate 		LEAVE
4620*7c478bd9Sstevel@tonic-gate 	}
4621*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
4622*7c478bd9Sstevel@tonic-gate 	/* otherwise lint complains */
4623*7c478bd9Sstevel@tonic-gate }
4624*7c478bd9Sstevel@tonic-gate 
4625*7c478bd9Sstevel@tonic-gate 
4626*7c478bd9Sstevel@tonic-gate int
4627*7c478bd9Sstevel@tonic-gate inflate_blocks_free(s, z)
4628*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4629*7c478bd9Sstevel@tonic-gate z_streamp z;
4630*7c478bd9Sstevel@tonic-gate {
4631*7c478bd9Sstevel@tonic-gate 	inflate_blocks_reset(s, z, Z_NULL);
4632*7c478bd9Sstevel@tonic-gate 	ZFREE(z, s->window);
4633*7c478bd9Sstevel@tonic-gate 	s->window = Z_NULL;
4634*7c478bd9Sstevel@tonic-gate 	ZFREE(z, s->hufts);
4635*7c478bd9Sstevel@tonic-gate 	s->hufts = Z_NULL;
4636*7c478bd9Sstevel@tonic-gate 	ZFREE(z, s);
4637*7c478bd9Sstevel@tonic-gate 	Trace((stderr, "inflate:   blocks freed\n"));
4638*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
4639*7c478bd9Sstevel@tonic-gate }
4640*7c478bd9Sstevel@tonic-gate 
4641*7c478bd9Sstevel@tonic-gate 
4642*7c478bd9Sstevel@tonic-gate void
4643*7c478bd9Sstevel@tonic-gate inflate_set_dictionary(s, d, n)
4644*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4645*7c478bd9Sstevel@tonic-gate const Bytef *d;
4646*7c478bd9Sstevel@tonic-gate uInt  n;
4647*7c478bd9Sstevel@tonic-gate {
4648*7c478bd9Sstevel@tonic-gate 	Assert(s->window + n <= s->end, "set dict");
4649*7c478bd9Sstevel@tonic-gate 	zmemcpy((charf *)s->window, d, n);
4650*7c478bd9Sstevel@tonic-gate 	s->read = s->write = s->window + n;
4651*7c478bd9Sstevel@tonic-gate }
4652*7c478bd9Sstevel@tonic-gate 
4653*7c478bd9Sstevel@tonic-gate /*
4654*7c478bd9Sstevel@tonic-gate  * Returns true if inflate is currently at the end of a block
4655*7c478bd9Sstevel@tonic-gate  * generated by Z_SYNC_FLUSH or Z_FULL_FLUSH.
4656*7c478bd9Sstevel@tonic-gate  * IN assertion: s != Z_NULL
4657*7c478bd9Sstevel@tonic-gate  */
4658*7c478bd9Sstevel@tonic-gate int
4659*7c478bd9Sstevel@tonic-gate inflate_blocks_sync_point(s)
4660*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4661*7c478bd9Sstevel@tonic-gate {
4662*7c478bd9Sstevel@tonic-gate 	return (s->mode == LENS);
4663*7c478bd9Sstevel@tonic-gate }
4664*7c478bd9Sstevel@tonic-gate 
4665*7c478bd9Sstevel@tonic-gate /*
4666*7c478bd9Sstevel@tonic-gate  * This subroutine adds the data at next_in/avail_in to the output history
4667*7c478bd9Sstevel@tonic-gate  * without performing any output.  The output buffer must be "caught up";
4668*7c478bd9Sstevel@tonic-gate  * i.e. no pending output (hence s->read equals s->write), and the state must
4669*7c478bd9Sstevel@tonic-gate  * be BLOCKS (i.e. we should be willing to see the start of a series of
4670*7c478bd9Sstevel@tonic-gate  * BLOCKS).  On exit, the output will also be caught up, and the checksum
4671*7c478bd9Sstevel@tonic-gate  * will have been updated if need be.
4672*7c478bd9Sstevel@tonic-gate  */
4673*7c478bd9Sstevel@tonic-gate int
4674*7c478bd9Sstevel@tonic-gate inflate_addhistory(s, z)
4675*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
4676*7c478bd9Sstevel@tonic-gate z_stream *z;
4677*7c478bd9Sstevel@tonic-gate {
4678*7c478bd9Sstevel@tonic-gate 	uLong b;	/* bit buffer */  /* NOT USED HERE */
4679*7c478bd9Sstevel@tonic-gate 	uInt k;	/* bits in bit buffer */ /* NOT USED HERE */
4680*7c478bd9Sstevel@tonic-gate 	uInt t;	/* temporary storage */
4681*7c478bd9Sstevel@tonic-gate 	Bytef *p;	/* input data pointer */
4682*7c478bd9Sstevel@tonic-gate 	uInt n;	/* bytes available there */
4683*7c478bd9Sstevel@tonic-gate 	Bytef *q;	/* output window write pointer */
4684*7c478bd9Sstevel@tonic-gate 	uInt m;	/* bytes to end of window or read pointer */
4685*7c478bd9Sstevel@tonic-gate 
4686*7c478bd9Sstevel@tonic-gate 	if (s->read != s->write)
4687*7c478bd9Sstevel@tonic-gate 		return (Z_STREAM_ERROR);
4688*7c478bd9Sstevel@tonic-gate 	if (s->mode != TYPE)
4689*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
4690*7c478bd9Sstevel@tonic-gate 
4691*7c478bd9Sstevel@tonic-gate 	/* we're ready to rock */
4692*7c478bd9Sstevel@tonic-gate 	LOAD;
4693*7c478bd9Sstevel@tonic-gate 	/*
4694*7c478bd9Sstevel@tonic-gate 	 * while there is input ready, copy to output buffer, moving
4695*7c478bd9Sstevel@tonic-gate 	 * pointers as needed.
4696*7c478bd9Sstevel@tonic-gate 	 */
4697*7c478bd9Sstevel@tonic-gate 	while (n) {
4698*7c478bd9Sstevel@tonic-gate 		t = n;	/* how many to do */
4699*7c478bd9Sstevel@tonic-gate 		/* is there room until end of buffer? */
4700*7c478bd9Sstevel@tonic-gate 		if (t > m) t = m;
4701*7c478bd9Sstevel@tonic-gate 		/* update check information */
4702*7c478bd9Sstevel@tonic-gate 		if (s->checkfn != Z_NULL)
4703*7c478bd9Sstevel@tonic-gate 			s->check = (*s->checkfn)(s->check, q, t);
4704*7c478bd9Sstevel@tonic-gate 		zmemcpy(q, p, t);
4705*7c478bd9Sstevel@tonic-gate 		q += t;
4706*7c478bd9Sstevel@tonic-gate 		p += t;
4707*7c478bd9Sstevel@tonic-gate 		n -= t;
4708*7c478bd9Sstevel@tonic-gate 		z->total_out += t;
4709*7c478bd9Sstevel@tonic-gate 		s->read = q;	/* drag read pointer forward */
4710*7c478bd9Sstevel@tonic-gate /* WWRAP */	/* expand WWRAP macro by hand to handle s->read */
4711*7c478bd9Sstevel@tonic-gate 		if (q == s->end) {
4712*7c478bd9Sstevel@tonic-gate 			s->read = q = s->window;
4713*7c478bd9Sstevel@tonic-gate 			m = WAVAIL;
4714*7c478bd9Sstevel@tonic-gate 		}
4715*7c478bd9Sstevel@tonic-gate 	}
4716*7c478bd9Sstevel@tonic-gate 	UPDATE;
4717*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
4718*7c478bd9Sstevel@tonic-gate }
4719*7c478bd9Sstevel@tonic-gate 
4720*7c478bd9Sstevel@tonic-gate 
4721*7c478bd9Sstevel@tonic-gate /*
4722*7c478bd9Sstevel@tonic-gate  * At the end of a Deflate-compressed PPP packet, we expect to have seen
4723*7c478bd9Sstevel@tonic-gate  * a `stored' block type value but not the (zero) length bytes.
4724*7c478bd9Sstevel@tonic-gate  */
4725*7c478bd9Sstevel@tonic-gate int
4726*7c478bd9Sstevel@tonic-gate inflate_packet_flush(s)
4727*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *s;
4728*7c478bd9Sstevel@tonic-gate {
4729*7c478bd9Sstevel@tonic-gate 	if (s->mode != LENS)
4730*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
4731*7c478bd9Sstevel@tonic-gate 	s->mode = TYPE;
4732*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
4733*7c478bd9Sstevel@tonic-gate }
4734*7c478bd9Sstevel@tonic-gate /* --- infblock.c */
4735*7c478bd9Sstevel@tonic-gate 
4736*7c478bd9Sstevel@tonic-gate /* +++ inftrees.c */
4737*7c478bd9Sstevel@tonic-gate /*
4738*7c478bd9Sstevel@tonic-gate  * inftrees.c -- generate Huffman trees for efficient decoding
4739*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
4740*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
4741*7c478bd9Sstevel@tonic-gate  */
4742*7c478bd9Sstevel@tonic-gate 
4743*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
4744*7c478bd9Sstevel@tonic-gate /* #include "inftrees.h" */
4745*7c478bd9Sstevel@tonic-gate 
4746*7c478bd9Sstevel@tonic-gate const char inflate_copyright[] =
4747*7c478bd9Sstevel@tonic-gate " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
4748*7c478bd9Sstevel@tonic-gate /*
4749*7c478bd9Sstevel@tonic-gate  * If you use the zlib library in a product, an acknowledgment is
4750*7c478bd9Sstevel@tonic-gate  * welcome in the documentation of your product. If for some reason
4751*7c478bd9Sstevel@tonic-gate  * you cannot include such an acknowledgment, I would appreciate that
4752*7c478bd9Sstevel@tonic-gate  * you keep this copyright string in the executable of your product.
4753*7c478bd9Sstevel@tonic-gate  */
4754*7c478bd9Sstevel@tonic-gate 
4755*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
4756*7c478bd9Sstevel@tonic-gate struct internal_state  {int dummy; };	/* for buggy compilers */
4757*7c478bd9Sstevel@tonic-gate #endif
4758*7c478bd9Sstevel@tonic-gate 
4759*7c478bd9Sstevel@tonic-gate /* simplify the use of the inflate_huft type with some defines */
4760*7c478bd9Sstevel@tonic-gate #define	exop word.what.Exop
4761*7c478bd9Sstevel@tonic-gate #define	bits word.what.Bits
4762*7c478bd9Sstevel@tonic-gate 
4763*7c478bd9Sstevel@tonic-gate 
4764*7c478bd9Sstevel@tonic-gate local int huft_build OF((
4765*7c478bd9Sstevel@tonic-gate 	uIntf *,	/* code lengths in bits */
4766*7c478bd9Sstevel@tonic-gate 	uInt,		/* number of codes */
4767*7c478bd9Sstevel@tonic-gate 	uInt,		/* number of "simple" codes */
4768*7c478bd9Sstevel@tonic-gate 	const uIntf *,	/* list of base values for non-simple codes */
4769*7c478bd9Sstevel@tonic-gate 	const uIntf *,	/* list of extra bits for non-simple codes */
4770*7c478bd9Sstevel@tonic-gate 	inflate_huft * FAR*, /* result: starting table */
4771*7c478bd9Sstevel@tonic-gate 	uIntf *,	/* maximum lookup bits (returns actual) */
4772*7c478bd9Sstevel@tonic-gate 	inflate_huft *hp,	/* space for trees */
4773*7c478bd9Sstevel@tonic-gate 	uInt *hn,	/* hufts used in space */
4774*7c478bd9Sstevel@tonic-gate 	uIntf *v));	/* working area: values in order of bit length */
4775*7c478bd9Sstevel@tonic-gate 
4776*7c478bd9Sstevel@tonic-gate /* Tables for deflate from PKZIP's appnote.txt. */
4777*7c478bd9Sstevel@tonic-gate local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
4778*7c478bd9Sstevel@tonic-gate 	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
4779*7c478bd9Sstevel@tonic-gate 	35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
4780*7c478bd9Sstevel@tonic-gate 	/* see note #13 above about 258 */
4781*7c478bd9Sstevel@tonic-gate local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
4782*7c478bd9Sstevel@tonic-gate 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
4783*7c478bd9Sstevel@tonic-gate 	3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112};
4784*7c478bd9Sstevel@tonic-gate 	/* 112==invalid */
4785*7c478bd9Sstevel@tonic-gate local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
4786*7c478bd9Sstevel@tonic-gate 	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
4787*7c478bd9Sstevel@tonic-gate 	257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
4788*7c478bd9Sstevel@tonic-gate 	8193, 12289, 16385, 24577};
4789*7c478bd9Sstevel@tonic-gate local const uInt cpdext[30] = { /* Extra bits for distance codes */
4790*7c478bd9Sstevel@tonic-gate 	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
4791*7c478bd9Sstevel@tonic-gate 	7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
4792*7c478bd9Sstevel@tonic-gate 	12, 12, 13, 13};
4793*7c478bd9Sstevel@tonic-gate 
4794*7c478bd9Sstevel@tonic-gate /*
4795*7c478bd9Sstevel@tonic-gate  * Huffman code decoding is performed using a multi-level table
4796*7c478bd9Sstevel@tonic-gate  * lookup.  The fastest way to decode is to simply build a lookup
4797*7c478bd9Sstevel@tonic-gate  * table whose size is determined by the longest code.  However, the
4798*7c478bd9Sstevel@tonic-gate  * time it takes to build this table can also be a factor if the data
4799*7c478bd9Sstevel@tonic-gate  * being decoded is not very long.  The most common codes are
4800*7c478bd9Sstevel@tonic-gate  * necessarily the shortest codes, so those codes dominate the
4801*7c478bd9Sstevel@tonic-gate  * decoding time, and hence the speed.  The idea is you can have a
4802*7c478bd9Sstevel@tonic-gate  * shorter table that decodes the shorter, more probable codes, and
4803*7c478bd9Sstevel@tonic-gate  * then point to subsidiary tables for the longer codes.  The time it
4804*7c478bd9Sstevel@tonic-gate  * costs to decode the longer codes is then traded against the time it
4805*7c478bd9Sstevel@tonic-gate  * takes to make longer tables.
4806*7c478bd9Sstevel@tonic-gate  *
4807*7c478bd9Sstevel@tonic-gate  * This results of this trade are in the variables lbits and dbits
4808*7c478bd9Sstevel@tonic-gate  * below.  lbits is the number of bits the first level table for
4809*7c478bd9Sstevel@tonic-gate  * literal/ length codes can decode in one step, and dbits is the same
4810*7c478bd9Sstevel@tonic-gate  * thing for the distance codes.  Subsequent tables are also less than
4811*7c478bd9Sstevel@tonic-gate  * or equal to those sizes.  These values may be adjusted either when
4812*7c478bd9Sstevel@tonic-gate  * all of the codes are shorter than that, in which case the longest
4813*7c478bd9Sstevel@tonic-gate  * code length in bits is used, or when the shortest code is *longer*
4814*7c478bd9Sstevel@tonic-gate  * than the requested table size, in which case the length of the
4815*7c478bd9Sstevel@tonic-gate  * shortest code in bits is used.
4816*7c478bd9Sstevel@tonic-gate  *
4817*7c478bd9Sstevel@tonic-gate  * There are two different values for the two tables, since they code
4818*7c478bd9Sstevel@tonic-gate  * a different number of possibilities each.  The literal/length table
4819*7c478bd9Sstevel@tonic-gate  * codes 286 possible values, or in a flat code, a little over eight
4820*7c478bd9Sstevel@tonic-gate  * bits.  The distance table codes 30 possible values, or a little
4821*7c478bd9Sstevel@tonic-gate  * less than five bits, flat.  The optimum values for speed end up
4822*7c478bd9Sstevel@tonic-gate  * being about one bit more than those, so lbits is 8+1 and dbits is
4823*7c478bd9Sstevel@tonic-gate  * 5+1.  The optimum values may differ though from machine to machine,
4824*7c478bd9Sstevel@tonic-gate  * and possibly even between compilers.  Your mileage may vary.
4825*7c478bd9Sstevel@tonic-gate  */
4826*7c478bd9Sstevel@tonic-gate 
4827*7c478bd9Sstevel@tonic-gate 
4828*7c478bd9Sstevel@tonic-gate /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
4829*7c478bd9Sstevel@tonic-gate #define	BMAX 15		/* maximum bit length of any code */
4830*7c478bd9Sstevel@tonic-gate 
4831*7c478bd9Sstevel@tonic-gate 
4832*7c478bd9Sstevel@tonic-gate local int
4833*7c478bd9Sstevel@tonic-gate huft_build(b, n, s, d, e, t, m, hp, hn, v)
4834*7c478bd9Sstevel@tonic-gate uIntf *b;	/* code lengths in bits (all assumed <= BMAX) */
4835*7c478bd9Sstevel@tonic-gate uInt n;	/* number of codes (assumed <= 288) */
4836*7c478bd9Sstevel@tonic-gate uInt s;	/* number of simple-valued codes (0..s-1) */
4837*7c478bd9Sstevel@tonic-gate const uIntf *d;	/* list of base values for non-simple codes */
4838*7c478bd9Sstevel@tonic-gate const uIntf *e;	/* list of extra bits for non-simple codes */
4839*7c478bd9Sstevel@tonic-gate inflate_huft * FAR *t;	/* result: starting table */
4840*7c478bd9Sstevel@tonic-gate uIntf *m;	/* maximum lookup bits, returns actual */
4841*7c478bd9Sstevel@tonic-gate inflate_huft *hp;	/* space for trees */
4842*7c478bd9Sstevel@tonic-gate uInt *hn;		/* hufts used in space */
4843*7c478bd9Sstevel@tonic-gate uIntf *v;		/* working area: values in order of bit length */
4844*7c478bd9Sstevel@tonic-gate /*
4845*7c478bd9Sstevel@tonic-gate  * Given a list of code lengths and a maximum table size, make a set
4846*7c478bd9Sstevel@tonic-gate  * of tables to decode that set of codes.  Return Z_OK on success,
4847*7c478bd9Sstevel@tonic-gate  * Z_BUF_ERROR if the given code set is incomplete (the tables are
4848*7c478bd9Sstevel@tonic-gate  * still built in this case), Z_DATA_ERROR if the input is invalid (an
4849*7c478bd9Sstevel@tonic-gate  * over-subscribed set of lengths), or Z_MEM_ERROR if not enough
4850*7c478bd9Sstevel@tonic-gate  * memory.
4851*7c478bd9Sstevel@tonic-gate  */
4852*7c478bd9Sstevel@tonic-gate {
4853*7c478bd9Sstevel@tonic-gate 
4854*7c478bd9Sstevel@tonic-gate 	uInt a;	/* counter for codes of length k */
4855*7c478bd9Sstevel@tonic-gate 	uInt c[BMAX+1];	/* bit length count table */
4856*7c478bd9Sstevel@tonic-gate 	uInt f;	/* i repeats in table every f entries */
4857*7c478bd9Sstevel@tonic-gate 	int g;	/* maximum code length */
4858*7c478bd9Sstevel@tonic-gate 	int h;	/* table level */
4859*7c478bd9Sstevel@tonic-gate 	register uInt i;	/* counter, current code */
4860*7c478bd9Sstevel@tonic-gate 	register uInt j;	/* counter */
4861*7c478bd9Sstevel@tonic-gate 	register int k;	/* number of bits in current code */
4862*7c478bd9Sstevel@tonic-gate 	int l;	/* bits per table (returned in m) */
4863*7c478bd9Sstevel@tonic-gate 	register uIntf *p;	/* pointer into c[], b[], or v[] */
4864*7c478bd9Sstevel@tonic-gate 	inflate_huft *q;	/* points to current table */
4865*7c478bd9Sstevel@tonic-gate 	struct inflate_huft_s r; /* table entry for structure assignment */
4866*7c478bd9Sstevel@tonic-gate 	inflate_huft *u[BMAX];	/* table stack */
4867*7c478bd9Sstevel@tonic-gate 	uInt mask;	/* (1 << w) - 1, to avoid cc -O bug on HP */
4868*7c478bd9Sstevel@tonic-gate 	register int w;	/* bits before this table == (l * h) */
4869*7c478bd9Sstevel@tonic-gate 	uInt x[BMAX+1];	/* bit offsets, then code stack */
4870*7c478bd9Sstevel@tonic-gate 	uIntf *xp;	/* pointer into x */
4871*7c478bd9Sstevel@tonic-gate 	int y;	/* number of dummy codes added */
4872*7c478bd9Sstevel@tonic-gate 	uInt z;	/* number of entries in current table */
4873*7c478bd9Sstevel@tonic-gate 
4874*7c478bd9Sstevel@tonic-gate 	(void) inflate_copyright;
4875*7c478bd9Sstevel@tonic-gate 	/* Generate counts for each bit length */
4876*7c478bd9Sstevel@tonic-gate 	p = c;
4877*7c478bd9Sstevel@tonic-gate #define	C0 *p++ = 0;
4878*7c478bd9Sstevel@tonic-gate #define	C2 C0 C0 C0 C0
4879*7c478bd9Sstevel@tonic-gate #define	C4 C2 C2 C2 C2
4880*7c478bd9Sstevel@tonic-gate 	C4	/* clear c[]--assume BMAX+1 is 16 */
4881*7c478bd9Sstevel@tonic-gate 	    p = b;  i = n;
4882*7c478bd9Sstevel@tonic-gate 	do {
4883*7c478bd9Sstevel@tonic-gate 		c[*p++]++;	/* assume all entries <= BMAX */
4884*7c478bd9Sstevel@tonic-gate 	} while (--i);
4885*7c478bd9Sstevel@tonic-gate 	if (c[0] == n)		/* null input--all zero length codes */
4886*7c478bd9Sstevel@tonic-gate 	{
4887*7c478bd9Sstevel@tonic-gate 		*t = (inflate_huft *)Z_NULL;
4888*7c478bd9Sstevel@tonic-gate 		*m = 0;
4889*7c478bd9Sstevel@tonic-gate 		return (Z_OK);
4890*7c478bd9Sstevel@tonic-gate 	}
4891*7c478bd9Sstevel@tonic-gate 
4892*7c478bd9Sstevel@tonic-gate 
4893*7c478bd9Sstevel@tonic-gate 	/* Find minimum and maximum length, bound *m by those */
4894*7c478bd9Sstevel@tonic-gate 	l = *m;
4895*7c478bd9Sstevel@tonic-gate 	for (j = 1; j <= BMAX; j++)
4896*7c478bd9Sstevel@tonic-gate 		if (c[j])
4897*7c478bd9Sstevel@tonic-gate 			break;
4898*7c478bd9Sstevel@tonic-gate 	k = j;	/* minimum code length */
4899*7c478bd9Sstevel@tonic-gate 	if ((uInt)l < j)
4900*7c478bd9Sstevel@tonic-gate 		l = j;
4901*7c478bd9Sstevel@tonic-gate 	for (i = BMAX; i; i--)
4902*7c478bd9Sstevel@tonic-gate 		if (c[i])
4903*7c478bd9Sstevel@tonic-gate 			break;
4904*7c478bd9Sstevel@tonic-gate 	g = i;	/* maximum code length */
4905*7c478bd9Sstevel@tonic-gate 	if ((uInt)l > i)
4906*7c478bd9Sstevel@tonic-gate 		l = i;
4907*7c478bd9Sstevel@tonic-gate 	*m = l;
4908*7c478bd9Sstevel@tonic-gate 
4909*7c478bd9Sstevel@tonic-gate 
4910*7c478bd9Sstevel@tonic-gate 	/* Adjust last length count to fill out codes, if needed */
4911*7c478bd9Sstevel@tonic-gate 	for (y = 1 << j; j < i; j++, y <<= 1)
4912*7c478bd9Sstevel@tonic-gate 		if ((y -= c[j]) < 0)
4913*7c478bd9Sstevel@tonic-gate 			return (Z_DATA_ERROR);
4914*7c478bd9Sstevel@tonic-gate 	if ((y -= c[i]) < 0)
4915*7c478bd9Sstevel@tonic-gate 		return (Z_DATA_ERROR);
4916*7c478bd9Sstevel@tonic-gate 	c[i] += y;
4917*7c478bd9Sstevel@tonic-gate 
4918*7c478bd9Sstevel@tonic-gate 
4919*7c478bd9Sstevel@tonic-gate 	/* Generate starting offsets into the value table for each length */
4920*7c478bd9Sstevel@tonic-gate 	x[1] = j = 0;
4921*7c478bd9Sstevel@tonic-gate 	p = c + 1;  xp = x + 2;
4922*7c478bd9Sstevel@tonic-gate 	while (--i) {		/* note that i == g from above */
4923*7c478bd9Sstevel@tonic-gate 		*xp++ = (j += *p++);
4924*7c478bd9Sstevel@tonic-gate 	}
4925*7c478bd9Sstevel@tonic-gate 
4926*7c478bd9Sstevel@tonic-gate 
4927*7c478bd9Sstevel@tonic-gate 	/* Make a table of values in order of bit lengths */
4928*7c478bd9Sstevel@tonic-gate 	p = b;  i = 0;
4929*7c478bd9Sstevel@tonic-gate 	do {
4930*7c478bd9Sstevel@tonic-gate 		if ((j = *p++) != 0)
4931*7c478bd9Sstevel@tonic-gate 			v[x[j]++] = i;
4932*7c478bd9Sstevel@tonic-gate 	} while (++i < n);
4933*7c478bd9Sstevel@tonic-gate 	n = x[g];	/* set n to length of v */
4934*7c478bd9Sstevel@tonic-gate 
4935*7c478bd9Sstevel@tonic-gate 
4936*7c478bd9Sstevel@tonic-gate 	/* Generate the Huffman codes and for each, make the table entries */
4937*7c478bd9Sstevel@tonic-gate 	x[0] = i = 0;	/* first Huffman code is zero */
4938*7c478bd9Sstevel@tonic-gate 	p = v;	/* grab values in bit order */
4939*7c478bd9Sstevel@tonic-gate 	h = -1;	/* no tables yet--level -1 */
4940*7c478bd9Sstevel@tonic-gate 	w = -l;	/* bits decoded == (l * h) */
4941*7c478bd9Sstevel@tonic-gate 	u[0] = (inflate_huft *)Z_NULL;	/* just to keep compilers happy */
4942*7c478bd9Sstevel@tonic-gate 	q = (inflate_huft *)Z_NULL;	/* ditto */
4943*7c478bd9Sstevel@tonic-gate 	z = 0;	/* ditto */
4944*7c478bd9Sstevel@tonic-gate 
4945*7c478bd9Sstevel@tonic-gate 	/* go through the bit lengths (k already is bits in shortest code) */
4946*7c478bd9Sstevel@tonic-gate 	for (; k <= g; k++) {
4947*7c478bd9Sstevel@tonic-gate 		a = c[k];
4948*7c478bd9Sstevel@tonic-gate 		while (a--) {
4949*7c478bd9Sstevel@tonic-gate 			/*
4950*7c478bd9Sstevel@tonic-gate 			 * here i is the Huffman code of length k bits
4951*7c478bd9Sstevel@tonic-gate 			 * for value *p.  make tables up to required
4952*7c478bd9Sstevel@tonic-gate 			 * level.
4953*7c478bd9Sstevel@tonic-gate 			 */
4954*7c478bd9Sstevel@tonic-gate 			while (k > w + l) {
4955*7c478bd9Sstevel@tonic-gate 				h++;
4956*7c478bd9Sstevel@tonic-gate 				w += l;	/* previous table always l bits */
4957*7c478bd9Sstevel@tonic-gate 
4958*7c478bd9Sstevel@tonic-gate 				/*
4959*7c478bd9Sstevel@tonic-gate 				 * compute minimum size table less
4960*7c478bd9Sstevel@tonic-gate 				 * than or equal to l bits
4961*7c478bd9Sstevel@tonic-gate 				 */
4962*7c478bd9Sstevel@tonic-gate 				z = g - w;
4963*7c478bd9Sstevel@tonic-gate 				/* table size upper limit */
4964*7c478bd9Sstevel@tonic-gate 				z = z > (uInt)l ? l : z;
4965*7c478bd9Sstevel@tonic-gate 				/* try a k-w bit table */
4966*7c478bd9Sstevel@tonic-gate 				if ((f = 1 << (j = k - w)) > a + 1) {
4967*7c478bd9Sstevel@tonic-gate 					/* too few codes for k-w bit table */
4968*7c478bd9Sstevel@tonic-gate 					/* deduct codes from patterns left */
4969*7c478bd9Sstevel@tonic-gate 					f -= a + 1;
4970*7c478bd9Sstevel@tonic-gate 					xp = c + k;
4971*7c478bd9Sstevel@tonic-gate 					if (j < z)
4972*7c478bd9Sstevel@tonic-gate 						/*
4973*7c478bd9Sstevel@tonic-gate 						 * try smaller tables
4974*7c478bd9Sstevel@tonic-gate 						 * up to z bits
4975*7c478bd9Sstevel@tonic-gate 						 */
4976*7c478bd9Sstevel@tonic-gate 						while (++j < z) {
4977*7c478bd9Sstevel@tonic-gate 							/*
4978*7c478bd9Sstevel@tonic-gate 							 * enough
4979*7c478bd9Sstevel@tonic-gate 							 * codes to
4980*7c478bd9Sstevel@tonic-gate 							 * use up j
4981*7c478bd9Sstevel@tonic-gate 							 * bits
4982*7c478bd9Sstevel@tonic-gate 							 */
4983*7c478bd9Sstevel@tonic-gate 							if ((f <<= 1) <= *++xp)
4984*7c478bd9Sstevel@tonic-gate 								break;
4985*7c478bd9Sstevel@tonic-gate 							f -= *xp;
4986*7c478bd9Sstevel@tonic-gate 							/*
4987*7c478bd9Sstevel@tonic-gate 							 * else deduct
4988*7c478bd9Sstevel@tonic-gate 							 * codes from
4989*7c478bd9Sstevel@tonic-gate 							 * patterns
4990*7c478bd9Sstevel@tonic-gate 							 */
4991*7c478bd9Sstevel@tonic-gate 						}
4992*7c478bd9Sstevel@tonic-gate 				}
4993*7c478bd9Sstevel@tonic-gate 				/* table entries for j-bit table */
4994*7c478bd9Sstevel@tonic-gate 				z = 1 << j;
4995*7c478bd9Sstevel@tonic-gate 
4996*7c478bd9Sstevel@tonic-gate 				/* allocate new table */
4997*7c478bd9Sstevel@tonic-gate 				/* (note: doesn't matter for fixed) */
4998*7c478bd9Sstevel@tonic-gate 				/* not enough memory */
4999*7c478bd9Sstevel@tonic-gate 				if (*hn + z > MANY)
5000*7c478bd9Sstevel@tonic-gate 					return (Z_MEM_ERROR);
5001*7c478bd9Sstevel@tonic-gate 				u[h] = q = hp + *hn;
5002*7c478bd9Sstevel@tonic-gate 				*hn += z;
5003*7c478bd9Sstevel@tonic-gate 
5004*7c478bd9Sstevel@tonic-gate 				/* connect to last table, if there is one */
5005*7c478bd9Sstevel@tonic-gate 				if (h) {
5006*7c478bd9Sstevel@tonic-gate 					/* save pattern for backing up */
5007*7c478bd9Sstevel@tonic-gate 					x[h] = i;
5008*7c478bd9Sstevel@tonic-gate 					/* bits to dump before this table */
5009*7c478bd9Sstevel@tonic-gate 					r.bits = (Byte)l;
5010*7c478bd9Sstevel@tonic-gate 					/* bits in this table */
5011*7c478bd9Sstevel@tonic-gate 					r.exop = (Byte)j;
5012*7c478bd9Sstevel@tonic-gate 					j = i >> (w - l);
5013*7c478bd9Sstevel@tonic-gate 					/* offset to this table */
5014*7c478bd9Sstevel@tonic-gate 					r.base = (uInt)(q - u[h-1] - j);
5015*7c478bd9Sstevel@tonic-gate 					/* connect to last table */
5016*7c478bd9Sstevel@tonic-gate 					u[h-1][j] = r;
5017*7c478bd9Sstevel@tonic-gate 				} else
5018*7c478bd9Sstevel@tonic-gate 					/* first table is returned result */
5019*7c478bd9Sstevel@tonic-gate 					*t = q;
5020*7c478bd9Sstevel@tonic-gate 			}
5021*7c478bd9Sstevel@tonic-gate 
5022*7c478bd9Sstevel@tonic-gate 			/* set up table entry in r */
5023*7c478bd9Sstevel@tonic-gate 			r.bits = (Byte)(k - w);
5024*7c478bd9Sstevel@tonic-gate 			if (p >= v + n)
5025*7c478bd9Sstevel@tonic-gate 				/* out of values--invalid code */
5026*7c478bd9Sstevel@tonic-gate 				r.exop = 128 + 64;
5027*7c478bd9Sstevel@tonic-gate 			else if (*p < s)
5028*7c478bd9Sstevel@tonic-gate 			{
5029*7c478bd9Sstevel@tonic-gate 				/* 256 is end-of-block */
5030*7c478bd9Sstevel@tonic-gate 				r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);
5031*7c478bd9Sstevel@tonic-gate 				/* simple code is just the value */
5032*7c478bd9Sstevel@tonic-gate 				r.base = *p++;
5033*7c478bd9Sstevel@tonic-gate 			}
5034*7c478bd9Sstevel@tonic-gate 			else
5035*7c478bd9Sstevel@tonic-gate 			{
5036*7c478bd9Sstevel@tonic-gate 				/* non-simple--look up in lists */
5037*7c478bd9Sstevel@tonic-gate 				r.exop = (Byte)(e[*p - s] + 16 + 64);
5038*7c478bd9Sstevel@tonic-gate 				r.base = d[*p++ - s];
5039*7c478bd9Sstevel@tonic-gate 			}
5040*7c478bd9Sstevel@tonic-gate 
5041*7c478bd9Sstevel@tonic-gate 			/* fill code-like entries with r */
5042*7c478bd9Sstevel@tonic-gate 			f = 1 << (k - w);
5043*7c478bd9Sstevel@tonic-gate 			for (j = i >> w; j < z; j += f)
5044*7c478bd9Sstevel@tonic-gate 				q[j] = r;
5045*7c478bd9Sstevel@tonic-gate 
5046*7c478bd9Sstevel@tonic-gate 			/* backwards increment the k-bit code i */
5047*7c478bd9Sstevel@tonic-gate 			for (j = 1 << (k - 1); i & j; j >>= 1)
5048*7c478bd9Sstevel@tonic-gate 				i ^= j;
5049*7c478bd9Sstevel@tonic-gate 			i ^= j;
5050*7c478bd9Sstevel@tonic-gate 
5051*7c478bd9Sstevel@tonic-gate 			/* backup over finished tables */
5052*7c478bd9Sstevel@tonic-gate 			mask = (1 << w) - 1;	/* needed on HP, cc -O bug */
5053*7c478bd9Sstevel@tonic-gate 			while ((i & mask) != x[h])
5054*7c478bd9Sstevel@tonic-gate 			{
5055*7c478bd9Sstevel@tonic-gate 				h--;	/* don't need to update q */
5056*7c478bd9Sstevel@tonic-gate 				w -= l;
5057*7c478bd9Sstevel@tonic-gate 				mask = (1 << w) - 1;
5058*7c478bd9Sstevel@tonic-gate 			}
5059*7c478bd9Sstevel@tonic-gate 		}
5060*7c478bd9Sstevel@tonic-gate 	}
5061*7c478bd9Sstevel@tonic-gate 
5062*7c478bd9Sstevel@tonic-gate 
5063*7c478bd9Sstevel@tonic-gate 	/* Return Z_BUF_ERROR if we were given an incomplete table */
5064*7c478bd9Sstevel@tonic-gate 	return (y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK);
5065*7c478bd9Sstevel@tonic-gate }
5066*7c478bd9Sstevel@tonic-gate 
5067*7c478bd9Sstevel@tonic-gate 
5068*7c478bd9Sstevel@tonic-gate int
5069*7c478bd9Sstevel@tonic-gate inflate_trees_bits(c, bb, tb, hp, z)
5070*7c478bd9Sstevel@tonic-gate uIntf *c;	/* 19 code lengths */
5071*7c478bd9Sstevel@tonic-gate uIntf *bb;	/* bits tree desired/actual depth */
5072*7c478bd9Sstevel@tonic-gate inflate_huft * FAR *tb;	/* bits tree result */
5073*7c478bd9Sstevel@tonic-gate inflate_huft *hp;	/* space for trees */
5074*7c478bd9Sstevel@tonic-gate z_streamp z;	/* for zfree function */
5075*7c478bd9Sstevel@tonic-gate {
5076*7c478bd9Sstevel@tonic-gate 	int r;
5077*7c478bd9Sstevel@tonic-gate 	uInt hn = 0;		/* hufts used in space */
5078*7c478bd9Sstevel@tonic-gate 	uIntf v[19];		/* work area for huft_build */
5079*7c478bd9Sstevel@tonic-gate 
5080*7c478bd9Sstevel@tonic-gate 	r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb,
5081*7c478bd9Sstevel@tonic-gate 	    hp, &hn, v);
5082*7c478bd9Sstevel@tonic-gate 	if (r == Z_DATA_ERROR)
5083*7c478bd9Sstevel@tonic-gate 		z->msg = "oversubscribed dynamic bit lengths tree";
5084*7c478bd9Sstevel@tonic-gate 	else if (r == Z_BUF_ERROR || *bb == 0)
5085*7c478bd9Sstevel@tonic-gate 	{
5086*7c478bd9Sstevel@tonic-gate 		z->msg = "incomplete dynamic bit lengths tree";
5087*7c478bd9Sstevel@tonic-gate 		r = Z_DATA_ERROR;
5088*7c478bd9Sstevel@tonic-gate 	}
5089*7c478bd9Sstevel@tonic-gate 	return (r);
5090*7c478bd9Sstevel@tonic-gate }
5091*7c478bd9Sstevel@tonic-gate 
5092*7c478bd9Sstevel@tonic-gate 
5093*7c478bd9Sstevel@tonic-gate int
5094*7c478bd9Sstevel@tonic-gate inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
5095*7c478bd9Sstevel@tonic-gate uInt nl;	/* number of literal/length codes */
5096*7c478bd9Sstevel@tonic-gate uInt nd;	/* number of distance codes */
5097*7c478bd9Sstevel@tonic-gate uIntf *c;	/* that many (total) code lengths */
5098*7c478bd9Sstevel@tonic-gate uIntf *bl;	/* literal desired/actual bit depth */
5099*7c478bd9Sstevel@tonic-gate uIntf *bd;	/* distance desired/actual bit depth */
5100*7c478bd9Sstevel@tonic-gate inflate_huft * FAR *tl;	/* literal/length tree result */
5101*7c478bd9Sstevel@tonic-gate inflate_huft * FAR *td;	/* distance tree result */
5102*7c478bd9Sstevel@tonic-gate inflate_huft *hp;	/* space for trees */
5103*7c478bd9Sstevel@tonic-gate z_streamp z;	/* for zfree function */
5104*7c478bd9Sstevel@tonic-gate {
5105*7c478bd9Sstevel@tonic-gate 	int r;
5106*7c478bd9Sstevel@tonic-gate 	uInt hn = 0;		/* hufts used in space */
5107*7c478bd9Sstevel@tonic-gate 	uIntf v[288];		/* work area for huft_build */
5108*7c478bd9Sstevel@tonic-gate 
5109*7c478bd9Sstevel@tonic-gate 	/* build literal/length tree */
5110*7c478bd9Sstevel@tonic-gate 	r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
5111*7c478bd9Sstevel@tonic-gate 	if (r != Z_OK || *bl == 0)
5112*7c478bd9Sstevel@tonic-gate 	{
5113*7c478bd9Sstevel@tonic-gate 		if (r == Z_DATA_ERROR)
5114*7c478bd9Sstevel@tonic-gate 			z->msg = "oversubscribed literal/length tree";
5115*7c478bd9Sstevel@tonic-gate 		else if (r != Z_MEM_ERROR)
5116*7c478bd9Sstevel@tonic-gate 		{
5117*7c478bd9Sstevel@tonic-gate 			z->msg = "incomplete literal/length tree";
5118*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5119*7c478bd9Sstevel@tonic-gate 		}
5120*7c478bd9Sstevel@tonic-gate 		return (r);
5121*7c478bd9Sstevel@tonic-gate 	}
5122*7c478bd9Sstevel@tonic-gate 
5123*7c478bd9Sstevel@tonic-gate 	/* build distance tree */
5124*7c478bd9Sstevel@tonic-gate 	r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
5125*7c478bd9Sstevel@tonic-gate 	if (r != Z_OK || (*bd == 0 && nl > 257))
5126*7c478bd9Sstevel@tonic-gate 	{
5127*7c478bd9Sstevel@tonic-gate 		if (r == Z_DATA_ERROR)
5128*7c478bd9Sstevel@tonic-gate 			z->msg = "oversubscribed distance tree";
5129*7c478bd9Sstevel@tonic-gate 		else if (r == Z_BUF_ERROR) {
5130*7c478bd9Sstevel@tonic-gate #ifdef PKZIP_BUG_WORKAROUND
5131*7c478bd9Sstevel@tonic-gate 			r = Z_OK;
5132*7c478bd9Sstevel@tonic-gate #else
5133*7c478bd9Sstevel@tonic-gate 			z->msg = "incomplete distance tree";
5134*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5135*7c478bd9Sstevel@tonic-gate 		} else if (r != Z_MEM_ERROR) {
5136*7c478bd9Sstevel@tonic-gate 			z->msg = "empty distance tree with lengths";
5137*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5138*7c478bd9Sstevel@tonic-gate #endif
5139*7c478bd9Sstevel@tonic-gate 		}
5140*7c478bd9Sstevel@tonic-gate 		return (r);
5141*7c478bd9Sstevel@tonic-gate 	}
5142*7c478bd9Sstevel@tonic-gate 
5143*7c478bd9Sstevel@tonic-gate /* done */
5144*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
5145*7c478bd9Sstevel@tonic-gate }
5146*7c478bd9Sstevel@tonic-gate 
5147*7c478bd9Sstevel@tonic-gate 
5148*7c478bd9Sstevel@tonic-gate /* build fixed tables only once--keep them here */
5149*7c478bd9Sstevel@tonic-gate /* #define	BUILDFIXED */
5150*7c478bd9Sstevel@tonic-gate #ifdef BUILDFIXED
5151*7c478bd9Sstevel@tonic-gate local int fixed_built = 0;
5152*7c478bd9Sstevel@tonic-gate #define	FIXEDH 544	/* number of hufts used by fixed tables */
5153*7c478bd9Sstevel@tonic-gate local inflate_huft fixed_mem[FIXEDH];
5154*7c478bd9Sstevel@tonic-gate local uInt fixed_bl;
5155*7c478bd9Sstevel@tonic-gate local uInt fixed_bd;
5156*7c478bd9Sstevel@tonic-gate local inflate_huft *fixed_tl;
5157*7c478bd9Sstevel@tonic-gate local inflate_huft *fixed_td;
5158*7c478bd9Sstevel@tonic-gate #else
5159*7c478bd9Sstevel@tonic-gate #include "inffixed.h"
5160*7c478bd9Sstevel@tonic-gate #endif
5161*7c478bd9Sstevel@tonic-gate 
5162*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5163*7c478bd9Sstevel@tonic-gate int
5164*7c478bd9Sstevel@tonic-gate inflate_trees_fixed(bl, bd, tl, td, z)
5165*7c478bd9Sstevel@tonic-gate uIntf *bl;	/* literal desired/actual bit depth */
5166*7c478bd9Sstevel@tonic-gate uIntf *bd;	/* distance desired/actual bit depth */
5167*7c478bd9Sstevel@tonic-gate const inflate_huft * FAR *tl;	/* literal/length tree result */
5168*7c478bd9Sstevel@tonic-gate const inflate_huft * FAR *td;	/* distance tree result */
5169*7c478bd9Sstevel@tonic-gate z_streamp z;	/* for memory allocation */
5170*7c478bd9Sstevel@tonic-gate {
5171*7c478bd9Sstevel@tonic-gate #ifdef BUILDFIXED
5172*7c478bd9Sstevel@tonic-gate 	/*
5173*7c478bd9Sstevel@tonic-gate 	 * build fixed tables if not already (multiple overlapped
5174*7c478bd9Sstevel@tonic-gate 	 * executions ok)
5175*7c478bd9Sstevel@tonic-gate 	 */
5176*7c478bd9Sstevel@tonic-gate 	if (!fixed_built)
5177*7c478bd9Sstevel@tonic-gate 	{
5178*7c478bd9Sstevel@tonic-gate 		int k;	/* temporary variable */
5179*7c478bd9Sstevel@tonic-gate 		uInt f = 0;	/* number of hufts used in fixed_mem */
5180*7c478bd9Sstevel@tonic-gate 		uIntf *c;	/* length list for huft_build */
5181*7c478bd9Sstevel@tonic-gate 		uIntf *v;
5182*7c478bd9Sstevel@tonic-gate 
5183*7c478bd9Sstevel@tonic-gate 		/* allocate memory */
5184*7c478bd9Sstevel@tonic-gate 		if ((c = (uIntf*)ZALLOC(z, 288, sizeof (uInt))) == Z_NULL)
5185*7c478bd9Sstevel@tonic-gate 			return (Z_MEM_ERROR);
5186*7c478bd9Sstevel@tonic-gate 		if ((v = (uIntf*)ZALLOC(z, 288, sizeof (uInt))) == Z_NULL)
5187*7c478bd9Sstevel@tonic-gate 		{
5188*7c478bd9Sstevel@tonic-gate 			ZFREE(z, c);
5189*7c478bd9Sstevel@tonic-gate 			return (Z_MEM_ERROR);
5190*7c478bd9Sstevel@tonic-gate 		}
5191*7c478bd9Sstevel@tonic-gate 		/* literal table */
5192*7c478bd9Sstevel@tonic-gate 		for (k = 0; k < 144; k++)
5193*7c478bd9Sstevel@tonic-gate 			c[k] = 8;
5194*7c478bd9Sstevel@tonic-gate 		for (; k < 256; k++)
5195*7c478bd9Sstevel@tonic-gate 			c[k] = 9;
5196*7c478bd9Sstevel@tonic-gate 		for (; k < 280; k++)
5197*7c478bd9Sstevel@tonic-gate 			c[k] = 7;
5198*7c478bd9Sstevel@tonic-gate 		for (; k < 288; k++)
5199*7c478bd9Sstevel@tonic-gate 			c[k] = 8;
5200*7c478bd9Sstevel@tonic-gate 		fixed_bl = 9;
5201*7c478bd9Sstevel@tonic-gate 		(void) huft_build(c, 288, 257, cplens, cplext, &fixed_tl,
5202*7c478bd9Sstevel@tonic-gate 		    &fixed_bl, fixed_mem, &f, v);
5203*7c478bd9Sstevel@tonic-gate 
5204*7c478bd9Sstevel@tonic-gate 		/* distance table */
5205*7c478bd9Sstevel@tonic-gate 		for (k = 0; k < 30; k++)
5206*7c478bd9Sstevel@tonic-gate 			c[k] = 5;
5207*7c478bd9Sstevel@tonic-gate 		fixed_bd = 5;
5208*7c478bd9Sstevel@tonic-gate 		(void) huft_build(c, 30, 0, cpdist, cpdext, &fixed_td,
5209*7c478bd9Sstevel@tonic-gate 		    &fixed_bd, fixed_mem, &f, v);
5210*7c478bd9Sstevel@tonic-gate 
5211*7c478bd9Sstevel@tonic-gate 		/* done */
5212*7c478bd9Sstevel@tonic-gate 		ZFREE(z, v);
5213*7c478bd9Sstevel@tonic-gate 		ZFREE(z, c);
5214*7c478bd9Sstevel@tonic-gate 		fixed_built = 1;
5215*7c478bd9Sstevel@tonic-gate 	}
5216*7c478bd9Sstevel@tonic-gate #endif
5217*7c478bd9Sstevel@tonic-gate 	*bl = fixed_bl;
5218*7c478bd9Sstevel@tonic-gate 	*bd = fixed_bd;
5219*7c478bd9Sstevel@tonic-gate 	*tl = fixed_tl;
5220*7c478bd9Sstevel@tonic-gate 	*td = fixed_td;
5221*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
5222*7c478bd9Sstevel@tonic-gate }
5223*7c478bd9Sstevel@tonic-gate /* --- inftrees.c */
5224*7c478bd9Sstevel@tonic-gate 
5225*7c478bd9Sstevel@tonic-gate /* +++ infcodes.c */
5226*7c478bd9Sstevel@tonic-gate /*
5227*7c478bd9Sstevel@tonic-gate  * infcodes.c -- process literals and length/distance pairs
5228*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
5229*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
5230*7c478bd9Sstevel@tonic-gate  */
5231*7c478bd9Sstevel@tonic-gate 
5232*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
5233*7c478bd9Sstevel@tonic-gate /* #include "inftrees.h" */
5234*7c478bd9Sstevel@tonic-gate /* #include "infblock.h" */
5235*7c478bd9Sstevel@tonic-gate /* #include "infcodes.h" */
5236*7c478bd9Sstevel@tonic-gate /* #include "infutil.h" */
5237*7c478bd9Sstevel@tonic-gate 
5238*7c478bd9Sstevel@tonic-gate /* +++ inffast.h */
5239*7c478bd9Sstevel@tonic-gate /*
5240*7c478bd9Sstevel@tonic-gate  * inffast.h -- header to use inffast.c
5241*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
5242*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
5243*7c478bd9Sstevel@tonic-gate  */
5244*7c478bd9Sstevel@tonic-gate 
5245*7c478bd9Sstevel@tonic-gate /*
5246*7c478bd9Sstevel@tonic-gate  * WARNING: this file should *not* be used by applications. It is part
5247*7c478bd9Sstevel@tonic-gate  * of the implementation of the compression library and is subject to
5248*7c478bd9Sstevel@tonic-gate  * change. Applications should only use zlib.h.
5249*7c478bd9Sstevel@tonic-gate  */
5250*7c478bd9Sstevel@tonic-gate 
5251*7c478bd9Sstevel@tonic-gate extern int inflate_fast OF((
5252*7c478bd9Sstevel@tonic-gate     uInt,
5253*7c478bd9Sstevel@tonic-gate     uInt,
5254*7c478bd9Sstevel@tonic-gate     const inflate_huft *,
5255*7c478bd9Sstevel@tonic-gate     const inflate_huft *,
5256*7c478bd9Sstevel@tonic-gate     inflate_blocks_statef *,
5257*7c478bd9Sstevel@tonic-gate     z_streamp));
5258*7c478bd9Sstevel@tonic-gate /* --- inffast.h */
5259*7c478bd9Sstevel@tonic-gate 
5260*7c478bd9Sstevel@tonic-gate /* simplify the use of the inflate_huft type with some defines */
5261*7c478bd9Sstevel@tonic-gate #define	exop word.what.Exop
5262*7c478bd9Sstevel@tonic-gate #define	bits word.what.Bits
5263*7c478bd9Sstevel@tonic-gate 
5264*7c478bd9Sstevel@tonic-gate /* inflate codes private state */
5265*7c478bd9Sstevel@tonic-gate struct inflate_codes_state {
5266*7c478bd9Sstevel@tonic-gate 
5267*7c478bd9Sstevel@tonic-gate 	/* mode */
5268*7c478bd9Sstevel@tonic-gate 	enum {	/* waiting for "i:"=input, "o:"=output, "x:"=nothing */
5269*7c478bd9Sstevel@tonic-gate 		START,	/* x: set up for LEN */
5270*7c478bd9Sstevel@tonic-gate 		LEN,	/* i: get length/literal/eob next */
5271*7c478bd9Sstevel@tonic-gate 		LENEXT,	/* i: getting length extra (have base) */
5272*7c478bd9Sstevel@tonic-gate 		DIST,	/* i: get distance next */
5273*7c478bd9Sstevel@tonic-gate 		DISTEXT,	/* i: getting distance extra */
5274*7c478bd9Sstevel@tonic-gate 		COPY,	/* o: copying bytes in window, waiting for space */
5275*7c478bd9Sstevel@tonic-gate 		LIT,	/* o: got literal, waiting for output space */
5276*7c478bd9Sstevel@tonic-gate 		WASH,	/* o: got eob, possibly still output waiting */
5277*7c478bd9Sstevel@tonic-gate 		END,	/* x: got eob and all data flushed */
5278*7c478bd9Sstevel@tonic-gate 		BADCODE}	/* x: got error */
5279*7c478bd9Sstevel@tonic-gate 	mode;	/* current inflate_codes mode */
5280*7c478bd9Sstevel@tonic-gate 
5281*7c478bd9Sstevel@tonic-gate 	/* mode dependent information */
5282*7c478bd9Sstevel@tonic-gate 	uInt len;
5283*7c478bd9Sstevel@tonic-gate 	union {
5284*7c478bd9Sstevel@tonic-gate 		struct {
5285*7c478bd9Sstevel@tonic-gate 			const inflate_huft *tree;	/* pointer into tree */
5286*7c478bd9Sstevel@tonic-gate 			uInt need;	/* bits needed */
5287*7c478bd9Sstevel@tonic-gate 		} code;	/* if LEN or DIST, where in tree */
5288*7c478bd9Sstevel@tonic-gate 		uInt lit;	/* if LIT, literal */
5289*7c478bd9Sstevel@tonic-gate 		struct {
5290*7c478bd9Sstevel@tonic-gate 			uInt get;	/* bits to get for extra */
5291*7c478bd9Sstevel@tonic-gate 			uInt dist;	/* distance back to copy from */
5292*7c478bd9Sstevel@tonic-gate 		} copy;	/* if EXT or COPY, where and how much */
5293*7c478bd9Sstevel@tonic-gate 	} sub;	/* submode */
5294*7c478bd9Sstevel@tonic-gate 
5295*7c478bd9Sstevel@tonic-gate 	/* mode independent information */
5296*7c478bd9Sstevel@tonic-gate 	Byte lbits;	/* ltree bits decoded per branch */
5297*7c478bd9Sstevel@tonic-gate 	Byte dbits;	/* dtree bits decoder per branch */
5298*7c478bd9Sstevel@tonic-gate 	const inflate_huft *ltree;	/* literal/length/eob tree */
5299*7c478bd9Sstevel@tonic-gate 	const inflate_huft *dtree;	/* distance tree */
5300*7c478bd9Sstevel@tonic-gate 
5301*7c478bd9Sstevel@tonic-gate };
5302*7c478bd9Sstevel@tonic-gate 
5303*7c478bd9Sstevel@tonic-gate 
5304*7c478bd9Sstevel@tonic-gate inflate_codes_statef *
5305*7c478bd9Sstevel@tonic-gate inflate_codes_new(bl, bd, tl, td, z)
5306*7c478bd9Sstevel@tonic-gate uInt bl, bd;
5307*7c478bd9Sstevel@tonic-gate const inflate_huft *tl;
5308*7c478bd9Sstevel@tonic-gate const inflate_huft *td;	/* need separate declaration for Borland C++ */
5309*7c478bd9Sstevel@tonic-gate z_streamp z;
5310*7c478bd9Sstevel@tonic-gate {
5311*7c478bd9Sstevel@tonic-gate 	inflate_codes_statef *c;
5312*7c478bd9Sstevel@tonic-gate 
5313*7c478bd9Sstevel@tonic-gate 	if ((c = (inflate_codes_statef *)
5314*7c478bd9Sstevel@tonic-gate 	    ZALLOC(z, 1, sizeof (struct inflate_codes_state))) != Z_NULL)
5315*7c478bd9Sstevel@tonic-gate 	{
5316*7c478bd9Sstevel@tonic-gate 		c->mode = START;
5317*7c478bd9Sstevel@tonic-gate 		c->lbits = (Byte)bl;
5318*7c478bd9Sstevel@tonic-gate 		c->dbits = (Byte)bd;
5319*7c478bd9Sstevel@tonic-gate 		c->ltree = tl;
5320*7c478bd9Sstevel@tonic-gate 		c->dtree = td;
5321*7c478bd9Sstevel@tonic-gate 		Tracev((stderr, "inflate:       codes new\n"));
5322*7c478bd9Sstevel@tonic-gate 	}
5323*7c478bd9Sstevel@tonic-gate 	return (c);
5324*7c478bd9Sstevel@tonic-gate }
5325*7c478bd9Sstevel@tonic-gate 
5326*7c478bd9Sstevel@tonic-gate 
5327*7c478bd9Sstevel@tonic-gate int
5328*7c478bd9Sstevel@tonic-gate inflate_codes(s, z, r)
5329*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
5330*7c478bd9Sstevel@tonic-gate z_streamp z;
5331*7c478bd9Sstevel@tonic-gate int r;
5332*7c478bd9Sstevel@tonic-gate {
5333*7c478bd9Sstevel@tonic-gate 	uInt j;	/* temporary storage */
5334*7c478bd9Sstevel@tonic-gate 	const inflate_huft *t;	/* temporary pointer */
5335*7c478bd9Sstevel@tonic-gate 	uInt e;	/* extra bits or operation */
5336*7c478bd9Sstevel@tonic-gate 	uLong b;	/* bit buffer */
5337*7c478bd9Sstevel@tonic-gate 	uInt k;	/* bits in bit buffer */
5338*7c478bd9Sstevel@tonic-gate 	Bytef *p;	/* input data pointer */
5339*7c478bd9Sstevel@tonic-gate 	uInt n;	/* bytes available there */
5340*7c478bd9Sstevel@tonic-gate 	Bytef *q;	/* output window write pointer */
5341*7c478bd9Sstevel@tonic-gate 	uInt m;	/* bytes to end of window or read pointer */
5342*7c478bd9Sstevel@tonic-gate 	Bytef *f;	/* pointer to copy strings from */
5343*7c478bd9Sstevel@tonic-gate 	inflate_codes_statef *c = s->sub.decode.codes;	/* codes state */
5344*7c478bd9Sstevel@tonic-gate 
5345*7c478bd9Sstevel@tonic-gate 	/* copy input/output information to locals (UPDATE macro restores) */
5346*7c478bd9Sstevel@tonic-gate 	LOAD;
5347*7c478bd9Sstevel@tonic-gate 
5348*7c478bd9Sstevel@tonic-gate 	/* process input and output based on current state */
5349*7c478bd9Sstevel@tonic-gate 	/* CONSTCOND */
5350*7c478bd9Sstevel@tonic-gate 	while (1)
5351*7c478bd9Sstevel@tonic-gate 		/* waiting for "i:"=input, "o:"=output, "x:"=nothing */
5352*7c478bd9Sstevel@tonic-gate 		switch (c->mode) {
5353*7c478bd9Sstevel@tonic-gate 		case START:	/* x: set up for LEN */
5354*7c478bd9Sstevel@tonic-gate #ifndef SLOW
5355*7c478bd9Sstevel@tonic-gate 			if (m >= 258 && n >= 10)
5356*7c478bd9Sstevel@tonic-gate 			{
5357*7c478bd9Sstevel@tonic-gate 				UPDATE;
5358*7c478bd9Sstevel@tonic-gate 				r = inflate_fast(c->lbits, c->dbits,
5359*7c478bd9Sstevel@tonic-gate 				    c->ltree, c->dtree, s, z);
5360*7c478bd9Sstevel@tonic-gate 				LOAD;
5361*7c478bd9Sstevel@tonic-gate 				if (r != Z_OK) {
5362*7c478bd9Sstevel@tonic-gate 					c->mode = r == Z_STREAM_END ?
5363*7c478bd9Sstevel@tonic-gate 					    WASH : BADCODE;
5364*7c478bd9Sstevel@tonic-gate 					break;
5365*7c478bd9Sstevel@tonic-gate 				}
5366*7c478bd9Sstevel@tonic-gate 			}
5367*7c478bd9Sstevel@tonic-gate #endif /* !SLOW */
5368*7c478bd9Sstevel@tonic-gate 			c->sub.code.need = c->lbits;
5369*7c478bd9Sstevel@tonic-gate 			c->sub.code.tree = c->ltree;
5370*7c478bd9Sstevel@tonic-gate 			c->mode = LEN;
5371*7c478bd9Sstevel@tonic-gate 			/* FALLTHRU */
5372*7c478bd9Sstevel@tonic-gate 		case LEN:	/* i: get length/literal/eob next */
5373*7c478bd9Sstevel@tonic-gate 			j = c->sub.code.need;
5374*7c478bd9Sstevel@tonic-gate 			NEEDBITS(j);
5375*7c478bd9Sstevel@tonic-gate 			t = c->sub.code.tree +
5376*7c478bd9Sstevel@tonic-gate 			    ((uInt)b & inflate_mask[j]);
5377*7c478bd9Sstevel@tonic-gate 			DUMPBITS(t->bits);
5378*7c478bd9Sstevel@tonic-gate 			e = (uInt)(t->exop);
5379*7c478bd9Sstevel@tonic-gate 			if (e == 0) {	/* literal */
5380*7c478bd9Sstevel@tonic-gate 				c->sub.lit = t->base;
5381*7c478bd9Sstevel@tonic-gate 				Tracevv((stderr, t->base >= 0x20 &&
5382*7c478bd9Sstevel@tonic-gate 				    t->base < 0x7f ?
5383*7c478bd9Sstevel@tonic-gate 				    "inflate:         literal '%c'\n" :
5384*7c478bd9Sstevel@tonic-gate 				    "inflate:         literal 0x%02x\n",
5385*7c478bd9Sstevel@tonic-gate 				    t->base));
5386*7c478bd9Sstevel@tonic-gate 				c->mode = LIT;
5387*7c478bd9Sstevel@tonic-gate 				break;
5388*7c478bd9Sstevel@tonic-gate 			}
5389*7c478bd9Sstevel@tonic-gate 			if (e & 16) {	/* length */
5390*7c478bd9Sstevel@tonic-gate 				c->sub.copy.get = e & 15;
5391*7c478bd9Sstevel@tonic-gate 				c->len = t->base;
5392*7c478bd9Sstevel@tonic-gate 				c->mode = LENEXT;
5393*7c478bd9Sstevel@tonic-gate 				break;
5394*7c478bd9Sstevel@tonic-gate 			}
5395*7c478bd9Sstevel@tonic-gate 			if ((e & 64) == 0) {	/* next table */
5396*7c478bd9Sstevel@tonic-gate 				c->sub.code.need = e;
5397*7c478bd9Sstevel@tonic-gate 				c->sub.code.tree = t + t->base;
5398*7c478bd9Sstevel@tonic-gate 				break;
5399*7c478bd9Sstevel@tonic-gate 			}
5400*7c478bd9Sstevel@tonic-gate 			if (e & 32) {	/* end of block */
5401*7c478bd9Sstevel@tonic-gate 				Tracevv((stderr,
5402*7c478bd9Sstevel@tonic-gate 				    "inflate:         end of block\n"));
5403*7c478bd9Sstevel@tonic-gate 				c->mode = WASH;
5404*7c478bd9Sstevel@tonic-gate 				break;
5405*7c478bd9Sstevel@tonic-gate 			}
5406*7c478bd9Sstevel@tonic-gate 			c->mode = BADCODE;	/* invalid code */
5407*7c478bd9Sstevel@tonic-gate 			z->msg = "invalid literal/length code";
5408*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5409*7c478bd9Sstevel@tonic-gate 			LEAVE
5410*7c478bd9Sstevel@tonic-gate 		case LENEXT:	/* i: getting length extra (have base) */
5411*7c478bd9Sstevel@tonic-gate 			j = c->sub.copy.get;
5412*7c478bd9Sstevel@tonic-gate 			NEEDBITS(j);
5413*7c478bd9Sstevel@tonic-gate 			c->len += (uInt)b & inflate_mask[j];
5414*7c478bd9Sstevel@tonic-gate 			DUMPBITS(j);
5415*7c478bd9Sstevel@tonic-gate 			c->sub.code.need = c->dbits;
5416*7c478bd9Sstevel@tonic-gate 			c->sub.code.tree = c->dtree;
5417*7c478bd9Sstevel@tonic-gate 			Tracevv((stderr,
5418*7c478bd9Sstevel@tonic-gate 			    "inflate:         length %u\n", c->len));
5419*7c478bd9Sstevel@tonic-gate 			c->mode = DIST;
5420*7c478bd9Sstevel@tonic-gate 			/* FALLTHRU */
5421*7c478bd9Sstevel@tonic-gate 		case DIST:	/* i: get distance next */
5422*7c478bd9Sstevel@tonic-gate 			j = c->sub.code.need;
5423*7c478bd9Sstevel@tonic-gate 			NEEDBITS(j);
5424*7c478bd9Sstevel@tonic-gate 			t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
5425*7c478bd9Sstevel@tonic-gate 			DUMPBITS(t->bits);
5426*7c478bd9Sstevel@tonic-gate 			e = (uInt)(t->exop);
5427*7c478bd9Sstevel@tonic-gate 			if (e & 16) {	/* distance */
5428*7c478bd9Sstevel@tonic-gate 				c->sub.copy.get = e & 15;
5429*7c478bd9Sstevel@tonic-gate 				c->sub.copy.dist = t->base;
5430*7c478bd9Sstevel@tonic-gate 				c->mode = DISTEXT;
5431*7c478bd9Sstevel@tonic-gate 				break;
5432*7c478bd9Sstevel@tonic-gate 			}
5433*7c478bd9Sstevel@tonic-gate 			if ((e & 64) == 0) {	/* next table */
5434*7c478bd9Sstevel@tonic-gate 				c->sub.code.need = e;
5435*7c478bd9Sstevel@tonic-gate 				c->sub.code.tree = t + t->base;
5436*7c478bd9Sstevel@tonic-gate 				break;
5437*7c478bd9Sstevel@tonic-gate 			}
5438*7c478bd9Sstevel@tonic-gate 			c->mode = BADCODE;	/* invalid code */
5439*7c478bd9Sstevel@tonic-gate 			z->msg = "invalid distance code";
5440*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5441*7c478bd9Sstevel@tonic-gate 			LEAVE
5442*7c478bd9Sstevel@tonic-gate 		case DISTEXT:	/* i: getting distance extra */
5443*7c478bd9Sstevel@tonic-gate 			j = c->sub.copy.get;
5444*7c478bd9Sstevel@tonic-gate 			NEEDBITS(j);
5445*7c478bd9Sstevel@tonic-gate 			c->sub.copy.dist += (uInt)b & inflate_mask[j];
5446*7c478bd9Sstevel@tonic-gate 			DUMPBITS(j);
5447*7c478bd9Sstevel@tonic-gate 			Tracevv((stderr,
5448*7c478bd9Sstevel@tonic-gate 			    "inflate:         distance %u\n",
5449*7c478bd9Sstevel@tonic-gate 			    c->sub.copy.dist));
5450*7c478bd9Sstevel@tonic-gate 			c->mode = COPY;
5451*7c478bd9Sstevel@tonic-gate 			/* FALLTHRU */
5452*7c478bd9Sstevel@tonic-gate 		case COPY:
5453*7c478bd9Sstevel@tonic-gate 			/* o: copying bytes in window, waiting for space */
5454*7c478bd9Sstevel@tonic-gate #ifndef __TURBOC__ /* Turbo C bug for following expression */
5455*7c478bd9Sstevel@tonic-gate 			f = (uInt)(q - s->window) < c->sub.copy.dist ?
5456*7c478bd9Sstevel@tonic-gate 			    s->end - (c->sub.copy.dist - (q - s->window)) :
5457*7c478bd9Sstevel@tonic-gate 				q - c->sub.copy.dist;
5458*7c478bd9Sstevel@tonic-gate #else
5459*7c478bd9Sstevel@tonic-gate 			f = q - c->sub.copy.dist;
5460*7c478bd9Sstevel@tonic-gate 			if ((uInt)(q - s->window) < c->sub.copy.dist)
5461*7c478bd9Sstevel@tonic-gate 				f = s->end - (c->sub.copy.dist -
5462*7c478bd9Sstevel@tonic-gate 				    (uInt)(q - s->window));
5463*7c478bd9Sstevel@tonic-gate #endif
5464*7c478bd9Sstevel@tonic-gate 			while (c->len)
5465*7c478bd9Sstevel@tonic-gate 			{
5466*7c478bd9Sstevel@tonic-gate 				NEEDOUT;
5467*7c478bd9Sstevel@tonic-gate 				OUTBYTE(*f++);
5468*7c478bd9Sstevel@tonic-gate 				if (f == s->end)
5469*7c478bd9Sstevel@tonic-gate 					f = s->window;
5470*7c478bd9Sstevel@tonic-gate 				c->len--;
5471*7c478bd9Sstevel@tonic-gate 			}
5472*7c478bd9Sstevel@tonic-gate 			c->mode = START;
5473*7c478bd9Sstevel@tonic-gate 			break;
5474*7c478bd9Sstevel@tonic-gate 		case LIT:	/* o: got literal, waiting for output space */
5475*7c478bd9Sstevel@tonic-gate 			NEEDOUT;
5476*7c478bd9Sstevel@tonic-gate 			OUTBYTE(c->sub.lit);
5477*7c478bd9Sstevel@tonic-gate 			c->mode = START;
5478*7c478bd9Sstevel@tonic-gate 			break;
5479*7c478bd9Sstevel@tonic-gate 		case WASH:	/* o: got eob, possibly more output */
5480*7c478bd9Sstevel@tonic-gate 			if (k > 7) {	/* return unused byte, if any */
5481*7c478bd9Sstevel@tonic-gate 				Assert(k < 16,
5482*7c478bd9Sstevel@tonic-gate 				    "inflate_codes grabbed too many bytes");
5483*7c478bd9Sstevel@tonic-gate 				k -= 8;
5484*7c478bd9Sstevel@tonic-gate 				n++;
5485*7c478bd9Sstevel@tonic-gate 				p--;	/* can always return one */
5486*7c478bd9Sstevel@tonic-gate 			}
5487*7c478bd9Sstevel@tonic-gate 			FLUSH;
5488*7c478bd9Sstevel@tonic-gate 			if (s->read != s->write)
5489*7c478bd9Sstevel@tonic-gate 				LEAVE
5490*7c478bd9Sstevel@tonic-gate 			c->mode = END;
5491*7c478bd9Sstevel@tonic-gate 			/* FALLTHRU */
5492*7c478bd9Sstevel@tonic-gate 		case END:
5493*7c478bd9Sstevel@tonic-gate 			r = Z_STREAM_END;
5494*7c478bd9Sstevel@tonic-gate 			LEAVE
5495*7c478bd9Sstevel@tonic-gate 		case BADCODE:	/* x: got error */
5496*7c478bd9Sstevel@tonic-gate 			r = Z_DATA_ERROR;
5497*7c478bd9Sstevel@tonic-gate 			LEAVE
5498*7c478bd9Sstevel@tonic-gate 		default:
5499*7c478bd9Sstevel@tonic-gate 			r = Z_STREAM_ERROR;
5500*7c478bd9Sstevel@tonic-gate 			LEAVE
5501*7c478bd9Sstevel@tonic-gate 		}
5502*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
5503*7c478bd9Sstevel@tonic-gate 	/* otherwise lint complains */
5504*7c478bd9Sstevel@tonic-gate }
5505*7c478bd9Sstevel@tonic-gate 
5506*7c478bd9Sstevel@tonic-gate 
5507*7c478bd9Sstevel@tonic-gate void
5508*7c478bd9Sstevel@tonic-gate inflate_codes_free(c, z)
5509*7c478bd9Sstevel@tonic-gate inflate_codes_statef *c;
5510*7c478bd9Sstevel@tonic-gate z_streamp z;
5511*7c478bd9Sstevel@tonic-gate {
5512*7c478bd9Sstevel@tonic-gate 	ZFREE(z, c);
5513*7c478bd9Sstevel@tonic-gate 	Tracev((stderr, "inflate:       codes free\n"));
5514*7c478bd9Sstevel@tonic-gate }
5515*7c478bd9Sstevel@tonic-gate /* --- infcodes.c */
5516*7c478bd9Sstevel@tonic-gate 
5517*7c478bd9Sstevel@tonic-gate /* +++ infutil.c */
5518*7c478bd9Sstevel@tonic-gate /*
5519*7c478bd9Sstevel@tonic-gate  * inflate_util.c -- data and routines common to blocks and codes
5520*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
5521*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
5522*7c478bd9Sstevel@tonic-gate  */
5523*7c478bd9Sstevel@tonic-gate 
5524*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
5525*7c478bd9Sstevel@tonic-gate /* #include "infblock.h" */
5526*7c478bd9Sstevel@tonic-gate /* #include "inftrees.h" */
5527*7c478bd9Sstevel@tonic-gate /* #include "infcodes.h" */
5528*7c478bd9Sstevel@tonic-gate /* #include "infutil.h" */
5529*7c478bd9Sstevel@tonic-gate 
5530*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
5531*7c478bd9Sstevel@tonic-gate struct inflate_codes_state {int dummy; };	/* for buggy compilers */
5532*7c478bd9Sstevel@tonic-gate #endif
5533*7c478bd9Sstevel@tonic-gate 
5534*7c478bd9Sstevel@tonic-gate /* And'ing with mask[n] masks the lower n bits */
5535*7c478bd9Sstevel@tonic-gate uInt inflate_mask[17] = {
5536*7c478bd9Sstevel@tonic-gate 	0x0000,
5537*7c478bd9Sstevel@tonic-gate 	0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
5538*7c478bd9Sstevel@tonic-gate 	0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
5539*7c478bd9Sstevel@tonic-gate };
5540*7c478bd9Sstevel@tonic-gate 
5541*7c478bd9Sstevel@tonic-gate 
5542*7c478bd9Sstevel@tonic-gate /* copy as much as possible from the sliding window to the output area */
5543*7c478bd9Sstevel@tonic-gate int
5544*7c478bd9Sstevel@tonic-gate inflate_flush(s, z, r)
5545*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
5546*7c478bd9Sstevel@tonic-gate z_streamp z;
5547*7c478bd9Sstevel@tonic-gate int r;
5548*7c478bd9Sstevel@tonic-gate {
5549*7c478bd9Sstevel@tonic-gate 	uInt n;
5550*7c478bd9Sstevel@tonic-gate 	Bytef *p;
5551*7c478bd9Sstevel@tonic-gate 	Bytef *q;
5552*7c478bd9Sstevel@tonic-gate 
5553*7c478bd9Sstevel@tonic-gate 	/* local copies of source and destination pointers */
5554*7c478bd9Sstevel@tonic-gate 	p = z->next_out;
5555*7c478bd9Sstevel@tonic-gate 	q = s->read;
5556*7c478bd9Sstevel@tonic-gate 
5557*7c478bd9Sstevel@tonic-gate 	/* compute number of bytes to copy as far as end of window */
5558*7c478bd9Sstevel@tonic-gate 	n = (uInt)((q <= s->write ? s->write : s->end) - q);
5559*7c478bd9Sstevel@tonic-gate 	if (n > z->avail_out) n = z->avail_out;
5560*7c478bd9Sstevel@tonic-gate 	if (n && r == Z_BUF_ERROR) r = Z_OK;
5561*7c478bd9Sstevel@tonic-gate 
5562*7c478bd9Sstevel@tonic-gate 	/* update counters */
5563*7c478bd9Sstevel@tonic-gate 	z->avail_out -= n;
5564*7c478bd9Sstevel@tonic-gate 	z->total_out += n;
5565*7c478bd9Sstevel@tonic-gate 
5566*7c478bd9Sstevel@tonic-gate 	/* update check information */
5567*7c478bd9Sstevel@tonic-gate 	if (s->checkfn != Z_NULL)
5568*7c478bd9Sstevel@tonic-gate 		z->adler = s->check = (*s->checkfn)(s->check, q, n);
5569*7c478bd9Sstevel@tonic-gate 
5570*7c478bd9Sstevel@tonic-gate 	/* copy as far as end of window */
5571*7c478bd9Sstevel@tonic-gate 	if (p != Z_NULL) {	/* PPP */
5572*7c478bd9Sstevel@tonic-gate 		zmemcpy(p, q, n);
5573*7c478bd9Sstevel@tonic-gate 		p += n;
5574*7c478bd9Sstevel@tonic-gate 	}	/* PPP */
5575*7c478bd9Sstevel@tonic-gate 	q += n;
5576*7c478bd9Sstevel@tonic-gate 
5577*7c478bd9Sstevel@tonic-gate 	/* see if more to copy at beginning of window */
5578*7c478bd9Sstevel@tonic-gate 	if (q == s->end)
5579*7c478bd9Sstevel@tonic-gate 	{
5580*7c478bd9Sstevel@tonic-gate 		/* wrap pointers */
5581*7c478bd9Sstevel@tonic-gate 		q = s->window;
5582*7c478bd9Sstevel@tonic-gate 		if (s->write == s->end)
5583*7c478bd9Sstevel@tonic-gate 			s->write = s->window;
5584*7c478bd9Sstevel@tonic-gate 
5585*7c478bd9Sstevel@tonic-gate 		/* compute bytes to copy */
5586*7c478bd9Sstevel@tonic-gate 		n = (uInt)(s->write - q);
5587*7c478bd9Sstevel@tonic-gate 		if (n > z->avail_out) n = z->avail_out;
5588*7c478bd9Sstevel@tonic-gate 		if (n && r == Z_BUF_ERROR) r = Z_OK;
5589*7c478bd9Sstevel@tonic-gate 
5590*7c478bd9Sstevel@tonic-gate 		/* update counters */
5591*7c478bd9Sstevel@tonic-gate 		z->avail_out -= n;
5592*7c478bd9Sstevel@tonic-gate 		z->total_out += n;
5593*7c478bd9Sstevel@tonic-gate 
5594*7c478bd9Sstevel@tonic-gate 		/* update check information */
5595*7c478bd9Sstevel@tonic-gate 		if (s->checkfn != Z_NULL)
5596*7c478bd9Sstevel@tonic-gate 			z->adler = s->check = (*s->checkfn)(s->check, q, n);
5597*7c478bd9Sstevel@tonic-gate 
5598*7c478bd9Sstevel@tonic-gate 		/* copy */
5599*7c478bd9Sstevel@tonic-gate 		if (p != Z_NULL) {	/* PPP */
5600*7c478bd9Sstevel@tonic-gate 			zmemcpy(p, q, n);
5601*7c478bd9Sstevel@tonic-gate 			p += n;
5602*7c478bd9Sstevel@tonic-gate 		}	/* PPP */
5603*7c478bd9Sstevel@tonic-gate 		q += n;
5604*7c478bd9Sstevel@tonic-gate 	}
5605*7c478bd9Sstevel@tonic-gate 
5606*7c478bd9Sstevel@tonic-gate 	/* update pointers */
5607*7c478bd9Sstevel@tonic-gate 	z->next_out = p;
5608*7c478bd9Sstevel@tonic-gate 	s->read = q;
5609*7c478bd9Sstevel@tonic-gate 
5610*7c478bd9Sstevel@tonic-gate 	/* done */
5611*7c478bd9Sstevel@tonic-gate 	return (r);
5612*7c478bd9Sstevel@tonic-gate }
5613*7c478bd9Sstevel@tonic-gate /* --- infutil.c */
5614*7c478bd9Sstevel@tonic-gate 
5615*7c478bd9Sstevel@tonic-gate /* +++ inffast.c */
5616*7c478bd9Sstevel@tonic-gate /*
5617*7c478bd9Sstevel@tonic-gate  * inffast.c -- process literals and length/distance pairs fast
5618*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
5619*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
5620*7c478bd9Sstevel@tonic-gate  */
5621*7c478bd9Sstevel@tonic-gate 
5622*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
5623*7c478bd9Sstevel@tonic-gate /* #include "inftrees.h" */
5624*7c478bd9Sstevel@tonic-gate /* #include "infblock.h" */
5625*7c478bd9Sstevel@tonic-gate /* #include "infcodes.h" */
5626*7c478bd9Sstevel@tonic-gate /* #include "infutil.h" */
5627*7c478bd9Sstevel@tonic-gate /* #include "inffast.h" */
5628*7c478bd9Sstevel@tonic-gate 
5629*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
5630*7c478bd9Sstevel@tonic-gate struct inflate_codes_state {int dummy; };	/* for buggy compilers */
5631*7c478bd9Sstevel@tonic-gate #endif
5632*7c478bd9Sstevel@tonic-gate 
5633*7c478bd9Sstevel@tonic-gate /* simplify the use of the inflate_huft type with some defines */
5634*7c478bd9Sstevel@tonic-gate #define	exop word.what.Exop
5635*7c478bd9Sstevel@tonic-gate #define	bits word.what.Bits
5636*7c478bd9Sstevel@tonic-gate 
5637*7c478bd9Sstevel@tonic-gate /* macros for bit input with no checking and for returning unused bytes */
5638*7c478bd9Sstevel@tonic-gate #define	GRABBITS(j) { while (k < (j)) {b |= ((uLong)NEXTBYTE)<<k; k += 8; }}
5639*7c478bd9Sstevel@tonic-gate #define	UNGRAB {c = z->avail_in-n; c = (k>>3) < c?k>>3:c; n += c; p -= c; \
5640*7c478bd9Sstevel@tonic-gate 	k -= c<<3; }
5641*7c478bd9Sstevel@tonic-gate 
5642*7c478bd9Sstevel@tonic-gate /*
5643*7c478bd9Sstevel@tonic-gate  * Called with number of bytes left to write in window at least 258
5644*7c478bd9Sstevel@tonic-gate  * (the maximum string length) and number of input bytes available at
5645*7c478bd9Sstevel@tonic-gate  * least ten.  The ten bytes are six bytes for the longest length/
5646*7c478bd9Sstevel@tonic-gate  * distance pair plus four bytes for overloading the bit buffer.
5647*7c478bd9Sstevel@tonic-gate  */
5648*7c478bd9Sstevel@tonic-gate 
5649*7c478bd9Sstevel@tonic-gate int
5650*7c478bd9Sstevel@tonic-gate inflate_fast(bl, bd, tl, td, s, z)
5651*7c478bd9Sstevel@tonic-gate uInt bl, bd;
5652*7c478bd9Sstevel@tonic-gate const inflate_huft *tl;
5653*7c478bd9Sstevel@tonic-gate const inflate_huft *td;	/* need separate declaration for Borland C++ */
5654*7c478bd9Sstevel@tonic-gate inflate_blocks_statef *s;
5655*7c478bd9Sstevel@tonic-gate z_streamp z;
5656*7c478bd9Sstevel@tonic-gate {
5657*7c478bd9Sstevel@tonic-gate 	const inflate_huft *t;	/* temporary pointer */
5658*7c478bd9Sstevel@tonic-gate 	uInt e;	/* extra bits or operation */
5659*7c478bd9Sstevel@tonic-gate 	uLong b;	/* bit buffer */
5660*7c478bd9Sstevel@tonic-gate 	uInt k;	/* bits in bit buffer */
5661*7c478bd9Sstevel@tonic-gate 	Bytef *p;	/* input data pointer */
5662*7c478bd9Sstevel@tonic-gate 	uInt n;	/* bytes available there */
5663*7c478bd9Sstevel@tonic-gate 	Bytef *q;	/* output window write pointer */
5664*7c478bd9Sstevel@tonic-gate 	uInt m;	/* bytes to end of window or read pointer */
5665*7c478bd9Sstevel@tonic-gate 	uInt ml;	/* mask for literal/length tree */
5666*7c478bd9Sstevel@tonic-gate 	uInt md;	/* mask for distance tree */
5667*7c478bd9Sstevel@tonic-gate 	uInt c;	/* bytes to copy */
5668*7c478bd9Sstevel@tonic-gate 	uInt d;	/* distance back to copy from */
5669*7c478bd9Sstevel@tonic-gate 	Bytef *r;	/* copy source pointer */
5670*7c478bd9Sstevel@tonic-gate 
5671*7c478bd9Sstevel@tonic-gate 	/* load input, output, bit values */
5672*7c478bd9Sstevel@tonic-gate 	LOAD;
5673*7c478bd9Sstevel@tonic-gate 
5674*7c478bd9Sstevel@tonic-gate 	/* initialize masks */
5675*7c478bd9Sstevel@tonic-gate 	ml = inflate_mask[bl];
5676*7c478bd9Sstevel@tonic-gate 	md = inflate_mask[bd];
5677*7c478bd9Sstevel@tonic-gate 
5678*7c478bd9Sstevel@tonic-gate 	/* do until not enough input or output space for fast loop */
5679*7c478bd9Sstevel@tonic-gate 	do {	/* assume called with m >= 258 && n >= 10 */
5680*7c478bd9Sstevel@tonic-gate 		/* get literal/length code */
5681*7c478bd9Sstevel@tonic-gate 		/* max bits for literal/length code */
5682*7c478bd9Sstevel@tonic-gate 		GRABBITS(20);
5683*7c478bd9Sstevel@tonic-gate 		if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) {
5684*7c478bd9Sstevel@tonic-gate 			DUMPBITS(t->bits);
5685*7c478bd9Sstevel@tonic-gate 			Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
5686*7c478bd9Sstevel@tonic-gate 			    "inflate:         * literal '%c'\n" :
5687*7c478bd9Sstevel@tonic-gate 			    "inflate:         * literal 0x%02x\n", t->base));
5688*7c478bd9Sstevel@tonic-gate 			*q++ = (Byte)t->base;
5689*7c478bd9Sstevel@tonic-gate 			m--;
5690*7c478bd9Sstevel@tonic-gate 			continue;
5691*7c478bd9Sstevel@tonic-gate 		}
5692*7c478bd9Sstevel@tonic-gate 		do {
5693*7c478bd9Sstevel@tonic-gate 			DUMPBITS(t->bits);
5694*7c478bd9Sstevel@tonic-gate 			if (e & 16) {
5695*7c478bd9Sstevel@tonic-gate 				/* get extra bits for length */
5696*7c478bd9Sstevel@tonic-gate 				e &= 15;
5697*7c478bd9Sstevel@tonic-gate 				c = t->base + ((uInt)b & inflate_mask[e]);
5698*7c478bd9Sstevel@tonic-gate 				DUMPBITS(e);
5699*7c478bd9Sstevel@tonic-gate 				Tracevv((stderr,
5700*7c478bd9Sstevel@tonic-gate 				    "inflate:         * length %u\n", c));
5701*7c478bd9Sstevel@tonic-gate 
5702*7c478bd9Sstevel@tonic-gate 				/* decode distance base of block to copy */
5703*7c478bd9Sstevel@tonic-gate 				GRABBITS(15);	/* max bits for distance code */
5704*7c478bd9Sstevel@tonic-gate 				e = (t = td + ((uInt)b & md))->exop;
5705*7c478bd9Sstevel@tonic-gate 				do {
5706*7c478bd9Sstevel@tonic-gate 					DUMPBITS(t->bits);
5707*7c478bd9Sstevel@tonic-gate 					if (e & 16) {
5708*7c478bd9Sstevel@tonic-gate 						/*
5709*7c478bd9Sstevel@tonic-gate 						 * get extra bits to
5710*7c478bd9Sstevel@tonic-gate 						 * add to distance
5711*7c478bd9Sstevel@tonic-gate 						 * base
5712*7c478bd9Sstevel@tonic-gate 						 */
5713*7c478bd9Sstevel@tonic-gate 						e &= 15;
5714*7c478bd9Sstevel@tonic-gate 						/* get extra bits (up to 13) */
5715*7c478bd9Sstevel@tonic-gate 						GRABBITS(e);
5716*7c478bd9Sstevel@tonic-gate 						d = t->base + ((uInt)b &
5717*7c478bd9Sstevel@tonic-gate 						    inflate_mask[e]);
5718*7c478bd9Sstevel@tonic-gate 						DUMPBITS(e);
5719*7c478bd9Sstevel@tonic-gate 						Tracevv((stderr,
5720*7c478bd9Sstevel@tonic-gate 						    "inflate:         * "
5721*7c478bd9Sstevel@tonic-gate 						    "distance %u\n", d));
5722*7c478bd9Sstevel@tonic-gate 
5723*7c478bd9Sstevel@tonic-gate 						/* do the copy */
5724*7c478bd9Sstevel@tonic-gate 						m -= c;
5725*7c478bd9Sstevel@tonic-gate 						/* offset before dest */
5726*7c478bd9Sstevel@tonic-gate 						if ((uInt)(q - s->window) >= d)
5727*7c478bd9Sstevel@tonic-gate 							/*  just copy */
5728*7c478bd9Sstevel@tonic-gate 						{
5729*7c478bd9Sstevel@tonic-gate 							r = q - d;
5730*7c478bd9Sstevel@tonic-gate 							/*
5731*7c478bd9Sstevel@tonic-gate 							 * minimum
5732*7c478bd9Sstevel@tonic-gate 							 * count is
5733*7c478bd9Sstevel@tonic-gate 							 * three, so
5734*7c478bd9Sstevel@tonic-gate 							 * unroll loop
5735*7c478bd9Sstevel@tonic-gate 							 * a little
5736*7c478bd9Sstevel@tonic-gate 							 */
5737*7c478bd9Sstevel@tonic-gate 							*q++ = *r++;  c--;
5738*7c478bd9Sstevel@tonic-gate 							*q++ = *r++;  c--;
5739*7c478bd9Sstevel@tonic-gate 						}
5740*7c478bd9Sstevel@tonic-gate 					/* else offset after destination */
5741*7c478bd9Sstevel@tonic-gate 						else {
5742*7c478bd9Sstevel@tonic-gate 	/* bytes from offset to end */
5743*7c478bd9Sstevel@tonic-gate 							e = d - (uInt)(q -
5744*7c478bd9Sstevel@tonic-gate 							    s->window);
5745*7c478bd9Sstevel@tonic-gate 	/* pointer to offset */
5746*7c478bd9Sstevel@tonic-gate 							r = s->end - e;
5747*7c478bd9Sstevel@tonic-gate 							/* if source crosses */
5748*7c478bd9Sstevel@tonic-gate 							if (c > e) {
5749*7c478bd9Sstevel@tonic-gate 	/* copy to end of window */
5750*7c478bd9Sstevel@tonic-gate 								c -= e;
5751*7c478bd9Sstevel@tonic-gate 								do {
5752*7c478bd9Sstevel@tonic-gate 									*q++ =
5753*7c478bd9Sstevel@tonic-gate 									    *r
5754*7c478bd9Sstevel@tonic-gate 									    ++;
5755*7c478bd9Sstevel@tonic-gate 								} while (--e);
5756*7c478bd9Sstevel@tonic-gate 	/* copy rest from start of window */
5757*7c478bd9Sstevel@tonic-gate 								r = s->window;
5758*7c478bd9Sstevel@tonic-gate 							}
5759*7c478bd9Sstevel@tonic-gate 						}
5760*7c478bd9Sstevel@tonic-gate 						/* copy all or what's left */
5761*7c478bd9Sstevel@tonic-gate 						do {
5762*7c478bd9Sstevel@tonic-gate 							*q++ = *r++;
5763*7c478bd9Sstevel@tonic-gate 						} while (--c);
5764*7c478bd9Sstevel@tonic-gate 						break;
5765*7c478bd9Sstevel@tonic-gate 					} else if ((e & 64) == 0) {
5766*7c478bd9Sstevel@tonic-gate 						t += t->base;
5767*7c478bd9Sstevel@tonic-gate 						e = (t += ((uInt)b &
5768*7c478bd9Sstevel@tonic-gate 						    inflate_mask[e]))->exop;
5769*7c478bd9Sstevel@tonic-gate 					} else {
5770*7c478bd9Sstevel@tonic-gate 						z->msg =
5771*7c478bd9Sstevel@tonic-gate 						    "invalid distance code";
5772*7c478bd9Sstevel@tonic-gate 						UNGRAB;
5773*7c478bd9Sstevel@tonic-gate 						UPDATE;
5774*7c478bd9Sstevel@tonic-gate 						return (Z_DATA_ERROR);
5775*7c478bd9Sstevel@tonic-gate 					}
5776*7c478bd9Sstevel@tonic-gate 					/* CONSTCOND */
5777*7c478bd9Sstevel@tonic-gate 				} while (1);
5778*7c478bd9Sstevel@tonic-gate 				break;
5779*7c478bd9Sstevel@tonic-gate 			}
5780*7c478bd9Sstevel@tonic-gate 			if ((e & 64) == 0)
5781*7c478bd9Sstevel@tonic-gate 			{
5782*7c478bd9Sstevel@tonic-gate 				t += t->base;
5783*7c478bd9Sstevel@tonic-gate 				if ((e = (t += ((uInt)b &
5784*7c478bd9Sstevel@tonic-gate 				    inflate_mask[e]))->exop) == 0)
5785*7c478bd9Sstevel@tonic-gate 				{
5786*7c478bd9Sstevel@tonic-gate 					DUMPBITS(t->bits);
5787*7c478bd9Sstevel@tonic-gate 					Tracevv((stderr, t->base >= 0x20 &&
5788*7c478bd9Sstevel@tonic-gate 					    t->base < 0x7f ?
5789*7c478bd9Sstevel@tonic-gate 					    "inflate:         * literal '%c'\n"
5790*7c478bd9Sstevel@tonic-gate 					    :
5791*7c478bd9Sstevel@tonic-gate 					    "inflate:         * literal "
5792*7c478bd9Sstevel@tonic-gate 					    "0x%02x\n", t->base));
5793*7c478bd9Sstevel@tonic-gate 					*q++ = (Byte)t->base;
5794*7c478bd9Sstevel@tonic-gate 					m--;
5795*7c478bd9Sstevel@tonic-gate 					break;
5796*7c478bd9Sstevel@tonic-gate 				}
5797*7c478bd9Sstevel@tonic-gate 			} else if (e & 32) {
5798*7c478bd9Sstevel@tonic-gate 				Tracevv((stderr,
5799*7c478bd9Sstevel@tonic-gate 				    "inflate:         * end of block\n"));
5800*7c478bd9Sstevel@tonic-gate 				UNGRAB;
5801*7c478bd9Sstevel@tonic-gate 				UPDATE;
5802*7c478bd9Sstevel@tonic-gate 				return (Z_STREAM_END);
5803*7c478bd9Sstevel@tonic-gate 			} else {
5804*7c478bd9Sstevel@tonic-gate 				z->msg = "invalid literal/length code";
5805*7c478bd9Sstevel@tonic-gate 				UNGRAB;
5806*7c478bd9Sstevel@tonic-gate 				UPDATE;
5807*7c478bd9Sstevel@tonic-gate 				return (Z_DATA_ERROR);
5808*7c478bd9Sstevel@tonic-gate 			}
5809*7c478bd9Sstevel@tonic-gate 			/* CONSTCOND */
5810*7c478bd9Sstevel@tonic-gate 		} while (1);
5811*7c478bd9Sstevel@tonic-gate 	} while (m >= 258 && n >= 10);
5812*7c478bd9Sstevel@tonic-gate 
5813*7c478bd9Sstevel@tonic-gate 	/* not enough input or output--restore pointers and return */
5814*7c478bd9Sstevel@tonic-gate 	UNGRAB;
5815*7c478bd9Sstevel@tonic-gate 	UPDATE;
5816*7c478bd9Sstevel@tonic-gate 	return (Z_OK);
5817*7c478bd9Sstevel@tonic-gate }
5818*7c478bd9Sstevel@tonic-gate /* --- inffast.c */
5819*7c478bd9Sstevel@tonic-gate 
5820*7c478bd9Sstevel@tonic-gate /* +++ zutil.c */
5821*7c478bd9Sstevel@tonic-gate /*
5822*7c478bd9Sstevel@tonic-gate  * zutil.c -- target dependent utility functions for the compression library
5823*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Jean-loup Gailly.
5824*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
5825*7c478bd9Sstevel@tonic-gate  */
5826*7c478bd9Sstevel@tonic-gate 
5827*7c478bd9Sstevel@tonic-gate /* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
5828*7c478bd9Sstevel@tonic-gate 
5829*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
5830*7c478bd9Sstevel@tonic-gate #include <stdio.h>
5831*7c478bd9Sstevel@tonic-gate #endif
5832*7c478bd9Sstevel@tonic-gate 
5833*7c478bd9Sstevel@tonic-gate /* #include "zutil.h" */
5834*7c478bd9Sstevel@tonic-gate 
5835*7c478bd9Sstevel@tonic-gate #ifndef NO_DUMMY_DECL
5836*7c478bd9Sstevel@tonic-gate struct internal_state	{int dummy; };	/* for buggy compilers */
5837*7c478bd9Sstevel@tonic-gate #endif
5838*7c478bd9Sstevel@tonic-gate 
5839*7c478bd9Sstevel@tonic-gate #ifndef STDC
5840*7c478bd9Sstevel@tonic-gate extern void exit OF((int));
5841*7c478bd9Sstevel@tonic-gate #endif
5842*7c478bd9Sstevel@tonic-gate 
5843*7c478bd9Sstevel@tonic-gate const char *z_errmsg[10] = {
5844*7c478bd9Sstevel@tonic-gate "need dictionary",	/* Z_NEED_DICT		2 */
5845*7c478bd9Sstevel@tonic-gate "stream end",		/* Z_STREAM_END		1 */
5846*7c478bd9Sstevel@tonic-gate "",			/* Z_OK			0 */
5847*7c478bd9Sstevel@tonic-gate "file error",		/* Z_ERRNO		(-1) */
5848*7c478bd9Sstevel@tonic-gate "stream error",		/* Z_STREAM_ERROR	(-2) */
5849*7c478bd9Sstevel@tonic-gate "data error",		/* Z_DATA_ERROR		(-3) */
5850*7c478bd9Sstevel@tonic-gate "insufficient memory",	/* Z_MEM_ERROR		(-4) */
5851*7c478bd9Sstevel@tonic-gate "buffer error",		/* Z_BUF_ERROR		(-5) */
5852*7c478bd9Sstevel@tonic-gate "incompatible version",	/* Z_VERSION_ERROR	(-6) */
5853*7c478bd9Sstevel@tonic-gate ""};
5854*7c478bd9Sstevel@tonic-gate 
5855*7c478bd9Sstevel@tonic-gate 
5856*7c478bd9Sstevel@tonic-gate const char *
5857*7c478bd9Sstevel@tonic-gate zlibVersion()
5858*7c478bd9Sstevel@tonic-gate {
5859*7c478bd9Sstevel@tonic-gate 	return (ZLIB_VERSION);
5860*7c478bd9Sstevel@tonic-gate }
5861*7c478bd9Sstevel@tonic-gate 
5862*7c478bd9Sstevel@tonic-gate #ifdef DEBUG_ZLIB
5863*7c478bd9Sstevel@tonic-gate void
5864*7c478bd9Sstevel@tonic-gate z_error(m)
5865*7c478bd9Sstevel@tonic-gate     char *m;
5866*7c478bd9Sstevel@tonic-gate {
5867*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s\n", m);
5868*7c478bd9Sstevel@tonic-gate 	exit(1);
5869*7c478bd9Sstevel@tonic-gate }
5870*7c478bd9Sstevel@tonic-gate #endif
5871*7c478bd9Sstevel@tonic-gate 
5872*7c478bd9Sstevel@tonic-gate #ifndef HAVE_MEMCPY
5873*7c478bd9Sstevel@tonic-gate 
5874*7c478bd9Sstevel@tonic-gate void
5875*7c478bd9Sstevel@tonic-gate zmemcpy(dest, source, len)
5876*7c478bd9Sstevel@tonic-gate     Bytef* dest;
5877*7c478bd9Sstevel@tonic-gate     const Bytef* source;
5878*7c478bd9Sstevel@tonic-gate     uInt  len;
5879*7c478bd9Sstevel@tonic-gate {
5880*7c478bd9Sstevel@tonic-gate 	if (len == 0)
5881*7c478bd9Sstevel@tonic-gate 		return;
5882*7c478bd9Sstevel@tonic-gate 	do {
5883*7c478bd9Sstevel@tonic-gate 		*dest++ = *source++;	/* ??? to be unrolled */
5884*7c478bd9Sstevel@tonic-gate 	} while (--len != 0);
5885*7c478bd9Sstevel@tonic-gate }
5886*7c478bd9Sstevel@tonic-gate 
5887*7c478bd9Sstevel@tonic-gate int
5888*7c478bd9Sstevel@tonic-gate zmemcmp(s1, s2, len)
5889*7c478bd9Sstevel@tonic-gate const Bytef* s1;
5890*7c478bd9Sstevel@tonic-gate const Bytef* s2;
5891*7c478bd9Sstevel@tonic-gate uInt  len;
5892*7c478bd9Sstevel@tonic-gate {
5893*7c478bd9Sstevel@tonic-gate 	uInt j;
5894*7c478bd9Sstevel@tonic-gate 
5895*7c478bd9Sstevel@tonic-gate 	for (j = 0; j < len; j++) {
5896*7c478bd9Sstevel@tonic-gate 		if (s1[j] != s2[j])
5897*7c478bd9Sstevel@tonic-gate 			return (2*(s1[j] > s2[j])-1);
5898*7c478bd9Sstevel@tonic-gate 	}
5899*7c478bd9Sstevel@tonic-gate 	return (0);
5900*7c478bd9Sstevel@tonic-gate }
5901*7c478bd9Sstevel@tonic-gate 
5902*7c478bd9Sstevel@tonic-gate void
5903*7c478bd9Sstevel@tonic-gate zmemzero(dest, len)
5904*7c478bd9Sstevel@tonic-gate     Bytef* dest;
5905*7c478bd9Sstevel@tonic-gate     uInt  len;
5906*7c478bd9Sstevel@tonic-gate {
5907*7c478bd9Sstevel@tonic-gate 	if (len == 0)
5908*7c478bd9Sstevel@tonic-gate 		return;
5909*7c478bd9Sstevel@tonic-gate 	do {
5910*7c478bd9Sstevel@tonic-gate 		*dest++ = 0;	/* ??? to be unrolled */
5911*7c478bd9Sstevel@tonic-gate 	} while (--len != 0);
5912*7c478bd9Sstevel@tonic-gate }
5913*7c478bd9Sstevel@tonic-gate #endif
5914*7c478bd9Sstevel@tonic-gate 
5915*7c478bd9Sstevel@tonic-gate #ifdef __TURBOC__
5916*7c478bd9Sstevel@tonic-gate #if (defined(__BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
5917*7c478bd9Sstevel@tonic-gate /*
5918*7c478bd9Sstevel@tonic-gate  * Small and medium model in Turbo C are for now limited to near
5919*7c478bd9Sstevel@tonic-gate  * allocation with reduced MAX_WBITS and MAX_MEM_LEVEL
5920*7c478bd9Sstevel@tonic-gate  */
5921*7c478bd9Sstevel@tonic-gate #define	MY_ZCALLOC
5922*7c478bd9Sstevel@tonic-gate 
5923*7c478bd9Sstevel@tonic-gate /*
5924*7c478bd9Sstevel@tonic-gate  * Turbo C malloc() does not allow dynamic allocation of 64K bytes and
5925*7c478bd9Sstevel@tonic-gate  * farmalloc(64K) returns a pointer with an offset of 8, so we must
5926*7c478bd9Sstevel@tonic-gate  * fix the pointer. Warning: the pointer must be put back to its
5927*7c478bd9Sstevel@tonic-gate  * original form in order to free it, use zcfree().
5928*7c478bd9Sstevel@tonic-gate  */
5929*7c478bd9Sstevel@tonic-gate 
5930*7c478bd9Sstevel@tonic-gate #define	MAX_PTR 10
5931*7c478bd9Sstevel@tonic-gate /* 10*64K = 640K */
5932*7c478bd9Sstevel@tonic-gate 
5933*7c478bd9Sstevel@tonic-gate local int next_ptr = 0;
5934*7c478bd9Sstevel@tonic-gate 
5935*7c478bd9Sstevel@tonic-gate typedef struct ptr_table_s {
5936*7c478bd9Sstevel@tonic-gate 	voidpf org_ptr;
5937*7c478bd9Sstevel@tonic-gate 	voidpf new_ptr;
5938*7c478bd9Sstevel@tonic-gate } ptr_table;
5939*7c478bd9Sstevel@tonic-gate 
5940*7c478bd9Sstevel@tonic-gate local ptr_table table[MAX_PTR];
5941*7c478bd9Sstevel@tonic-gate /*
5942*7c478bd9Sstevel@tonic-gate  * This table is used to remember the original form of pointers to
5943*7c478bd9Sstevel@tonic-gate  * large buffers (64K). Such pointers are normalized with a zero
5944*7c478bd9Sstevel@tonic-gate  * offset.  Since MSDOS is not a preemptive multitasking OS, this
5945*7c478bd9Sstevel@tonic-gate  * table is not protected from concurrent access. This hack doesn't
5946*7c478bd9Sstevel@tonic-gate  * work anyway on a protected system like OS/2. Use Microsoft C
5947*7c478bd9Sstevel@tonic-gate  * instead.
5948*7c478bd9Sstevel@tonic-gate  */
5949*7c478bd9Sstevel@tonic-gate 
5950*7c478bd9Sstevel@tonic-gate voidpf
5951*7c478bd9Sstevel@tonic-gate zcalloc(voidpf opaque, unsigned items, unsigned size)
5952*7c478bd9Sstevel@tonic-gate {
5953*7c478bd9Sstevel@tonic-gate 	voidpf buf = opaque;	/* just to make some compilers happy */
5954*7c478bd9Sstevel@tonic-gate 	ulg bsize = (ulg)items*size;
5955*7c478bd9Sstevel@tonic-gate 
5956*7c478bd9Sstevel@tonic-gate 	/*
5957*7c478bd9Sstevel@tonic-gate 	 * If we allocate less than 65520 bytes, we assume that
5958*7c478bd9Sstevel@tonic-gate 	 * farmalloc will return a usable pointer which doesn't have
5959*7c478bd9Sstevel@tonic-gate 	 * to be normalized.
5960*7c478bd9Sstevel@tonic-gate 	 */
5961*7c478bd9Sstevel@tonic-gate 	if (bsize < 65520L) {
5962*7c478bd9Sstevel@tonic-gate 		buf = farmalloc(bsize);
5963*7c478bd9Sstevel@tonic-gate 		if (*(ush *)&buf != 0)
5964*7c478bd9Sstevel@tonic-gate 			return (buf);
5965*7c478bd9Sstevel@tonic-gate 	} else {
5966*7c478bd9Sstevel@tonic-gate 		buf = farmalloc(bsize + 16L);
5967*7c478bd9Sstevel@tonic-gate 	}
5968*7c478bd9Sstevel@tonic-gate 	if (buf == NULL || next_ptr >= MAX_PTR)
5969*7c478bd9Sstevel@tonic-gate 		return (NULL);
5970*7c478bd9Sstevel@tonic-gate 	table[next_ptr].org_ptr = buf;
5971*7c478bd9Sstevel@tonic-gate 
5972*7c478bd9Sstevel@tonic-gate 	/* Normalize the pointer to seg:0 */
5973*7c478bd9Sstevel@tonic-gate 	*((ush *)&buf+1) += ((ush)((uch *)buf-0) + 15) >> 4;
5974*7c478bd9Sstevel@tonic-gate 	*(ush *)&buf = 0;
5975*7c478bd9Sstevel@tonic-gate 	table[next_ptr++].new_ptr = buf;
5976*7c478bd9Sstevel@tonic-gate 	return (buf);
5977*7c478bd9Sstevel@tonic-gate }
5978*7c478bd9Sstevel@tonic-gate 
5979*7c478bd9Sstevel@tonic-gate void
5980*7c478bd9Sstevel@tonic-gate zcfree(voidpf opaque, voidpf ptr)
5981*7c478bd9Sstevel@tonic-gate {
5982*7c478bd9Sstevel@tonic-gate 	int n;
5983*7c478bd9Sstevel@tonic-gate 	if (*(ush*)&ptr != 0) { /* object < 64K */
5984*7c478bd9Sstevel@tonic-gate 		farfree(ptr);
5985*7c478bd9Sstevel@tonic-gate 		return;
5986*7c478bd9Sstevel@tonic-gate 	}
5987*7c478bd9Sstevel@tonic-gate 	/* Find the original pointer */
5988*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < next_ptr; n++) {
5989*7c478bd9Sstevel@tonic-gate 		if (ptr != table[n].new_ptr)
5990*7c478bd9Sstevel@tonic-gate 			continue;
5991*7c478bd9Sstevel@tonic-gate 
5992*7c478bd9Sstevel@tonic-gate 		farfree(table[n].org_ptr);
5993*7c478bd9Sstevel@tonic-gate 		while (++n < next_ptr) {
5994*7c478bd9Sstevel@tonic-gate 			table[n-1] = table[n];
5995*7c478bd9Sstevel@tonic-gate 		}
5996*7c478bd9Sstevel@tonic-gate 		next_ptr--;
5997*7c478bd9Sstevel@tonic-gate 		return;
5998*7c478bd9Sstevel@tonic-gate 	}
5999*7c478bd9Sstevel@tonic-gate 	ptr = opaque;	/* just to make some compilers happy */
6000*7c478bd9Sstevel@tonic-gate 	Assert(0, "zcfree: ptr not found");
6001*7c478bd9Sstevel@tonic-gate }
6002*7c478bd9Sstevel@tonic-gate #endif
6003*7c478bd9Sstevel@tonic-gate #endif /* __TURBOC__ */
6004*7c478bd9Sstevel@tonic-gate 
6005*7c478bd9Sstevel@tonic-gate 
6006*7c478bd9Sstevel@tonic-gate #if defined(M_I86) && !defined(__32BIT__)
6007*7c478bd9Sstevel@tonic-gate /* Microsoft C in 16-bit mode */
6008*7c478bd9Sstevel@tonic-gate 
6009*7c478bd9Sstevel@tonic-gate #define	MY_ZCALLOC
6010*7c478bd9Sstevel@tonic-gate 
6011*7c478bd9Sstevel@tonic-gate #if (!defined(_MSC_VER) || (_MSC_VER <= 600))
6012*7c478bd9Sstevel@tonic-gate #define	_halloc  halloc
6013*7c478bd9Sstevel@tonic-gate #define	_hfree   hfree
6014*7c478bd9Sstevel@tonic-gate #endif
6015*7c478bd9Sstevel@tonic-gate 
6016*7c478bd9Sstevel@tonic-gate voidpf
6017*7c478bd9Sstevel@tonic-gate zcalloc(voidpf opaque, unsigned items, unsigned size)
6018*7c478bd9Sstevel@tonic-gate {
6019*7c478bd9Sstevel@tonic-gate 	if (opaque) opaque = 0;	/* to make compiler happy */
6020*7c478bd9Sstevel@tonic-gate 	return (_halloc((long)items, size));
6021*7c478bd9Sstevel@tonic-gate }
6022*7c478bd9Sstevel@tonic-gate 
6023*7c478bd9Sstevel@tonic-gate void
6024*7c478bd9Sstevel@tonic-gate zcfree(voidpf opaque, voidpf ptr)
6025*7c478bd9Sstevel@tonic-gate {
6026*7c478bd9Sstevel@tonic-gate 	if (opaque) opaque = 0;	/* to make compiler happy */
6027*7c478bd9Sstevel@tonic-gate 	_hfree(ptr);
6028*7c478bd9Sstevel@tonic-gate }
6029*7c478bd9Sstevel@tonic-gate 
6030*7c478bd9Sstevel@tonic-gate #endif /* MSC */
6031*7c478bd9Sstevel@tonic-gate 
6032*7c478bd9Sstevel@tonic-gate 
6033*7c478bd9Sstevel@tonic-gate #ifndef MY_ZCALLOC /* Any system without a special alloc function */
6034*7c478bd9Sstevel@tonic-gate 
6035*7c478bd9Sstevel@tonic-gate #ifndef STDC
6036*7c478bd9Sstevel@tonic-gate extern voidp  calloc OF((uInt items, uInt size));
6037*7c478bd9Sstevel@tonic-gate extern void   free   OF((voidpf ptr));
6038*7c478bd9Sstevel@tonic-gate #endif
6039*7c478bd9Sstevel@tonic-gate 
6040*7c478bd9Sstevel@tonic-gate voidpf
6041*7c478bd9Sstevel@tonic-gate zcalloc(opaque, items, size)
6042*7c478bd9Sstevel@tonic-gate     voidpf opaque;
6043*7c478bd9Sstevel@tonic-gate     unsigned items;
6044*7c478bd9Sstevel@tonic-gate     unsigned size;
6045*7c478bd9Sstevel@tonic-gate {
6046*7c478bd9Sstevel@tonic-gate 	if (opaque) items += size - size;	/* make compiler happy */
6047*7c478bd9Sstevel@tonic-gate 	return ((voidpf)calloc(items, size));
6048*7c478bd9Sstevel@tonic-gate }
6049*7c478bd9Sstevel@tonic-gate 
6050*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6051*7c478bd9Sstevel@tonic-gate void
6052*7c478bd9Sstevel@tonic-gate zcfree(opaque, ptr)
6053*7c478bd9Sstevel@tonic-gate     voidpf opaque;
6054*7c478bd9Sstevel@tonic-gate     voidpf ptr;
6055*7c478bd9Sstevel@tonic-gate {
6056*7c478bd9Sstevel@tonic-gate 	free(ptr);
6057*7c478bd9Sstevel@tonic-gate }
6058*7c478bd9Sstevel@tonic-gate 
6059*7c478bd9Sstevel@tonic-gate #endif /* MY_ZCALLOC */
6060*7c478bd9Sstevel@tonic-gate /* --- zutil.c */
6061*7c478bd9Sstevel@tonic-gate 
6062*7c478bd9Sstevel@tonic-gate /* +++ adler32.c */
6063*7c478bd9Sstevel@tonic-gate /*
6064*7c478bd9Sstevel@tonic-gate  * adler32.c -- compute the Adler-32 checksum of a data stream
6065*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-1998 Mark Adler
6066*7c478bd9Sstevel@tonic-gate  * For conditions of distribution and use, see copyright notice in zlib.h
6067*7c478bd9Sstevel@tonic-gate  */
6068*7c478bd9Sstevel@tonic-gate 
6069*7c478bd9Sstevel@tonic-gate /* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
6070*7c478bd9Sstevel@tonic-gate 
6071*7c478bd9Sstevel@tonic-gate /* #include "zlib.h" */
6072*7c478bd9Sstevel@tonic-gate 
6073*7c478bd9Sstevel@tonic-gate #define	BASE 65521L /* largest prime smaller than 65536 */
6074*7c478bd9Sstevel@tonic-gate #define	NMAX 5552
6075*7c478bd9Sstevel@tonic-gate /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
6076*7c478bd9Sstevel@tonic-gate 
6077*7c478bd9Sstevel@tonic-gate #define	DO1(buf, i)  {s1 += buf[i]; s2 += s1; }
6078*7c478bd9Sstevel@tonic-gate #define	DO2(buf, i)  DO1(buf, i); DO1(buf, i+1);
6079*7c478bd9Sstevel@tonic-gate #define	DO4(buf, i)  DO2(buf, i); DO2(buf, i+2);
6080*7c478bd9Sstevel@tonic-gate #define	DO8(buf, i)  DO4(buf, i); DO4(buf, i+4);
6081*7c478bd9Sstevel@tonic-gate #define	DO16(buf)   DO8(buf, 0); DO8(buf, 8);
6082*7c478bd9Sstevel@tonic-gate 
6083*7c478bd9Sstevel@tonic-gate /* ========================================================================= */
6084*7c478bd9Sstevel@tonic-gate uLong
6085*7c478bd9Sstevel@tonic-gate adler32(adler, buf, len)
6086*7c478bd9Sstevel@tonic-gate     uLong adler;
6087*7c478bd9Sstevel@tonic-gate     const Bytef *buf;
6088*7c478bd9Sstevel@tonic-gate     uInt len;
6089*7c478bd9Sstevel@tonic-gate {
6090*7c478bd9Sstevel@tonic-gate 	unsigned long s1 = adler & 0xffff;
6091*7c478bd9Sstevel@tonic-gate 	unsigned long s2 = (adler >> 16) & 0xffff;
6092*7c478bd9Sstevel@tonic-gate 	int k;
6093*7c478bd9Sstevel@tonic-gate 
6094*7c478bd9Sstevel@tonic-gate 	if (buf == Z_NULL)
6095*7c478bd9Sstevel@tonic-gate 		return (1L);
6096*7c478bd9Sstevel@tonic-gate 
6097*7c478bd9Sstevel@tonic-gate 	while (len > 0) {
6098*7c478bd9Sstevel@tonic-gate 		k = len < NMAX ? len : NMAX;
6099*7c478bd9Sstevel@tonic-gate 		len -= k;
6100*7c478bd9Sstevel@tonic-gate 		while (k >= 16) {
6101*7c478bd9Sstevel@tonic-gate 			DO16(buf);
6102*7c478bd9Sstevel@tonic-gate 			buf += 16;
6103*7c478bd9Sstevel@tonic-gate 			k -= 16;
6104*7c478bd9Sstevel@tonic-gate 		}
6105*7c478bd9Sstevel@tonic-gate 		if (k != 0) do {
6106*7c478bd9Sstevel@tonic-gate 			s1 += *buf++;
6107*7c478bd9Sstevel@tonic-gate 			s2 += s1;
6108*7c478bd9Sstevel@tonic-gate 		} while (--k);
6109*7c478bd9Sstevel@tonic-gate 		s1 %= BASE;
6110*7c478bd9Sstevel@tonic-gate 		s2 %= BASE;
6111*7c478bd9Sstevel@tonic-gate 	}
6112*7c478bd9Sstevel@tonic-gate 	return ((s2 << 16) | s1);
6113*7c478bd9Sstevel@tonic-gate }
6114*7c478bd9Sstevel@tonic-gate /* --- adler32.c */
6115