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