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