Dependencies:   emwin_lib

Fork of DMemWin by Embedded Artists

Committer:
destinyXfate
Date:
Thu Jun 02 04:55:08 2016 +0000
Revision:
4:20387dbf7ecf
Parent:
2:0e2ef1edf01b
;

Who changed what in which revision?

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