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