1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions * Copyright (c) 2008-2020 Apple Inc. All rights reserved.
3*43a90889SApple OSS Distributions *
4*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*43a90889SApple OSS Distributions *
6*43a90889SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*43a90889SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*43a90889SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*43a90889SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*43a90889SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*43a90889SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*43a90889SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*43a90889SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*43a90889SApple OSS Distributions *
15*43a90889SApple OSS Distributions * Please obtain a copy of the License at
16*43a90889SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*43a90889SApple OSS Distributions *
18*43a90889SApple OSS Distributions * The Original Code and all software distributed under the License are
19*43a90889SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*43a90889SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*43a90889SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*43a90889SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*43a90889SApple OSS Distributions * Please see the License for the specific language governing rights and
24*43a90889SApple OSS Distributions * limitations under the License.
25*43a90889SApple OSS Distributions *
26*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*43a90889SApple OSS Distributions */
28*43a90889SApple OSS Distributions /* inflate.c -- zlib decompression
29*43a90889SApple OSS Distributions * Copyright (C) 1995-2005 Mark Adler
30*43a90889SApple OSS Distributions * For conditions of distribution and use, see copyright notice in zlib.h
31*43a90889SApple OSS Distributions */
32*43a90889SApple OSS Distributions
33*43a90889SApple OSS Distributions /*
34*43a90889SApple OSS Distributions * Change history:
35*43a90889SApple OSS Distributions *
36*43a90889SApple OSS Distributions * 1.2.beta0 24 Nov 2002
37*43a90889SApple OSS Distributions * - First version -- complete rewrite of inflate to simplify code, avoid
38*43a90889SApple OSS Distributions * creation of window when not needed, minimize use of window when it is
39*43a90889SApple OSS Distributions * needed, make inffast.c even faster, implement gzip decoding, and to
40*43a90889SApple OSS Distributions * improve code readability and style over the previous zlib inflate code
41*43a90889SApple OSS Distributions *
42*43a90889SApple OSS Distributions * 1.2.beta1 25 Nov 2002
43*43a90889SApple OSS Distributions * - Use pointers for available input and output checking in inffast.c
44*43a90889SApple OSS Distributions * - Remove input and output counters in inffast.c
45*43a90889SApple OSS Distributions * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
46*43a90889SApple OSS Distributions * - Remove unnecessary second byte pull from length extra in inffast.c
47*43a90889SApple OSS Distributions * - Unroll direct copy to three copies per loop in inffast.c
48*43a90889SApple OSS Distributions *
49*43a90889SApple OSS Distributions * 1.2.beta2 4 Dec 2002
50*43a90889SApple OSS Distributions * - Change external routine names to reduce potential conflicts
51*43a90889SApple OSS Distributions * - Correct filename to inffixed.h for fixed tables in inflate.c
52*43a90889SApple OSS Distributions * - Make hbuf[] unsigned char to match parameter type in inflate.c
53*43a90889SApple OSS Distributions * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
54*43a90889SApple OSS Distributions * to avoid negation problem on Alphas (64 bit) in inflate.c
55*43a90889SApple OSS Distributions *
56*43a90889SApple OSS Distributions * 1.2.beta3 22 Dec 2002
57*43a90889SApple OSS Distributions * - Add comments on state->bits assertion in inffast.c
58*43a90889SApple OSS Distributions * - Add comments on op field in inftrees.h
59*43a90889SApple OSS Distributions * - Fix bug in reuse of allocated window after inflateReset()
60*43a90889SApple OSS Distributions * - Remove bit fields--back to byte structure for speed
61*43a90889SApple OSS Distributions * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
62*43a90889SApple OSS Distributions * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
63*43a90889SApple OSS Distributions * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
64*43a90889SApple OSS Distributions * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
65*43a90889SApple OSS Distributions * - Use local copies of stream next and avail values, as well as local bit
66*43a90889SApple OSS Distributions * buffer and bit count in inflate()--for speed when inflate_fast() not used
67*43a90889SApple OSS Distributions *
68*43a90889SApple OSS Distributions * 1.2.beta4 1 Jan 2003
69*43a90889SApple OSS Distributions * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
70*43a90889SApple OSS Distributions * - Move a comment on output buffer sizes from inffast.c to inflate.c
71*43a90889SApple OSS Distributions * - Add comments in inffast.c to introduce the inflate_fast() routine
72*43a90889SApple OSS Distributions * - Rearrange window copies in inflate_fast() for speed and simplification
73*43a90889SApple OSS Distributions * - Unroll last copy for window match in inflate_fast()
74*43a90889SApple OSS Distributions * - Use local copies of window variables in inflate_fast() for speed
75*43a90889SApple OSS Distributions * - Pull out common write == 0 case for speed in inflate_fast()
76*43a90889SApple OSS Distributions * - Make op and len in inflate_fast() unsigned for consistency
77*43a90889SApple OSS Distributions * - Add FAR to lcode and dcode declarations in inflate_fast()
78*43a90889SApple OSS Distributions * - Simplified bad distance check in inflate_fast()
79*43a90889SApple OSS Distributions * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
80*43a90889SApple OSS Distributions * source file infback.c to provide a call-back interface to inflate for
81*43a90889SApple OSS Distributions * programs like gzip and unzip -- uses window as output buffer to avoid
82*43a90889SApple OSS Distributions * window copying
83*43a90889SApple OSS Distributions *
84*43a90889SApple OSS Distributions * 1.2.beta5 1 Jan 2003
85*43a90889SApple OSS Distributions * - Improved inflateBack() interface to allow the caller to provide initial
86*43a90889SApple OSS Distributions * input in strm.
87*43a90889SApple OSS Distributions * - Fixed stored blocks bug in inflateBack()
88*43a90889SApple OSS Distributions *
89*43a90889SApple OSS Distributions * 1.2.beta6 4 Jan 2003
90*43a90889SApple OSS Distributions * - Added comments in inffast.c on effectiveness of POSTINC
91*43a90889SApple OSS Distributions * - Typecasting all around to reduce compiler warnings
92*43a90889SApple OSS Distributions * - Changed loops from while (1) or do {} while (1) to for (;;), again to
93*43a90889SApple OSS Distributions * make compilers happy
94*43a90889SApple OSS Distributions * - Changed type of window in inflateBackInit() to unsigned char *
95*43a90889SApple OSS Distributions *
96*43a90889SApple OSS Distributions * 1.2.beta7 27 Jan 2003
97*43a90889SApple OSS Distributions * - Changed many types to unsigned or unsigned short to avoid warnings
98*43a90889SApple OSS Distributions * - Added inflateCopy() function
99*43a90889SApple OSS Distributions *
100*43a90889SApple OSS Distributions * 1.2.0 9 Mar 2003
101*43a90889SApple OSS Distributions * - Changed inflateBack() interface to provide separate opaque descriptors
102*43a90889SApple OSS Distributions * for the in() and out() functions
103*43a90889SApple OSS Distributions * - Changed inflateBack() argument and in_func typedef to swap the length
104*43a90889SApple OSS Distributions * and buffer address return values for the input function
105*43a90889SApple OSS Distributions * - Check next_in and next_out for Z_NULL on entry to inflate()
106*43a90889SApple OSS Distributions *
107*43a90889SApple OSS Distributions * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
108*43a90889SApple OSS Distributions */
109*43a90889SApple OSS Distributions
110*43a90889SApple OSS Distributions #include "zutil.h"
111*43a90889SApple OSS Distributions #include "inftrees.h"
112*43a90889SApple OSS Distributions #include "inflate.h"
113*43a90889SApple OSS Distributions #include "inffast.h"
114*43a90889SApple OSS Distributions #include <os/base.h>
115*43a90889SApple OSS Distributions
116*43a90889SApple OSS Distributions #ifdef MAKEFIXED
117*43a90889SApple OSS Distributions # ifndef BUILDFIXED
118*43a90889SApple OSS Distributions # define BUILDFIXED
119*43a90889SApple OSS Distributions # endif
120*43a90889SApple OSS Distributions #endif
121*43a90889SApple OSS Distributions
122*43a90889SApple OSS Distributions /* function prototypes */
123*43a90889SApple OSS Distributions local void fixedtables OF((struct inflate_state FAR *state));
124*43a90889SApple OSS Distributions local int updatewindow OF((z_streamp strm, unsigned out));
125*43a90889SApple OSS Distributions #ifdef BUILDFIXED
126*43a90889SApple OSS Distributions void makefixed OF((void));
127*43a90889SApple OSS Distributions #endif
128*43a90889SApple OSS Distributions local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
129*43a90889SApple OSS Distributions unsigned len));
130*43a90889SApple OSS Distributions
131*43a90889SApple OSS Distributions int ZEXPORT
inflateReset(z_streamp strm)132*43a90889SApple OSS Distributions inflateReset(z_streamp strm)
133*43a90889SApple OSS Distributions {
134*43a90889SApple OSS Distributions struct inflate_state FAR *state;
135*43a90889SApple OSS Distributions
136*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
137*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
138*43a90889SApple OSS Distributions strm->total_in = strm->total_out = state->total = 0;
139*43a90889SApple OSS Distributions strm->msg = Z_NULL;
140*43a90889SApple OSS Distributions strm->adler = 1; /* to support ill-conceived Java test suite */
141*43a90889SApple OSS Distributions state->mode = HEAD;
142*43a90889SApple OSS Distributions state->last = 0;
143*43a90889SApple OSS Distributions state->havedict = 0;
144*43a90889SApple OSS Distributions state->dmax = 32768U;
145*43a90889SApple OSS Distributions state->head = Z_NULL;
146*43a90889SApple OSS Distributions state->wsize = 0;
147*43a90889SApple OSS Distributions state->whave = 0;
148*43a90889SApple OSS Distributions state->write = 0;
149*43a90889SApple OSS Distributions state->hold = 0;
150*43a90889SApple OSS Distributions state->bits = 0;
151*43a90889SApple OSS Distributions state->lencode = state->distcode = state->next = state->codes;
152*43a90889SApple OSS Distributions Tracev((stderr, "inflate: reset\n"));
153*43a90889SApple OSS Distributions return Z_OK;
154*43a90889SApple OSS Distributions }
155*43a90889SApple OSS Distributions
156*43a90889SApple OSS Distributions int ZEXPORT
inflatePrime(z_streamp strm,int bits,int value)157*43a90889SApple OSS Distributions inflatePrime(z_streamp strm, int bits, int value)
158*43a90889SApple OSS Distributions {
159*43a90889SApple OSS Distributions struct inflate_state FAR *state;
160*43a90889SApple OSS Distributions
161*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
162*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
163*43a90889SApple OSS Distributions if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
164*43a90889SApple OSS Distributions value &= (1L << bits) - 1;
165*43a90889SApple OSS Distributions state->hold += value << state->bits;
166*43a90889SApple OSS Distributions state->bits += bits;
167*43a90889SApple OSS Distributions return Z_OK;
168*43a90889SApple OSS Distributions }
169*43a90889SApple OSS Distributions
170*43a90889SApple OSS Distributions int ZEXPORT
inflateInit2_(z_streamp strm,int windowBits,const char * version,int stream_size)171*43a90889SApple OSS Distributions inflateInit2_(z_streamp strm, int windowBits, const char *version,
172*43a90889SApple OSS Distributions int stream_size)
173*43a90889SApple OSS Distributions {
174*43a90889SApple OSS Distributions struct inflate_state FAR *state;
175*43a90889SApple OSS Distributions
176*43a90889SApple OSS Distributions if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
177*43a90889SApple OSS Distributions stream_size != (int)(sizeof(z_stream)))
178*43a90889SApple OSS Distributions return Z_VERSION_ERROR;
179*43a90889SApple OSS Distributions if (strm == Z_NULL) return Z_STREAM_ERROR;
180*43a90889SApple OSS Distributions strm->msg = Z_NULL; /* in case we return an error */
181*43a90889SApple OSS Distributions #ifndef NO_ZCFUNCS
182*43a90889SApple OSS Distributions if (strm->zalloc == (alloc_func)0) {
183*43a90889SApple OSS Distributions strm->zalloc = zcalloc;
184*43a90889SApple OSS Distributions strm->opaque = (voidpf)0;
185*43a90889SApple OSS Distributions }
186*43a90889SApple OSS Distributions if (strm->zfree == (free_func)0) strm->zfree = zcfree;
187*43a90889SApple OSS Distributions #endif /* NO_ZCFUNCS */
188*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)
189*43a90889SApple OSS Distributions ZALLOC(strm, 1, sizeof(struct inflate_state));
190*43a90889SApple OSS Distributions if (state == Z_NULL) return Z_MEM_ERROR;
191*43a90889SApple OSS Distributions Tracev((stderr, "inflate: allocated\n"));
192*43a90889SApple OSS Distributions strm->state = (struct internal_state FAR *)state;
193*43a90889SApple OSS Distributions if (windowBits < 0) {
194*43a90889SApple OSS Distributions state->wrap = 0;
195*43a90889SApple OSS Distributions windowBits = -windowBits;
196*43a90889SApple OSS Distributions }
197*43a90889SApple OSS Distributions else {
198*43a90889SApple OSS Distributions state->wrap = (windowBits >> 4) + 1;
199*43a90889SApple OSS Distributions #ifdef GUNZIP
200*43a90889SApple OSS Distributions if (windowBits < 48) windowBits &= 15;
201*43a90889SApple OSS Distributions #endif
202*43a90889SApple OSS Distributions }
203*43a90889SApple OSS Distributions if (windowBits < 8 || windowBits > 15) {
204*43a90889SApple OSS Distributions ZFREE(strm, state);
205*43a90889SApple OSS Distributions strm->state = Z_NULL;
206*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
207*43a90889SApple OSS Distributions }
208*43a90889SApple OSS Distributions state->wbits = (unsigned)windowBits;
209*43a90889SApple OSS Distributions state->window = Z_NULL;
210*43a90889SApple OSS Distributions return inflateReset(strm);
211*43a90889SApple OSS Distributions }
212*43a90889SApple OSS Distributions
213*43a90889SApple OSS Distributions int ZEXPORT
inflateInit_(z_streamp strm,const char * version,int stream_size)214*43a90889SApple OSS Distributions inflateInit_(z_streamp strm, const char *version, int stream_size)
215*43a90889SApple OSS Distributions {
216*43a90889SApple OSS Distributions return inflateInit2_(strm, DEF_WBITS, version, stream_size);
217*43a90889SApple OSS Distributions }
218*43a90889SApple OSS Distributions
219*43a90889SApple OSS Distributions /*
220*43a90889SApple OSS Distributions Return state with length and distance decoding tables and index sizes set to
221*43a90889SApple OSS Distributions fixed code decoding. Normally this returns fixed tables from inffixed.h.
222*43a90889SApple OSS Distributions If BUILDFIXED is defined, then instead this routine builds the tables the
223*43a90889SApple OSS Distributions first time it's called, and returns those tables the first time and
224*43a90889SApple OSS Distributions thereafter. This reduces the size of the code by about 2K bytes, in
225*43a90889SApple OSS Distributions exchange for a little execution time. However, BUILDFIXED should not be
226*43a90889SApple OSS Distributions used for threaded applications, since the rewriting of the tables and virgin
227*43a90889SApple OSS Distributions may not be thread-safe.
228*43a90889SApple OSS Distributions */
229*43a90889SApple OSS Distributions local void
fixedtables(struct inflate_state FAR * state)230*43a90889SApple OSS Distributions fixedtables(struct inflate_state FAR *state)
231*43a90889SApple OSS Distributions {
232*43a90889SApple OSS Distributions #ifdef BUILDFIXED
233*43a90889SApple OSS Distributions static int virgin = 1;
234*43a90889SApple OSS Distributions static code *lenfix, *distfix;
235*43a90889SApple OSS Distributions static code fixed[544];
236*43a90889SApple OSS Distributions
237*43a90889SApple OSS Distributions /* build fixed huffman tables if first call (may not be thread safe) */
238*43a90889SApple OSS Distributions if (virgin) {
239*43a90889SApple OSS Distributions unsigned sym, bits;
240*43a90889SApple OSS Distributions static code *next;
241*43a90889SApple OSS Distributions
242*43a90889SApple OSS Distributions /* literal/length table */
243*43a90889SApple OSS Distributions sym = 0;
244*43a90889SApple OSS Distributions while (sym < 144) state->lens[sym++] = 8;
245*43a90889SApple OSS Distributions while (sym < 256) state->lens[sym++] = 9;
246*43a90889SApple OSS Distributions while (sym < 280) state->lens[sym++] = 7;
247*43a90889SApple OSS Distributions while (sym < 288) state->lens[sym++] = 8;
248*43a90889SApple OSS Distributions next = fixed;
249*43a90889SApple OSS Distributions lenfix = next;
250*43a90889SApple OSS Distributions bits = 9;
251*43a90889SApple OSS Distributions inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
252*43a90889SApple OSS Distributions
253*43a90889SApple OSS Distributions /* distance table */
254*43a90889SApple OSS Distributions sym = 0;
255*43a90889SApple OSS Distributions while (sym < 32) state->lens[sym++] = 5;
256*43a90889SApple OSS Distributions distfix = next;
257*43a90889SApple OSS Distributions bits = 5;
258*43a90889SApple OSS Distributions inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
259*43a90889SApple OSS Distributions
260*43a90889SApple OSS Distributions /* do this just once */
261*43a90889SApple OSS Distributions virgin = 0;
262*43a90889SApple OSS Distributions }
263*43a90889SApple OSS Distributions #else /* !BUILDFIXED */
264*43a90889SApple OSS Distributions # include "inffixed.h"
265*43a90889SApple OSS Distributions #endif /* BUILDFIXED */
266*43a90889SApple OSS Distributions state->lencode = lenfix;
267*43a90889SApple OSS Distributions state->lenbits = 9;
268*43a90889SApple OSS Distributions state->distcode = distfix;
269*43a90889SApple OSS Distributions state->distbits = 5;
270*43a90889SApple OSS Distributions }
271*43a90889SApple OSS Distributions
272*43a90889SApple OSS Distributions #ifdef MAKEFIXED
273*43a90889SApple OSS Distributions #include <stdio.h>
274*43a90889SApple OSS Distributions
275*43a90889SApple OSS Distributions /*
276*43a90889SApple OSS Distributions Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
277*43a90889SApple OSS Distributions defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
278*43a90889SApple OSS Distributions those tables to stdout, which would be piped to inffixed.h. A small program
279*43a90889SApple OSS Distributions can simply call makefixed to do this:
280*43a90889SApple OSS Distributions
281*43a90889SApple OSS Distributions void makefixed(void);
282*43a90889SApple OSS Distributions
283*43a90889SApple OSS Distributions int main(void)
284*43a90889SApple OSS Distributions {
285*43a90889SApple OSS Distributions makefixed();
286*43a90889SApple OSS Distributions return 0;
287*43a90889SApple OSS Distributions }
288*43a90889SApple OSS Distributions
289*43a90889SApple OSS Distributions Then that can be linked with zlib built with MAKEFIXED defined and run:
290*43a90889SApple OSS Distributions
291*43a90889SApple OSS Distributions a.out > inffixed.h
292*43a90889SApple OSS Distributions */
293*43a90889SApple OSS Distributions void
makefixed(void)294*43a90889SApple OSS Distributions makefixed(void)
295*43a90889SApple OSS Distributions {
296*43a90889SApple OSS Distributions unsigned low, size;
297*43a90889SApple OSS Distributions struct inflate_state state;
298*43a90889SApple OSS Distributions
299*43a90889SApple OSS Distributions fixedtables(&state);
300*43a90889SApple OSS Distributions puts(" /* inffixed.h -- table for decoding fixed codes");
301*43a90889SApple OSS Distributions puts(" * Generated automatically by makefixed().");
302*43a90889SApple OSS Distributions puts(" */");
303*43a90889SApple OSS Distributions puts("");
304*43a90889SApple OSS Distributions puts(" /* WARNING: this file should *not* be used by applications.");
305*43a90889SApple OSS Distributions puts(" It is part of the implementation of this library and is");
306*43a90889SApple OSS Distributions puts(" subject to change. Applications should only use zlib.h.");
307*43a90889SApple OSS Distributions puts(" */");
308*43a90889SApple OSS Distributions puts("");
309*43a90889SApple OSS Distributions size = 1U << 9;
310*43a90889SApple OSS Distributions printf(" static const code lenfix[%u] = {", size);
311*43a90889SApple OSS Distributions low = 0;
312*43a90889SApple OSS Distributions for (;;) {
313*43a90889SApple OSS Distributions if ((low % 7) == 0) printf("\n ");
314*43a90889SApple OSS Distributions printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
315*43a90889SApple OSS Distributions state.lencode[low].val);
316*43a90889SApple OSS Distributions if (++low == size) break;
317*43a90889SApple OSS Distributions putchar(',');
318*43a90889SApple OSS Distributions }
319*43a90889SApple OSS Distributions puts("\n };");
320*43a90889SApple OSS Distributions size = 1U << 5;
321*43a90889SApple OSS Distributions printf("\n static const code distfix[%u] = {", size);
322*43a90889SApple OSS Distributions low = 0;
323*43a90889SApple OSS Distributions for (;;) {
324*43a90889SApple OSS Distributions if ((low % 6) == 0) printf("\n ");
325*43a90889SApple OSS Distributions printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
326*43a90889SApple OSS Distributions state.distcode[low].val);
327*43a90889SApple OSS Distributions if (++low == size) break;
328*43a90889SApple OSS Distributions putchar(',');
329*43a90889SApple OSS Distributions }
330*43a90889SApple OSS Distributions puts("\n };");
331*43a90889SApple OSS Distributions }
332*43a90889SApple OSS Distributions #endif /* MAKEFIXED */
333*43a90889SApple OSS Distributions
334*43a90889SApple OSS Distributions /*
335*43a90889SApple OSS Distributions Update the window with the last wsize (normally 32K) bytes written before
336*43a90889SApple OSS Distributions returning. If window does not exist yet, create it. This is only called
337*43a90889SApple OSS Distributions when a window is already in use, or when output has been written during this
338*43a90889SApple OSS Distributions inflate call, but the end of the deflate stream has not been reached yet.
339*43a90889SApple OSS Distributions It is also called to create a window for dictionary data when a dictionary
340*43a90889SApple OSS Distributions is loaded.
341*43a90889SApple OSS Distributions
342*43a90889SApple OSS Distributions Providing output buffers larger than 32K to inflate() should provide a speed
343*43a90889SApple OSS Distributions advantage, since only the last 32K of output is copied to the sliding window
344*43a90889SApple OSS Distributions upon return from inflate(), and since all distances after the first 32K of
345*43a90889SApple OSS Distributions output will fall in the output data, making match copies simpler and faster.
346*43a90889SApple OSS Distributions The advantage may be dependent on the size of the processor's data caches.
347*43a90889SApple OSS Distributions */
348*43a90889SApple OSS Distributions local int
updatewindow(z_streamp strm,unsigned out)349*43a90889SApple OSS Distributions updatewindow(z_streamp strm, unsigned out)
350*43a90889SApple OSS Distributions {
351*43a90889SApple OSS Distributions struct inflate_state FAR *state;
352*43a90889SApple OSS Distributions unsigned copy, dist;
353*43a90889SApple OSS Distributions
354*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
355*43a90889SApple OSS Distributions
356*43a90889SApple OSS Distributions /* if it hasn't been done already, allocate space for the window */
357*43a90889SApple OSS Distributions if (state->window == Z_NULL) {
358*43a90889SApple OSS Distributions state->window = (unsigned char FAR *)
359*43a90889SApple OSS Distributions ZALLOC(strm, 1U << state->wbits,
360*43a90889SApple OSS Distributions sizeof(unsigned char));
361*43a90889SApple OSS Distributions if (state->window == Z_NULL) return 1;
362*43a90889SApple OSS Distributions }
363*43a90889SApple OSS Distributions
364*43a90889SApple OSS Distributions /* if window not in use yet, initialize */
365*43a90889SApple OSS Distributions if (state->wsize == 0) {
366*43a90889SApple OSS Distributions state->wsize = 1U << state->wbits;
367*43a90889SApple OSS Distributions state->write = 0;
368*43a90889SApple OSS Distributions state->whave = 0;
369*43a90889SApple OSS Distributions }
370*43a90889SApple OSS Distributions
371*43a90889SApple OSS Distributions /* copy state->wsize or less output bytes into the circular window */
372*43a90889SApple OSS Distributions copy = out - strm->avail_out;
373*43a90889SApple OSS Distributions if (copy >= state->wsize) {
374*43a90889SApple OSS Distributions zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
375*43a90889SApple OSS Distributions state->write = 0;
376*43a90889SApple OSS Distributions state->whave = state->wsize;
377*43a90889SApple OSS Distributions }
378*43a90889SApple OSS Distributions else {
379*43a90889SApple OSS Distributions dist = state->wsize - state->write;
380*43a90889SApple OSS Distributions if (dist > copy) dist = copy;
381*43a90889SApple OSS Distributions zmemcpy(state->window + state->write, strm->next_out - copy, dist);
382*43a90889SApple OSS Distributions copy -= dist;
383*43a90889SApple OSS Distributions if (copy) {
384*43a90889SApple OSS Distributions zmemcpy(state->window, strm->next_out - copy, copy);
385*43a90889SApple OSS Distributions state->write = copy;
386*43a90889SApple OSS Distributions state->whave = state->wsize;
387*43a90889SApple OSS Distributions }
388*43a90889SApple OSS Distributions else {
389*43a90889SApple OSS Distributions state->write += dist;
390*43a90889SApple OSS Distributions if (state->write == state->wsize) state->write = 0;
391*43a90889SApple OSS Distributions if (state->whave < state->wsize) state->whave += dist;
392*43a90889SApple OSS Distributions }
393*43a90889SApple OSS Distributions }
394*43a90889SApple OSS Distributions return 0;
395*43a90889SApple OSS Distributions }
396*43a90889SApple OSS Distributions
397*43a90889SApple OSS Distributions /* Macros for inflate(): */
398*43a90889SApple OSS Distributions
399*43a90889SApple OSS Distributions /* check function to use adler32() for zlib or z_crc32() for gzip */
400*43a90889SApple OSS Distributions #ifdef GUNZIP
401*43a90889SApple OSS Distributions # define UPDATE(check, buf, len) \
402*43a90889SApple OSS Distributions (state->flags ? z_crc32(check, buf, len) : adler32(check, buf, len))
403*43a90889SApple OSS Distributions #else
404*43a90889SApple OSS Distributions # define UPDATE(check, buf, len) adler32(check, buf, len)
405*43a90889SApple OSS Distributions #endif
406*43a90889SApple OSS Distributions
407*43a90889SApple OSS Distributions /* check macros for header crc */
408*43a90889SApple OSS Distributions #ifdef GUNZIP
409*43a90889SApple OSS Distributions # define CRC2(check, word) \
410*43a90889SApple OSS Distributions do { \
411*43a90889SApple OSS Distributions hbuf[0] = (unsigned char)(word); \
412*43a90889SApple OSS Distributions hbuf[1] = (unsigned char)((word) >> 8); \
413*43a90889SApple OSS Distributions check = z_crc32(check, hbuf, 2); \
414*43a90889SApple OSS Distributions } while (0)
415*43a90889SApple OSS Distributions
416*43a90889SApple OSS Distributions # define CRC4(check, word) \
417*43a90889SApple OSS Distributions do { \
418*43a90889SApple OSS Distributions hbuf[0] = (unsigned char)(word); \
419*43a90889SApple OSS Distributions hbuf[1] = (unsigned char)((word) >> 8); \
420*43a90889SApple OSS Distributions hbuf[2] = (unsigned char)((word) >> 16); \
421*43a90889SApple OSS Distributions hbuf[3] = (unsigned char)((word) >> 24); \
422*43a90889SApple OSS Distributions check = z_crc32(check, hbuf, 4); \
423*43a90889SApple OSS Distributions } while (0)
424*43a90889SApple OSS Distributions #endif
425*43a90889SApple OSS Distributions
426*43a90889SApple OSS Distributions /* Load registers with state in inflate() for speed */
427*43a90889SApple OSS Distributions #define LOAD() \
428*43a90889SApple OSS Distributions do { \
429*43a90889SApple OSS Distributions put = strm->next_out; \
430*43a90889SApple OSS Distributions left = strm->avail_out; \
431*43a90889SApple OSS Distributions next = strm->next_in; \
432*43a90889SApple OSS Distributions have = strm->avail_in; \
433*43a90889SApple OSS Distributions hold = state->hold; \
434*43a90889SApple OSS Distributions bits = state->bits; \
435*43a90889SApple OSS Distributions } while (0)
436*43a90889SApple OSS Distributions
437*43a90889SApple OSS Distributions /* Restore state from registers in inflate() */
438*43a90889SApple OSS Distributions #define RESTORE() \
439*43a90889SApple OSS Distributions do { \
440*43a90889SApple OSS Distributions strm->next_out = put; \
441*43a90889SApple OSS Distributions strm->avail_out = left; \
442*43a90889SApple OSS Distributions strm->next_in = next; \
443*43a90889SApple OSS Distributions strm->avail_in = have; \
444*43a90889SApple OSS Distributions state->hold = hold; \
445*43a90889SApple OSS Distributions state->bits = bits; \
446*43a90889SApple OSS Distributions } while (0)
447*43a90889SApple OSS Distributions
448*43a90889SApple OSS Distributions /* Clear the input bit accumulator */
449*43a90889SApple OSS Distributions #define INITBITS() \
450*43a90889SApple OSS Distributions do { \
451*43a90889SApple OSS Distributions hold = 0; \
452*43a90889SApple OSS Distributions bits = 0; \
453*43a90889SApple OSS Distributions } while (0)
454*43a90889SApple OSS Distributions
455*43a90889SApple OSS Distributions /* Get a byte of input into the bit accumulator, or return from inflate()
456*43a90889SApple OSS Distributions if there is no input available. */
457*43a90889SApple OSS Distributions #define PULLBYTE() \
458*43a90889SApple OSS Distributions do { \
459*43a90889SApple OSS Distributions if (have == 0) goto inf_leave; \
460*43a90889SApple OSS Distributions have--; \
461*43a90889SApple OSS Distributions hold += (unsigned long)(*next++) << bits; \
462*43a90889SApple OSS Distributions bits += 8; \
463*43a90889SApple OSS Distributions } while (0)
464*43a90889SApple OSS Distributions
465*43a90889SApple OSS Distributions /* Assure that there are at least n bits in the bit accumulator. If there is
466*43a90889SApple OSS Distributions not enough available input to do that, then return from inflate(). */
467*43a90889SApple OSS Distributions #define NEEDBITS(n) \
468*43a90889SApple OSS Distributions do { \
469*43a90889SApple OSS Distributions while (bits < (unsigned)(n)) \
470*43a90889SApple OSS Distributions PULLBYTE(); \
471*43a90889SApple OSS Distributions } while (0)
472*43a90889SApple OSS Distributions
473*43a90889SApple OSS Distributions /* Return the low n bits of the bit accumulator (n < 16) */
474*43a90889SApple OSS Distributions #define BITS(n) \
475*43a90889SApple OSS Distributions ((unsigned)hold & ((1U << (n)) - 1))
476*43a90889SApple OSS Distributions
477*43a90889SApple OSS Distributions /* Remove n bits from the bit accumulator */
478*43a90889SApple OSS Distributions #define DROPBITS(n) \
479*43a90889SApple OSS Distributions do { \
480*43a90889SApple OSS Distributions hold >>= (n); \
481*43a90889SApple OSS Distributions bits -= (unsigned)(n); \
482*43a90889SApple OSS Distributions } while (0)
483*43a90889SApple OSS Distributions
484*43a90889SApple OSS Distributions /* Remove zero to seven bits as needed to go to a byte boundary */
485*43a90889SApple OSS Distributions #define BYTEBITS() \
486*43a90889SApple OSS Distributions do { \
487*43a90889SApple OSS Distributions hold >>= bits & 7; \
488*43a90889SApple OSS Distributions bits -= bits & 7; \
489*43a90889SApple OSS Distributions } while (0)
490*43a90889SApple OSS Distributions
491*43a90889SApple OSS Distributions /* Reverse the bytes in a 32-bit value */
492*43a90889SApple OSS Distributions #define REVERSE(q) \
493*43a90889SApple OSS Distributions ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
494*43a90889SApple OSS Distributions (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
495*43a90889SApple OSS Distributions
496*43a90889SApple OSS Distributions /*
497*43a90889SApple OSS Distributions inflate() uses a state machine to process as much input data and generate as
498*43a90889SApple OSS Distributions much output data as possible before returning. The state machine is
499*43a90889SApple OSS Distributions structured roughly as follows:
500*43a90889SApple OSS Distributions
501*43a90889SApple OSS Distributions for (;;) switch (state) {
502*43a90889SApple OSS Distributions ...
503*43a90889SApple OSS Distributions case STATEn:
504*43a90889SApple OSS Distributions if (not enough input data or output space to make progress)
505*43a90889SApple OSS Distributions return;
506*43a90889SApple OSS Distributions ... make progress ...
507*43a90889SApple OSS Distributions state = STATEm;
508*43a90889SApple OSS Distributions break;
509*43a90889SApple OSS Distributions ...
510*43a90889SApple OSS Distributions }
511*43a90889SApple OSS Distributions
512*43a90889SApple OSS Distributions so when inflate() is called again, the same case is attempted again, and
513*43a90889SApple OSS Distributions if the appropriate resources are provided, the machine proceeds to the
514*43a90889SApple OSS Distributions next state. The NEEDBITS() macro is usually the way the state evaluates
515*43a90889SApple OSS Distributions whether it can proceed or should return. NEEDBITS() does the return if
516*43a90889SApple OSS Distributions the requested bits are not available. The typical use of the BITS macros
517*43a90889SApple OSS Distributions is:
518*43a90889SApple OSS Distributions
519*43a90889SApple OSS Distributions NEEDBITS(n);
520*43a90889SApple OSS Distributions ... do something with BITS(n) ...
521*43a90889SApple OSS Distributions DROPBITS(n);
522*43a90889SApple OSS Distributions
523*43a90889SApple OSS Distributions where NEEDBITS(n) either returns from inflate() if there isn't enough
524*43a90889SApple OSS Distributions input left to load n bits into the accumulator, or it continues. BITS(n)
525*43a90889SApple OSS Distributions gives the low n bits in the accumulator. When done, DROPBITS(n) drops
526*43a90889SApple OSS Distributions the low n bits off the accumulator. INITBITS() clears the accumulator
527*43a90889SApple OSS Distributions and sets the number of available bits to zero. BYTEBITS() discards just
528*43a90889SApple OSS Distributions enough bits to put the accumulator on a byte boundary. After BYTEBITS()
529*43a90889SApple OSS Distributions and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
530*43a90889SApple OSS Distributions
531*43a90889SApple OSS Distributions NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
532*43a90889SApple OSS Distributions if there is no input available. The decoding of variable length codes uses
533*43a90889SApple OSS Distributions PULLBYTE() directly in order to pull just enough bytes to decode the next
534*43a90889SApple OSS Distributions code, and no more.
535*43a90889SApple OSS Distributions
536*43a90889SApple OSS Distributions Some states loop until they get enough input, making sure that enough
537*43a90889SApple OSS Distributions state information is maintained to continue the loop where it left off
538*43a90889SApple OSS Distributions if NEEDBITS() returns in the loop. For example, want, need, and keep
539*43a90889SApple OSS Distributions would all have to actually be part of the saved state in case NEEDBITS()
540*43a90889SApple OSS Distributions returns:
541*43a90889SApple OSS Distributions
542*43a90889SApple OSS Distributions case STATEw:
543*43a90889SApple OSS Distributions while (want < need) {
544*43a90889SApple OSS Distributions NEEDBITS(n);
545*43a90889SApple OSS Distributions keep[want++] = BITS(n);
546*43a90889SApple OSS Distributions DROPBITS(n);
547*43a90889SApple OSS Distributions }
548*43a90889SApple OSS Distributions state = STATEx;
549*43a90889SApple OSS Distributions case STATEx:
550*43a90889SApple OSS Distributions
551*43a90889SApple OSS Distributions As shown above, if the next state is also the next case, then the break
552*43a90889SApple OSS Distributions is omitted.
553*43a90889SApple OSS Distributions
554*43a90889SApple OSS Distributions A state may also return if there is not enough output space available to
555*43a90889SApple OSS Distributions complete that state. Those states are copying stored data, writing a
556*43a90889SApple OSS Distributions literal byte, and copying a matching string.
557*43a90889SApple OSS Distributions
558*43a90889SApple OSS Distributions When returning, a "goto inf_leave" is used to update the total counters,
559*43a90889SApple OSS Distributions update the check value, and determine whether any progress has been made
560*43a90889SApple OSS Distributions during that inflate() call in order to return the proper return code.
561*43a90889SApple OSS Distributions Progress is defined as a change in either strm->avail_in or strm->avail_out.
562*43a90889SApple OSS Distributions When there is a window, goto inf_leave will update the window with the last
563*43a90889SApple OSS Distributions output written. If a goto inf_leave occurs in the middle of decompression
564*43a90889SApple OSS Distributions and there is no window currently, goto inf_leave will create one and copy
565*43a90889SApple OSS Distributions output to the window for the next call of inflate().
566*43a90889SApple OSS Distributions
567*43a90889SApple OSS Distributions In this implementation, the flush parameter of inflate() only affects the
568*43a90889SApple OSS Distributions return code (per zlib.h). inflate() always writes as much as possible to
569*43a90889SApple OSS Distributions strm->next_out, given the space available and the provided input--the effect
570*43a90889SApple OSS Distributions documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
571*43a90889SApple OSS Distributions the allocation of and copying into a sliding window until necessary, which
572*43a90889SApple OSS Distributions provides the effect documented in zlib.h for Z_FINISH when the entire input
573*43a90889SApple OSS Distributions stream available. So the only thing the flush parameter actually does is:
574*43a90889SApple OSS Distributions when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
575*43a90889SApple OSS Distributions will return Z_BUF_ERROR if it has not reached the end of the stream.
576*43a90889SApple OSS Distributions */
577*43a90889SApple OSS Distributions
578*43a90889SApple OSS Distributions int ZEXPORT
inflate(z_streamp strm,int flush)579*43a90889SApple OSS Distributions inflate(z_streamp strm, int flush)
580*43a90889SApple OSS Distributions {
581*43a90889SApple OSS Distributions struct inflate_state FAR *state;
582*43a90889SApple OSS Distributions unsigned char FAR *next; /* next input */
583*43a90889SApple OSS Distributions unsigned char FAR *put; /* next output */
584*43a90889SApple OSS Distributions unsigned have, left; /* available input and output */
585*43a90889SApple OSS Distributions unsigned long hold; /* bit buffer */
586*43a90889SApple OSS Distributions unsigned bits; /* bits in bit buffer */
587*43a90889SApple OSS Distributions unsigned in, out; /* save starting available input and output */
588*43a90889SApple OSS Distributions unsigned copy; /* number of stored or match bytes to copy */
589*43a90889SApple OSS Distributions unsigned char FAR *from; /* where to copy match bytes from */
590*43a90889SApple OSS Distributions code this; /* current decoding table entry */
591*43a90889SApple OSS Distributions code last; /* parent table entry */
592*43a90889SApple OSS Distributions unsigned len; /* length to copy for repeats, bits to drop */
593*43a90889SApple OSS Distributions int ret; /* return code */
594*43a90889SApple OSS Distributions #ifdef GUNZIP
595*43a90889SApple OSS Distributions unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
596*43a90889SApple OSS Distributions #endif
597*43a90889SApple OSS Distributions static const unsigned short order[19] = /* permutation of code lengths */
598*43a90889SApple OSS Distributions {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
599*43a90889SApple OSS Distributions
600*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
601*43a90889SApple OSS Distributions (strm->next_in == Z_NULL && strm->avail_in != 0))
602*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
603*43a90889SApple OSS Distributions
604*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
605*43a90889SApple OSS Distributions if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
606*43a90889SApple OSS Distributions LOAD();
607*43a90889SApple OSS Distributions in = have;
608*43a90889SApple OSS Distributions out = left;
609*43a90889SApple OSS Distributions ret = Z_OK;
610*43a90889SApple OSS Distributions for (;;)
611*43a90889SApple OSS Distributions switch (state->mode) {
612*43a90889SApple OSS Distributions case HEAD:
613*43a90889SApple OSS Distributions if (state->wrap == 0) {
614*43a90889SApple OSS Distributions state->mode = TYPEDO;
615*43a90889SApple OSS Distributions break;
616*43a90889SApple OSS Distributions }
617*43a90889SApple OSS Distributions NEEDBITS(16);
618*43a90889SApple OSS Distributions #ifdef GUNZIP
619*43a90889SApple OSS Distributions if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
620*43a90889SApple OSS Distributions state->check = z_crc32(0L, Z_NULL, 0);
621*43a90889SApple OSS Distributions CRC2(state->check, hold);
622*43a90889SApple OSS Distributions INITBITS();
623*43a90889SApple OSS Distributions state->mode = FLAGS;
624*43a90889SApple OSS Distributions break;
625*43a90889SApple OSS Distributions }
626*43a90889SApple OSS Distributions state->flags = 0; /* expect zlib header */
627*43a90889SApple OSS Distributions if (state->head != Z_NULL)
628*43a90889SApple OSS Distributions state->head->done = -1;
629*43a90889SApple OSS Distributions if (!(state->wrap & 1) || /* check if zlib header allowed */
630*43a90889SApple OSS Distributions #else
631*43a90889SApple OSS Distributions if (
632*43a90889SApple OSS Distributions #endif
633*43a90889SApple OSS Distributions ((BITS(8) << 8) + (hold >> 8)) % 31) {
634*43a90889SApple OSS Distributions strm->msg = (char *)"incorrect header check";
635*43a90889SApple OSS Distributions state->mode = BAD;
636*43a90889SApple OSS Distributions break;
637*43a90889SApple OSS Distributions }
638*43a90889SApple OSS Distributions if (BITS(4) != Z_DEFLATED) {
639*43a90889SApple OSS Distributions strm->msg = (char *)"unknown compression method";
640*43a90889SApple OSS Distributions state->mode = BAD;
641*43a90889SApple OSS Distributions break;
642*43a90889SApple OSS Distributions }
643*43a90889SApple OSS Distributions DROPBITS(4);
644*43a90889SApple OSS Distributions len = BITS(4) + 8;
645*43a90889SApple OSS Distributions if (len > state->wbits) {
646*43a90889SApple OSS Distributions strm->msg = (char *)"invalid window size";
647*43a90889SApple OSS Distributions state->mode = BAD;
648*43a90889SApple OSS Distributions break;
649*43a90889SApple OSS Distributions }
650*43a90889SApple OSS Distributions state->dmax = 1U << len;
651*43a90889SApple OSS Distributions Tracev((stderr, "inflate: zlib header ok\n"));
652*43a90889SApple OSS Distributions strm->adler = state->check = adler32(0L, Z_NULL, 0);
653*43a90889SApple OSS Distributions state->mode = hold & 0x200 ? DICTID : TYPE;
654*43a90889SApple OSS Distributions INITBITS();
655*43a90889SApple OSS Distributions break;
656*43a90889SApple OSS Distributions #ifdef GUNZIP
657*43a90889SApple OSS Distributions case FLAGS:
658*43a90889SApple OSS Distributions NEEDBITS(16);
659*43a90889SApple OSS Distributions state->flags = (int)(hold);
660*43a90889SApple OSS Distributions if ((state->flags & 0xff) != Z_DEFLATED) {
661*43a90889SApple OSS Distributions strm->msg = (char *)"unknown compression method";
662*43a90889SApple OSS Distributions state->mode = BAD;
663*43a90889SApple OSS Distributions break;
664*43a90889SApple OSS Distributions }
665*43a90889SApple OSS Distributions if (state->flags & 0xe000) {
666*43a90889SApple OSS Distributions strm->msg = (char *)"unknown header flags set";
667*43a90889SApple OSS Distributions state->mode = BAD;
668*43a90889SApple OSS Distributions break;
669*43a90889SApple OSS Distributions }
670*43a90889SApple OSS Distributions if (state->head != Z_NULL)
671*43a90889SApple OSS Distributions state->head->text = (int)((hold >> 8) & 1);
672*43a90889SApple OSS Distributions if (state->flags & 0x0200) CRC2(state->check, hold);
673*43a90889SApple OSS Distributions INITBITS();
674*43a90889SApple OSS Distributions state->mode = TIME;
675*43a90889SApple OSS Distributions OS_FALLTHROUGH;
676*43a90889SApple OSS Distributions case TIME:
677*43a90889SApple OSS Distributions NEEDBITS(32);
678*43a90889SApple OSS Distributions if (state->head != Z_NULL)
679*43a90889SApple OSS Distributions state->head->time = hold;
680*43a90889SApple OSS Distributions if (state->flags & 0x0200) CRC4(state->check, hold);
681*43a90889SApple OSS Distributions INITBITS();
682*43a90889SApple OSS Distributions state->mode = OS;
683*43a90889SApple OSS Distributions OS_FALLTHROUGH;
684*43a90889SApple OSS Distributions case OS:
685*43a90889SApple OSS Distributions NEEDBITS(16);
686*43a90889SApple OSS Distributions if (state->head != Z_NULL) {
687*43a90889SApple OSS Distributions state->head->xflags = (int)(hold & 0xff);
688*43a90889SApple OSS Distributions state->head->os = (int)(hold >> 8);
689*43a90889SApple OSS Distributions }
690*43a90889SApple OSS Distributions if (state->flags & 0x0200) CRC2(state->check, hold);
691*43a90889SApple OSS Distributions INITBITS();
692*43a90889SApple OSS Distributions state->mode = EXLEN;
693*43a90889SApple OSS Distributions OS_FALLTHROUGH;
694*43a90889SApple OSS Distributions case EXLEN:
695*43a90889SApple OSS Distributions if (state->flags & 0x0400) {
696*43a90889SApple OSS Distributions NEEDBITS(16);
697*43a90889SApple OSS Distributions state->length = (unsigned)(hold);
698*43a90889SApple OSS Distributions if (state->head != Z_NULL)
699*43a90889SApple OSS Distributions state->head->extra_len = (unsigned)hold;
700*43a90889SApple OSS Distributions if (state->flags & 0x0200) CRC2(state->check, hold);
701*43a90889SApple OSS Distributions INITBITS();
702*43a90889SApple OSS Distributions }
703*43a90889SApple OSS Distributions else if (state->head != Z_NULL)
704*43a90889SApple OSS Distributions state->head->extra = Z_NULL;
705*43a90889SApple OSS Distributions state->mode = EXTRA;
706*43a90889SApple OSS Distributions OS_FALLTHROUGH;
707*43a90889SApple OSS Distributions case EXTRA:
708*43a90889SApple OSS Distributions if (state->flags & 0x0400) {
709*43a90889SApple OSS Distributions copy = state->length;
710*43a90889SApple OSS Distributions if (copy > have) copy = have;
711*43a90889SApple OSS Distributions if (copy) {
712*43a90889SApple OSS Distributions if (state->head != Z_NULL &&
713*43a90889SApple OSS Distributions state->head->extra != Z_NULL) {
714*43a90889SApple OSS Distributions len = state->head->extra_len - state->length;
715*43a90889SApple OSS Distributions zmemcpy(state->head->extra + len, next,
716*43a90889SApple OSS Distributions len + copy > state->head->extra_max ?
717*43a90889SApple OSS Distributions state->head->extra_max - len : copy);
718*43a90889SApple OSS Distributions }
719*43a90889SApple OSS Distributions if (state->flags & 0x0200)
720*43a90889SApple OSS Distributions state->check = z_crc32(state->check, next, copy);
721*43a90889SApple OSS Distributions have -= copy;
722*43a90889SApple OSS Distributions next += copy;
723*43a90889SApple OSS Distributions state->length -= copy;
724*43a90889SApple OSS Distributions }
725*43a90889SApple OSS Distributions if (state->length) goto inf_leave;
726*43a90889SApple OSS Distributions }
727*43a90889SApple OSS Distributions state->length = 0;
728*43a90889SApple OSS Distributions state->mode = NAME;
729*43a90889SApple OSS Distributions OS_FALLTHROUGH;
730*43a90889SApple OSS Distributions case NAME:
731*43a90889SApple OSS Distributions if (state->flags & 0x0800) {
732*43a90889SApple OSS Distributions if (have == 0) goto inf_leave;
733*43a90889SApple OSS Distributions copy = 0;
734*43a90889SApple OSS Distributions do {
735*43a90889SApple OSS Distributions len = (unsigned)(next[copy++]);
736*43a90889SApple OSS Distributions if (state->head != Z_NULL &&
737*43a90889SApple OSS Distributions state->head->name != Z_NULL &&
738*43a90889SApple OSS Distributions state->length < state->head->name_max)
739*43a90889SApple OSS Distributions state->head->name[state->length++] = (Bytef)len;
740*43a90889SApple OSS Distributions } while (len && copy < have);
741*43a90889SApple OSS Distributions if (state->flags & 0x0200)
742*43a90889SApple OSS Distributions state->check = z_crc32(state->check, next, copy);
743*43a90889SApple OSS Distributions have -= copy;
744*43a90889SApple OSS Distributions next += copy;
745*43a90889SApple OSS Distributions if (len) goto inf_leave;
746*43a90889SApple OSS Distributions }
747*43a90889SApple OSS Distributions else if (state->head != Z_NULL)
748*43a90889SApple OSS Distributions state->head->name = Z_NULL;
749*43a90889SApple OSS Distributions state->length = 0;
750*43a90889SApple OSS Distributions state->mode = COMMENT;
751*43a90889SApple OSS Distributions OS_FALLTHROUGH;
752*43a90889SApple OSS Distributions case COMMENT:
753*43a90889SApple OSS Distributions if (state->flags & 0x1000) {
754*43a90889SApple OSS Distributions if (have == 0) goto inf_leave;
755*43a90889SApple OSS Distributions copy = 0;
756*43a90889SApple OSS Distributions do {
757*43a90889SApple OSS Distributions len = (unsigned)(next[copy++]);
758*43a90889SApple OSS Distributions if (state->head != Z_NULL &&
759*43a90889SApple OSS Distributions state->head->comment != Z_NULL &&
760*43a90889SApple OSS Distributions state->length < state->head->comm_max)
761*43a90889SApple OSS Distributions state->head->comment[state->length++] = (Bytef)len;
762*43a90889SApple OSS Distributions } while (len && copy < have);
763*43a90889SApple OSS Distributions if (state->flags & 0x0200)
764*43a90889SApple OSS Distributions state->check = z_crc32(state->check, next, copy);
765*43a90889SApple OSS Distributions have -= copy;
766*43a90889SApple OSS Distributions next += copy;
767*43a90889SApple OSS Distributions if (len) goto inf_leave;
768*43a90889SApple OSS Distributions }
769*43a90889SApple OSS Distributions else if (state->head != Z_NULL)
770*43a90889SApple OSS Distributions state->head->comment = Z_NULL;
771*43a90889SApple OSS Distributions state->mode = HCRC;
772*43a90889SApple OSS Distributions OS_FALLTHROUGH;
773*43a90889SApple OSS Distributions case HCRC:
774*43a90889SApple OSS Distributions if (state->flags & 0x0200) {
775*43a90889SApple OSS Distributions NEEDBITS(16);
776*43a90889SApple OSS Distributions if (hold != (state->check & 0xffff)) {
777*43a90889SApple OSS Distributions strm->msg = (char *)"header crc mismatch";
778*43a90889SApple OSS Distributions state->mode = BAD;
779*43a90889SApple OSS Distributions break;
780*43a90889SApple OSS Distributions }
781*43a90889SApple OSS Distributions INITBITS();
782*43a90889SApple OSS Distributions }
783*43a90889SApple OSS Distributions if (state->head != Z_NULL) {
784*43a90889SApple OSS Distributions state->head->hcrc = (int)((state->flags >> 9) & 1);
785*43a90889SApple OSS Distributions state->head->done = 1;
786*43a90889SApple OSS Distributions }
787*43a90889SApple OSS Distributions strm->adler = state->check = z_crc32(0L, Z_NULL, 0);
788*43a90889SApple OSS Distributions state->mode = TYPE;
789*43a90889SApple OSS Distributions break;
790*43a90889SApple OSS Distributions #else
791*43a90889SApple OSS Distributions OS_FALLTHROUGH;
792*43a90889SApple OSS Distributions #endif
793*43a90889SApple OSS Distributions case DICTID:
794*43a90889SApple OSS Distributions NEEDBITS(32);
795*43a90889SApple OSS Distributions strm->adler = state->check = REVERSE(hold);
796*43a90889SApple OSS Distributions INITBITS();
797*43a90889SApple OSS Distributions state->mode = DICT;
798*43a90889SApple OSS Distributions OS_FALLTHROUGH;
799*43a90889SApple OSS Distributions case DICT:
800*43a90889SApple OSS Distributions if (state->havedict == 0) {
801*43a90889SApple OSS Distributions RESTORE();
802*43a90889SApple OSS Distributions return Z_NEED_DICT;
803*43a90889SApple OSS Distributions }
804*43a90889SApple OSS Distributions strm->adler = state->check = adler32(0L, Z_NULL, 0);
805*43a90889SApple OSS Distributions state->mode = TYPE;
806*43a90889SApple OSS Distributions OS_FALLTHROUGH;
807*43a90889SApple OSS Distributions case TYPE:
808*43a90889SApple OSS Distributions if (flush == Z_BLOCK) goto inf_leave;
809*43a90889SApple OSS Distributions OS_FALLTHROUGH;
810*43a90889SApple OSS Distributions case TYPEDO:
811*43a90889SApple OSS Distributions if (state->last) {
812*43a90889SApple OSS Distributions BYTEBITS();
813*43a90889SApple OSS Distributions state->mode = CHECK;
814*43a90889SApple OSS Distributions break;
815*43a90889SApple OSS Distributions }
816*43a90889SApple OSS Distributions NEEDBITS(3);
817*43a90889SApple OSS Distributions state->last = BITS(1);
818*43a90889SApple OSS Distributions DROPBITS(1);
819*43a90889SApple OSS Distributions switch (BITS(2)) {
820*43a90889SApple OSS Distributions case 0: /* stored block */
821*43a90889SApple OSS Distributions Tracev((stderr, "inflate: stored block%s\n",
822*43a90889SApple OSS Distributions state->last ? " (last)" : ""));
823*43a90889SApple OSS Distributions state->mode = STORED;
824*43a90889SApple OSS Distributions break;
825*43a90889SApple OSS Distributions case 1: /* fixed block */
826*43a90889SApple OSS Distributions fixedtables(state);
827*43a90889SApple OSS Distributions Tracev((stderr, "inflate: fixed codes block%s\n",
828*43a90889SApple OSS Distributions state->last ? " (last)" : ""));
829*43a90889SApple OSS Distributions state->mode = LEN; /* decode codes */
830*43a90889SApple OSS Distributions break;
831*43a90889SApple OSS Distributions case 2: /* dynamic block */
832*43a90889SApple OSS Distributions Tracev((stderr, "inflate: dynamic codes block%s\n",
833*43a90889SApple OSS Distributions state->last ? " (last)" : ""));
834*43a90889SApple OSS Distributions state->mode = TABLE;
835*43a90889SApple OSS Distributions break;
836*43a90889SApple OSS Distributions case 3:
837*43a90889SApple OSS Distributions strm->msg = (char *)"invalid block type";
838*43a90889SApple OSS Distributions state->mode = BAD;
839*43a90889SApple OSS Distributions }
840*43a90889SApple OSS Distributions DROPBITS(2);
841*43a90889SApple OSS Distributions break;
842*43a90889SApple OSS Distributions case STORED:
843*43a90889SApple OSS Distributions BYTEBITS(); /* go to byte boundary */
844*43a90889SApple OSS Distributions NEEDBITS(32);
845*43a90889SApple OSS Distributions if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
846*43a90889SApple OSS Distributions strm->msg = (char *)"invalid stored block lengths";
847*43a90889SApple OSS Distributions state->mode = BAD;
848*43a90889SApple OSS Distributions break;
849*43a90889SApple OSS Distributions }
850*43a90889SApple OSS Distributions state->length = (unsigned)hold & 0xffff;
851*43a90889SApple OSS Distributions Tracev((stderr, "inflate: stored length %u\n",
852*43a90889SApple OSS Distributions state->length));
853*43a90889SApple OSS Distributions INITBITS();
854*43a90889SApple OSS Distributions state->mode = COPY;
855*43a90889SApple OSS Distributions OS_FALLTHROUGH;
856*43a90889SApple OSS Distributions case COPY:
857*43a90889SApple OSS Distributions copy = state->length;
858*43a90889SApple OSS Distributions if (copy) {
859*43a90889SApple OSS Distributions if (copy > have) copy = have;
860*43a90889SApple OSS Distributions if (copy > left) copy = left;
861*43a90889SApple OSS Distributions if (copy == 0) goto inf_leave;
862*43a90889SApple OSS Distributions zmemcpy(put, next, copy);
863*43a90889SApple OSS Distributions have -= copy;
864*43a90889SApple OSS Distributions next += copy;
865*43a90889SApple OSS Distributions left -= copy;
866*43a90889SApple OSS Distributions put += copy;
867*43a90889SApple OSS Distributions state->length -= copy;
868*43a90889SApple OSS Distributions break;
869*43a90889SApple OSS Distributions }
870*43a90889SApple OSS Distributions Tracev((stderr, "inflate: stored end\n"));
871*43a90889SApple OSS Distributions state->mode = TYPE;
872*43a90889SApple OSS Distributions break;
873*43a90889SApple OSS Distributions case TABLE:
874*43a90889SApple OSS Distributions NEEDBITS(14);
875*43a90889SApple OSS Distributions state->nlen = BITS(5) + 257;
876*43a90889SApple OSS Distributions DROPBITS(5);
877*43a90889SApple OSS Distributions state->ndist = BITS(5) + 1;
878*43a90889SApple OSS Distributions DROPBITS(5);
879*43a90889SApple OSS Distributions state->ncode = BITS(4) + 4;
880*43a90889SApple OSS Distributions DROPBITS(4);
881*43a90889SApple OSS Distributions #ifndef PKZIP_BUG_WORKAROUND
882*43a90889SApple OSS Distributions if (state->nlen > 286 || state->ndist > 30) {
883*43a90889SApple OSS Distributions strm->msg = (char *)"too many length or distance symbols";
884*43a90889SApple OSS Distributions state->mode = BAD;
885*43a90889SApple OSS Distributions break;
886*43a90889SApple OSS Distributions }
887*43a90889SApple OSS Distributions #endif
888*43a90889SApple OSS Distributions Tracev((stderr, "inflate: table sizes ok\n"));
889*43a90889SApple OSS Distributions state->have = 0;
890*43a90889SApple OSS Distributions state->mode = LENLENS;
891*43a90889SApple OSS Distributions OS_FALLTHROUGH;
892*43a90889SApple OSS Distributions case LENLENS:
893*43a90889SApple OSS Distributions while (state->have < state->ncode) {
894*43a90889SApple OSS Distributions NEEDBITS(3);
895*43a90889SApple OSS Distributions state->lens[order[state->have++]] = (unsigned short)BITS(3);
896*43a90889SApple OSS Distributions DROPBITS(3);
897*43a90889SApple OSS Distributions }
898*43a90889SApple OSS Distributions while (state->have < 19)
899*43a90889SApple OSS Distributions state->lens[order[state->have++]] = 0;
900*43a90889SApple OSS Distributions state->next = state->codes;
901*43a90889SApple OSS Distributions state->lencode = (code const FAR *)(state->next);
902*43a90889SApple OSS Distributions state->lenbits = 7;
903*43a90889SApple OSS Distributions ret = inflate_table(CODES, state->lens, 19, &(state->next),
904*43a90889SApple OSS Distributions &(state->lenbits), state->work);
905*43a90889SApple OSS Distributions if (ret) {
906*43a90889SApple OSS Distributions strm->msg = (char *)"invalid code lengths set";
907*43a90889SApple OSS Distributions state->mode = BAD;
908*43a90889SApple OSS Distributions break;
909*43a90889SApple OSS Distributions }
910*43a90889SApple OSS Distributions Tracev((stderr, "inflate: code lengths ok\n"));
911*43a90889SApple OSS Distributions state->have = 0;
912*43a90889SApple OSS Distributions state->mode = CODELENS;
913*43a90889SApple OSS Distributions OS_FALLTHROUGH;
914*43a90889SApple OSS Distributions case CODELENS:
915*43a90889SApple OSS Distributions while (state->have < state->nlen + state->ndist) {
916*43a90889SApple OSS Distributions for (;;) {
917*43a90889SApple OSS Distributions this = state->lencode[BITS(state->lenbits)];
918*43a90889SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
919*43a90889SApple OSS Distributions PULLBYTE();
920*43a90889SApple OSS Distributions }
921*43a90889SApple OSS Distributions if (this.val < 16) {
922*43a90889SApple OSS Distributions NEEDBITS(this.bits);
923*43a90889SApple OSS Distributions DROPBITS(this.bits);
924*43a90889SApple OSS Distributions state->lens[state->have++] = this.val;
925*43a90889SApple OSS Distributions }
926*43a90889SApple OSS Distributions else {
927*43a90889SApple OSS Distributions if (this.val == 16) {
928*43a90889SApple OSS Distributions NEEDBITS(this.bits + 2);
929*43a90889SApple OSS Distributions DROPBITS(this.bits);
930*43a90889SApple OSS Distributions if (state->have == 0) {
931*43a90889SApple OSS Distributions strm->msg = (char *)"invalid bit length repeat";
932*43a90889SApple OSS Distributions state->mode = BAD;
933*43a90889SApple OSS Distributions break;
934*43a90889SApple OSS Distributions }
935*43a90889SApple OSS Distributions len = state->lens[state->have - 1];
936*43a90889SApple OSS Distributions copy = 3 + BITS(2);
937*43a90889SApple OSS Distributions DROPBITS(2);
938*43a90889SApple OSS Distributions }
939*43a90889SApple OSS Distributions else if (this.val == 17) {
940*43a90889SApple OSS Distributions NEEDBITS(this.bits + 3);
941*43a90889SApple OSS Distributions DROPBITS(this.bits);
942*43a90889SApple OSS Distributions len = 0;
943*43a90889SApple OSS Distributions copy = 3 + BITS(3);
944*43a90889SApple OSS Distributions DROPBITS(3);
945*43a90889SApple OSS Distributions }
946*43a90889SApple OSS Distributions else {
947*43a90889SApple OSS Distributions NEEDBITS(this.bits + 7);
948*43a90889SApple OSS Distributions DROPBITS(this.bits);
949*43a90889SApple OSS Distributions len = 0;
950*43a90889SApple OSS Distributions copy = 11 + BITS(7);
951*43a90889SApple OSS Distributions DROPBITS(7);
952*43a90889SApple OSS Distributions }
953*43a90889SApple OSS Distributions if (state->have + copy > state->nlen + state->ndist) {
954*43a90889SApple OSS Distributions strm->msg = (char *)"invalid bit length repeat";
955*43a90889SApple OSS Distributions state->mode = BAD;
956*43a90889SApple OSS Distributions break;
957*43a90889SApple OSS Distributions }
958*43a90889SApple OSS Distributions while (copy--)
959*43a90889SApple OSS Distributions state->lens[state->have++] = (unsigned short)len;
960*43a90889SApple OSS Distributions }
961*43a90889SApple OSS Distributions }
962*43a90889SApple OSS Distributions
963*43a90889SApple OSS Distributions /* handle error breaks in while */
964*43a90889SApple OSS Distributions if (state->mode == BAD) break;
965*43a90889SApple OSS Distributions
966*43a90889SApple OSS Distributions /* build code tables */
967*43a90889SApple OSS Distributions state->next = state->codes;
968*43a90889SApple OSS Distributions state->lencode = (code const FAR *)(state->next);
969*43a90889SApple OSS Distributions state->lenbits = 9;
970*43a90889SApple OSS Distributions ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
971*43a90889SApple OSS Distributions &(state->lenbits), state->work);
972*43a90889SApple OSS Distributions if (ret) {
973*43a90889SApple OSS Distributions strm->msg = (char *)"invalid literal/lengths set";
974*43a90889SApple OSS Distributions state->mode = BAD;
975*43a90889SApple OSS Distributions break;
976*43a90889SApple OSS Distributions }
977*43a90889SApple OSS Distributions state->distcode = (code const FAR *)(state->next);
978*43a90889SApple OSS Distributions state->distbits = 6;
979*43a90889SApple OSS Distributions ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
980*43a90889SApple OSS Distributions &(state->next), &(state->distbits), state->work);
981*43a90889SApple OSS Distributions if (ret) {
982*43a90889SApple OSS Distributions strm->msg = (char *)"invalid distances set";
983*43a90889SApple OSS Distributions state->mode = BAD;
984*43a90889SApple OSS Distributions break;
985*43a90889SApple OSS Distributions }
986*43a90889SApple OSS Distributions Tracev((stderr, "inflate: codes ok\n"));
987*43a90889SApple OSS Distributions state->mode = LEN;
988*43a90889SApple OSS Distributions OS_FALLTHROUGH;
989*43a90889SApple OSS Distributions case LEN:
990*43a90889SApple OSS Distributions if (have >= 6 && left >= 258) {
991*43a90889SApple OSS Distributions RESTORE();
992*43a90889SApple OSS Distributions inflate_fast(strm, out);
993*43a90889SApple OSS Distributions LOAD();
994*43a90889SApple OSS Distributions break;
995*43a90889SApple OSS Distributions }
996*43a90889SApple OSS Distributions for (;;) {
997*43a90889SApple OSS Distributions this = state->lencode[BITS(state->lenbits)];
998*43a90889SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
999*43a90889SApple OSS Distributions PULLBYTE();
1000*43a90889SApple OSS Distributions }
1001*43a90889SApple OSS Distributions if (this.op && (this.op & 0xf0) == 0) {
1002*43a90889SApple OSS Distributions last = this;
1003*43a90889SApple OSS Distributions for (;;) {
1004*43a90889SApple OSS Distributions this = state->lencode[last.val +
1005*43a90889SApple OSS Distributions (BITS(last.bits + last.op) >> last.bits)];
1006*43a90889SApple OSS Distributions if ((unsigned)(last.bits + this.bits) <= bits) break;
1007*43a90889SApple OSS Distributions PULLBYTE();
1008*43a90889SApple OSS Distributions }
1009*43a90889SApple OSS Distributions DROPBITS(last.bits);
1010*43a90889SApple OSS Distributions }
1011*43a90889SApple OSS Distributions DROPBITS(this.bits);
1012*43a90889SApple OSS Distributions state->length = (unsigned)this.val;
1013*43a90889SApple OSS Distributions if ((int)(this.op) == 0) {
1014*43a90889SApple OSS Distributions Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
1015*43a90889SApple OSS Distributions "inflate: literal '%c'\n" :
1016*43a90889SApple OSS Distributions "inflate: literal 0x%02x\n", this.val));
1017*43a90889SApple OSS Distributions state->mode = LIT;
1018*43a90889SApple OSS Distributions break;
1019*43a90889SApple OSS Distributions }
1020*43a90889SApple OSS Distributions if (this.op & 32) {
1021*43a90889SApple OSS Distributions Tracevv((stderr, "inflate: end of block\n"));
1022*43a90889SApple OSS Distributions state->mode = TYPE;
1023*43a90889SApple OSS Distributions break;
1024*43a90889SApple OSS Distributions }
1025*43a90889SApple OSS Distributions if (this.op & 64) {
1026*43a90889SApple OSS Distributions strm->msg = (char *)"invalid literal/length code";
1027*43a90889SApple OSS Distributions state->mode = BAD;
1028*43a90889SApple OSS Distributions break;
1029*43a90889SApple OSS Distributions }
1030*43a90889SApple OSS Distributions state->extra = (unsigned)(this.op) & 15;
1031*43a90889SApple OSS Distributions state->mode = LENEXT;
1032*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1033*43a90889SApple OSS Distributions case LENEXT:
1034*43a90889SApple OSS Distributions if (state->extra) {
1035*43a90889SApple OSS Distributions NEEDBITS(state->extra);
1036*43a90889SApple OSS Distributions state->length += BITS(state->extra);
1037*43a90889SApple OSS Distributions DROPBITS(state->extra);
1038*43a90889SApple OSS Distributions }
1039*43a90889SApple OSS Distributions Tracevv((stderr, "inflate: length %u\n", state->length));
1040*43a90889SApple OSS Distributions state->mode = DIST;
1041*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1042*43a90889SApple OSS Distributions case DIST:
1043*43a90889SApple OSS Distributions for (;;) {
1044*43a90889SApple OSS Distributions this = state->distcode[BITS(state->distbits)];
1045*43a90889SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
1046*43a90889SApple OSS Distributions PULLBYTE();
1047*43a90889SApple OSS Distributions }
1048*43a90889SApple OSS Distributions if ((this.op & 0xf0) == 0) {
1049*43a90889SApple OSS Distributions last = this;
1050*43a90889SApple OSS Distributions for (;;) {
1051*43a90889SApple OSS Distributions this = state->distcode[last.val +
1052*43a90889SApple OSS Distributions (BITS(last.bits + last.op) >> last.bits)];
1053*43a90889SApple OSS Distributions if ((unsigned)(last.bits + this.bits) <= bits) break;
1054*43a90889SApple OSS Distributions PULLBYTE();
1055*43a90889SApple OSS Distributions }
1056*43a90889SApple OSS Distributions DROPBITS(last.bits);
1057*43a90889SApple OSS Distributions }
1058*43a90889SApple OSS Distributions DROPBITS(this.bits);
1059*43a90889SApple OSS Distributions if (this.op & 64) {
1060*43a90889SApple OSS Distributions strm->msg = (char *)"invalid distance code";
1061*43a90889SApple OSS Distributions state->mode = BAD;
1062*43a90889SApple OSS Distributions break;
1063*43a90889SApple OSS Distributions }
1064*43a90889SApple OSS Distributions state->offset = (unsigned)this.val;
1065*43a90889SApple OSS Distributions state->extra = (unsigned)(this.op) & 15;
1066*43a90889SApple OSS Distributions state->mode = DISTEXT;
1067*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1068*43a90889SApple OSS Distributions case DISTEXT:
1069*43a90889SApple OSS Distributions if (state->extra) {
1070*43a90889SApple OSS Distributions NEEDBITS(state->extra);
1071*43a90889SApple OSS Distributions state->offset += BITS(state->extra);
1072*43a90889SApple OSS Distributions DROPBITS(state->extra);
1073*43a90889SApple OSS Distributions }
1074*43a90889SApple OSS Distributions #ifdef INFLATE_STRICT
1075*43a90889SApple OSS Distributions if (state->offset > state->dmax) {
1076*43a90889SApple OSS Distributions strm->msg = (char *)"invalid distance too far back";
1077*43a90889SApple OSS Distributions state->mode = BAD;
1078*43a90889SApple OSS Distributions break;
1079*43a90889SApple OSS Distributions }
1080*43a90889SApple OSS Distributions #endif
1081*43a90889SApple OSS Distributions if (state->offset > state->whave + out - left) {
1082*43a90889SApple OSS Distributions strm->msg = (char *)"invalid distance too far back";
1083*43a90889SApple OSS Distributions state->mode = BAD;
1084*43a90889SApple OSS Distributions break;
1085*43a90889SApple OSS Distributions }
1086*43a90889SApple OSS Distributions Tracevv((stderr, "inflate: distance %u\n", state->offset));
1087*43a90889SApple OSS Distributions state->mode = MATCH;
1088*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1089*43a90889SApple OSS Distributions case MATCH:
1090*43a90889SApple OSS Distributions if (left == 0) goto inf_leave;
1091*43a90889SApple OSS Distributions copy = out - left;
1092*43a90889SApple OSS Distributions if (state->offset > copy) { /* copy from window */
1093*43a90889SApple OSS Distributions copy = state->offset - copy;
1094*43a90889SApple OSS Distributions if (copy > state->write) {
1095*43a90889SApple OSS Distributions copy -= state->write;
1096*43a90889SApple OSS Distributions from = state->window + (state->wsize - copy);
1097*43a90889SApple OSS Distributions }
1098*43a90889SApple OSS Distributions else
1099*43a90889SApple OSS Distributions from = state->window + (state->write - copy);
1100*43a90889SApple OSS Distributions if (copy > state->length) copy = state->length;
1101*43a90889SApple OSS Distributions }
1102*43a90889SApple OSS Distributions else { /* copy from output */
1103*43a90889SApple OSS Distributions from = put - state->offset;
1104*43a90889SApple OSS Distributions copy = state->length;
1105*43a90889SApple OSS Distributions }
1106*43a90889SApple OSS Distributions if (copy > left) copy = left;
1107*43a90889SApple OSS Distributions left -= copy;
1108*43a90889SApple OSS Distributions state->length -= copy;
1109*43a90889SApple OSS Distributions do {
1110*43a90889SApple OSS Distributions *put++ = *from++;
1111*43a90889SApple OSS Distributions } while (--copy);
1112*43a90889SApple OSS Distributions if (state->length == 0) state->mode = LEN;
1113*43a90889SApple OSS Distributions break;
1114*43a90889SApple OSS Distributions case LIT:
1115*43a90889SApple OSS Distributions if (left == 0) goto inf_leave;
1116*43a90889SApple OSS Distributions *put++ = (unsigned char)(state->length);
1117*43a90889SApple OSS Distributions left--;
1118*43a90889SApple OSS Distributions state->mode = LEN;
1119*43a90889SApple OSS Distributions break;
1120*43a90889SApple OSS Distributions case CHECK:
1121*43a90889SApple OSS Distributions if (state->wrap) {
1122*43a90889SApple OSS Distributions NEEDBITS(32);
1123*43a90889SApple OSS Distributions out -= left;
1124*43a90889SApple OSS Distributions strm->total_out += out;
1125*43a90889SApple OSS Distributions state->total += out;
1126*43a90889SApple OSS Distributions if (out)
1127*43a90889SApple OSS Distributions strm->adler = state->check =
1128*43a90889SApple OSS Distributions UPDATE(state->check, put - out, out);
1129*43a90889SApple OSS Distributions out = left;
1130*43a90889SApple OSS Distributions if ((
1131*43a90889SApple OSS Distributions #ifdef GUNZIP
1132*43a90889SApple OSS Distributions state->flags ? hold :
1133*43a90889SApple OSS Distributions #endif
1134*43a90889SApple OSS Distributions REVERSE(hold)) != state->check) {
1135*43a90889SApple OSS Distributions strm->msg = (char *)"incorrect data check";
1136*43a90889SApple OSS Distributions state->mode = BAD;
1137*43a90889SApple OSS Distributions break;
1138*43a90889SApple OSS Distributions }
1139*43a90889SApple OSS Distributions INITBITS();
1140*43a90889SApple OSS Distributions Tracev((stderr, "inflate: check matches trailer\n"));
1141*43a90889SApple OSS Distributions }
1142*43a90889SApple OSS Distributions #ifdef GUNZIP
1143*43a90889SApple OSS Distributions state->mode = LENGTH;
1144*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1145*43a90889SApple OSS Distributions case LENGTH:
1146*43a90889SApple OSS Distributions if (state->wrap && state->flags) {
1147*43a90889SApple OSS Distributions NEEDBITS(32);
1148*43a90889SApple OSS Distributions if (hold != (state->total & 0xffffffffUL)) {
1149*43a90889SApple OSS Distributions strm->msg = (char *)"incorrect length check";
1150*43a90889SApple OSS Distributions state->mode = BAD;
1151*43a90889SApple OSS Distributions break;
1152*43a90889SApple OSS Distributions }
1153*43a90889SApple OSS Distributions INITBITS();
1154*43a90889SApple OSS Distributions Tracev((stderr, "inflate: length matches trailer\n"));
1155*43a90889SApple OSS Distributions }
1156*43a90889SApple OSS Distributions #endif
1157*43a90889SApple OSS Distributions state->mode = DONE;
1158*43a90889SApple OSS Distributions OS_FALLTHROUGH;
1159*43a90889SApple OSS Distributions case DONE:
1160*43a90889SApple OSS Distributions ret = Z_STREAM_END;
1161*43a90889SApple OSS Distributions goto inf_leave;
1162*43a90889SApple OSS Distributions case BAD:
1163*43a90889SApple OSS Distributions ret = Z_DATA_ERROR;
1164*43a90889SApple OSS Distributions goto inf_leave;
1165*43a90889SApple OSS Distributions case MEM:
1166*43a90889SApple OSS Distributions return Z_MEM_ERROR;
1167*43a90889SApple OSS Distributions case SYNC:
1168*43a90889SApple OSS Distributions default:
1169*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
1170*43a90889SApple OSS Distributions }
1171*43a90889SApple OSS Distributions
1172*43a90889SApple OSS Distributions /*
1173*43a90889SApple OSS Distributions Return from inflate(), updating the total counts and the check value.
1174*43a90889SApple OSS Distributions If there was no progress during the inflate() call, return a buffer
1175*43a90889SApple OSS Distributions error. Call updatewindow() to create and/or update the window state.
1176*43a90889SApple OSS Distributions Note: a memory error from inflate() is non-recoverable.
1177*43a90889SApple OSS Distributions */
1178*43a90889SApple OSS Distributions inf_leave:
1179*43a90889SApple OSS Distributions RESTORE();
1180*43a90889SApple OSS Distributions if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
1181*43a90889SApple OSS Distributions if (updatewindow(strm, out)) {
1182*43a90889SApple OSS Distributions state->mode = MEM;
1183*43a90889SApple OSS Distributions return Z_MEM_ERROR;
1184*43a90889SApple OSS Distributions }
1185*43a90889SApple OSS Distributions in -= strm->avail_in;
1186*43a90889SApple OSS Distributions out -= strm->avail_out;
1187*43a90889SApple OSS Distributions strm->total_in += in;
1188*43a90889SApple OSS Distributions strm->total_out += out;
1189*43a90889SApple OSS Distributions state->total += out;
1190*43a90889SApple OSS Distributions if (state->wrap && out)
1191*43a90889SApple OSS Distributions strm->adler = state->check =
1192*43a90889SApple OSS Distributions UPDATE(state->check, strm->next_out - out, out);
1193*43a90889SApple OSS Distributions strm->data_type = state->bits + (state->last ? 64 : 0) +
1194*43a90889SApple OSS Distributions (state->mode == TYPE ? 128 : 0);
1195*43a90889SApple OSS Distributions if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1196*43a90889SApple OSS Distributions ret = Z_BUF_ERROR;
1197*43a90889SApple OSS Distributions return ret;
1198*43a90889SApple OSS Distributions }
1199*43a90889SApple OSS Distributions
1200*43a90889SApple OSS Distributions int ZEXPORT
inflateEnd(z_streamp strm)1201*43a90889SApple OSS Distributions inflateEnd(z_streamp strm)
1202*43a90889SApple OSS Distributions {
1203*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1204*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
1205*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
1206*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
1207*43a90889SApple OSS Distributions if (state->window != Z_NULL) ZFREE(strm, state->window);
1208*43a90889SApple OSS Distributions ZFREE(strm, strm->state);
1209*43a90889SApple OSS Distributions strm->state = Z_NULL;
1210*43a90889SApple OSS Distributions Tracev((stderr, "inflate: end\n"));
1211*43a90889SApple OSS Distributions return Z_OK;
1212*43a90889SApple OSS Distributions }
1213*43a90889SApple OSS Distributions
1214*43a90889SApple OSS Distributions int ZEXPORT
inflateSetDictionary(z_streamp strm,const Bytef * dictionary,uInt dictLength)1215*43a90889SApple OSS Distributions inflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength)
1216*43a90889SApple OSS Distributions {
1217*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1218*43a90889SApple OSS Distributions unsigned long id;
1219*43a90889SApple OSS Distributions
1220*43a90889SApple OSS Distributions /* check state */
1221*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1222*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
1223*43a90889SApple OSS Distributions if (state->wrap != 0 && state->mode != DICT)
1224*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
1225*43a90889SApple OSS Distributions
1226*43a90889SApple OSS Distributions /* check for correct dictionary id */
1227*43a90889SApple OSS Distributions if (state->mode == DICT) {
1228*43a90889SApple OSS Distributions id = adler32(0L, Z_NULL, 0);
1229*43a90889SApple OSS Distributions id = adler32(id, dictionary, dictLength);
1230*43a90889SApple OSS Distributions if (id != state->check)
1231*43a90889SApple OSS Distributions return Z_DATA_ERROR;
1232*43a90889SApple OSS Distributions }
1233*43a90889SApple OSS Distributions
1234*43a90889SApple OSS Distributions /* copy dictionary to window */
1235*43a90889SApple OSS Distributions if (updatewindow(strm, strm->avail_out)) {
1236*43a90889SApple OSS Distributions state->mode = MEM;
1237*43a90889SApple OSS Distributions return Z_MEM_ERROR;
1238*43a90889SApple OSS Distributions }
1239*43a90889SApple OSS Distributions if (dictLength > state->wsize) {
1240*43a90889SApple OSS Distributions zmemcpy(state->window, dictionary + dictLength - state->wsize,
1241*43a90889SApple OSS Distributions state->wsize);
1242*43a90889SApple OSS Distributions state->whave = state->wsize;
1243*43a90889SApple OSS Distributions }
1244*43a90889SApple OSS Distributions else {
1245*43a90889SApple OSS Distributions zmemcpy(state->window + state->wsize - dictLength, dictionary,
1246*43a90889SApple OSS Distributions dictLength);
1247*43a90889SApple OSS Distributions state->whave = dictLength;
1248*43a90889SApple OSS Distributions }
1249*43a90889SApple OSS Distributions state->havedict = 1;
1250*43a90889SApple OSS Distributions Tracev((stderr, "inflate: dictionary set\n"));
1251*43a90889SApple OSS Distributions return Z_OK;
1252*43a90889SApple OSS Distributions }
1253*43a90889SApple OSS Distributions
1254*43a90889SApple OSS Distributions int ZEXPORT
inflateGetHeader(z_streamp strm,gz_headerp head)1255*43a90889SApple OSS Distributions inflateGetHeader(z_streamp strm, gz_headerp head)
1256*43a90889SApple OSS Distributions {
1257*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1258*43a90889SApple OSS Distributions
1259*43a90889SApple OSS Distributions /* check state */
1260*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1261*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
1262*43a90889SApple OSS Distributions if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
1263*43a90889SApple OSS Distributions
1264*43a90889SApple OSS Distributions /* save header structure */
1265*43a90889SApple OSS Distributions state->head = head;
1266*43a90889SApple OSS Distributions head->done = 0;
1267*43a90889SApple OSS Distributions return Z_OK;
1268*43a90889SApple OSS Distributions }
1269*43a90889SApple OSS Distributions
1270*43a90889SApple OSS Distributions /*
1271*43a90889SApple OSS Distributions Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
1272*43a90889SApple OSS Distributions or when out of input. When called, *have is the number of pattern bytes
1273*43a90889SApple OSS Distributions found in order so far, in 0..3. On return *have is updated to the new
1274*43a90889SApple OSS Distributions state. If on return *have equals four, then the pattern was found and the
1275*43a90889SApple OSS Distributions return value is how many bytes were read including the last byte of the
1276*43a90889SApple OSS Distributions pattern. If *have is less than four, then the pattern has not been found
1277*43a90889SApple OSS Distributions yet and the return value is len. In the latter case, syncsearch() can be
1278*43a90889SApple OSS Distributions called again with more data and the *have state. *have is initialized to
1279*43a90889SApple OSS Distributions zero for the first call.
1280*43a90889SApple OSS Distributions */
1281*43a90889SApple OSS Distributions local unsigned
syncsearch(unsigned FAR * have,unsigned char FAR * buf,unsigned len)1282*43a90889SApple OSS Distributions syncsearch(unsigned FAR *have, unsigned char FAR *buf, unsigned len)
1283*43a90889SApple OSS Distributions {
1284*43a90889SApple OSS Distributions unsigned got;
1285*43a90889SApple OSS Distributions unsigned next;
1286*43a90889SApple OSS Distributions
1287*43a90889SApple OSS Distributions got = *have;
1288*43a90889SApple OSS Distributions next = 0;
1289*43a90889SApple OSS Distributions while (next < len && got < 4) {
1290*43a90889SApple OSS Distributions if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
1291*43a90889SApple OSS Distributions got++;
1292*43a90889SApple OSS Distributions else if (buf[next])
1293*43a90889SApple OSS Distributions got = 0;
1294*43a90889SApple OSS Distributions else
1295*43a90889SApple OSS Distributions got = 4 - got;
1296*43a90889SApple OSS Distributions next++;
1297*43a90889SApple OSS Distributions }
1298*43a90889SApple OSS Distributions *have = got;
1299*43a90889SApple OSS Distributions return next;
1300*43a90889SApple OSS Distributions }
1301*43a90889SApple OSS Distributions
1302*43a90889SApple OSS Distributions int ZEXPORT
inflateSync(z_streamp strm)1303*43a90889SApple OSS Distributions inflateSync(z_streamp strm)
1304*43a90889SApple OSS Distributions {
1305*43a90889SApple OSS Distributions unsigned len; /* number of bytes to look at or looked at */
1306*43a90889SApple OSS Distributions unsigned long in, out; /* temporary to save total_in and total_out */
1307*43a90889SApple OSS Distributions unsigned char buf[4]; /* to restore bit buffer to byte string */
1308*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1309*43a90889SApple OSS Distributions
1310*43a90889SApple OSS Distributions /* check parameters */
1311*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1312*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
1313*43a90889SApple OSS Distributions if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
1314*43a90889SApple OSS Distributions
1315*43a90889SApple OSS Distributions /* if first time, start search in bit buffer */
1316*43a90889SApple OSS Distributions if (state->mode != SYNC) {
1317*43a90889SApple OSS Distributions state->mode = SYNC;
1318*43a90889SApple OSS Distributions state->hold <<= state->bits & 7;
1319*43a90889SApple OSS Distributions state->bits -= state->bits & 7;
1320*43a90889SApple OSS Distributions len = 0;
1321*43a90889SApple OSS Distributions while (state->bits >= 8) {
1322*43a90889SApple OSS Distributions buf[len++] = (unsigned char)(state->hold);
1323*43a90889SApple OSS Distributions state->hold >>= 8;
1324*43a90889SApple OSS Distributions state->bits -= 8;
1325*43a90889SApple OSS Distributions }
1326*43a90889SApple OSS Distributions state->have = 0;
1327*43a90889SApple OSS Distributions syncsearch(&(state->have), buf, len);
1328*43a90889SApple OSS Distributions }
1329*43a90889SApple OSS Distributions
1330*43a90889SApple OSS Distributions /* search available input */
1331*43a90889SApple OSS Distributions len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
1332*43a90889SApple OSS Distributions strm->avail_in -= len;
1333*43a90889SApple OSS Distributions strm->next_in += len;
1334*43a90889SApple OSS Distributions strm->total_in += len;
1335*43a90889SApple OSS Distributions
1336*43a90889SApple OSS Distributions /* return no joy or set up to restart inflate() on a new block */
1337*43a90889SApple OSS Distributions if (state->have != 4) return Z_DATA_ERROR;
1338*43a90889SApple OSS Distributions in = strm->total_in; out = strm->total_out;
1339*43a90889SApple OSS Distributions inflateReset(strm);
1340*43a90889SApple OSS Distributions strm->total_in = in; strm->total_out = out;
1341*43a90889SApple OSS Distributions state->mode = TYPE;
1342*43a90889SApple OSS Distributions return Z_OK;
1343*43a90889SApple OSS Distributions }
1344*43a90889SApple OSS Distributions
1345*43a90889SApple OSS Distributions /*
1346*43a90889SApple OSS Distributions Returns true if inflate is currently at the end of a block generated by
1347*43a90889SApple OSS Distributions Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1348*43a90889SApple OSS Distributions implementation to provide an additional safety check. PPP uses
1349*43a90889SApple OSS Distributions Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1350*43a90889SApple OSS Distributions block. When decompressing, PPP checks that at the end of input packet,
1351*43a90889SApple OSS Distributions inflate is waiting for these length bytes.
1352*43a90889SApple OSS Distributions */
1353*43a90889SApple OSS Distributions int ZEXPORT
inflateSyncPoint(z_streamp strm)1354*43a90889SApple OSS Distributions inflateSyncPoint(z_streamp strm)
1355*43a90889SApple OSS Distributions {
1356*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1357*43a90889SApple OSS Distributions
1358*43a90889SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1359*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
1360*43a90889SApple OSS Distributions return state->mode == STORED && state->bits == 0;
1361*43a90889SApple OSS Distributions }
1362*43a90889SApple OSS Distributions
1363*43a90889SApple OSS Distributions int ZEXPORT
inflateCopy(z_streamp dest,z_streamp source)1364*43a90889SApple OSS Distributions inflateCopy(z_streamp dest, z_streamp source)
1365*43a90889SApple OSS Distributions {
1366*43a90889SApple OSS Distributions struct inflate_state FAR *state;
1367*43a90889SApple OSS Distributions struct inflate_state FAR *copy;
1368*43a90889SApple OSS Distributions unsigned char FAR *window;
1369*43a90889SApple OSS Distributions unsigned wsize;
1370*43a90889SApple OSS Distributions
1371*43a90889SApple OSS Distributions /* check input */
1372*43a90889SApple OSS Distributions if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
1373*43a90889SApple OSS Distributions source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
1374*43a90889SApple OSS Distributions return Z_STREAM_ERROR;
1375*43a90889SApple OSS Distributions state = (struct inflate_state FAR *)source->state;
1376*43a90889SApple OSS Distributions
1377*43a90889SApple OSS Distributions /* allocate space */
1378*43a90889SApple OSS Distributions copy = (struct inflate_state FAR *)
1379*43a90889SApple OSS Distributions ZALLOC(source, 1, sizeof(struct inflate_state));
1380*43a90889SApple OSS Distributions if (copy == Z_NULL) return Z_MEM_ERROR;
1381*43a90889SApple OSS Distributions window = Z_NULL;
1382*43a90889SApple OSS Distributions if (state->window != Z_NULL) {
1383*43a90889SApple OSS Distributions window = (unsigned char FAR *)
1384*43a90889SApple OSS Distributions ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1385*43a90889SApple OSS Distributions if (window == Z_NULL) {
1386*43a90889SApple OSS Distributions ZFREE(source, copy);
1387*43a90889SApple OSS Distributions return Z_MEM_ERROR;
1388*43a90889SApple OSS Distributions }
1389*43a90889SApple OSS Distributions }
1390*43a90889SApple OSS Distributions
1391*43a90889SApple OSS Distributions /* copy state */
1392*43a90889SApple OSS Distributions zmemcpy(dest, source, sizeof(z_stream));
1393*43a90889SApple OSS Distributions zmemcpy(copy, state, sizeof(struct inflate_state));
1394*43a90889SApple OSS Distributions if (state->lencode >= state->codes &&
1395*43a90889SApple OSS Distributions state->lencode <= state->codes + ENOUGH - 1) {
1396*43a90889SApple OSS Distributions copy->lencode = copy->codes + (state->lencode - state->codes);
1397*43a90889SApple OSS Distributions copy->distcode = copy->codes + (state->distcode - state->codes);
1398*43a90889SApple OSS Distributions }
1399*43a90889SApple OSS Distributions copy->next = copy->codes + (state->next - state->codes);
1400*43a90889SApple OSS Distributions if (window != Z_NULL) {
1401*43a90889SApple OSS Distributions wsize = 1U << state->wbits;
1402*43a90889SApple OSS Distributions zmemcpy(window, state->window, wsize);
1403*43a90889SApple OSS Distributions }
1404*43a90889SApple OSS Distributions copy->window = window;
1405*43a90889SApple OSS Distributions dest->state = (struct internal_state FAR *)copy;
1406*43a90889SApple OSS Distributions return Z_OK;
1407*43a90889SApple OSS Distributions }
1408