xref: /titanic_54/usr/src/contrib/zlib/deflate.c (revision ab9e68a238043b4ee046d74742fe13407f00e542)
1*ab9e68a2SToomas Soome /* deflate.c -- compress data using the deflation algorithm
2*ab9e68a2SToomas Soome  * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
3*ab9e68a2SToomas Soome  * For conditions of distribution and use, see copyright notice in zlib.h
4*ab9e68a2SToomas Soome  */
5*ab9e68a2SToomas Soome 
6*ab9e68a2SToomas Soome /*
7*ab9e68a2SToomas Soome  *  ALGORITHM
8*ab9e68a2SToomas Soome  *
9*ab9e68a2SToomas Soome  *      The "deflation" process depends on being able to identify portions
10*ab9e68a2SToomas Soome  *      of the input text which are identical to earlier input (within a
11*ab9e68a2SToomas Soome  *      sliding window trailing behind the input currently being processed).
12*ab9e68a2SToomas Soome  *
13*ab9e68a2SToomas Soome  *      The most straightforward technique turns out to be the fastest for
14*ab9e68a2SToomas Soome  *      most input files: try all possible matches and select the longest.
15*ab9e68a2SToomas Soome  *      The key feature of this algorithm is that insertions into the string
16*ab9e68a2SToomas Soome  *      dictionary are very simple and thus fast, and deletions are avoided
17*ab9e68a2SToomas Soome  *      completely. Insertions are performed at each input character, whereas
18*ab9e68a2SToomas Soome  *      string matches are performed only when the previous match ends. So it
19*ab9e68a2SToomas Soome  *      is preferable to spend more time in matches to allow very fast string
20*ab9e68a2SToomas Soome  *      insertions and avoid deletions. The matching algorithm for small
21*ab9e68a2SToomas Soome  *      strings is inspired from that of Rabin & Karp. A brute force approach
22*ab9e68a2SToomas Soome  *      is used to find longer strings when a small match has been found.
23*ab9e68a2SToomas Soome  *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
24*ab9e68a2SToomas Soome  *      (by Leonid Broukhis).
25*ab9e68a2SToomas Soome  *         A previous version of this file used a more sophisticated algorithm
26*ab9e68a2SToomas Soome  *      (by Fiala and Greene) which is guaranteed to run in linear amortized
27*ab9e68a2SToomas Soome  *      time, but has a larger average cost, uses more memory and is patented.
28*ab9e68a2SToomas Soome  *      However the F&G algorithm may be faster for some highly redundant
29*ab9e68a2SToomas Soome  *      files if the parameter max_chain_length (described below) is too large.
30*ab9e68a2SToomas Soome  *
31*ab9e68a2SToomas Soome  *  ACKNOWLEDGEMENTS
32*ab9e68a2SToomas Soome  *
33*ab9e68a2SToomas Soome  *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
34*ab9e68a2SToomas Soome  *      I found it in 'freeze' written by Leonid Broukhis.
35*ab9e68a2SToomas Soome  *      Thanks to many people for bug reports and testing.
36*ab9e68a2SToomas Soome  *
37*ab9e68a2SToomas Soome  *  REFERENCES
38*ab9e68a2SToomas Soome  *
39*ab9e68a2SToomas Soome  *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
40*ab9e68a2SToomas Soome  *      Available in http://tools.ietf.org/html/rfc1951
41*ab9e68a2SToomas Soome  *
42*ab9e68a2SToomas Soome  *      A description of the Rabin and Karp algorithm is given in the book
43*ab9e68a2SToomas Soome  *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
44*ab9e68a2SToomas Soome  *
45*ab9e68a2SToomas Soome  *      Fiala,E.R., and Greene,D.H.
46*ab9e68a2SToomas Soome  *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
47*ab9e68a2SToomas Soome  *
48*ab9e68a2SToomas Soome  */
49*ab9e68a2SToomas Soome 
50*ab9e68a2SToomas Soome #include "deflate.h"
51*ab9e68a2SToomas Soome 
52*ab9e68a2SToomas Soome const char deflate_copyright[] =
53*ab9e68a2SToomas Soome    " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
54*ab9e68a2SToomas Soome /*
55*ab9e68a2SToomas Soome   If you use the zlib library in a product, an acknowledgment is welcome
56*ab9e68a2SToomas Soome   in the documentation of your product. If for some reason you cannot
57*ab9e68a2SToomas Soome   include such an acknowledgment, I would appreciate that you keep this
58*ab9e68a2SToomas Soome   copyright string in the executable of your product.
59*ab9e68a2SToomas Soome  */
60*ab9e68a2SToomas Soome 
61*ab9e68a2SToomas Soome /* ===========================================================================
62*ab9e68a2SToomas Soome  *  Function prototypes.
63*ab9e68a2SToomas Soome  */
64*ab9e68a2SToomas Soome typedef enum {
65*ab9e68a2SToomas Soome     need_more,      /* block not completed, need more input or more output */
66*ab9e68a2SToomas Soome     block_done,     /* block flush performed */
67*ab9e68a2SToomas Soome     finish_started, /* finish started, need only more output at next deflate */
68*ab9e68a2SToomas Soome     finish_done     /* finish done, accept no more input or output */
69*ab9e68a2SToomas Soome } block_state;
70*ab9e68a2SToomas Soome 
71*ab9e68a2SToomas Soome typedef block_state (*compress_func) OF((deflate_state *s, int flush));
72*ab9e68a2SToomas Soome /* Compression function. Returns the block state after the call. */
73*ab9e68a2SToomas Soome 
74*ab9e68a2SToomas Soome local int deflateStateCheck      OF((z_streamp strm));
75*ab9e68a2SToomas Soome local void slide_hash     OF((deflate_state *s));
76*ab9e68a2SToomas Soome local void fill_window    OF((deflate_state *s));
77*ab9e68a2SToomas Soome local block_state deflate_stored OF((deflate_state *s, int flush));
78*ab9e68a2SToomas Soome local block_state deflate_fast   OF((deflate_state *s, int flush));
79*ab9e68a2SToomas Soome #ifndef FASTEST
80*ab9e68a2SToomas Soome local block_state deflate_slow   OF((deflate_state *s, int flush));
81*ab9e68a2SToomas Soome #endif
82*ab9e68a2SToomas Soome local block_state deflate_rle    OF((deflate_state *s, int flush));
83*ab9e68a2SToomas Soome local block_state deflate_huff   OF((deflate_state *s, int flush));
84*ab9e68a2SToomas Soome local void lm_init        OF((deflate_state *s));
85*ab9e68a2SToomas Soome local void putShortMSB    OF((deflate_state *s, uInt b));
86*ab9e68a2SToomas Soome local void flush_pending  OF((z_streamp strm));
87*ab9e68a2SToomas Soome local unsigned read_buf   OF((z_streamp strm, Bytef *buf, unsigned size));
88*ab9e68a2SToomas Soome #ifdef ASMV
89*ab9e68a2SToomas Soome #  pragma message("Assembler code may have bugs -- use at your own risk")
90*ab9e68a2SToomas Soome       void match_init OF((void)); /* asm code initialization */
91*ab9e68a2SToomas Soome       uInt longest_match  OF((deflate_state *s, IPos cur_match));
92*ab9e68a2SToomas Soome #else
93*ab9e68a2SToomas Soome local uInt longest_match  OF((deflate_state *s, IPos cur_match));
94*ab9e68a2SToomas Soome #endif
95*ab9e68a2SToomas Soome 
96*ab9e68a2SToomas Soome #ifdef ZLIB_DEBUG
97*ab9e68a2SToomas Soome local  void check_match OF((deflate_state *s, IPos start, IPos match,
98*ab9e68a2SToomas Soome                             int length));
99*ab9e68a2SToomas Soome #endif
100*ab9e68a2SToomas Soome 
101*ab9e68a2SToomas Soome /* ===========================================================================
102*ab9e68a2SToomas Soome  * Local data
103*ab9e68a2SToomas Soome  */
104*ab9e68a2SToomas Soome 
105*ab9e68a2SToomas Soome #define NIL 0
106*ab9e68a2SToomas Soome /* Tail of hash chains */
107*ab9e68a2SToomas Soome 
108*ab9e68a2SToomas Soome #ifndef TOO_FAR
109*ab9e68a2SToomas Soome #  define TOO_FAR 4096
110*ab9e68a2SToomas Soome #endif
111*ab9e68a2SToomas Soome /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
112*ab9e68a2SToomas Soome 
113*ab9e68a2SToomas Soome /* Values for max_lazy_match, good_match and max_chain_length, depending on
114*ab9e68a2SToomas Soome  * the desired pack level (0..9). The values given below have been tuned to
115*ab9e68a2SToomas Soome  * exclude worst case performance for pathological files. Better values may be
116*ab9e68a2SToomas Soome  * found for specific files.
117*ab9e68a2SToomas Soome  */
118*ab9e68a2SToomas Soome typedef struct config_s {
119*ab9e68a2SToomas Soome    ush good_length; /* reduce lazy search above this match length */
120*ab9e68a2SToomas Soome    ush max_lazy;    /* do not perform lazy search above this match length */
121*ab9e68a2SToomas Soome    ush nice_length; /* quit search above this match length */
122*ab9e68a2SToomas Soome    ush max_chain;
123*ab9e68a2SToomas Soome    compress_func func;
124*ab9e68a2SToomas Soome } config;
125*ab9e68a2SToomas Soome 
126*ab9e68a2SToomas Soome #ifdef FASTEST
127*ab9e68a2SToomas Soome local const config configuration_table[2] = {
128*ab9e68a2SToomas Soome /*      good lazy nice chain */
129*ab9e68a2SToomas Soome /* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
130*ab9e68a2SToomas Soome /* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
131*ab9e68a2SToomas Soome #else
132*ab9e68a2SToomas Soome local const config configuration_table[10] = {
133*ab9e68a2SToomas Soome /*      good lazy nice chain */
134*ab9e68a2SToomas Soome /* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
135*ab9e68a2SToomas Soome /* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
136*ab9e68a2SToomas Soome /* 2 */ {4,    5, 16,    8, deflate_fast},
137*ab9e68a2SToomas Soome /* 3 */ {4,    6, 32,   32, deflate_fast},
138*ab9e68a2SToomas Soome 
139*ab9e68a2SToomas Soome /* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
140*ab9e68a2SToomas Soome /* 5 */ {8,   16, 32,   32, deflate_slow},
141*ab9e68a2SToomas Soome /* 6 */ {8,   16, 128, 128, deflate_slow},
142*ab9e68a2SToomas Soome /* 7 */ {8,   32, 128, 256, deflate_slow},
143*ab9e68a2SToomas Soome /* 8 */ {32, 128, 258, 1024, deflate_slow},
144*ab9e68a2SToomas Soome /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
145*ab9e68a2SToomas Soome #endif
146*ab9e68a2SToomas Soome 
147*ab9e68a2SToomas Soome /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
148*ab9e68a2SToomas Soome  * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
149*ab9e68a2SToomas Soome  * meaning.
150*ab9e68a2SToomas Soome  */
151*ab9e68a2SToomas Soome 
152*ab9e68a2SToomas Soome /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
153*ab9e68a2SToomas Soome #define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
154*ab9e68a2SToomas Soome 
155*ab9e68a2SToomas Soome /* ===========================================================================
156*ab9e68a2SToomas Soome  * Update a hash value with the given input byte
157*ab9e68a2SToomas Soome  * IN  assertion: all calls to UPDATE_HASH are made with consecutive input
158*ab9e68a2SToomas Soome  *    characters, so that a running hash key can be computed from the previous
159*ab9e68a2SToomas Soome  *    key instead of complete recalculation each time.
160*ab9e68a2SToomas Soome  */
161*ab9e68a2SToomas Soome #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
162*ab9e68a2SToomas Soome 
163*ab9e68a2SToomas Soome 
164*ab9e68a2SToomas Soome /* ===========================================================================
165*ab9e68a2SToomas Soome  * Insert string str in the dictionary and set match_head to the previous head
166*ab9e68a2SToomas Soome  * of the hash chain (the most recent string with same hash key). Return
167*ab9e68a2SToomas Soome  * the previous length of the hash chain.
168*ab9e68a2SToomas Soome  * If this file is compiled with -DFASTEST, the compression level is forced
169*ab9e68a2SToomas Soome  * to 1, and no hash chains are maintained.
170*ab9e68a2SToomas Soome  * IN  assertion: all calls to INSERT_STRING are made with consecutive input
171*ab9e68a2SToomas Soome  *    characters and the first MIN_MATCH bytes of str are valid (except for
172*ab9e68a2SToomas Soome  *    the last MIN_MATCH-1 bytes of the input file).
173*ab9e68a2SToomas Soome  */
174*ab9e68a2SToomas Soome #ifdef FASTEST
175*ab9e68a2SToomas Soome #define INSERT_STRING(s, str, match_head) \
176*ab9e68a2SToomas Soome    (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
177*ab9e68a2SToomas Soome     match_head = s->head[s->ins_h], \
178*ab9e68a2SToomas Soome     s->head[s->ins_h] = (Pos)(str))
179*ab9e68a2SToomas Soome #else
180*ab9e68a2SToomas Soome #define INSERT_STRING(s, str, match_head) \
181*ab9e68a2SToomas Soome    (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
182*ab9e68a2SToomas Soome     match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
183*ab9e68a2SToomas Soome     s->head[s->ins_h] = (Pos)(str))
184*ab9e68a2SToomas Soome #endif
185*ab9e68a2SToomas Soome 
186*ab9e68a2SToomas Soome /* ===========================================================================
187*ab9e68a2SToomas Soome  * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
188*ab9e68a2SToomas Soome  * prev[] will be initialized on the fly.
189*ab9e68a2SToomas Soome  */
190*ab9e68a2SToomas Soome #define CLEAR_HASH(s) \
191*ab9e68a2SToomas Soome     s->head[s->hash_size-1] = NIL; \
192*ab9e68a2SToomas Soome     zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
193*ab9e68a2SToomas Soome 
194*ab9e68a2SToomas Soome /* ===========================================================================
195*ab9e68a2SToomas Soome  * Slide the hash table when sliding the window down (could be avoided with 32
196*ab9e68a2SToomas Soome  * bit values at the expense of memory usage). We slide even when level == 0 to
197*ab9e68a2SToomas Soome  * keep the hash table consistent if we switch back to level > 0 later.
198*ab9e68a2SToomas Soome  */
199*ab9e68a2SToomas Soome local void slide_hash(s)
200*ab9e68a2SToomas Soome     deflate_state *s;
201*ab9e68a2SToomas Soome {
202*ab9e68a2SToomas Soome     unsigned n, m;
203*ab9e68a2SToomas Soome     Posf *p;
204*ab9e68a2SToomas Soome     uInt wsize = s->w_size;
205*ab9e68a2SToomas Soome 
206*ab9e68a2SToomas Soome     n = s->hash_size;
207*ab9e68a2SToomas Soome     p = &s->head[n];
208*ab9e68a2SToomas Soome     do {
209*ab9e68a2SToomas Soome         m = *--p;
210*ab9e68a2SToomas Soome         *p = (Pos)(m >= wsize ? m - wsize : NIL);
211*ab9e68a2SToomas Soome     } while (--n);
212*ab9e68a2SToomas Soome     n = wsize;
213*ab9e68a2SToomas Soome #ifndef FASTEST
214*ab9e68a2SToomas Soome     p = &s->prev[n];
215*ab9e68a2SToomas Soome     do {
216*ab9e68a2SToomas Soome         m = *--p;
217*ab9e68a2SToomas Soome         *p = (Pos)(m >= wsize ? m - wsize : NIL);
218*ab9e68a2SToomas Soome         /* If n is not on any hash chain, prev[n] is garbage but
219*ab9e68a2SToomas Soome          * its value will never be used.
220*ab9e68a2SToomas Soome          */
221*ab9e68a2SToomas Soome     } while (--n);
222*ab9e68a2SToomas Soome #endif
223*ab9e68a2SToomas Soome }
224*ab9e68a2SToomas Soome 
225*ab9e68a2SToomas Soome /* ========================================================================= */
226*ab9e68a2SToomas Soome int ZEXPORT deflateInit_(strm, level, version, stream_size)
227*ab9e68a2SToomas Soome     z_streamp strm;
228*ab9e68a2SToomas Soome     int level;
229*ab9e68a2SToomas Soome     const char *version;
230*ab9e68a2SToomas Soome     int stream_size;
231*ab9e68a2SToomas Soome {
232*ab9e68a2SToomas Soome     return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
233*ab9e68a2SToomas Soome                          Z_DEFAULT_STRATEGY, version, stream_size);
234*ab9e68a2SToomas Soome     /* To do: ignore strm->next_in if we use it as window */
235*ab9e68a2SToomas Soome }
236*ab9e68a2SToomas Soome 
237*ab9e68a2SToomas Soome /* ========================================================================= */
238*ab9e68a2SToomas Soome int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
239*ab9e68a2SToomas Soome                   version, stream_size)
240*ab9e68a2SToomas Soome     z_streamp strm;
241*ab9e68a2SToomas Soome     int  level;
242*ab9e68a2SToomas Soome     int  method;
243*ab9e68a2SToomas Soome     int  windowBits;
244*ab9e68a2SToomas Soome     int  memLevel;
245*ab9e68a2SToomas Soome     int  strategy;
246*ab9e68a2SToomas Soome     const char *version;
247*ab9e68a2SToomas Soome     int stream_size;
248*ab9e68a2SToomas Soome {
249*ab9e68a2SToomas Soome     deflate_state *s;
250*ab9e68a2SToomas Soome     int wrap = 1;
251*ab9e68a2SToomas Soome     static const char my_version[] = ZLIB_VERSION;
252*ab9e68a2SToomas Soome 
253*ab9e68a2SToomas Soome     ushf *overlay;
254*ab9e68a2SToomas Soome     /* We overlay pending_buf and d_buf+l_buf. This works since the average
255*ab9e68a2SToomas Soome      * output size for (length,distance) codes is <= 24 bits.
256*ab9e68a2SToomas Soome      */
257*ab9e68a2SToomas Soome 
258*ab9e68a2SToomas Soome     if (version == Z_NULL || version[0] != my_version[0] ||
259*ab9e68a2SToomas Soome         stream_size != sizeof(z_stream)) {
260*ab9e68a2SToomas Soome         return Z_VERSION_ERROR;
261*ab9e68a2SToomas Soome     }
262*ab9e68a2SToomas Soome     if (strm == Z_NULL) return Z_STREAM_ERROR;
263*ab9e68a2SToomas Soome 
264*ab9e68a2SToomas Soome     strm->msg = Z_NULL;
265*ab9e68a2SToomas Soome     if (strm->zalloc == (alloc_func)0) {
266*ab9e68a2SToomas Soome #ifdef Z_SOLO
267*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
268*ab9e68a2SToomas Soome #else
269*ab9e68a2SToomas Soome         strm->zalloc = zcalloc;
270*ab9e68a2SToomas Soome         strm->opaque = (voidpf)0;
271*ab9e68a2SToomas Soome #endif
272*ab9e68a2SToomas Soome     }
273*ab9e68a2SToomas Soome     if (strm->zfree == (free_func)0)
274*ab9e68a2SToomas Soome #ifdef Z_SOLO
275*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
276*ab9e68a2SToomas Soome #else
277*ab9e68a2SToomas Soome         strm->zfree = zcfree;
278*ab9e68a2SToomas Soome #endif
279*ab9e68a2SToomas Soome 
280*ab9e68a2SToomas Soome #ifdef FASTEST
281*ab9e68a2SToomas Soome     if (level != 0) level = 1;
282*ab9e68a2SToomas Soome #else
283*ab9e68a2SToomas Soome     if (level == Z_DEFAULT_COMPRESSION) level = 6;
284*ab9e68a2SToomas Soome #endif
285*ab9e68a2SToomas Soome 
286*ab9e68a2SToomas Soome     if (windowBits < 0) { /* suppress zlib wrapper */
287*ab9e68a2SToomas Soome         wrap = 0;
288*ab9e68a2SToomas Soome         windowBits = -windowBits;
289*ab9e68a2SToomas Soome     }
290*ab9e68a2SToomas Soome #ifdef GZIP
291*ab9e68a2SToomas Soome     else if (windowBits > 15) {
292*ab9e68a2SToomas Soome         wrap = 2;       /* write gzip wrapper instead */
293*ab9e68a2SToomas Soome         windowBits -= 16;
294*ab9e68a2SToomas Soome     }
295*ab9e68a2SToomas Soome #endif
296*ab9e68a2SToomas Soome     if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
297*ab9e68a2SToomas Soome         windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
298*ab9e68a2SToomas Soome         strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
299*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
300*ab9e68a2SToomas Soome     }
301*ab9e68a2SToomas Soome     if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
302*ab9e68a2SToomas Soome     s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
303*ab9e68a2SToomas Soome     if (s == Z_NULL) return Z_MEM_ERROR;
304*ab9e68a2SToomas Soome     strm->state = (struct internal_state FAR *)s;
305*ab9e68a2SToomas Soome     s->strm = strm;
306*ab9e68a2SToomas Soome     s->status = INIT_STATE;     /* to pass state test in deflateReset() */
307*ab9e68a2SToomas Soome 
308*ab9e68a2SToomas Soome     s->wrap = wrap;
309*ab9e68a2SToomas Soome     s->gzhead = Z_NULL;
310*ab9e68a2SToomas Soome     s->w_bits = (uInt)windowBits;
311*ab9e68a2SToomas Soome     s->w_size = 1 << s->w_bits;
312*ab9e68a2SToomas Soome     s->w_mask = s->w_size - 1;
313*ab9e68a2SToomas Soome 
314*ab9e68a2SToomas Soome     s->hash_bits = (uInt)memLevel + 7;
315*ab9e68a2SToomas Soome     s->hash_size = 1 << s->hash_bits;
316*ab9e68a2SToomas Soome     s->hash_mask = s->hash_size - 1;
317*ab9e68a2SToomas Soome     s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
318*ab9e68a2SToomas Soome 
319*ab9e68a2SToomas Soome     s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
320*ab9e68a2SToomas Soome     s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
321*ab9e68a2SToomas Soome     s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
322*ab9e68a2SToomas Soome 
323*ab9e68a2SToomas Soome     s->high_water = 0;      /* nothing written to s->window yet */
324*ab9e68a2SToomas Soome 
325*ab9e68a2SToomas Soome     s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
326*ab9e68a2SToomas Soome 
327*ab9e68a2SToomas Soome     overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
328*ab9e68a2SToomas Soome     s->pending_buf = (uchf *) overlay;
329*ab9e68a2SToomas Soome     s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
330*ab9e68a2SToomas Soome 
331*ab9e68a2SToomas Soome     if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
332*ab9e68a2SToomas Soome         s->pending_buf == Z_NULL) {
333*ab9e68a2SToomas Soome         s->status = FINISH_STATE;
334*ab9e68a2SToomas Soome         strm->msg = ERR_MSG(Z_MEM_ERROR);
335*ab9e68a2SToomas Soome         deflateEnd (strm);
336*ab9e68a2SToomas Soome         return Z_MEM_ERROR;
337*ab9e68a2SToomas Soome     }
338*ab9e68a2SToomas Soome     s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
339*ab9e68a2SToomas Soome     s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
340*ab9e68a2SToomas Soome 
341*ab9e68a2SToomas Soome     s->level = level;
342*ab9e68a2SToomas Soome     s->strategy = strategy;
343*ab9e68a2SToomas Soome     s->method = (Byte)method;
344*ab9e68a2SToomas Soome 
345*ab9e68a2SToomas Soome     return deflateReset(strm);
346*ab9e68a2SToomas Soome }
347*ab9e68a2SToomas Soome 
348*ab9e68a2SToomas Soome /* =========================================================================
349*ab9e68a2SToomas Soome  * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
350*ab9e68a2SToomas Soome  */
351*ab9e68a2SToomas Soome local int deflateStateCheck (strm)
352*ab9e68a2SToomas Soome     z_streamp strm;
353*ab9e68a2SToomas Soome {
354*ab9e68a2SToomas Soome     deflate_state *s;
355*ab9e68a2SToomas Soome     if (strm == Z_NULL ||
356*ab9e68a2SToomas Soome         strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
357*ab9e68a2SToomas Soome         return 1;
358*ab9e68a2SToomas Soome     s = strm->state;
359*ab9e68a2SToomas Soome     if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
360*ab9e68a2SToomas Soome #ifdef GZIP
361*ab9e68a2SToomas Soome                                            s->status != GZIP_STATE &&
362*ab9e68a2SToomas Soome #endif
363*ab9e68a2SToomas Soome                                            s->status != EXTRA_STATE &&
364*ab9e68a2SToomas Soome                                            s->status != NAME_STATE &&
365*ab9e68a2SToomas Soome                                            s->status != COMMENT_STATE &&
366*ab9e68a2SToomas Soome                                            s->status != HCRC_STATE &&
367*ab9e68a2SToomas Soome                                            s->status != BUSY_STATE &&
368*ab9e68a2SToomas Soome                                            s->status != FINISH_STATE))
369*ab9e68a2SToomas Soome         return 1;
370*ab9e68a2SToomas Soome     return 0;
371*ab9e68a2SToomas Soome }
372*ab9e68a2SToomas Soome 
373*ab9e68a2SToomas Soome /* ========================================================================= */
374*ab9e68a2SToomas Soome int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
375*ab9e68a2SToomas Soome     z_streamp strm;
376*ab9e68a2SToomas Soome     const Bytef *dictionary;
377*ab9e68a2SToomas Soome     uInt  dictLength;
378*ab9e68a2SToomas Soome {
379*ab9e68a2SToomas Soome     deflate_state *s;
380*ab9e68a2SToomas Soome     uInt str, n;
381*ab9e68a2SToomas Soome     int wrap;
382*ab9e68a2SToomas Soome     unsigned avail;
383*ab9e68a2SToomas Soome     z_const unsigned char *next;
384*ab9e68a2SToomas Soome 
385*ab9e68a2SToomas Soome     if (deflateStateCheck(strm) || dictionary == Z_NULL)
386*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
387*ab9e68a2SToomas Soome     s = strm->state;
388*ab9e68a2SToomas Soome     wrap = s->wrap;
389*ab9e68a2SToomas Soome     if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
390*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
391*ab9e68a2SToomas Soome 
392*ab9e68a2SToomas Soome     /* when using zlib wrappers, compute Adler-32 for provided dictionary */
393*ab9e68a2SToomas Soome     if (wrap == 1)
394*ab9e68a2SToomas Soome         strm->adler = adler32(strm->adler, dictionary, dictLength);
395*ab9e68a2SToomas Soome     s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
396*ab9e68a2SToomas Soome 
397*ab9e68a2SToomas Soome     /* if dictionary would fill window, just replace the history */
398*ab9e68a2SToomas Soome     if (dictLength >= s->w_size) {
399*ab9e68a2SToomas Soome         if (wrap == 0) {            /* already empty otherwise */
400*ab9e68a2SToomas Soome             CLEAR_HASH(s);
401*ab9e68a2SToomas Soome             s->strstart = 0;
402*ab9e68a2SToomas Soome             s->block_start = 0L;
403*ab9e68a2SToomas Soome             s->insert = 0;
404*ab9e68a2SToomas Soome         }
405*ab9e68a2SToomas Soome         dictionary += dictLength - s->w_size;  /* use the tail */
406*ab9e68a2SToomas Soome         dictLength = s->w_size;
407*ab9e68a2SToomas Soome     }
408*ab9e68a2SToomas Soome 
409*ab9e68a2SToomas Soome     /* insert dictionary into window and hash */
410*ab9e68a2SToomas Soome     avail = strm->avail_in;
411*ab9e68a2SToomas Soome     next = strm->next_in;
412*ab9e68a2SToomas Soome     strm->avail_in = dictLength;
413*ab9e68a2SToomas Soome     strm->next_in = (z_const Bytef *)dictionary;
414*ab9e68a2SToomas Soome     fill_window(s);
415*ab9e68a2SToomas Soome     while (s->lookahead >= MIN_MATCH) {
416*ab9e68a2SToomas Soome         str = s->strstart;
417*ab9e68a2SToomas Soome         n = s->lookahead - (MIN_MATCH-1);
418*ab9e68a2SToomas Soome         do {
419*ab9e68a2SToomas Soome             UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
420*ab9e68a2SToomas Soome #ifndef FASTEST
421*ab9e68a2SToomas Soome             s->prev[str & s->w_mask] = s->head[s->ins_h];
422*ab9e68a2SToomas Soome #endif
423*ab9e68a2SToomas Soome             s->head[s->ins_h] = (Pos)str;
424*ab9e68a2SToomas Soome             str++;
425*ab9e68a2SToomas Soome         } while (--n);
426*ab9e68a2SToomas Soome         s->strstart = str;
427*ab9e68a2SToomas Soome         s->lookahead = MIN_MATCH-1;
428*ab9e68a2SToomas Soome         fill_window(s);
429*ab9e68a2SToomas Soome     }
430*ab9e68a2SToomas Soome     s->strstart += s->lookahead;
431*ab9e68a2SToomas Soome     s->block_start = (long)s->strstart;
432*ab9e68a2SToomas Soome     s->insert = s->lookahead;
433*ab9e68a2SToomas Soome     s->lookahead = 0;
434*ab9e68a2SToomas Soome     s->match_length = s->prev_length = MIN_MATCH-1;
435*ab9e68a2SToomas Soome     s->match_available = 0;
436*ab9e68a2SToomas Soome     strm->next_in = next;
437*ab9e68a2SToomas Soome     strm->avail_in = avail;
438*ab9e68a2SToomas Soome     s->wrap = wrap;
439*ab9e68a2SToomas Soome     return Z_OK;
440*ab9e68a2SToomas Soome }
441*ab9e68a2SToomas Soome 
442*ab9e68a2SToomas Soome /* ========================================================================= */
443*ab9e68a2SToomas Soome int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
444*ab9e68a2SToomas Soome     z_streamp strm;
445*ab9e68a2SToomas Soome     Bytef *dictionary;
446*ab9e68a2SToomas Soome     uInt  *dictLength;
447*ab9e68a2SToomas Soome {
448*ab9e68a2SToomas Soome     deflate_state *s;
449*ab9e68a2SToomas Soome     uInt len;
450*ab9e68a2SToomas Soome 
451*ab9e68a2SToomas Soome     if (deflateStateCheck(strm))
452*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
453*ab9e68a2SToomas Soome     s = strm->state;
454*ab9e68a2SToomas Soome     len = s->strstart + s->lookahead;
455*ab9e68a2SToomas Soome     if (len > s->w_size)
456*ab9e68a2SToomas Soome         len = s->w_size;
457*ab9e68a2SToomas Soome     if (dictionary != Z_NULL && len)
458*ab9e68a2SToomas Soome         zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
459*ab9e68a2SToomas Soome     if (dictLength != Z_NULL)
460*ab9e68a2SToomas Soome         *dictLength = len;
461*ab9e68a2SToomas Soome     return Z_OK;
462*ab9e68a2SToomas Soome }
463*ab9e68a2SToomas Soome 
464*ab9e68a2SToomas Soome /* ========================================================================= */
465*ab9e68a2SToomas Soome int ZEXPORT deflateResetKeep (strm)
466*ab9e68a2SToomas Soome     z_streamp strm;
467*ab9e68a2SToomas Soome {
468*ab9e68a2SToomas Soome     deflate_state *s;
469*ab9e68a2SToomas Soome 
470*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) {
471*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
472*ab9e68a2SToomas Soome     }
473*ab9e68a2SToomas Soome 
474*ab9e68a2SToomas Soome     strm->total_in = strm->total_out = 0;
475*ab9e68a2SToomas Soome     strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
476*ab9e68a2SToomas Soome     strm->data_type = Z_UNKNOWN;
477*ab9e68a2SToomas Soome 
478*ab9e68a2SToomas Soome     s = (deflate_state *)strm->state;
479*ab9e68a2SToomas Soome     s->pending = 0;
480*ab9e68a2SToomas Soome     s->pending_out = s->pending_buf;
481*ab9e68a2SToomas Soome 
482*ab9e68a2SToomas Soome     if (s->wrap < 0) {
483*ab9e68a2SToomas Soome         s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
484*ab9e68a2SToomas Soome     }
485*ab9e68a2SToomas Soome     s->status =
486*ab9e68a2SToomas Soome #ifdef GZIP
487*ab9e68a2SToomas Soome         s->wrap == 2 ? GZIP_STATE :
488*ab9e68a2SToomas Soome #endif
489*ab9e68a2SToomas Soome         s->wrap ? INIT_STATE : BUSY_STATE;
490*ab9e68a2SToomas Soome     strm->adler =
491*ab9e68a2SToomas Soome #ifdef GZIP
492*ab9e68a2SToomas Soome         s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
493*ab9e68a2SToomas Soome #endif
494*ab9e68a2SToomas Soome         adler32(0L, Z_NULL, 0);
495*ab9e68a2SToomas Soome     s->last_flush = Z_NO_FLUSH;
496*ab9e68a2SToomas Soome 
497*ab9e68a2SToomas Soome     _tr_init(s);
498*ab9e68a2SToomas Soome 
499*ab9e68a2SToomas Soome     return Z_OK;
500*ab9e68a2SToomas Soome }
501*ab9e68a2SToomas Soome 
502*ab9e68a2SToomas Soome /* ========================================================================= */
503*ab9e68a2SToomas Soome int ZEXPORT deflateReset (strm)
504*ab9e68a2SToomas Soome     z_streamp strm;
505*ab9e68a2SToomas Soome {
506*ab9e68a2SToomas Soome     int ret;
507*ab9e68a2SToomas Soome 
508*ab9e68a2SToomas Soome     ret = deflateResetKeep(strm);
509*ab9e68a2SToomas Soome     if (ret == Z_OK)
510*ab9e68a2SToomas Soome         lm_init(strm->state);
511*ab9e68a2SToomas Soome     return ret;
512*ab9e68a2SToomas Soome }
513*ab9e68a2SToomas Soome 
514*ab9e68a2SToomas Soome /* ========================================================================= */
515*ab9e68a2SToomas Soome int ZEXPORT deflateSetHeader (strm, head)
516*ab9e68a2SToomas Soome     z_streamp strm;
517*ab9e68a2SToomas Soome     gz_headerp head;
518*ab9e68a2SToomas Soome {
519*ab9e68a2SToomas Soome     if (deflateStateCheck(strm) || strm->state->wrap != 2)
520*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
521*ab9e68a2SToomas Soome     strm->state->gzhead = head;
522*ab9e68a2SToomas Soome     return Z_OK;
523*ab9e68a2SToomas Soome }
524*ab9e68a2SToomas Soome 
525*ab9e68a2SToomas Soome /* ========================================================================= */
526*ab9e68a2SToomas Soome int ZEXPORT deflatePending (strm, pending, bits)
527*ab9e68a2SToomas Soome     unsigned *pending;
528*ab9e68a2SToomas Soome     int *bits;
529*ab9e68a2SToomas Soome     z_streamp strm;
530*ab9e68a2SToomas Soome {
531*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
532*ab9e68a2SToomas Soome     if (pending != Z_NULL)
533*ab9e68a2SToomas Soome         *pending = strm->state->pending;
534*ab9e68a2SToomas Soome     if (bits != Z_NULL)
535*ab9e68a2SToomas Soome         *bits = strm->state->bi_valid;
536*ab9e68a2SToomas Soome     return Z_OK;
537*ab9e68a2SToomas Soome }
538*ab9e68a2SToomas Soome 
539*ab9e68a2SToomas Soome /* ========================================================================= */
540*ab9e68a2SToomas Soome int ZEXPORT deflatePrime (strm, bits, value)
541*ab9e68a2SToomas Soome     z_streamp strm;
542*ab9e68a2SToomas Soome     int bits;
543*ab9e68a2SToomas Soome     int value;
544*ab9e68a2SToomas Soome {
545*ab9e68a2SToomas Soome     deflate_state *s;
546*ab9e68a2SToomas Soome     int put;
547*ab9e68a2SToomas Soome 
548*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
549*ab9e68a2SToomas Soome     s = strm->state;
550*ab9e68a2SToomas Soome     if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
551*ab9e68a2SToomas Soome         return Z_BUF_ERROR;
552*ab9e68a2SToomas Soome     do {
553*ab9e68a2SToomas Soome         put = Buf_size - s->bi_valid;
554*ab9e68a2SToomas Soome         if (put > bits)
555*ab9e68a2SToomas Soome             put = bits;
556*ab9e68a2SToomas Soome         s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
557*ab9e68a2SToomas Soome         s->bi_valid += put;
558*ab9e68a2SToomas Soome         _tr_flush_bits(s);
559*ab9e68a2SToomas Soome         value >>= put;
560*ab9e68a2SToomas Soome         bits -= put;
561*ab9e68a2SToomas Soome     } while (bits);
562*ab9e68a2SToomas Soome     return Z_OK;
563*ab9e68a2SToomas Soome }
564*ab9e68a2SToomas Soome 
565*ab9e68a2SToomas Soome /* ========================================================================= */
566*ab9e68a2SToomas Soome int ZEXPORT deflateParams(strm, level, strategy)
567*ab9e68a2SToomas Soome     z_streamp strm;
568*ab9e68a2SToomas Soome     int level;
569*ab9e68a2SToomas Soome     int strategy;
570*ab9e68a2SToomas Soome {
571*ab9e68a2SToomas Soome     deflate_state *s;
572*ab9e68a2SToomas Soome     compress_func func;
573*ab9e68a2SToomas Soome 
574*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
575*ab9e68a2SToomas Soome     s = strm->state;
576*ab9e68a2SToomas Soome 
577*ab9e68a2SToomas Soome #ifdef FASTEST
578*ab9e68a2SToomas Soome     if (level != 0) level = 1;
579*ab9e68a2SToomas Soome #else
580*ab9e68a2SToomas Soome     if (level == Z_DEFAULT_COMPRESSION) level = 6;
581*ab9e68a2SToomas Soome #endif
582*ab9e68a2SToomas Soome     if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
583*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
584*ab9e68a2SToomas Soome     }
585*ab9e68a2SToomas Soome     func = configuration_table[s->level].func;
586*ab9e68a2SToomas Soome 
587*ab9e68a2SToomas Soome     if ((strategy != s->strategy || func != configuration_table[level].func) &&
588*ab9e68a2SToomas Soome         s->high_water) {
589*ab9e68a2SToomas Soome         /* Flush the last buffer: */
590*ab9e68a2SToomas Soome         int err = deflate(strm, Z_BLOCK);
591*ab9e68a2SToomas Soome         if (err == Z_STREAM_ERROR)
592*ab9e68a2SToomas Soome             return err;
593*ab9e68a2SToomas Soome         if (strm->avail_out == 0)
594*ab9e68a2SToomas Soome             return Z_BUF_ERROR;
595*ab9e68a2SToomas Soome     }
596*ab9e68a2SToomas Soome     if (s->level != level) {
597*ab9e68a2SToomas Soome         if (s->level == 0 && s->matches != 0) {
598*ab9e68a2SToomas Soome             if (s->matches == 1)
599*ab9e68a2SToomas Soome                 slide_hash(s);
600*ab9e68a2SToomas Soome             else
601*ab9e68a2SToomas Soome                 CLEAR_HASH(s);
602*ab9e68a2SToomas Soome             s->matches = 0;
603*ab9e68a2SToomas Soome         }
604*ab9e68a2SToomas Soome         s->level = level;
605*ab9e68a2SToomas Soome         s->max_lazy_match   = configuration_table[level].max_lazy;
606*ab9e68a2SToomas Soome         s->good_match       = configuration_table[level].good_length;
607*ab9e68a2SToomas Soome         s->nice_match       = configuration_table[level].nice_length;
608*ab9e68a2SToomas Soome         s->max_chain_length = configuration_table[level].max_chain;
609*ab9e68a2SToomas Soome     }
610*ab9e68a2SToomas Soome     s->strategy = strategy;
611*ab9e68a2SToomas Soome     return Z_OK;
612*ab9e68a2SToomas Soome }
613*ab9e68a2SToomas Soome 
614*ab9e68a2SToomas Soome /* ========================================================================= */
615*ab9e68a2SToomas Soome int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
616*ab9e68a2SToomas Soome     z_streamp strm;
617*ab9e68a2SToomas Soome     int good_length;
618*ab9e68a2SToomas Soome     int max_lazy;
619*ab9e68a2SToomas Soome     int nice_length;
620*ab9e68a2SToomas Soome     int max_chain;
621*ab9e68a2SToomas Soome {
622*ab9e68a2SToomas Soome     deflate_state *s;
623*ab9e68a2SToomas Soome 
624*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
625*ab9e68a2SToomas Soome     s = strm->state;
626*ab9e68a2SToomas Soome     s->good_match = (uInt)good_length;
627*ab9e68a2SToomas Soome     s->max_lazy_match = (uInt)max_lazy;
628*ab9e68a2SToomas Soome     s->nice_match = nice_length;
629*ab9e68a2SToomas Soome     s->max_chain_length = (uInt)max_chain;
630*ab9e68a2SToomas Soome     return Z_OK;
631*ab9e68a2SToomas Soome }
632*ab9e68a2SToomas Soome 
633*ab9e68a2SToomas Soome /* =========================================================================
634*ab9e68a2SToomas Soome  * For the default windowBits of 15 and memLevel of 8, this function returns
635*ab9e68a2SToomas Soome  * a close to exact, as well as small, upper bound on the compressed size.
636*ab9e68a2SToomas Soome  * They are coded as constants here for a reason--if the #define's are
637*ab9e68a2SToomas Soome  * changed, then this function needs to be changed as well.  The return
638*ab9e68a2SToomas Soome  * value for 15 and 8 only works for those exact settings.
639*ab9e68a2SToomas Soome  *
640*ab9e68a2SToomas Soome  * For any setting other than those defaults for windowBits and memLevel,
641*ab9e68a2SToomas Soome  * the value returned is a conservative worst case for the maximum expansion
642*ab9e68a2SToomas Soome  * resulting from using fixed blocks instead of stored blocks, which deflate
643*ab9e68a2SToomas Soome  * can emit on compressed data for some combinations of the parameters.
644*ab9e68a2SToomas Soome  *
645*ab9e68a2SToomas Soome  * This function could be more sophisticated to provide closer upper bounds for
646*ab9e68a2SToomas Soome  * every combination of windowBits and memLevel.  But even the conservative
647*ab9e68a2SToomas Soome  * upper bound of about 14% expansion does not seem onerous for output buffer
648*ab9e68a2SToomas Soome  * allocation.
649*ab9e68a2SToomas Soome  */
650*ab9e68a2SToomas Soome uLong ZEXPORT deflateBound(strm, sourceLen)
651*ab9e68a2SToomas Soome     z_streamp strm;
652*ab9e68a2SToomas Soome     uLong sourceLen;
653*ab9e68a2SToomas Soome {
654*ab9e68a2SToomas Soome     deflate_state *s;
655*ab9e68a2SToomas Soome     uLong complen, wraplen;
656*ab9e68a2SToomas Soome 
657*ab9e68a2SToomas Soome     /* conservative upper bound for compressed data */
658*ab9e68a2SToomas Soome     complen = sourceLen +
659*ab9e68a2SToomas Soome               ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
660*ab9e68a2SToomas Soome 
661*ab9e68a2SToomas Soome     /* if can't get parameters, return conservative bound plus zlib wrapper */
662*ab9e68a2SToomas Soome     if (deflateStateCheck(strm))
663*ab9e68a2SToomas Soome         return complen + 6;
664*ab9e68a2SToomas Soome 
665*ab9e68a2SToomas Soome     /* compute wrapper length */
666*ab9e68a2SToomas Soome     s = strm->state;
667*ab9e68a2SToomas Soome     switch (s->wrap) {
668*ab9e68a2SToomas Soome     case 0:                                 /* raw deflate */
669*ab9e68a2SToomas Soome         wraplen = 0;
670*ab9e68a2SToomas Soome         break;
671*ab9e68a2SToomas Soome     case 1:                                 /* zlib wrapper */
672*ab9e68a2SToomas Soome         wraplen = 6 + (s->strstart ? 4 : 0);
673*ab9e68a2SToomas Soome         break;
674*ab9e68a2SToomas Soome #ifdef GZIP
675*ab9e68a2SToomas Soome     case 2:                                 /* gzip wrapper */
676*ab9e68a2SToomas Soome         wraplen = 18;
677*ab9e68a2SToomas Soome         if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
678*ab9e68a2SToomas Soome             Bytef *str;
679*ab9e68a2SToomas Soome             if (s->gzhead->extra != Z_NULL)
680*ab9e68a2SToomas Soome                 wraplen += 2 + s->gzhead->extra_len;
681*ab9e68a2SToomas Soome             str = s->gzhead->name;
682*ab9e68a2SToomas Soome             if (str != Z_NULL)
683*ab9e68a2SToomas Soome                 do {
684*ab9e68a2SToomas Soome                     wraplen++;
685*ab9e68a2SToomas Soome                 } while (*str++);
686*ab9e68a2SToomas Soome             str = s->gzhead->comment;
687*ab9e68a2SToomas Soome             if (str != Z_NULL)
688*ab9e68a2SToomas Soome                 do {
689*ab9e68a2SToomas Soome                     wraplen++;
690*ab9e68a2SToomas Soome                 } while (*str++);
691*ab9e68a2SToomas Soome             if (s->gzhead->hcrc)
692*ab9e68a2SToomas Soome                 wraplen += 2;
693*ab9e68a2SToomas Soome         }
694*ab9e68a2SToomas Soome         break;
695*ab9e68a2SToomas Soome #endif
696*ab9e68a2SToomas Soome     default:                                /* for compiler happiness */
697*ab9e68a2SToomas Soome         wraplen = 6;
698*ab9e68a2SToomas Soome     }
699*ab9e68a2SToomas Soome 
700*ab9e68a2SToomas Soome     /* if not default parameters, return conservative bound */
701*ab9e68a2SToomas Soome     if (s->w_bits != 15 || s->hash_bits != 8 + 7)
702*ab9e68a2SToomas Soome         return complen + wraplen;
703*ab9e68a2SToomas Soome 
704*ab9e68a2SToomas Soome     /* default settings: return tight bound for that case */
705*ab9e68a2SToomas Soome     return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
706*ab9e68a2SToomas Soome            (sourceLen >> 25) + 13 - 6 + wraplen;
707*ab9e68a2SToomas Soome }
708*ab9e68a2SToomas Soome 
709*ab9e68a2SToomas Soome /* =========================================================================
710*ab9e68a2SToomas Soome  * Put a short in the pending buffer. The 16-bit value is put in MSB order.
711*ab9e68a2SToomas Soome  * IN assertion: the stream state is correct and there is enough room in
712*ab9e68a2SToomas Soome  * pending_buf.
713*ab9e68a2SToomas Soome  */
714*ab9e68a2SToomas Soome local void putShortMSB (s, b)
715*ab9e68a2SToomas Soome     deflate_state *s;
716*ab9e68a2SToomas Soome     uInt b;
717*ab9e68a2SToomas Soome {
718*ab9e68a2SToomas Soome     put_byte(s, (Byte)(b >> 8));
719*ab9e68a2SToomas Soome     put_byte(s, (Byte)(b & 0xff));
720*ab9e68a2SToomas Soome }
721*ab9e68a2SToomas Soome 
722*ab9e68a2SToomas Soome /* =========================================================================
723*ab9e68a2SToomas Soome  * Flush as much pending output as possible. All deflate() output, except for
724*ab9e68a2SToomas Soome  * some deflate_stored() output, goes through this function so some
725*ab9e68a2SToomas Soome  * applications may wish to modify it to avoid allocating a large
726*ab9e68a2SToomas Soome  * strm->next_out buffer and copying into it. (See also read_buf()).
727*ab9e68a2SToomas Soome  */
728*ab9e68a2SToomas Soome local void flush_pending(strm)
729*ab9e68a2SToomas Soome     z_streamp strm;
730*ab9e68a2SToomas Soome {
731*ab9e68a2SToomas Soome     unsigned len;
732*ab9e68a2SToomas Soome     deflate_state *s = strm->state;
733*ab9e68a2SToomas Soome 
734*ab9e68a2SToomas Soome     _tr_flush_bits(s);
735*ab9e68a2SToomas Soome     len = s->pending;
736*ab9e68a2SToomas Soome     if (len > strm->avail_out) len = strm->avail_out;
737*ab9e68a2SToomas Soome     if (len == 0) return;
738*ab9e68a2SToomas Soome 
739*ab9e68a2SToomas Soome     zmemcpy(strm->next_out, s->pending_out, len);
740*ab9e68a2SToomas Soome     strm->next_out  += len;
741*ab9e68a2SToomas Soome     s->pending_out  += len;
742*ab9e68a2SToomas Soome     strm->total_out += len;
743*ab9e68a2SToomas Soome     strm->avail_out -= len;
744*ab9e68a2SToomas Soome     s->pending      -= len;
745*ab9e68a2SToomas Soome     if (s->pending == 0) {
746*ab9e68a2SToomas Soome         s->pending_out = s->pending_buf;
747*ab9e68a2SToomas Soome     }
748*ab9e68a2SToomas Soome }
749*ab9e68a2SToomas Soome 
750*ab9e68a2SToomas Soome /* ===========================================================================
751*ab9e68a2SToomas Soome  * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
752*ab9e68a2SToomas Soome  */
753*ab9e68a2SToomas Soome #define HCRC_UPDATE(beg) \
754*ab9e68a2SToomas Soome     do { \
755*ab9e68a2SToomas Soome         if (s->gzhead->hcrc && s->pending > (beg)) \
756*ab9e68a2SToomas Soome             strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
757*ab9e68a2SToomas Soome                                 s->pending - (beg)); \
758*ab9e68a2SToomas Soome     } while (0)
759*ab9e68a2SToomas Soome 
760*ab9e68a2SToomas Soome /* ========================================================================= */
761*ab9e68a2SToomas Soome int ZEXPORT deflate (strm, flush)
762*ab9e68a2SToomas Soome     z_streamp strm;
763*ab9e68a2SToomas Soome     int flush;
764*ab9e68a2SToomas Soome {
765*ab9e68a2SToomas Soome     int old_flush; /* value of flush param for previous deflate call */
766*ab9e68a2SToomas Soome     deflate_state *s;
767*ab9e68a2SToomas Soome 
768*ab9e68a2SToomas Soome     if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
769*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
770*ab9e68a2SToomas Soome     }
771*ab9e68a2SToomas Soome     s = strm->state;
772*ab9e68a2SToomas Soome 
773*ab9e68a2SToomas Soome     if (strm->next_out == Z_NULL ||
774*ab9e68a2SToomas Soome         (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
775*ab9e68a2SToomas Soome         (s->status == FINISH_STATE && flush != Z_FINISH)) {
776*ab9e68a2SToomas Soome         ERR_RETURN(strm, Z_STREAM_ERROR);
777*ab9e68a2SToomas Soome     }
778*ab9e68a2SToomas Soome     if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
779*ab9e68a2SToomas Soome 
780*ab9e68a2SToomas Soome     old_flush = s->last_flush;
781*ab9e68a2SToomas Soome     s->last_flush = flush;
782*ab9e68a2SToomas Soome 
783*ab9e68a2SToomas Soome     /* Flush as much pending output as possible */
784*ab9e68a2SToomas Soome     if (s->pending != 0) {
785*ab9e68a2SToomas Soome         flush_pending(strm);
786*ab9e68a2SToomas Soome         if (strm->avail_out == 0) {
787*ab9e68a2SToomas Soome             /* Since avail_out is 0, deflate will be called again with
788*ab9e68a2SToomas Soome              * more output space, but possibly with both pending and
789*ab9e68a2SToomas Soome              * avail_in equal to zero. There won't be anything to do,
790*ab9e68a2SToomas Soome              * but this is not an error situation so make sure we
791*ab9e68a2SToomas Soome              * return OK instead of BUF_ERROR at next call of deflate:
792*ab9e68a2SToomas Soome              */
793*ab9e68a2SToomas Soome             s->last_flush = -1;
794*ab9e68a2SToomas Soome             return Z_OK;
795*ab9e68a2SToomas Soome         }
796*ab9e68a2SToomas Soome 
797*ab9e68a2SToomas Soome     /* Make sure there is something to do and avoid duplicate consecutive
798*ab9e68a2SToomas Soome      * flushes. For repeated and useless calls with Z_FINISH, we keep
799*ab9e68a2SToomas Soome      * returning Z_STREAM_END instead of Z_BUF_ERROR.
800*ab9e68a2SToomas Soome      */
801*ab9e68a2SToomas Soome     } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
802*ab9e68a2SToomas Soome                flush != Z_FINISH) {
803*ab9e68a2SToomas Soome         ERR_RETURN(strm, Z_BUF_ERROR);
804*ab9e68a2SToomas Soome     }
805*ab9e68a2SToomas Soome 
806*ab9e68a2SToomas Soome     /* User must not provide more input after the first FINISH: */
807*ab9e68a2SToomas Soome     if (s->status == FINISH_STATE && strm->avail_in != 0) {
808*ab9e68a2SToomas Soome         ERR_RETURN(strm, Z_BUF_ERROR);
809*ab9e68a2SToomas Soome     }
810*ab9e68a2SToomas Soome 
811*ab9e68a2SToomas Soome     /* Write the header */
812*ab9e68a2SToomas Soome     if (s->status == INIT_STATE) {
813*ab9e68a2SToomas Soome         /* zlib header */
814*ab9e68a2SToomas Soome         uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
815*ab9e68a2SToomas Soome         uInt level_flags;
816*ab9e68a2SToomas Soome 
817*ab9e68a2SToomas Soome         if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
818*ab9e68a2SToomas Soome             level_flags = 0;
819*ab9e68a2SToomas Soome         else if (s->level < 6)
820*ab9e68a2SToomas Soome             level_flags = 1;
821*ab9e68a2SToomas Soome         else if (s->level == 6)
822*ab9e68a2SToomas Soome             level_flags = 2;
823*ab9e68a2SToomas Soome         else
824*ab9e68a2SToomas Soome             level_flags = 3;
825*ab9e68a2SToomas Soome         header |= (level_flags << 6);
826*ab9e68a2SToomas Soome         if (s->strstart != 0) header |= PRESET_DICT;
827*ab9e68a2SToomas Soome         header += 31 - (header % 31);
828*ab9e68a2SToomas Soome 
829*ab9e68a2SToomas Soome         putShortMSB(s, header);
830*ab9e68a2SToomas Soome 
831*ab9e68a2SToomas Soome         /* Save the adler32 of the preset dictionary: */
832*ab9e68a2SToomas Soome         if (s->strstart != 0) {
833*ab9e68a2SToomas Soome             putShortMSB(s, (uInt)(strm->adler >> 16));
834*ab9e68a2SToomas Soome             putShortMSB(s, (uInt)(strm->adler & 0xffff));
835*ab9e68a2SToomas Soome         }
836*ab9e68a2SToomas Soome         strm->adler = adler32(0L, Z_NULL, 0);
837*ab9e68a2SToomas Soome         s->status = BUSY_STATE;
838*ab9e68a2SToomas Soome 
839*ab9e68a2SToomas Soome         /* Compression must start with an empty pending buffer */
840*ab9e68a2SToomas Soome         flush_pending(strm);
841*ab9e68a2SToomas Soome         if (s->pending != 0) {
842*ab9e68a2SToomas Soome             s->last_flush = -1;
843*ab9e68a2SToomas Soome             return Z_OK;
844*ab9e68a2SToomas Soome         }
845*ab9e68a2SToomas Soome     }
846*ab9e68a2SToomas Soome #ifdef GZIP
847*ab9e68a2SToomas Soome     if (s->status == GZIP_STATE) {
848*ab9e68a2SToomas Soome         /* gzip header */
849*ab9e68a2SToomas Soome         strm->adler = crc32(0L, Z_NULL, 0);
850*ab9e68a2SToomas Soome         put_byte(s, 31);
851*ab9e68a2SToomas Soome         put_byte(s, 139);
852*ab9e68a2SToomas Soome         put_byte(s, 8);
853*ab9e68a2SToomas Soome         if (s->gzhead == Z_NULL) {
854*ab9e68a2SToomas Soome             put_byte(s, 0);
855*ab9e68a2SToomas Soome             put_byte(s, 0);
856*ab9e68a2SToomas Soome             put_byte(s, 0);
857*ab9e68a2SToomas Soome             put_byte(s, 0);
858*ab9e68a2SToomas Soome             put_byte(s, 0);
859*ab9e68a2SToomas Soome             put_byte(s, s->level == 9 ? 2 :
860*ab9e68a2SToomas Soome                      (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
861*ab9e68a2SToomas Soome                       4 : 0));
862*ab9e68a2SToomas Soome             put_byte(s, OS_CODE);
863*ab9e68a2SToomas Soome             s->status = BUSY_STATE;
864*ab9e68a2SToomas Soome 
865*ab9e68a2SToomas Soome             /* Compression must start with an empty pending buffer */
866*ab9e68a2SToomas Soome             flush_pending(strm);
867*ab9e68a2SToomas Soome             if (s->pending != 0) {
868*ab9e68a2SToomas Soome                 s->last_flush = -1;
869*ab9e68a2SToomas Soome                 return Z_OK;
870*ab9e68a2SToomas Soome             }
871*ab9e68a2SToomas Soome         }
872*ab9e68a2SToomas Soome         else {
873*ab9e68a2SToomas Soome             put_byte(s, (s->gzhead->text ? 1 : 0) +
874*ab9e68a2SToomas Soome                      (s->gzhead->hcrc ? 2 : 0) +
875*ab9e68a2SToomas Soome                      (s->gzhead->extra == Z_NULL ? 0 : 4) +
876*ab9e68a2SToomas Soome                      (s->gzhead->name == Z_NULL ? 0 : 8) +
877*ab9e68a2SToomas Soome                      (s->gzhead->comment == Z_NULL ? 0 : 16)
878*ab9e68a2SToomas Soome                      );
879*ab9e68a2SToomas Soome             put_byte(s, (Byte)(s->gzhead->time & 0xff));
880*ab9e68a2SToomas Soome             put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
881*ab9e68a2SToomas Soome             put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
882*ab9e68a2SToomas Soome             put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
883*ab9e68a2SToomas Soome             put_byte(s, s->level == 9 ? 2 :
884*ab9e68a2SToomas Soome                      (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
885*ab9e68a2SToomas Soome                       4 : 0));
886*ab9e68a2SToomas Soome             put_byte(s, s->gzhead->os & 0xff);
887*ab9e68a2SToomas Soome             if (s->gzhead->extra != Z_NULL) {
888*ab9e68a2SToomas Soome                 put_byte(s, s->gzhead->extra_len & 0xff);
889*ab9e68a2SToomas Soome                 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
890*ab9e68a2SToomas Soome             }
891*ab9e68a2SToomas Soome             if (s->gzhead->hcrc)
892*ab9e68a2SToomas Soome                 strm->adler = crc32(strm->adler, s->pending_buf,
893*ab9e68a2SToomas Soome                                     s->pending);
894*ab9e68a2SToomas Soome             s->gzindex = 0;
895*ab9e68a2SToomas Soome             s->status = EXTRA_STATE;
896*ab9e68a2SToomas Soome         }
897*ab9e68a2SToomas Soome     }
898*ab9e68a2SToomas Soome     if (s->status == EXTRA_STATE) {
899*ab9e68a2SToomas Soome         if (s->gzhead->extra != Z_NULL) {
900*ab9e68a2SToomas Soome             ulg beg = s->pending;   /* start of bytes to update crc */
901*ab9e68a2SToomas Soome             uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
902*ab9e68a2SToomas Soome             while (s->pending + left > s->pending_buf_size) {
903*ab9e68a2SToomas Soome                 uInt copy = s->pending_buf_size - s->pending;
904*ab9e68a2SToomas Soome                 zmemcpy(s->pending_buf + s->pending,
905*ab9e68a2SToomas Soome                         s->gzhead->extra + s->gzindex, copy);
906*ab9e68a2SToomas Soome                 s->pending = s->pending_buf_size;
907*ab9e68a2SToomas Soome                 HCRC_UPDATE(beg);
908*ab9e68a2SToomas Soome                 s->gzindex += copy;
909*ab9e68a2SToomas Soome                 flush_pending(strm);
910*ab9e68a2SToomas Soome                 if (s->pending != 0) {
911*ab9e68a2SToomas Soome                     s->last_flush = -1;
912*ab9e68a2SToomas Soome                     return Z_OK;
913*ab9e68a2SToomas Soome                 }
914*ab9e68a2SToomas Soome                 beg = 0;
915*ab9e68a2SToomas Soome                 left -= copy;
916*ab9e68a2SToomas Soome             }
917*ab9e68a2SToomas Soome             zmemcpy(s->pending_buf + s->pending,
918*ab9e68a2SToomas Soome                     s->gzhead->extra + s->gzindex, left);
919*ab9e68a2SToomas Soome             s->pending += left;
920*ab9e68a2SToomas Soome             HCRC_UPDATE(beg);
921*ab9e68a2SToomas Soome             s->gzindex = 0;
922*ab9e68a2SToomas Soome         }
923*ab9e68a2SToomas Soome         s->status = NAME_STATE;
924*ab9e68a2SToomas Soome     }
925*ab9e68a2SToomas Soome     if (s->status == NAME_STATE) {
926*ab9e68a2SToomas Soome         if (s->gzhead->name != Z_NULL) {
927*ab9e68a2SToomas Soome             ulg beg = s->pending;   /* start of bytes to update crc */
928*ab9e68a2SToomas Soome             int val;
929*ab9e68a2SToomas Soome             do {
930*ab9e68a2SToomas Soome                 if (s->pending == s->pending_buf_size) {
931*ab9e68a2SToomas Soome                     HCRC_UPDATE(beg);
932*ab9e68a2SToomas Soome                     flush_pending(strm);
933*ab9e68a2SToomas Soome                     if (s->pending != 0) {
934*ab9e68a2SToomas Soome                         s->last_flush = -1;
935*ab9e68a2SToomas Soome                         return Z_OK;
936*ab9e68a2SToomas Soome                     }
937*ab9e68a2SToomas Soome                     beg = 0;
938*ab9e68a2SToomas Soome                 }
939*ab9e68a2SToomas Soome                 val = s->gzhead->name[s->gzindex++];
940*ab9e68a2SToomas Soome                 put_byte(s, val);
941*ab9e68a2SToomas Soome             } while (val != 0);
942*ab9e68a2SToomas Soome             HCRC_UPDATE(beg);
943*ab9e68a2SToomas Soome             s->gzindex = 0;
944*ab9e68a2SToomas Soome         }
945*ab9e68a2SToomas Soome         s->status = COMMENT_STATE;
946*ab9e68a2SToomas Soome     }
947*ab9e68a2SToomas Soome     if (s->status == COMMENT_STATE) {
948*ab9e68a2SToomas Soome         if (s->gzhead->comment != Z_NULL) {
949*ab9e68a2SToomas Soome             ulg beg = s->pending;   /* start of bytes to update crc */
950*ab9e68a2SToomas Soome             int val;
951*ab9e68a2SToomas Soome             do {
952*ab9e68a2SToomas Soome                 if (s->pending == s->pending_buf_size) {
953*ab9e68a2SToomas Soome                     HCRC_UPDATE(beg);
954*ab9e68a2SToomas Soome                     flush_pending(strm);
955*ab9e68a2SToomas Soome                     if (s->pending != 0) {
956*ab9e68a2SToomas Soome                         s->last_flush = -1;
957*ab9e68a2SToomas Soome                         return Z_OK;
958*ab9e68a2SToomas Soome                     }
959*ab9e68a2SToomas Soome                     beg = 0;
960*ab9e68a2SToomas Soome                 }
961*ab9e68a2SToomas Soome                 val = s->gzhead->comment[s->gzindex++];
962*ab9e68a2SToomas Soome                 put_byte(s, val);
963*ab9e68a2SToomas Soome             } while (val != 0);
964*ab9e68a2SToomas Soome             HCRC_UPDATE(beg);
965*ab9e68a2SToomas Soome         }
966*ab9e68a2SToomas Soome         s->status = HCRC_STATE;
967*ab9e68a2SToomas Soome     }
968*ab9e68a2SToomas Soome     if (s->status == HCRC_STATE) {
969*ab9e68a2SToomas Soome         if (s->gzhead->hcrc) {
970*ab9e68a2SToomas Soome             if (s->pending + 2 > s->pending_buf_size) {
971*ab9e68a2SToomas Soome                 flush_pending(strm);
972*ab9e68a2SToomas Soome                 if (s->pending != 0) {
973*ab9e68a2SToomas Soome                     s->last_flush = -1;
974*ab9e68a2SToomas Soome                     return Z_OK;
975*ab9e68a2SToomas Soome                 }
976*ab9e68a2SToomas Soome             }
977*ab9e68a2SToomas Soome             put_byte(s, (Byte)(strm->adler & 0xff));
978*ab9e68a2SToomas Soome             put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
979*ab9e68a2SToomas Soome             strm->adler = crc32(0L, Z_NULL, 0);
980*ab9e68a2SToomas Soome         }
981*ab9e68a2SToomas Soome         s->status = BUSY_STATE;
982*ab9e68a2SToomas Soome 
983*ab9e68a2SToomas Soome         /* Compression must start with an empty pending buffer */
984*ab9e68a2SToomas Soome         flush_pending(strm);
985*ab9e68a2SToomas Soome         if (s->pending != 0) {
986*ab9e68a2SToomas Soome             s->last_flush = -1;
987*ab9e68a2SToomas Soome             return Z_OK;
988*ab9e68a2SToomas Soome         }
989*ab9e68a2SToomas Soome     }
990*ab9e68a2SToomas Soome #endif
991*ab9e68a2SToomas Soome 
992*ab9e68a2SToomas Soome     /* Start a new block or continue the current one.
993*ab9e68a2SToomas Soome      */
994*ab9e68a2SToomas Soome     if (strm->avail_in != 0 || s->lookahead != 0 ||
995*ab9e68a2SToomas Soome         (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
996*ab9e68a2SToomas Soome         block_state bstate;
997*ab9e68a2SToomas Soome 
998*ab9e68a2SToomas Soome         bstate = s->level == 0 ? deflate_stored(s, flush) :
999*ab9e68a2SToomas Soome                  s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
1000*ab9e68a2SToomas Soome                  s->strategy == Z_RLE ? deflate_rle(s, flush) :
1001*ab9e68a2SToomas Soome                  (*(configuration_table[s->level].func))(s, flush);
1002*ab9e68a2SToomas Soome 
1003*ab9e68a2SToomas Soome         if (bstate == finish_started || bstate == finish_done) {
1004*ab9e68a2SToomas Soome             s->status = FINISH_STATE;
1005*ab9e68a2SToomas Soome         }
1006*ab9e68a2SToomas Soome         if (bstate == need_more || bstate == finish_started) {
1007*ab9e68a2SToomas Soome             if (strm->avail_out == 0) {
1008*ab9e68a2SToomas Soome                 s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
1009*ab9e68a2SToomas Soome             }
1010*ab9e68a2SToomas Soome             return Z_OK;
1011*ab9e68a2SToomas Soome             /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
1012*ab9e68a2SToomas Soome              * of deflate should use the same flush parameter to make sure
1013*ab9e68a2SToomas Soome              * that the flush is complete. So we don't have to output an
1014*ab9e68a2SToomas Soome              * empty block here, this will be done at next call. This also
1015*ab9e68a2SToomas Soome              * ensures that for a very small output buffer, we emit at most
1016*ab9e68a2SToomas Soome              * one empty block.
1017*ab9e68a2SToomas Soome              */
1018*ab9e68a2SToomas Soome         }
1019*ab9e68a2SToomas Soome         if (bstate == block_done) {
1020*ab9e68a2SToomas Soome             if (flush == Z_PARTIAL_FLUSH) {
1021*ab9e68a2SToomas Soome                 _tr_align(s);
1022*ab9e68a2SToomas Soome             } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
1023*ab9e68a2SToomas Soome                 _tr_stored_block(s, (char*)0, 0L, 0);
1024*ab9e68a2SToomas Soome                 /* For a full flush, this empty block will be recognized
1025*ab9e68a2SToomas Soome                  * as a special marker by inflate_sync().
1026*ab9e68a2SToomas Soome                  */
1027*ab9e68a2SToomas Soome                 if (flush == Z_FULL_FLUSH) {
1028*ab9e68a2SToomas Soome                     CLEAR_HASH(s);             /* forget history */
1029*ab9e68a2SToomas Soome                     if (s->lookahead == 0) {
1030*ab9e68a2SToomas Soome                         s->strstart = 0;
1031*ab9e68a2SToomas Soome                         s->block_start = 0L;
1032*ab9e68a2SToomas Soome                         s->insert = 0;
1033*ab9e68a2SToomas Soome                     }
1034*ab9e68a2SToomas Soome                 }
1035*ab9e68a2SToomas Soome             }
1036*ab9e68a2SToomas Soome             flush_pending(strm);
1037*ab9e68a2SToomas Soome             if (strm->avail_out == 0) {
1038*ab9e68a2SToomas Soome               s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
1039*ab9e68a2SToomas Soome               return Z_OK;
1040*ab9e68a2SToomas Soome             }
1041*ab9e68a2SToomas Soome         }
1042*ab9e68a2SToomas Soome     }
1043*ab9e68a2SToomas Soome 
1044*ab9e68a2SToomas Soome     if (flush != Z_FINISH) return Z_OK;
1045*ab9e68a2SToomas Soome     if (s->wrap <= 0) return Z_STREAM_END;
1046*ab9e68a2SToomas Soome 
1047*ab9e68a2SToomas Soome     /* Write the trailer */
1048*ab9e68a2SToomas Soome #ifdef GZIP
1049*ab9e68a2SToomas Soome     if (s->wrap == 2) {
1050*ab9e68a2SToomas Soome         put_byte(s, (Byte)(strm->adler & 0xff));
1051*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
1052*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
1053*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
1054*ab9e68a2SToomas Soome         put_byte(s, (Byte)(strm->total_in & 0xff));
1055*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
1056*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
1057*ab9e68a2SToomas Soome         put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
1058*ab9e68a2SToomas Soome     }
1059*ab9e68a2SToomas Soome     else
1060*ab9e68a2SToomas Soome #endif
1061*ab9e68a2SToomas Soome     {
1062*ab9e68a2SToomas Soome         putShortMSB(s, (uInt)(strm->adler >> 16));
1063*ab9e68a2SToomas Soome         putShortMSB(s, (uInt)(strm->adler & 0xffff));
1064*ab9e68a2SToomas Soome     }
1065*ab9e68a2SToomas Soome     flush_pending(strm);
1066*ab9e68a2SToomas Soome     /* If avail_out is zero, the application will call deflate again
1067*ab9e68a2SToomas Soome      * to flush the rest.
1068*ab9e68a2SToomas Soome      */
1069*ab9e68a2SToomas Soome     if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
1070*ab9e68a2SToomas Soome     return s->pending != 0 ? Z_OK : Z_STREAM_END;
1071*ab9e68a2SToomas Soome }
1072*ab9e68a2SToomas Soome 
1073*ab9e68a2SToomas Soome /* ========================================================================= */
1074*ab9e68a2SToomas Soome int ZEXPORT deflateEnd (strm)
1075*ab9e68a2SToomas Soome     z_streamp strm;
1076*ab9e68a2SToomas Soome {
1077*ab9e68a2SToomas Soome     int status;
1078*ab9e68a2SToomas Soome 
1079*ab9e68a2SToomas Soome     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
1080*ab9e68a2SToomas Soome 
1081*ab9e68a2SToomas Soome     status = strm->state->status;
1082*ab9e68a2SToomas Soome 
1083*ab9e68a2SToomas Soome     /* Deallocate in reverse order of allocations: */
1084*ab9e68a2SToomas Soome     TRY_FREE(strm, strm->state->pending_buf);
1085*ab9e68a2SToomas Soome     TRY_FREE(strm, strm->state->head);
1086*ab9e68a2SToomas Soome     TRY_FREE(strm, strm->state->prev);
1087*ab9e68a2SToomas Soome     TRY_FREE(strm, strm->state->window);
1088*ab9e68a2SToomas Soome 
1089*ab9e68a2SToomas Soome     ZFREE(strm, strm->state);
1090*ab9e68a2SToomas Soome     strm->state = Z_NULL;
1091*ab9e68a2SToomas Soome 
1092*ab9e68a2SToomas Soome     return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
1093*ab9e68a2SToomas Soome }
1094*ab9e68a2SToomas Soome 
1095*ab9e68a2SToomas Soome /* =========================================================================
1096*ab9e68a2SToomas Soome  * Copy the source state to the destination state.
1097*ab9e68a2SToomas Soome  * To simplify the source, this is not supported for 16-bit MSDOS (which
1098*ab9e68a2SToomas Soome  * doesn't have enough memory anyway to duplicate compression states).
1099*ab9e68a2SToomas Soome  */
1100*ab9e68a2SToomas Soome int ZEXPORT deflateCopy (dest, source)
1101*ab9e68a2SToomas Soome     z_streamp dest;
1102*ab9e68a2SToomas Soome     z_streamp source;
1103*ab9e68a2SToomas Soome {
1104*ab9e68a2SToomas Soome #ifdef MAXSEG_64K
1105*ab9e68a2SToomas Soome     return Z_STREAM_ERROR;
1106*ab9e68a2SToomas Soome #else
1107*ab9e68a2SToomas Soome     deflate_state *ds;
1108*ab9e68a2SToomas Soome     deflate_state *ss;
1109*ab9e68a2SToomas Soome     ushf *overlay;
1110*ab9e68a2SToomas Soome 
1111*ab9e68a2SToomas Soome 
1112*ab9e68a2SToomas Soome     if (deflateStateCheck(source) || dest == Z_NULL) {
1113*ab9e68a2SToomas Soome         return Z_STREAM_ERROR;
1114*ab9e68a2SToomas Soome     }
1115*ab9e68a2SToomas Soome 
1116*ab9e68a2SToomas Soome     ss = source->state;
1117*ab9e68a2SToomas Soome 
1118*ab9e68a2SToomas Soome     zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1119*ab9e68a2SToomas Soome 
1120*ab9e68a2SToomas Soome     ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
1121*ab9e68a2SToomas Soome     if (ds == Z_NULL) return Z_MEM_ERROR;
1122*ab9e68a2SToomas Soome     dest->state = (struct internal_state FAR *) ds;
1123*ab9e68a2SToomas Soome     zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
1124*ab9e68a2SToomas Soome     ds->strm = dest;
1125*ab9e68a2SToomas Soome 
1126*ab9e68a2SToomas Soome     ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
1127*ab9e68a2SToomas Soome     ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
1128*ab9e68a2SToomas Soome     ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
1129*ab9e68a2SToomas Soome     overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
1130*ab9e68a2SToomas Soome     ds->pending_buf = (uchf *) overlay;
1131*ab9e68a2SToomas Soome 
1132*ab9e68a2SToomas Soome     if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
1133*ab9e68a2SToomas Soome         ds->pending_buf == Z_NULL) {
1134*ab9e68a2SToomas Soome         deflateEnd (dest);
1135*ab9e68a2SToomas Soome         return Z_MEM_ERROR;
1136*ab9e68a2SToomas Soome     }
1137*ab9e68a2SToomas Soome     /* following zmemcpy do not work for 16-bit MSDOS */
1138*ab9e68a2SToomas Soome     zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
1139*ab9e68a2SToomas Soome     zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
1140*ab9e68a2SToomas Soome     zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
1141*ab9e68a2SToomas Soome     zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
1142*ab9e68a2SToomas Soome 
1143*ab9e68a2SToomas Soome     ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
1144*ab9e68a2SToomas Soome     ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
1145*ab9e68a2SToomas Soome     ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
1146*ab9e68a2SToomas Soome 
1147*ab9e68a2SToomas Soome     ds->l_desc.dyn_tree = ds->dyn_ltree;
1148*ab9e68a2SToomas Soome     ds->d_desc.dyn_tree = ds->dyn_dtree;
1149*ab9e68a2SToomas Soome     ds->bl_desc.dyn_tree = ds->bl_tree;
1150*ab9e68a2SToomas Soome 
1151*ab9e68a2SToomas Soome     return Z_OK;
1152*ab9e68a2SToomas Soome #endif /* MAXSEG_64K */
1153*ab9e68a2SToomas Soome }
1154*ab9e68a2SToomas Soome 
1155*ab9e68a2SToomas Soome /* ===========================================================================
1156*ab9e68a2SToomas Soome  * Read a new buffer from the current input stream, update the adler32
1157*ab9e68a2SToomas Soome  * and total number of bytes read.  All deflate() input goes through
1158*ab9e68a2SToomas Soome  * this function so some applications may wish to modify it to avoid
1159*ab9e68a2SToomas Soome  * allocating a large strm->next_in buffer and copying from it.
1160*ab9e68a2SToomas Soome  * (See also flush_pending()).
1161*ab9e68a2SToomas Soome  */
1162*ab9e68a2SToomas Soome local unsigned read_buf(strm, buf, size)
1163*ab9e68a2SToomas Soome     z_streamp strm;
1164*ab9e68a2SToomas Soome     Bytef *buf;
1165*ab9e68a2SToomas Soome     unsigned size;
1166*ab9e68a2SToomas Soome {
1167*ab9e68a2SToomas Soome     unsigned len = strm->avail_in;
1168*ab9e68a2SToomas Soome 
1169*ab9e68a2SToomas Soome     if (len > size) len = size;
1170*ab9e68a2SToomas Soome     if (len == 0) return 0;
1171*ab9e68a2SToomas Soome 
1172*ab9e68a2SToomas Soome     strm->avail_in  -= len;
1173*ab9e68a2SToomas Soome 
1174*ab9e68a2SToomas Soome     zmemcpy(buf, strm->next_in, len);
1175*ab9e68a2SToomas Soome     if (strm->state->wrap == 1) {
1176*ab9e68a2SToomas Soome         strm->adler = adler32(strm->adler, buf, len);
1177*ab9e68a2SToomas Soome     }
1178*ab9e68a2SToomas Soome #ifdef GZIP
1179*ab9e68a2SToomas Soome     else if (strm->state->wrap == 2) {
1180*ab9e68a2SToomas Soome         strm->adler = crc32(strm->adler, buf, len);
1181*ab9e68a2SToomas Soome     }
1182*ab9e68a2SToomas Soome #endif
1183*ab9e68a2SToomas Soome     strm->next_in  += len;
1184*ab9e68a2SToomas Soome     strm->total_in += len;
1185*ab9e68a2SToomas Soome 
1186*ab9e68a2SToomas Soome     return len;
1187*ab9e68a2SToomas Soome }
1188*ab9e68a2SToomas Soome 
1189*ab9e68a2SToomas Soome /* ===========================================================================
1190*ab9e68a2SToomas Soome  * Initialize the "longest match" routines for a new zlib stream
1191*ab9e68a2SToomas Soome  */
1192*ab9e68a2SToomas Soome local void lm_init (s)
1193*ab9e68a2SToomas Soome     deflate_state *s;
1194*ab9e68a2SToomas Soome {
1195*ab9e68a2SToomas Soome     s->window_size = (ulg)2L*s->w_size;
1196*ab9e68a2SToomas Soome 
1197*ab9e68a2SToomas Soome     CLEAR_HASH(s);
1198*ab9e68a2SToomas Soome 
1199*ab9e68a2SToomas Soome     /* Set the default configuration parameters:
1200*ab9e68a2SToomas Soome      */
1201*ab9e68a2SToomas Soome     s->max_lazy_match   = configuration_table[s->level].max_lazy;
1202*ab9e68a2SToomas Soome     s->good_match       = configuration_table[s->level].good_length;
1203*ab9e68a2SToomas Soome     s->nice_match       = configuration_table[s->level].nice_length;
1204*ab9e68a2SToomas Soome     s->max_chain_length = configuration_table[s->level].max_chain;
1205*ab9e68a2SToomas Soome 
1206*ab9e68a2SToomas Soome     s->strstart = 0;
1207*ab9e68a2SToomas Soome     s->block_start = 0L;
1208*ab9e68a2SToomas Soome     s->lookahead = 0;
1209*ab9e68a2SToomas Soome     s->insert = 0;
1210*ab9e68a2SToomas Soome     s->match_length = s->prev_length = MIN_MATCH-1;
1211*ab9e68a2SToomas Soome     s->match_available = 0;
1212*ab9e68a2SToomas Soome     s->ins_h = 0;
1213*ab9e68a2SToomas Soome #ifndef FASTEST
1214*ab9e68a2SToomas Soome #ifdef ASMV
1215*ab9e68a2SToomas Soome     match_init(); /* initialize the asm code */
1216*ab9e68a2SToomas Soome #endif
1217*ab9e68a2SToomas Soome #endif
1218*ab9e68a2SToomas Soome }
1219*ab9e68a2SToomas Soome 
1220*ab9e68a2SToomas Soome #ifndef FASTEST
1221*ab9e68a2SToomas Soome /* ===========================================================================
1222*ab9e68a2SToomas Soome  * Set match_start to the longest match starting at the given string and
1223*ab9e68a2SToomas Soome  * return its length. Matches shorter or equal to prev_length are discarded,
1224*ab9e68a2SToomas Soome  * in which case the result is equal to prev_length and match_start is
1225*ab9e68a2SToomas Soome  * garbage.
1226*ab9e68a2SToomas Soome  * IN assertions: cur_match is the head of the hash chain for the current
1227*ab9e68a2SToomas Soome  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
1228*ab9e68a2SToomas Soome  * OUT assertion: the match length is not greater than s->lookahead.
1229*ab9e68a2SToomas Soome  */
1230*ab9e68a2SToomas Soome #ifndef ASMV
1231*ab9e68a2SToomas Soome /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
1232*ab9e68a2SToomas Soome  * match.S. The code will be functionally equivalent.
1233*ab9e68a2SToomas Soome  */
1234*ab9e68a2SToomas Soome local uInt longest_match(s, cur_match)
1235*ab9e68a2SToomas Soome     deflate_state *s;
1236*ab9e68a2SToomas Soome     IPos cur_match;                             /* current match */
1237*ab9e68a2SToomas Soome {
1238*ab9e68a2SToomas Soome     unsigned chain_length = s->max_chain_length;/* max hash chain length */
1239*ab9e68a2SToomas Soome     register Bytef *scan = s->window + s->strstart; /* current string */
1240*ab9e68a2SToomas Soome     register Bytef *match;                      /* matched string */
1241*ab9e68a2SToomas Soome     register int len;                           /* length of current match */
1242*ab9e68a2SToomas Soome     int best_len = (int)s->prev_length;         /* best match length so far */
1243*ab9e68a2SToomas Soome     int nice_match = s->nice_match;             /* stop if match long enough */
1244*ab9e68a2SToomas Soome     IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
1245*ab9e68a2SToomas Soome         s->strstart - (IPos)MAX_DIST(s) : NIL;
1246*ab9e68a2SToomas Soome     /* Stop when cur_match becomes <= limit. To simplify the code,
1247*ab9e68a2SToomas Soome      * we prevent matches with the string of window index 0.
1248*ab9e68a2SToomas Soome      */
1249*ab9e68a2SToomas Soome     Posf *prev = s->prev;
1250*ab9e68a2SToomas Soome     uInt wmask = s->w_mask;
1251*ab9e68a2SToomas Soome 
1252*ab9e68a2SToomas Soome #ifdef UNALIGNED_OK
1253*ab9e68a2SToomas Soome     /* Compare two bytes at a time. Note: this is not always beneficial.
1254*ab9e68a2SToomas Soome      * Try with and without -DUNALIGNED_OK to check.
1255*ab9e68a2SToomas Soome      */
1256*ab9e68a2SToomas Soome     register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
1257*ab9e68a2SToomas Soome     register ush scan_start = *(ushf*)scan;
1258*ab9e68a2SToomas Soome     register ush scan_end   = *(ushf*)(scan+best_len-1);
1259*ab9e68a2SToomas Soome #else
1260*ab9e68a2SToomas Soome     register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1261*ab9e68a2SToomas Soome     register Byte scan_end1  = scan[best_len-1];
1262*ab9e68a2SToomas Soome     register Byte scan_end   = scan[best_len];
1263*ab9e68a2SToomas Soome #endif
1264*ab9e68a2SToomas Soome 
1265*ab9e68a2SToomas Soome     /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1266*ab9e68a2SToomas Soome      * It is easy to get rid of this optimization if necessary.
1267*ab9e68a2SToomas Soome      */
1268*ab9e68a2SToomas Soome     Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1269*ab9e68a2SToomas Soome 
1270*ab9e68a2SToomas Soome     /* Do not waste too much time if we already have a good match: */
1271*ab9e68a2SToomas Soome     if (s->prev_length >= s->good_match) {
1272*ab9e68a2SToomas Soome         chain_length >>= 2;
1273*ab9e68a2SToomas Soome     }
1274*ab9e68a2SToomas Soome     /* Do not look for matches beyond the end of the input. This is necessary
1275*ab9e68a2SToomas Soome      * to make deflate deterministic.
1276*ab9e68a2SToomas Soome      */
1277*ab9e68a2SToomas Soome     if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
1278*ab9e68a2SToomas Soome 
1279*ab9e68a2SToomas Soome     Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
1280*ab9e68a2SToomas Soome 
1281*ab9e68a2SToomas Soome     do {
1282*ab9e68a2SToomas Soome         Assert(cur_match < s->strstart, "no future");
1283*ab9e68a2SToomas Soome         match = s->window + cur_match;
1284*ab9e68a2SToomas Soome 
1285*ab9e68a2SToomas Soome         /* Skip to next match if the match length cannot increase
1286*ab9e68a2SToomas Soome          * or if the match length is less than 2.  Note that the checks below
1287*ab9e68a2SToomas Soome          * for insufficient lookahead only occur occasionally for performance
1288*ab9e68a2SToomas Soome          * reasons.  Therefore uninitialized memory will be accessed, and
1289*ab9e68a2SToomas Soome          * conditional jumps will be made that depend on those values.
1290*ab9e68a2SToomas Soome          * However the length of the match is limited to the lookahead, so
1291*ab9e68a2SToomas Soome          * the output of deflate is not affected by the uninitialized values.
1292*ab9e68a2SToomas Soome          */
1293*ab9e68a2SToomas Soome #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
1294*ab9e68a2SToomas Soome         /* This code assumes sizeof(unsigned short) == 2. Do not use
1295*ab9e68a2SToomas Soome          * UNALIGNED_OK if your compiler uses a different size.
1296*ab9e68a2SToomas Soome          */
1297*ab9e68a2SToomas Soome         if (*(ushf*)(match+best_len-1) != scan_end ||
1298*ab9e68a2SToomas Soome             *(ushf*)match != scan_start) continue;
1299*ab9e68a2SToomas Soome 
1300*ab9e68a2SToomas Soome         /* It is not necessary to compare scan[2] and match[2] since they are
1301*ab9e68a2SToomas Soome          * always equal when the other bytes match, given that the hash keys
1302*ab9e68a2SToomas Soome          * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
1303*ab9e68a2SToomas Soome          * strstart+3, +5, ... up to strstart+257. We check for insufficient
1304*ab9e68a2SToomas Soome          * lookahead only every 4th comparison; the 128th check will be made
1305*ab9e68a2SToomas Soome          * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
1306*ab9e68a2SToomas Soome          * necessary to put more guard bytes at the end of the window, or
1307*ab9e68a2SToomas Soome          * to check more often for insufficient lookahead.
1308*ab9e68a2SToomas Soome          */
1309*ab9e68a2SToomas Soome         Assert(scan[2] == match[2], "scan[2]?");
1310*ab9e68a2SToomas Soome         scan++, match++;
1311*ab9e68a2SToomas Soome         do {
1312*ab9e68a2SToomas Soome         } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1313*ab9e68a2SToomas Soome                  *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1314*ab9e68a2SToomas Soome                  *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1315*ab9e68a2SToomas Soome                  *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1316*ab9e68a2SToomas Soome                  scan < strend);
1317*ab9e68a2SToomas Soome         /* The funny "do {}" generates better code on most compilers */
1318*ab9e68a2SToomas Soome 
1319*ab9e68a2SToomas Soome         /* Here, scan <= window+strstart+257 */
1320*ab9e68a2SToomas Soome         Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1321*ab9e68a2SToomas Soome         if (*scan == *match) scan++;
1322*ab9e68a2SToomas Soome 
1323*ab9e68a2SToomas Soome         len = (MAX_MATCH - 1) - (int)(strend-scan);
1324*ab9e68a2SToomas Soome         scan = strend - (MAX_MATCH-1);
1325*ab9e68a2SToomas Soome 
1326*ab9e68a2SToomas Soome #else /* UNALIGNED_OK */
1327*ab9e68a2SToomas Soome 
1328*ab9e68a2SToomas Soome         if (match[best_len]   != scan_end  ||
1329*ab9e68a2SToomas Soome             match[best_len-1] != scan_end1 ||
1330*ab9e68a2SToomas Soome             *match            != *scan     ||
1331*ab9e68a2SToomas Soome             *++match          != scan[1])      continue;
1332*ab9e68a2SToomas Soome 
1333*ab9e68a2SToomas Soome         /* The check at best_len-1 can be removed because it will be made
1334*ab9e68a2SToomas Soome          * again later. (This heuristic is not always a win.)
1335*ab9e68a2SToomas Soome          * It is not necessary to compare scan[2] and match[2] since they
1336*ab9e68a2SToomas Soome          * are always equal when the other bytes match, given that
1337*ab9e68a2SToomas Soome          * the hash keys are equal and that HASH_BITS >= 8.
1338*ab9e68a2SToomas Soome          */
1339*ab9e68a2SToomas Soome         scan += 2, match++;
1340*ab9e68a2SToomas Soome         Assert(*scan == *match, "match[2]?");
1341*ab9e68a2SToomas Soome 
1342*ab9e68a2SToomas Soome         /* We check for insufficient lookahead only every 8th comparison;
1343*ab9e68a2SToomas Soome          * the 256th check will be made at strstart+258.
1344*ab9e68a2SToomas Soome          */
1345*ab9e68a2SToomas Soome         do {
1346*ab9e68a2SToomas Soome         } while (*++scan == *++match && *++scan == *++match &&
1347*ab9e68a2SToomas Soome                  *++scan == *++match && *++scan == *++match &&
1348*ab9e68a2SToomas Soome                  *++scan == *++match && *++scan == *++match &&
1349*ab9e68a2SToomas Soome                  *++scan == *++match && *++scan == *++match &&
1350*ab9e68a2SToomas Soome                  scan < strend);
1351*ab9e68a2SToomas Soome 
1352*ab9e68a2SToomas Soome         Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1353*ab9e68a2SToomas Soome 
1354*ab9e68a2SToomas Soome         len = MAX_MATCH - (int)(strend - scan);
1355*ab9e68a2SToomas Soome         scan = strend - MAX_MATCH;
1356*ab9e68a2SToomas Soome 
1357*ab9e68a2SToomas Soome #endif /* UNALIGNED_OK */
1358*ab9e68a2SToomas Soome 
1359*ab9e68a2SToomas Soome         if (len > best_len) {
1360*ab9e68a2SToomas Soome             s->match_start = cur_match;
1361*ab9e68a2SToomas Soome             best_len = len;
1362*ab9e68a2SToomas Soome             if (len >= nice_match) break;
1363*ab9e68a2SToomas Soome #ifdef UNALIGNED_OK
1364*ab9e68a2SToomas Soome             scan_end = *(ushf*)(scan+best_len-1);
1365*ab9e68a2SToomas Soome #else
1366*ab9e68a2SToomas Soome             scan_end1  = scan[best_len-1];
1367*ab9e68a2SToomas Soome             scan_end   = scan[best_len];
1368*ab9e68a2SToomas Soome #endif
1369*ab9e68a2SToomas Soome         }
1370*ab9e68a2SToomas Soome     } while ((cur_match = prev[cur_match & wmask]) > limit
1371*ab9e68a2SToomas Soome              && --chain_length != 0);
1372*ab9e68a2SToomas Soome 
1373*ab9e68a2SToomas Soome     if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
1374*ab9e68a2SToomas Soome     return s->lookahead;
1375*ab9e68a2SToomas Soome }
1376*ab9e68a2SToomas Soome #endif /* ASMV */
1377*ab9e68a2SToomas Soome 
1378*ab9e68a2SToomas Soome #else /* FASTEST */
1379*ab9e68a2SToomas Soome 
1380*ab9e68a2SToomas Soome /* ---------------------------------------------------------------------------
1381*ab9e68a2SToomas Soome  * Optimized version for FASTEST only
1382*ab9e68a2SToomas Soome  */
1383*ab9e68a2SToomas Soome local uInt longest_match(s, cur_match)
1384*ab9e68a2SToomas Soome     deflate_state *s;
1385*ab9e68a2SToomas Soome     IPos cur_match;                             /* current match */
1386*ab9e68a2SToomas Soome {
1387*ab9e68a2SToomas Soome     register Bytef *scan = s->window + s->strstart; /* current string */
1388*ab9e68a2SToomas Soome     register Bytef *match;                       /* matched string */
1389*ab9e68a2SToomas Soome     register int len;                           /* length of current match */
1390*ab9e68a2SToomas Soome     register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1391*ab9e68a2SToomas Soome 
1392*ab9e68a2SToomas Soome     /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1393*ab9e68a2SToomas Soome      * It is easy to get rid of this optimization if necessary.
1394*ab9e68a2SToomas Soome      */
1395*ab9e68a2SToomas Soome     Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1396*ab9e68a2SToomas Soome 
1397*ab9e68a2SToomas Soome     Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
1398*ab9e68a2SToomas Soome 
1399*ab9e68a2SToomas Soome     Assert(cur_match < s->strstart, "no future");
1400*ab9e68a2SToomas Soome 
1401*ab9e68a2SToomas Soome     match = s->window + cur_match;
1402*ab9e68a2SToomas Soome 
1403*ab9e68a2SToomas Soome     /* Return failure if the match length is less than 2:
1404*ab9e68a2SToomas Soome      */
1405*ab9e68a2SToomas Soome     if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
1406*ab9e68a2SToomas Soome 
1407*ab9e68a2SToomas Soome     /* The check at best_len-1 can be removed because it will be made
1408*ab9e68a2SToomas Soome      * again later. (This heuristic is not always a win.)
1409*ab9e68a2SToomas Soome      * It is not necessary to compare scan[2] and match[2] since they
1410*ab9e68a2SToomas Soome      * are always equal when the other bytes match, given that
1411*ab9e68a2SToomas Soome      * the hash keys are equal and that HASH_BITS >= 8.
1412*ab9e68a2SToomas Soome      */
1413*ab9e68a2SToomas Soome     scan += 2, match += 2;
1414*ab9e68a2SToomas Soome     Assert(*scan == *match, "match[2]?");
1415*ab9e68a2SToomas Soome 
1416*ab9e68a2SToomas Soome     /* We check for insufficient lookahead only every 8th comparison;
1417*ab9e68a2SToomas Soome      * the 256th check will be made at strstart+258.
1418*ab9e68a2SToomas Soome      */
1419*ab9e68a2SToomas Soome     do {
1420*ab9e68a2SToomas Soome     } while (*++scan == *++match && *++scan == *++match &&
1421*ab9e68a2SToomas Soome              *++scan == *++match && *++scan == *++match &&
1422*ab9e68a2SToomas Soome              *++scan == *++match && *++scan == *++match &&
1423*ab9e68a2SToomas Soome              *++scan == *++match && *++scan == *++match &&
1424*ab9e68a2SToomas Soome              scan < strend);
1425*ab9e68a2SToomas Soome 
1426*ab9e68a2SToomas Soome     Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1427*ab9e68a2SToomas Soome 
1428*ab9e68a2SToomas Soome     len = MAX_MATCH - (int)(strend - scan);
1429*ab9e68a2SToomas Soome 
1430*ab9e68a2SToomas Soome     if (len < MIN_MATCH) return MIN_MATCH - 1;
1431*ab9e68a2SToomas Soome 
1432*ab9e68a2SToomas Soome     s->match_start = cur_match;
1433*ab9e68a2SToomas Soome     return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
1434*ab9e68a2SToomas Soome }
1435*ab9e68a2SToomas Soome 
1436*ab9e68a2SToomas Soome #endif /* FASTEST */
1437*ab9e68a2SToomas Soome 
1438*ab9e68a2SToomas Soome #ifdef ZLIB_DEBUG
1439*ab9e68a2SToomas Soome 
1440*ab9e68a2SToomas Soome #define EQUAL 0
1441*ab9e68a2SToomas Soome /* result of memcmp for equal strings */
1442*ab9e68a2SToomas Soome 
1443*ab9e68a2SToomas Soome /* ===========================================================================
1444*ab9e68a2SToomas Soome  * Check that the match at match_start is indeed a match.
1445*ab9e68a2SToomas Soome  */
1446*ab9e68a2SToomas Soome local void check_match(s, start, match, length)
1447*ab9e68a2SToomas Soome     deflate_state *s;
1448*ab9e68a2SToomas Soome     IPos start, match;
1449*ab9e68a2SToomas Soome     int length;
1450*ab9e68a2SToomas Soome {
1451*ab9e68a2SToomas Soome     /* check that the match is indeed a match */
1452*ab9e68a2SToomas Soome     if (zmemcmp(s->window + match,
1453*ab9e68a2SToomas Soome                 s->window + start, length) != EQUAL) {
1454*ab9e68a2SToomas Soome         fprintf(stderr, " start %u, match %u, length %d\n",
1455*ab9e68a2SToomas Soome                 start, match, length);
1456*ab9e68a2SToomas Soome         do {
1457*ab9e68a2SToomas Soome             fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
1458*ab9e68a2SToomas Soome         } while (--length != 0);
1459*ab9e68a2SToomas Soome         z_error("invalid match");
1460*ab9e68a2SToomas Soome     }
1461*ab9e68a2SToomas Soome     if (z_verbose > 1) {
1462*ab9e68a2SToomas Soome         fprintf(stderr,"\\[%d,%d]", start-match, length);
1463*ab9e68a2SToomas Soome         do { putc(s->window[start++], stderr); } while (--length != 0);
1464*ab9e68a2SToomas Soome     }
1465*ab9e68a2SToomas Soome }
1466*ab9e68a2SToomas Soome #else
1467*ab9e68a2SToomas Soome #  define check_match(s, start, match, length)
1468*ab9e68a2SToomas Soome #endif /* ZLIB_DEBUG */
1469*ab9e68a2SToomas Soome 
1470*ab9e68a2SToomas Soome /* ===========================================================================
1471*ab9e68a2SToomas Soome  * Fill the window when the lookahead becomes insufficient.
1472*ab9e68a2SToomas Soome  * Updates strstart and lookahead.
1473*ab9e68a2SToomas Soome  *
1474*ab9e68a2SToomas Soome  * IN assertion: lookahead < MIN_LOOKAHEAD
1475*ab9e68a2SToomas Soome  * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
1476*ab9e68a2SToomas Soome  *    At least one byte has been read, or avail_in == 0; reads are
1477*ab9e68a2SToomas Soome  *    performed for at least two bytes (required for the zip translate_eol
1478*ab9e68a2SToomas Soome  *    option -- not supported here).
1479*ab9e68a2SToomas Soome  */
1480*ab9e68a2SToomas Soome local void fill_window(s)
1481*ab9e68a2SToomas Soome     deflate_state *s;
1482*ab9e68a2SToomas Soome {
1483*ab9e68a2SToomas Soome     unsigned n;
1484*ab9e68a2SToomas Soome     unsigned more;    /* Amount of free space at the end of the window. */
1485*ab9e68a2SToomas Soome     uInt wsize = s->w_size;
1486*ab9e68a2SToomas Soome 
1487*ab9e68a2SToomas Soome     Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
1488*ab9e68a2SToomas Soome 
1489*ab9e68a2SToomas Soome     do {
1490*ab9e68a2SToomas Soome         more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
1491*ab9e68a2SToomas Soome 
1492*ab9e68a2SToomas Soome         /* Deal with !@#$% 64K limit: */
1493*ab9e68a2SToomas Soome         if (sizeof(int) <= 2) {
1494*ab9e68a2SToomas Soome             if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
1495*ab9e68a2SToomas Soome                 more = wsize;
1496*ab9e68a2SToomas Soome 
1497*ab9e68a2SToomas Soome             } else if (more == (unsigned)(-1)) {
1498*ab9e68a2SToomas Soome                 /* Very unlikely, but possible on 16 bit machine if
1499*ab9e68a2SToomas Soome                  * strstart == 0 && lookahead == 1 (input done a byte at time)
1500*ab9e68a2SToomas Soome                  */
1501*ab9e68a2SToomas Soome                 more--;
1502*ab9e68a2SToomas Soome             }
1503*ab9e68a2SToomas Soome         }
1504*ab9e68a2SToomas Soome 
1505*ab9e68a2SToomas Soome         /* If the window is almost full and there is insufficient lookahead,
1506*ab9e68a2SToomas Soome          * move the upper half to the lower one to make room in the upper half.
1507*ab9e68a2SToomas Soome          */
1508*ab9e68a2SToomas Soome         if (s->strstart >= wsize+MAX_DIST(s)) {
1509*ab9e68a2SToomas Soome 
1510*ab9e68a2SToomas Soome             zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
1511*ab9e68a2SToomas Soome             s->match_start -= wsize;
1512*ab9e68a2SToomas Soome             s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
1513*ab9e68a2SToomas Soome             s->block_start -= (long) wsize;
1514*ab9e68a2SToomas Soome             slide_hash(s);
1515*ab9e68a2SToomas Soome             more += wsize;
1516*ab9e68a2SToomas Soome         }
1517*ab9e68a2SToomas Soome         if (s->strm->avail_in == 0) break;
1518*ab9e68a2SToomas Soome 
1519*ab9e68a2SToomas Soome         /* If there was no sliding:
1520*ab9e68a2SToomas Soome          *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
1521*ab9e68a2SToomas Soome          *    more == window_size - lookahead - strstart
1522*ab9e68a2SToomas Soome          * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
1523*ab9e68a2SToomas Soome          * => more >= window_size - 2*WSIZE + 2
1524*ab9e68a2SToomas Soome          * In the BIG_MEM or MMAP case (not yet supported),
1525*ab9e68a2SToomas Soome          *   window_size == input_size + MIN_LOOKAHEAD  &&
1526*ab9e68a2SToomas Soome          *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
1527*ab9e68a2SToomas Soome          * Otherwise, window_size == 2*WSIZE so more >= 2.
1528*ab9e68a2SToomas Soome          * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
1529*ab9e68a2SToomas Soome          */
1530*ab9e68a2SToomas Soome         Assert(more >= 2, "more < 2");
1531*ab9e68a2SToomas Soome 
1532*ab9e68a2SToomas Soome         n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
1533*ab9e68a2SToomas Soome         s->lookahead += n;
1534*ab9e68a2SToomas Soome 
1535*ab9e68a2SToomas Soome         /* Initialize the hash value now that we have some input: */
1536*ab9e68a2SToomas Soome         if (s->lookahead + s->insert >= MIN_MATCH) {
1537*ab9e68a2SToomas Soome             uInt str = s->strstart - s->insert;
1538*ab9e68a2SToomas Soome             s->ins_h = s->window[str];
1539*ab9e68a2SToomas Soome             UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
1540*ab9e68a2SToomas Soome #if MIN_MATCH != 3
1541*ab9e68a2SToomas Soome             Call UPDATE_HASH() MIN_MATCH-3 more times
1542*ab9e68a2SToomas Soome #endif
1543*ab9e68a2SToomas Soome             while (s->insert) {
1544*ab9e68a2SToomas Soome                 UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
1545*ab9e68a2SToomas Soome #ifndef FASTEST
1546*ab9e68a2SToomas Soome                 s->prev[str & s->w_mask] = s->head[s->ins_h];
1547*ab9e68a2SToomas Soome #endif
1548*ab9e68a2SToomas Soome                 s->head[s->ins_h] = (Pos)str;
1549*ab9e68a2SToomas Soome                 str++;
1550*ab9e68a2SToomas Soome                 s->insert--;
1551*ab9e68a2SToomas Soome                 if (s->lookahead + s->insert < MIN_MATCH)
1552*ab9e68a2SToomas Soome                     break;
1553*ab9e68a2SToomas Soome             }
1554*ab9e68a2SToomas Soome         }
1555*ab9e68a2SToomas Soome         /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
1556*ab9e68a2SToomas Soome          * but this is not important since only literal bytes will be emitted.
1557*ab9e68a2SToomas Soome          */
1558*ab9e68a2SToomas Soome 
1559*ab9e68a2SToomas Soome     } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1560*ab9e68a2SToomas Soome 
1561*ab9e68a2SToomas Soome     /* If the WIN_INIT bytes after the end of the current data have never been
1562*ab9e68a2SToomas Soome      * written, then zero those bytes in order to avoid memory check reports of
1563*ab9e68a2SToomas Soome      * the use of uninitialized (or uninitialised as Julian writes) bytes by
1564*ab9e68a2SToomas Soome      * the longest match routines.  Update the high water mark for the next
1565*ab9e68a2SToomas Soome      * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
1566*ab9e68a2SToomas Soome      * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
1567*ab9e68a2SToomas Soome      */
1568*ab9e68a2SToomas Soome     if (s->high_water < s->window_size) {
1569*ab9e68a2SToomas Soome         ulg curr = s->strstart + (ulg)(s->lookahead);
1570*ab9e68a2SToomas Soome         ulg init;
1571*ab9e68a2SToomas Soome 
1572*ab9e68a2SToomas Soome         if (s->high_water < curr) {
1573*ab9e68a2SToomas Soome             /* Previous high water mark below current data -- zero WIN_INIT
1574*ab9e68a2SToomas Soome              * bytes or up to end of window, whichever is less.
1575*ab9e68a2SToomas Soome              */
1576*ab9e68a2SToomas Soome             init = s->window_size - curr;
1577*ab9e68a2SToomas Soome             if (init > WIN_INIT)
1578*ab9e68a2SToomas Soome                 init = WIN_INIT;
1579*ab9e68a2SToomas Soome             zmemzero(s->window + curr, (unsigned)init);
1580*ab9e68a2SToomas Soome             s->high_water = curr + init;
1581*ab9e68a2SToomas Soome         }
1582*ab9e68a2SToomas Soome         else if (s->high_water < (ulg)curr + WIN_INIT) {
1583*ab9e68a2SToomas Soome             /* High water mark at or above current data, but below current data
1584*ab9e68a2SToomas Soome              * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
1585*ab9e68a2SToomas Soome              * to end of window, whichever is less.
1586*ab9e68a2SToomas Soome              */
1587*ab9e68a2SToomas Soome             init = (ulg)curr + WIN_INIT - s->high_water;
1588*ab9e68a2SToomas Soome             if (init > s->window_size - s->high_water)
1589*ab9e68a2SToomas Soome                 init = s->window_size - s->high_water;
1590*ab9e68a2SToomas Soome             zmemzero(s->window + s->high_water, (unsigned)init);
1591*ab9e68a2SToomas Soome             s->high_water += init;
1592*ab9e68a2SToomas Soome         }
1593*ab9e68a2SToomas Soome     }
1594*ab9e68a2SToomas Soome 
1595*ab9e68a2SToomas Soome     Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
1596*ab9e68a2SToomas Soome            "not enough room for search");
1597*ab9e68a2SToomas Soome }
1598*ab9e68a2SToomas Soome 
1599*ab9e68a2SToomas Soome /* ===========================================================================
1600*ab9e68a2SToomas Soome  * Flush the current block, with given end-of-file flag.
1601*ab9e68a2SToomas Soome  * IN assertion: strstart is set to the end of the current match.
1602*ab9e68a2SToomas Soome  */
1603*ab9e68a2SToomas Soome #define FLUSH_BLOCK_ONLY(s, last) { \
1604*ab9e68a2SToomas Soome    _tr_flush_block(s, (s->block_start >= 0L ? \
1605*ab9e68a2SToomas Soome                    (charf *)&s->window[(unsigned)s->block_start] : \
1606*ab9e68a2SToomas Soome                    (charf *)Z_NULL), \
1607*ab9e68a2SToomas Soome                 (ulg)((long)s->strstart - s->block_start), \
1608*ab9e68a2SToomas Soome                 (last)); \
1609*ab9e68a2SToomas Soome    s->block_start = s->strstart; \
1610*ab9e68a2SToomas Soome    flush_pending(s->strm); \
1611*ab9e68a2SToomas Soome    Tracev((stderr,"[FLUSH]")); \
1612*ab9e68a2SToomas Soome }
1613*ab9e68a2SToomas Soome 
1614*ab9e68a2SToomas Soome /* Same but force premature exit if necessary. */
1615*ab9e68a2SToomas Soome #define FLUSH_BLOCK(s, last) { \
1616*ab9e68a2SToomas Soome    FLUSH_BLOCK_ONLY(s, last); \
1617*ab9e68a2SToomas Soome    if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
1618*ab9e68a2SToomas Soome }
1619*ab9e68a2SToomas Soome 
1620*ab9e68a2SToomas Soome /* Maximum stored block length in deflate format (not including header). */
1621*ab9e68a2SToomas Soome #define MAX_STORED 65535
1622*ab9e68a2SToomas Soome 
1623*ab9e68a2SToomas Soome /* Minimum of a and b. */
1624*ab9e68a2SToomas Soome #define MIN(a, b) ((a) > (b) ? (b) : (a))
1625*ab9e68a2SToomas Soome 
1626*ab9e68a2SToomas Soome /* ===========================================================================
1627*ab9e68a2SToomas Soome  * Copy without compression as much as possible from the input stream, return
1628*ab9e68a2SToomas Soome  * the current block state.
1629*ab9e68a2SToomas Soome  *
1630*ab9e68a2SToomas Soome  * In case deflateParams() is used to later switch to a non-zero compression
1631*ab9e68a2SToomas Soome  * level, s->matches (otherwise unused when storing) keeps track of the number
1632*ab9e68a2SToomas Soome  * of hash table slides to perform. If s->matches is 1, then one hash table
1633*ab9e68a2SToomas Soome  * slide will be done when switching. If s->matches is 2, the maximum value
1634*ab9e68a2SToomas Soome  * allowed here, then the hash table will be cleared, since two or more slides
1635*ab9e68a2SToomas Soome  * is the same as a clear.
1636*ab9e68a2SToomas Soome  *
1637*ab9e68a2SToomas Soome  * deflate_stored() is written to minimize the number of times an input byte is
1638*ab9e68a2SToomas Soome  * copied. It is most efficient with large input and output buffers, which
1639*ab9e68a2SToomas Soome  * maximizes the opportunites to have a single copy from next_in to next_out.
1640*ab9e68a2SToomas Soome  */
1641*ab9e68a2SToomas Soome local block_state deflate_stored(s, flush)
1642*ab9e68a2SToomas Soome     deflate_state *s;
1643*ab9e68a2SToomas Soome     int flush;
1644*ab9e68a2SToomas Soome {
1645*ab9e68a2SToomas Soome     /* Smallest worthy block size when not flushing or finishing. By default
1646*ab9e68a2SToomas Soome      * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
1647*ab9e68a2SToomas Soome      * large input and output buffers, the stored block size will be larger.
1648*ab9e68a2SToomas Soome      */
1649*ab9e68a2SToomas Soome     unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
1650*ab9e68a2SToomas Soome 
1651*ab9e68a2SToomas Soome     /* Copy as many min_block or larger stored blocks directly to next_out as
1652*ab9e68a2SToomas Soome      * possible. If flushing, copy the remaining available input to next_out as
1653*ab9e68a2SToomas Soome      * stored blocks, if there is enough space.
1654*ab9e68a2SToomas Soome      */
1655*ab9e68a2SToomas Soome     unsigned len, left, have, last = 0;
1656*ab9e68a2SToomas Soome     unsigned used = s->strm->avail_in;
1657*ab9e68a2SToomas Soome     do {
1658*ab9e68a2SToomas Soome         /* Set len to the maximum size block that we can copy directly with the
1659*ab9e68a2SToomas Soome          * available input data and output space. Set left to how much of that
1660*ab9e68a2SToomas Soome          * would be copied from what's left in the window.
1661*ab9e68a2SToomas Soome          */
1662*ab9e68a2SToomas Soome         len = MAX_STORED;       /* maximum deflate stored block length */
1663*ab9e68a2SToomas Soome         have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
1664*ab9e68a2SToomas Soome         if (s->strm->avail_out < have)          /* need room for header */
1665*ab9e68a2SToomas Soome             break;
1666*ab9e68a2SToomas Soome             /* maximum stored block length that will fit in avail_out: */
1667*ab9e68a2SToomas Soome         have = s->strm->avail_out - have;
1668*ab9e68a2SToomas Soome         left = s->strstart - s->block_start;    /* bytes left in window */
1669*ab9e68a2SToomas Soome         if (len > (ulg)left + s->strm->avail_in)
1670*ab9e68a2SToomas Soome             len = left + s->strm->avail_in;     /* limit len to the input */
1671*ab9e68a2SToomas Soome         if (len > have)
1672*ab9e68a2SToomas Soome             len = have;                         /* limit len to the output */
1673*ab9e68a2SToomas Soome 
1674*ab9e68a2SToomas Soome         /* If the stored block would be less than min_block in length, or if
1675*ab9e68a2SToomas Soome          * unable to copy all of the available input when flushing, then try
1676*ab9e68a2SToomas Soome          * copying to the window and the pending buffer instead. Also don't
1677*ab9e68a2SToomas Soome          * write an empty block when flushing -- deflate() does that.
1678*ab9e68a2SToomas Soome          */
1679*ab9e68a2SToomas Soome         if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
1680*ab9e68a2SToomas Soome                                 flush == Z_NO_FLUSH ||
1681*ab9e68a2SToomas Soome                                 len != left + s->strm->avail_in))
1682*ab9e68a2SToomas Soome             break;
1683*ab9e68a2SToomas Soome 
1684*ab9e68a2SToomas Soome         /* Make a dummy stored block in pending to get the header bytes,
1685*ab9e68a2SToomas Soome          * including any pending bits. This also updates the debugging counts.
1686*ab9e68a2SToomas Soome          */
1687*ab9e68a2SToomas Soome         last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
1688*ab9e68a2SToomas Soome         _tr_stored_block(s, (char *)0, 0L, last);
1689*ab9e68a2SToomas Soome 
1690*ab9e68a2SToomas Soome         /* Replace the lengths in the dummy stored block with len. */
1691*ab9e68a2SToomas Soome         s->pending_buf[s->pending - 4] = len;
1692*ab9e68a2SToomas Soome         s->pending_buf[s->pending - 3] = len >> 8;
1693*ab9e68a2SToomas Soome         s->pending_buf[s->pending - 2] = ~len;
1694*ab9e68a2SToomas Soome         s->pending_buf[s->pending - 1] = ~len >> 8;
1695*ab9e68a2SToomas Soome 
1696*ab9e68a2SToomas Soome         /* Write the stored block header bytes. */
1697*ab9e68a2SToomas Soome         flush_pending(s->strm);
1698*ab9e68a2SToomas Soome 
1699*ab9e68a2SToomas Soome #ifdef ZLIB_DEBUG
1700*ab9e68a2SToomas Soome         /* Update debugging counts for the data about to be copied. */
1701*ab9e68a2SToomas Soome         s->compressed_len += len << 3;
1702*ab9e68a2SToomas Soome         s->bits_sent += len << 3;
1703*ab9e68a2SToomas Soome #endif
1704*ab9e68a2SToomas Soome 
1705*ab9e68a2SToomas Soome         /* Copy uncompressed bytes from the window to next_out. */
1706*ab9e68a2SToomas Soome         if (left) {
1707*ab9e68a2SToomas Soome             if (left > len)
1708*ab9e68a2SToomas Soome                 left = len;
1709*ab9e68a2SToomas Soome             zmemcpy(s->strm->next_out, s->window + s->block_start, left);
1710*ab9e68a2SToomas Soome             s->strm->next_out += left;
1711*ab9e68a2SToomas Soome             s->strm->avail_out -= left;
1712*ab9e68a2SToomas Soome             s->strm->total_out += left;
1713*ab9e68a2SToomas Soome             s->block_start += left;
1714*ab9e68a2SToomas Soome             len -= left;
1715*ab9e68a2SToomas Soome         }
1716*ab9e68a2SToomas Soome 
1717*ab9e68a2SToomas Soome         /* Copy uncompressed bytes directly from next_in to next_out, updating
1718*ab9e68a2SToomas Soome          * the check value.
1719*ab9e68a2SToomas Soome          */
1720*ab9e68a2SToomas Soome         if (len) {
1721*ab9e68a2SToomas Soome             read_buf(s->strm, s->strm->next_out, len);
1722*ab9e68a2SToomas Soome             s->strm->next_out += len;
1723*ab9e68a2SToomas Soome             s->strm->avail_out -= len;
1724*ab9e68a2SToomas Soome             s->strm->total_out += len;
1725*ab9e68a2SToomas Soome         }
1726*ab9e68a2SToomas Soome     } while (last == 0);
1727*ab9e68a2SToomas Soome 
1728*ab9e68a2SToomas Soome     /* Update the sliding window with the last s->w_size bytes of the copied
1729*ab9e68a2SToomas Soome      * data, or append all of the copied data to the existing window if less
1730*ab9e68a2SToomas Soome      * than s->w_size bytes were copied. Also update the number of bytes to
1731*ab9e68a2SToomas Soome      * insert in the hash tables, in the event that deflateParams() switches to
1732*ab9e68a2SToomas Soome      * a non-zero compression level.
1733*ab9e68a2SToomas Soome      */
1734*ab9e68a2SToomas Soome     used -= s->strm->avail_in;      /* number of input bytes directly copied */
1735*ab9e68a2SToomas Soome     if (used) {
1736*ab9e68a2SToomas Soome         /* If any input was used, then no unused input remains in the window,
1737*ab9e68a2SToomas Soome          * therefore s->block_start == s->strstart.
1738*ab9e68a2SToomas Soome          */
1739*ab9e68a2SToomas Soome         if (used >= s->w_size) {    /* supplant the previous history */
1740*ab9e68a2SToomas Soome             s->matches = 2;         /* clear hash */
1741*ab9e68a2SToomas Soome             zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
1742*ab9e68a2SToomas Soome             s->strstart = s->w_size;
1743*ab9e68a2SToomas Soome         }
1744*ab9e68a2SToomas Soome         else {
1745*ab9e68a2SToomas Soome             if (s->window_size - s->strstart <= used) {
1746*ab9e68a2SToomas Soome                 /* Slide the window down. */
1747*ab9e68a2SToomas Soome                 s->strstart -= s->w_size;
1748*ab9e68a2SToomas Soome                 zmemcpy(s->window, s->window + s->w_size, s->strstart);
1749*ab9e68a2SToomas Soome                 if (s->matches < 2)
1750*ab9e68a2SToomas Soome                     s->matches++;   /* add a pending slide_hash() */
1751*ab9e68a2SToomas Soome             }
1752*ab9e68a2SToomas Soome             zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
1753*ab9e68a2SToomas Soome             s->strstart += used;
1754*ab9e68a2SToomas Soome         }
1755*ab9e68a2SToomas Soome         s->block_start = s->strstart;
1756*ab9e68a2SToomas Soome         s->insert += MIN(used, s->w_size - s->insert);
1757*ab9e68a2SToomas Soome     }
1758*ab9e68a2SToomas Soome     if (s->high_water < s->strstart)
1759*ab9e68a2SToomas Soome         s->high_water = s->strstart;
1760*ab9e68a2SToomas Soome 
1761*ab9e68a2SToomas Soome     /* If the last block was written to next_out, then done. */
1762*ab9e68a2SToomas Soome     if (last)
1763*ab9e68a2SToomas Soome         return finish_done;
1764*ab9e68a2SToomas Soome 
1765*ab9e68a2SToomas Soome     /* If flushing and all input has been consumed, then done. */
1766*ab9e68a2SToomas Soome     if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
1767*ab9e68a2SToomas Soome         s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
1768*ab9e68a2SToomas Soome         return block_done;
1769*ab9e68a2SToomas Soome 
1770*ab9e68a2SToomas Soome     /* Fill the window with any remaining input. */
1771*ab9e68a2SToomas Soome     have = s->window_size - s->strstart - 1;
1772*ab9e68a2SToomas Soome     if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
1773*ab9e68a2SToomas Soome         /* Slide the window down. */
1774*ab9e68a2SToomas Soome         s->block_start -= s->w_size;
1775*ab9e68a2SToomas Soome         s->strstart -= s->w_size;
1776*ab9e68a2SToomas Soome         zmemcpy(s->window, s->window + s->w_size, s->strstart);
1777*ab9e68a2SToomas Soome         if (s->matches < 2)
1778*ab9e68a2SToomas Soome             s->matches++;           /* add a pending slide_hash() */
1779*ab9e68a2SToomas Soome         have += s->w_size;          /* more space now */
1780*ab9e68a2SToomas Soome     }
1781*ab9e68a2SToomas Soome     if (have > s->strm->avail_in)
1782*ab9e68a2SToomas Soome         have = s->strm->avail_in;
1783*ab9e68a2SToomas Soome     if (have) {
1784*ab9e68a2SToomas Soome         read_buf(s->strm, s->window + s->strstart, have);
1785*ab9e68a2SToomas Soome         s->strstart += have;
1786*ab9e68a2SToomas Soome     }
1787*ab9e68a2SToomas Soome     if (s->high_water < s->strstart)
1788*ab9e68a2SToomas Soome         s->high_water = s->strstart;
1789*ab9e68a2SToomas Soome 
1790*ab9e68a2SToomas Soome     /* There was not enough avail_out to write a complete worthy or flushed
1791*ab9e68a2SToomas Soome      * stored block to next_out. Write a stored block to pending instead, if we
1792*ab9e68a2SToomas Soome      * have enough input for a worthy block, or if flushing and there is enough
1793*ab9e68a2SToomas Soome      * room for the remaining input as a stored block in the pending buffer.
1794*ab9e68a2SToomas Soome      */
1795*ab9e68a2SToomas Soome     have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
1796*ab9e68a2SToomas Soome         /* maximum stored block length that will fit in pending: */
1797*ab9e68a2SToomas Soome     have = MIN(s->pending_buf_size - have, MAX_STORED);
1798*ab9e68a2SToomas Soome     min_block = MIN(have, s->w_size);
1799*ab9e68a2SToomas Soome     left = s->strstart - s->block_start;
1800*ab9e68a2SToomas Soome     if (left >= min_block ||
1801*ab9e68a2SToomas Soome         ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
1802*ab9e68a2SToomas Soome          s->strm->avail_in == 0 && left <= have)) {
1803*ab9e68a2SToomas Soome         len = MIN(left, have);
1804*ab9e68a2SToomas Soome         last = flush == Z_FINISH && s->strm->avail_in == 0 &&
1805*ab9e68a2SToomas Soome                len == left ? 1 : 0;
1806*ab9e68a2SToomas Soome         _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
1807*ab9e68a2SToomas Soome         s->block_start += len;
1808*ab9e68a2SToomas Soome         flush_pending(s->strm);
1809*ab9e68a2SToomas Soome     }
1810*ab9e68a2SToomas Soome 
1811*ab9e68a2SToomas Soome     /* We've done all we can with the available input and output. */
1812*ab9e68a2SToomas Soome     return last ? finish_started : need_more;
1813*ab9e68a2SToomas Soome }
1814*ab9e68a2SToomas Soome 
1815*ab9e68a2SToomas Soome /* ===========================================================================
1816*ab9e68a2SToomas Soome  * Compress as much as possible from the input stream, return the current
1817*ab9e68a2SToomas Soome  * block state.
1818*ab9e68a2SToomas Soome  * This function does not perform lazy evaluation of matches and inserts
1819*ab9e68a2SToomas Soome  * new strings in the dictionary only for unmatched strings or for short
1820*ab9e68a2SToomas Soome  * matches. It is used only for the fast compression options.
1821*ab9e68a2SToomas Soome  */
1822*ab9e68a2SToomas Soome local block_state deflate_fast(s, flush)
1823*ab9e68a2SToomas Soome     deflate_state *s;
1824*ab9e68a2SToomas Soome     int flush;
1825*ab9e68a2SToomas Soome {
1826*ab9e68a2SToomas Soome     IPos hash_head;       /* head of the hash chain */
1827*ab9e68a2SToomas Soome     int bflush;           /* set if current block must be flushed */
1828*ab9e68a2SToomas Soome 
1829*ab9e68a2SToomas Soome     for (;;) {
1830*ab9e68a2SToomas Soome         /* Make sure that we always have enough lookahead, except
1831*ab9e68a2SToomas Soome          * at the end of the input file. We need MAX_MATCH bytes
1832*ab9e68a2SToomas Soome          * for the next match, plus MIN_MATCH bytes to insert the
1833*ab9e68a2SToomas Soome          * string following the next match.
1834*ab9e68a2SToomas Soome          */
1835*ab9e68a2SToomas Soome         if (s->lookahead < MIN_LOOKAHEAD) {
1836*ab9e68a2SToomas Soome             fill_window(s);
1837*ab9e68a2SToomas Soome             if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1838*ab9e68a2SToomas Soome                 return need_more;
1839*ab9e68a2SToomas Soome             }
1840*ab9e68a2SToomas Soome             if (s->lookahead == 0) break; /* flush the current block */
1841*ab9e68a2SToomas Soome         }
1842*ab9e68a2SToomas Soome 
1843*ab9e68a2SToomas Soome         /* Insert the string window[strstart .. strstart+2] in the
1844*ab9e68a2SToomas Soome          * dictionary, and set hash_head to the head of the hash chain:
1845*ab9e68a2SToomas Soome          */
1846*ab9e68a2SToomas Soome         hash_head = NIL;
1847*ab9e68a2SToomas Soome         if (s->lookahead >= MIN_MATCH) {
1848*ab9e68a2SToomas Soome             INSERT_STRING(s, s->strstart, hash_head);
1849*ab9e68a2SToomas Soome         }
1850*ab9e68a2SToomas Soome 
1851*ab9e68a2SToomas Soome         /* Find the longest match, discarding those <= prev_length.
1852*ab9e68a2SToomas Soome          * At this point we have always match_length < MIN_MATCH
1853*ab9e68a2SToomas Soome          */
1854*ab9e68a2SToomas Soome         if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
1855*ab9e68a2SToomas Soome             /* To simplify the code, we prevent matches with the string
1856*ab9e68a2SToomas Soome              * of window index 0 (in particular we have to avoid a match
1857*ab9e68a2SToomas Soome              * of the string with itself at the start of the input file).
1858*ab9e68a2SToomas Soome              */
1859*ab9e68a2SToomas Soome             s->match_length = longest_match (s, hash_head);
1860*ab9e68a2SToomas Soome             /* longest_match() sets match_start */
1861*ab9e68a2SToomas Soome         }
1862*ab9e68a2SToomas Soome         if (s->match_length >= MIN_MATCH) {
1863*ab9e68a2SToomas Soome             check_match(s, s->strstart, s->match_start, s->match_length);
1864*ab9e68a2SToomas Soome 
1865*ab9e68a2SToomas Soome             _tr_tally_dist(s, s->strstart - s->match_start,
1866*ab9e68a2SToomas Soome                            s->match_length - MIN_MATCH, bflush);
1867*ab9e68a2SToomas Soome 
1868*ab9e68a2SToomas Soome             s->lookahead -= s->match_length;
1869*ab9e68a2SToomas Soome 
1870*ab9e68a2SToomas Soome             /* Insert new strings in the hash table only if the match length
1871*ab9e68a2SToomas Soome              * is not too large. This saves time but degrades compression.
1872*ab9e68a2SToomas Soome              */
1873*ab9e68a2SToomas Soome #ifndef FASTEST
1874*ab9e68a2SToomas Soome             if (s->match_length <= s->max_insert_length &&
1875*ab9e68a2SToomas Soome                 s->lookahead >= MIN_MATCH) {
1876*ab9e68a2SToomas Soome                 s->match_length--; /* string at strstart already in table */
1877*ab9e68a2SToomas Soome                 do {
1878*ab9e68a2SToomas Soome                     s->strstart++;
1879*ab9e68a2SToomas Soome                     INSERT_STRING(s, s->strstart, hash_head);
1880*ab9e68a2SToomas Soome                     /* strstart never exceeds WSIZE-MAX_MATCH, so there are
1881*ab9e68a2SToomas Soome                      * always MIN_MATCH bytes ahead.
1882*ab9e68a2SToomas Soome                      */
1883*ab9e68a2SToomas Soome                 } while (--s->match_length != 0);
1884*ab9e68a2SToomas Soome                 s->strstart++;
1885*ab9e68a2SToomas Soome             } else
1886*ab9e68a2SToomas Soome #endif
1887*ab9e68a2SToomas Soome             {
1888*ab9e68a2SToomas Soome                 s->strstart += s->match_length;
1889*ab9e68a2SToomas Soome                 s->match_length = 0;
1890*ab9e68a2SToomas Soome                 s->ins_h = s->window[s->strstart];
1891*ab9e68a2SToomas Soome                 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1892*ab9e68a2SToomas Soome #if MIN_MATCH != 3
1893*ab9e68a2SToomas Soome                 Call UPDATE_HASH() MIN_MATCH-3 more times
1894*ab9e68a2SToomas Soome #endif
1895*ab9e68a2SToomas Soome                 /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
1896*ab9e68a2SToomas Soome                  * matter since it will be recomputed at next deflate call.
1897*ab9e68a2SToomas Soome                  */
1898*ab9e68a2SToomas Soome             }
1899*ab9e68a2SToomas Soome         } else {
1900*ab9e68a2SToomas Soome             /* No match, output a literal byte */
1901*ab9e68a2SToomas Soome             Tracevv((stderr,"%c", s->window[s->strstart]));
1902*ab9e68a2SToomas Soome             _tr_tally_lit (s, s->window[s->strstart], bflush);
1903*ab9e68a2SToomas Soome             s->lookahead--;
1904*ab9e68a2SToomas Soome             s->strstart++;
1905*ab9e68a2SToomas Soome         }
1906*ab9e68a2SToomas Soome         if (bflush) FLUSH_BLOCK(s, 0);
1907*ab9e68a2SToomas Soome     }
1908*ab9e68a2SToomas Soome     s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
1909*ab9e68a2SToomas Soome     if (flush == Z_FINISH) {
1910*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 1);
1911*ab9e68a2SToomas Soome         return finish_done;
1912*ab9e68a2SToomas Soome     }
1913*ab9e68a2SToomas Soome     if (s->last_lit)
1914*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 0);
1915*ab9e68a2SToomas Soome     return block_done;
1916*ab9e68a2SToomas Soome }
1917*ab9e68a2SToomas Soome 
1918*ab9e68a2SToomas Soome #ifndef FASTEST
1919*ab9e68a2SToomas Soome /* ===========================================================================
1920*ab9e68a2SToomas Soome  * Same as above, but achieves better compression. We use a lazy
1921*ab9e68a2SToomas Soome  * evaluation for matches: a match is finally adopted only if there is
1922*ab9e68a2SToomas Soome  * no better match at the next window position.
1923*ab9e68a2SToomas Soome  */
1924*ab9e68a2SToomas Soome local block_state deflate_slow(s, flush)
1925*ab9e68a2SToomas Soome     deflate_state *s;
1926*ab9e68a2SToomas Soome     int flush;
1927*ab9e68a2SToomas Soome {
1928*ab9e68a2SToomas Soome     IPos hash_head;          /* head of hash chain */
1929*ab9e68a2SToomas Soome     int bflush;              /* set if current block must be flushed */
1930*ab9e68a2SToomas Soome 
1931*ab9e68a2SToomas Soome     /* Process the input block. */
1932*ab9e68a2SToomas Soome     for (;;) {
1933*ab9e68a2SToomas Soome         /* Make sure that we always have enough lookahead, except
1934*ab9e68a2SToomas Soome          * at the end of the input file. We need MAX_MATCH bytes
1935*ab9e68a2SToomas Soome          * for the next match, plus MIN_MATCH bytes to insert the
1936*ab9e68a2SToomas Soome          * string following the next match.
1937*ab9e68a2SToomas Soome          */
1938*ab9e68a2SToomas Soome         if (s->lookahead < MIN_LOOKAHEAD) {
1939*ab9e68a2SToomas Soome             fill_window(s);
1940*ab9e68a2SToomas Soome             if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1941*ab9e68a2SToomas Soome                 return need_more;
1942*ab9e68a2SToomas Soome             }
1943*ab9e68a2SToomas Soome             if (s->lookahead == 0) break; /* flush the current block */
1944*ab9e68a2SToomas Soome         }
1945*ab9e68a2SToomas Soome 
1946*ab9e68a2SToomas Soome         /* Insert the string window[strstart .. strstart+2] in the
1947*ab9e68a2SToomas Soome          * dictionary, and set hash_head to the head of the hash chain:
1948*ab9e68a2SToomas Soome          */
1949*ab9e68a2SToomas Soome         hash_head = NIL;
1950*ab9e68a2SToomas Soome         if (s->lookahead >= MIN_MATCH) {
1951*ab9e68a2SToomas Soome             INSERT_STRING(s, s->strstart, hash_head);
1952*ab9e68a2SToomas Soome         }
1953*ab9e68a2SToomas Soome 
1954*ab9e68a2SToomas Soome         /* Find the longest match, discarding those <= prev_length.
1955*ab9e68a2SToomas Soome          */
1956*ab9e68a2SToomas Soome         s->prev_length = s->match_length, s->prev_match = s->match_start;
1957*ab9e68a2SToomas Soome         s->match_length = MIN_MATCH-1;
1958*ab9e68a2SToomas Soome 
1959*ab9e68a2SToomas Soome         if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
1960*ab9e68a2SToomas Soome             s->strstart - hash_head <= MAX_DIST(s)) {
1961*ab9e68a2SToomas Soome             /* To simplify the code, we prevent matches with the string
1962*ab9e68a2SToomas Soome              * of window index 0 (in particular we have to avoid a match
1963*ab9e68a2SToomas Soome              * of the string with itself at the start of the input file).
1964*ab9e68a2SToomas Soome              */
1965*ab9e68a2SToomas Soome             s->match_length = longest_match (s, hash_head);
1966*ab9e68a2SToomas Soome             /* longest_match() sets match_start */
1967*ab9e68a2SToomas Soome 
1968*ab9e68a2SToomas Soome             if (s->match_length <= 5 && (s->strategy == Z_FILTERED
1969*ab9e68a2SToomas Soome #if TOO_FAR <= 32767
1970*ab9e68a2SToomas Soome                 || (s->match_length == MIN_MATCH &&
1971*ab9e68a2SToomas Soome                     s->strstart - s->match_start > TOO_FAR)
1972*ab9e68a2SToomas Soome #endif
1973*ab9e68a2SToomas Soome                 )) {
1974*ab9e68a2SToomas Soome 
1975*ab9e68a2SToomas Soome                 /* If prev_match is also MIN_MATCH, match_start is garbage
1976*ab9e68a2SToomas Soome                  * but we will ignore the current match anyway.
1977*ab9e68a2SToomas Soome                  */
1978*ab9e68a2SToomas Soome                 s->match_length = MIN_MATCH-1;
1979*ab9e68a2SToomas Soome             }
1980*ab9e68a2SToomas Soome         }
1981*ab9e68a2SToomas Soome         /* If there was a match at the previous step and the current
1982*ab9e68a2SToomas Soome          * match is not better, output the previous match:
1983*ab9e68a2SToomas Soome          */
1984*ab9e68a2SToomas Soome         if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
1985*ab9e68a2SToomas Soome             uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
1986*ab9e68a2SToomas Soome             /* Do not insert strings in hash table beyond this. */
1987*ab9e68a2SToomas Soome 
1988*ab9e68a2SToomas Soome             check_match(s, s->strstart-1, s->prev_match, s->prev_length);
1989*ab9e68a2SToomas Soome 
1990*ab9e68a2SToomas Soome             _tr_tally_dist(s, s->strstart -1 - s->prev_match,
1991*ab9e68a2SToomas Soome                            s->prev_length - MIN_MATCH, bflush);
1992*ab9e68a2SToomas Soome 
1993*ab9e68a2SToomas Soome             /* Insert in hash table all strings up to the end of the match.
1994*ab9e68a2SToomas Soome              * strstart-1 and strstart are already inserted. If there is not
1995*ab9e68a2SToomas Soome              * enough lookahead, the last two strings are not inserted in
1996*ab9e68a2SToomas Soome              * the hash table.
1997*ab9e68a2SToomas Soome              */
1998*ab9e68a2SToomas Soome             s->lookahead -= s->prev_length-1;
1999*ab9e68a2SToomas Soome             s->prev_length -= 2;
2000*ab9e68a2SToomas Soome             do {
2001*ab9e68a2SToomas Soome                 if (++s->strstart <= max_insert) {
2002*ab9e68a2SToomas Soome                     INSERT_STRING(s, s->strstart, hash_head);
2003*ab9e68a2SToomas Soome                 }
2004*ab9e68a2SToomas Soome             } while (--s->prev_length != 0);
2005*ab9e68a2SToomas Soome             s->match_available = 0;
2006*ab9e68a2SToomas Soome             s->match_length = MIN_MATCH-1;
2007*ab9e68a2SToomas Soome             s->strstart++;
2008*ab9e68a2SToomas Soome 
2009*ab9e68a2SToomas Soome             if (bflush) FLUSH_BLOCK(s, 0);
2010*ab9e68a2SToomas Soome 
2011*ab9e68a2SToomas Soome         } else if (s->match_available) {
2012*ab9e68a2SToomas Soome             /* If there was no match at the previous position, output a
2013*ab9e68a2SToomas Soome              * single literal. If there was a match but the current match
2014*ab9e68a2SToomas Soome              * is longer, truncate the previous match to a single literal.
2015*ab9e68a2SToomas Soome              */
2016*ab9e68a2SToomas Soome             Tracevv((stderr,"%c", s->window[s->strstart-1]));
2017*ab9e68a2SToomas Soome             _tr_tally_lit(s, s->window[s->strstart-1], bflush);
2018*ab9e68a2SToomas Soome             if (bflush) {
2019*ab9e68a2SToomas Soome                 FLUSH_BLOCK_ONLY(s, 0);
2020*ab9e68a2SToomas Soome             }
2021*ab9e68a2SToomas Soome             s->strstart++;
2022*ab9e68a2SToomas Soome             s->lookahead--;
2023*ab9e68a2SToomas Soome             if (s->strm->avail_out == 0) return need_more;
2024*ab9e68a2SToomas Soome         } else {
2025*ab9e68a2SToomas Soome             /* There is no previous match to compare with, wait for
2026*ab9e68a2SToomas Soome              * the next step to decide.
2027*ab9e68a2SToomas Soome              */
2028*ab9e68a2SToomas Soome             s->match_available = 1;
2029*ab9e68a2SToomas Soome             s->strstart++;
2030*ab9e68a2SToomas Soome             s->lookahead--;
2031*ab9e68a2SToomas Soome         }
2032*ab9e68a2SToomas Soome     }
2033*ab9e68a2SToomas Soome     Assert (flush != Z_NO_FLUSH, "no flush?");
2034*ab9e68a2SToomas Soome     if (s->match_available) {
2035*ab9e68a2SToomas Soome         Tracevv((stderr,"%c", s->window[s->strstart-1]));
2036*ab9e68a2SToomas Soome         _tr_tally_lit(s, s->window[s->strstart-1], bflush);
2037*ab9e68a2SToomas Soome         s->match_available = 0;
2038*ab9e68a2SToomas Soome     }
2039*ab9e68a2SToomas Soome     s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
2040*ab9e68a2SToomas Soome     if (flush == Z_FINISH) {
2041*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 1);
2042*ab9e68a2SToomas Soome         return finish_done;
2043*ab9e68a2SToomas Soome     }
2044*ab9e68a2SToomas Soome     if (s->last_lit)
2045*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 0);
2046*ab9e68a2SToomas Soome     return block_done;
2047*ab9e68a2SToomas Soome }
2048*ab9e68a2SToomas Soome #endif /* FASTEST */
2049*ab9e68a2SToomas Soome 
2050*ab9e68a2SToomas Soome /* ===========================================================================
2051*ab9e68a2SToomas Soome  * For Z_RLE, simply look for runs of bytes, generate matches only of distance
2052*ab9e68a2SToomas Soome  * one.  Do not maintain a hash table.  (It will be regenerated if this run of
2053*ab9e68a2SToomas Soome  * deflate switches away from Z_RLE.)
2054*ab9e68a2SToomas Soome  */
2055*ab9e68a2SToomas Soome local block_state deflate_rle(s, flush)
2056*ab9e68a2SToomas Soome     deflate_state *s;
2057*ab9e68a2SToomas Soome     int flush;
2058*ab9e68a2SToomas Soome {
2059*ab9e68a2SToomas Soome     int bflush;             /* set if current block must be flushed */
2060*ab9e68a2SToomas Soome     uInt prev;              /* byte at distance one to match */
2061*ab9e68a2SToomas Soome     Bytef *scan, *strend;   /* scan goes up to strend for length of run */
2062*ab9e68a2SToomas Soome 
2063*ab9e68a2SToomas Soome     for (;;) {
2064*ab9e68a2SToomas Soome         /* Make sure that we always have enough lookahead, except
2065*ab9e68a2SToomas Soome          * at the end of the input file. We need MAX_MATCH bytes
2066*ab9e68a2SToomas Soome          * for the longest run, plus one for the unrolled loop.
2067*ab9e68a2SToomas Soome          */
2068*ab9e68a2SToomas Soome         if (s->lookahead <= MAX_MATCH) {
2069*ab9e68a2SToomas Soome             fill_window(s);
2070*ab9e68a2SToomas Soome             if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
2071*ab9e68a2SToomas Soome                 return need_more;
2072*ab9e68a2SToomas Soome             }
2073*ab9e68a2SToomas Soome             if (s->lookahead == 0) break; /* flush the current block */
2074*ab9e68a2SToomas Soome         }
2075*ab9e68a2SToomas Soome 
2076*ab9e68a2SToomas Soome         /* See how many times the previous byte repeats */
2077*ab9e68a2SToomas Soome         s->match_length = 0;
2078*ab9e68a2SToomas Soome         if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
2079*ab9e68a2SToomas Soome             scan = s->window + s->strstart - 1;
2080*ab9e68a2SToomas Soome             prev = *scan;
2081*ab9e68a2SToomas Soome             if (prev == *++scan && prev == *++scan && prev == *++scan) {
2082*ab9e68a2SToomas Soome                 strend = s->window + s->strstart + MAX_MATCH;
2083*ab9e68a2SToomas Soome                 do {
2084*ab9e68a2SToomas Soome                 } while (prev == *++scan && prev == *++scan &&
2085*ab9e68a2SToomas Soome                          prev == *++scan && prev == *++scan &&
2086*ab9e68a2SToomas Soome                          prev == *++scan && prev == *++scan &&
2087*ab9e68a2SToomas Soome                          prev == *++scan && prev == *++scan &&
2088*ab9e68a2SToomas Soome                          scan < strend);
2089*ab9e68a2SToomas Soome                 s->match_length = MAX_MATCH - (uInt)(strend - scan);
2090*ab9e68a2SToomas Soome                 if (s->match_length > s->lookahead)
2091*ab9e68a2SToomas Soome                     s->match_length = s->lookahead;
2092*ab9e68a2SToomas Soome             }
2093*ab9e68a2SToomas Soome             Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
2094*ab9e68a2SToomas Soome         }
2095*ab9e68a2SToomas Soome 
2096*ab9e68a2SToomas Soome         /* Emit match if have run of MIN_MATCH or longer, else emit literal */
2097*ab9e68a2SToomas Soome         if (s->match_length >= MIN_MATCH) {
2098*ab9e68a2SToomas Soome             check_match(s, s->strstart, s->strstart - 1, s->match_length);
2099*ab9e68a2SToomas Soome 
2100*ab9e68a2SToomas Soome             _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
2101*ab9e68a2SToomas Soome 
2102*ab9e68a2SToomas Soome             s->lookahead -= s->match_length;
2103*ab9e68a2SToomas Soome             s->strstart += s->match_length;
2104*ab9e68a2SToomas Soome             s->match_length = 0;
2105*ab9e68a2SToomas Soome         } else {
2106*ab9e68a2SToomas Soome             /* No match, output a literal byte */
2107*ab9e68a2SToomas Soome             Tracevv((stderr,"%c", s->window[s->strstart]));
2108*ab9e68a2SToomas Soome             _tr_tally_lit (s, s->window[s->strstart], bflush);
2109*ab9e68a2SToomas Soome             s->lookahead--;
2110*ab9e68a2SToomas Soome             s->strstart++;
2111*ab9e68a2SToomas Soome         }
2112*ab9e68a2SToomas Soome         if (bflush) FLUSH_BLOCK(s, 0);
2113*ab9e68a2SToomas Soome     }
2114*ab9e68a2SToomas Soome     s->insert = 0;
2115*ab9e68a2SToomas Soome     if (flush == Z_FINISH) {
2116*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 1);
2117*ab9e68a2SToomas Soome         return finish_done;
2118*ab9e68a2SToomas Soome     }
2119*ab9e68a2SToomas Soome     if (s->last_lit)
2120*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 0);
2121*ab9e68a2SToomas Soome     return block_done;
2122*ab9e68a2SToomas Soome }
2123*ab9e68a2SToomas Soome 
2124*ab9e68a2SToomas Soome /* ===========================================================================
2125*ab9e68a2SToomas Soome  * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
2126*ab9e68a2SToomas Soome  * (It will be regenerated if this run of deflate switches away from Huffman.)
2127*ab9e68a2SToomas Soome  */
2128*ab9e68a2SToomas Soome local block_state deflate_huff(s, flush)
2129*ab9e68a2SToomas Soome     deflate_state *s;
2130*ab9e68a2SToomas Soome     int flush;
2131*ab9e68a2SToomas Soome {
2132*ab9e68a2SToomas Soome     int bflush;             /* set if current block must be flushed */
2133*ab9e68a2SToomas Soome 
2134*ab9e68a2SToomas Soome     for (;;) {
2135*ab9e68a2SToomas Soome         /* Make sure that we have a literal to write. */
2136*ab9e68a2SToomas Soome         if (s->lookahead == 0) {
2137*ab9e68a2SToomas Soome             fill_window(s);
2138*ab9e68a2SToomas Soome             if (s->lookahead == 0) {
2139*ab9e68a2SToomas Soome                 if (flush == Z_NO_FLUSH)
2140*ab9e68a2SToomas Soome                     return need_more;
2141*ab9e68a2SToomas Soome                 break;      /* flush the current block */
2142*ab9e68a2SToomas Soome             }
2143*ab9e68a2SToomas Soome         }
2144*ab9e68a2SToomas Soome 
2145*ab9e68a2SToomas Soome         /* Output a literal byte */
2146*ab9e68a2SToomas Soome         s->match_length = 0;
2147*ab9e68a2SToomas Soome         Tracevv((stderr,"%c", s->window[s->strstart]));
2148*ab9e68a2SToomas Soome         _tr_tally_lit (s, s->window[s->strstart], bflush);
2149*ab9e68a2SToomas Soome         s->lookahead--;
2150*ab9e68a2SToomas Soome         s->strstart++;
2151*ab9e68a2SToomas Soome         if (bflush) FLUSH_BLOCK(s, 0);
2152*ab9e68a2SToomas Soome     }
2153*ab9e68a2SToomas Soome     s->insert = 0;
2154*ab9e68a2SToomas Soome     if (flush == Z_FINISH) {
2155*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 1);
2156*ab9e68a2SToomas Soome         return finish_done;
2157*ab9e68a2SToomas Soome     }
2158*ab9e68a2SToomas Soome     if (s->last_lit)
2159*ab9e68a2SToomas Soome         FLUSH_BLOCK(s, 0);
2160*ab9e68a2SToomas Soome     return block_done;
2161*ab9e68a2SToomas Soome }
2162