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