| Index: third_party/zlib/deflate.c
|
| ===================================================================
|
| --- third_party/zlib/deflate.c (revision 112951)
|
| +++ third_party/zlib/deflate.c (working copy)
|
| @@ -1,5 +1,5 @@
|
| /* deflate.c -- compress data using the deflation algorithm
|
| - * Copyright (C) 1995-2005 Jean-loup Gailly.
|
| + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
| * For conditions of distribution and use, see copyright notice in zlib.h
|
| */
|
|
|
| @@ -47,12 +47,12 @@
|
| *
|
| */
|
|
|
| -/* @(#) $Id: deflate.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
|
| +/* @(#) $Id$ */
|
|
|
| #include "deflate.h"
|
|
|
| const char deflate_copyright[] =
|
| - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
|
| + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
|
| /*
|
| If you use the zlib library in a product, an acknowledgment is welcome
|
| in the documentation of your product. If for some reason you cannot
|
| @@ -79,19 +79,18 @@
|
| #ifndef FASTEST
|
| local block_state deflate_slow OF((deflate_state *s, int flush));
|
| #endif
|
| +local block_state deflate_rle OF((deflate_state *s, int flush));
|
| +local block_state deflate_huff OF((deflate_state *s, int flush));
|
| local void lm_init OF((deflate_state *s));
|
| local void putShortMSB OF((deflate_state *s, uInt b));
|
| local void flush_pending OF((z_streamp strm));
|
| local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
|
| -#ifndef FASTEST
|
| #ifdef ASMV
|
| void match_init OF((void)); /* asm code initialization */
|
| uInt longest_match OF((deflate_state *s, IPos cur_match));
|
| #else
|
| local uInt longest_match OF((deflate_state *s, IPos cur_match));
|
| #endif
|
| -#endif
|
| -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
|
|
|
| #ifdef DEBUG
|
| local void check_match OF((deflate_state *s, IPos start, IPos match,
|
| @@ -110,11 +109,6 @@
|
| #endif
|
| /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
|
|
| -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
| -/* Minimum amount of lookahead, except at the end of the input file.
|
| - * See deflate.c for comments about the MIN_MATCH+1.
|
| - */
|
| -
|
| /* Values for max_lazy_match, good_match and max_chain_length, depending on
|
| * the desired pack level (0..9). The values given below have been tuned to
|
| * exclude worst case performance for pathological files. Better values may be
|
| @@ -288,6 +282,8 @@
|
| s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
|
| s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
|
|
|
| + s->high_water = 0; /* nothing written to s->window yet */
|
| +
|
| s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
|
|
| overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
| @@ -332,8 +328,8 @@
|
| strm->adler = adler32(strm->adler, dictionary, dictLength);
|
|
|
| if (length < MIN_MATCH) return Z_OK;
|
| - if (length > MAX_DIST(s)) {
|
| - length = MAX_DIST(s);
|
| + if (length > s->w_size) {
|
| + length = s->w_size;
|
| dictionary += dictLength - length; /* use the tail of the dictionary */
|
| }
|
| zmemcpy(s->window, dictionary, length);
|
| @@ -435,9 +431,10 @@
|
| }
|
| func = configuration_table[s->level].func;
|
|
|
| - if (func != configuration_table[level].func && strm->total_in != 0) {
|
| + if ((strategy != s->strategy || func != configuration_table[level].func) &&
|
| + strm->total_in != 0) {
|
| /* Flush the last buffer: */
|
| - err = deflate(strm, Z_PARTIAL_FLUSH);
|
| + err = deflate(strm, Z_BLOCK);
|
| }
|
| if (s->level != level) {
|
| s->level = level;
|
| @@ -481,33 +478,66 @@
|
| * resulting from using fixed blocks instead of stored blocks, which deflate
|
| * can emit on compressed data for some combinations of the parameters.
|
| *
|
| - * This function could be more sophisticated to provide closer upper bounds
|
| - * for every combination of windowBits and memLevel, as well as wrap.
|
| - * But even the conservative upper bound of about 14% expansion does not
|
| - * seem onerous for output buffer allocation.
|
| + * This function could be more sophisticated to provide closer upper bounds for
|
| + * every combination of windowBits and memLevel. But even the conservative
|
| + * upper bound of about 14% expansion does not seem onerous for output buffer
|
| + * allocation.
|
| */
|
| uLong ZEXPORT deflateBound(strm, sourceLen)
|
| z_streamp strm;
|
| uLong sourceLen;
|
| {
|
| deflate_state *s;
|
| - uLong destLen;
|
| + uLong complen, wraplen;
|
| + Bytef *str;
|
|
|
| - /* conservative upper bound */
|
| - destLen = sourceLen +
|
| - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
|
| + /* conservative upper bound for compressed data */
|
| + complen = sourceLen +
|
| + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
|
|
|
| - /* if can't get parameters, return conservative bound */
|
| + /* if can't get parameters, return conservative bound plus zlib wrapper */
|
| if (strm == Z_NULL || strm->state == Z_NULL)
|
| - return destLen;
|
| + return complen + 6;
|
|
|
| + /* compute wrapper length */
|
| + s = strm->state;
|
| + switch (s->wrap) {
|
| + case 0: /* raw deflate */
|
| + wraplen = 0;
|
| + break;
|
| + case 1: /* zlib wrapper */
|
| + wraplen = 6 + (s->strstart ? 4 : 0);
|
| + break;
|
| + case 2: /* gzip wrapper */
|
| + wraplen = 18;
|
| + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
|
| + if (s->gzhead->extra != Z_NULL)
|
| + wraplen += 2 + s->gzhead->extra_len;
|
| + str = s->gzhead->name;
|
| + if (str != Z_NULL)
|
| + do {
|
| + wraplen++;
|
| + } while (*str++);
|
| + str = s->gzhead->comment;
|
| + if (str != Z_NULL)
|
| + do {
|
| + wraplen++;
|
| + } while (*str++);
|
| + if (s->gzhead->hcrc)
|
| + wraplen += 2;
|
| + }
|
| + break;
|
| + default: /* for compiler happiness */
|
| + wraplen = 6;
|
| + }
|
| +
|
| /* if not default parameters, return conservative bound */
|
| - s = strm->state;
|
| if (s->w_bits != 15 || s->hash_bits != 8 + 7)
|
| - return destLen;
|
| + return complen + wraplen;
|
|
|
| /* default settings: return tight bound for that case */
|
| - return compressBound(sourceLen);
|
| + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
| + (sourceLen >> 25) + 13 - 6 + wraplen;
|
| }
|
|
|
| /* =========================================================================
|
| @@ -557,7 +587,7 @@
|
| deflate_state *s;
|
|
|
| if (strm == Z_NULL || strm->state == Z_NULL ||
|
| - flush > Z_FINISH || flush < 0) {
|
| + flush > Z_BLOCK || flush < 0) {
|
| return Z_STREAM_ERROR;
|
| }
|
| s = strm->state;
|
| @@ -581,7 +611,7 @@
|
| put_byte(s, 31);
|
| put_byte(s, 139);
|
| put_byte(s, 8);
|
| - if (s->gzhead == NULL) {
|
| + if (s->gzhead == Z_NULL) {
|
| put_byte(s, 0);
|
| put_byte(s, 0);
|
| put_byte(s, 0);
|
| @@ -608,7 +638,7 @@
|
| (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
|
| 4 : 0));
|
| put_byte(s, s->gzhead->os & 0xff);
|
| - if (s->gzhead->extra != NULL) {
|
| + if (s->gzhead->extra != Z_NULL) {
|
| put_byte(s, s->gzhead->extra_len & 0xff);
|
| put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
|
| }
|
| @@ -650,7 +680,7 @@
|
| }
|
| #ifdef GZIP
|
| if (s->status == EXTRA_STATE) {
|
| - if (s->gzhead->extra != NULL) {
|
| + if (s->gzhead->extra != Z_NULL) {
|
| uInt beg = s->pending; /* start of bytes to update crc */
|
|
|
| while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
|
| @@ -678,7 +708,7 @@
|
| s->status = NAME_STATE;
|
| }
|
| if (s->status == NAME_STATE) {
|
| - if (s->gzhead->name != NULL) {
|
| + if (s->gzhead->name != Z_NULL) {
|
| uInt beg = s->pending; /* start of bytes to update crc */
|
| int val;
|
|
|
| @@ -709,7 +739,7 @@
|
| s->status = COMMENT_STATE;
|
| }
|
| if (s->status == COMMENT_STATE) {
|
| - if (s->gzhead->comment != NULL) {
|
| + if (s->gzhead->comment != Z_NULL) {
|
| uInt beg = s->pending; /* start of bytes to update crc */
|
| int val;
|
|
|
| @@ -787,7 +817,9 @@
|
| (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
|
| block_state bstate;
|
|
|
| - bstate = (*(configuration_table[s->level].func))(s, flush);
|
| + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
|
| + (s->strategy == Z_RLE ? deflate_rle(s, flush) :
|
| + (*(configuration_table[s->level].func))(s, flush));
|
|
|
| if (bstate == finish_started || bstate == finish_done) {
|
| s->status = FINISH_STATE;
|
| @@ -808,13 +840,17 @@
|
| if (bstate == block_done) {
|
| if (flush == Z_PARTIAL_FLUSH) {
|
| _tr_align(s);
|
| - } else { /* FULL_FLUSH or SYNC_FLUSH */
|
| + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
|
| _tr_stored_block(s, (char*)0, 0L, 0);
|
| /* For a full flush, this empty block will be recognized
|
| * as a special marker by inflate_sync().
|
| */
|
| if (flush == Z_FULL_FLUSH) {
|
| CLEAR_HASH(s); /* forget history */
|
| + if (s->lookahead == 0) {
|
| + s->strstart = 0;
|
| + s->block_start = 0L;
|
| + }
|
| }
|
| }
|
| flush_pending(strm);
|
| @@ -1167,12 +1203,13 @@
|
| return s->lookahead;
|
| }
|
| #endif /* ASMV */
|
| -#endif /* FASTEST */
|
|
|
| +#else /* FASTEST */
|
| +
|
| /* ---------------------------------------------------------------------------
|
| - * Optimized version for level == 1 or strategy == Z_RLE only
|
| + * Optimized version for FASTEST only
|
| */
|
| -local uInt longest_match_fast(s, cur_match)
|
| +local uInt longest_match(s, cur_match)
|
| deflate_state *s;
|
| IPos cur_match; /* current match */
|
| {
|
| @@ -1225,6 +1262,8 @@
|
| return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
|
| }
|
|
|
| +#endif /* FASTEST */
|
| +
|
| #ifdef DEBUG
|
| /* ===========================================================================
|
| * Check that the match at match_start is indeed a match.
|
| @@ -1303,7 +1342,6 @@
|
| later. (Using level 0 permanently is not an optimal usage of
|
| zlib, so we don't care about this pathological case.)
|
| */
|
| - /* %%% avoid this when Z_RLE */
|
| n = s->hash_size;
|
| p = &s->head[n];
|
| do {
|
| @@ -1355,27 +1393,61 @@
|
| */
|
|
|
| } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
|
| +
|
| + /* If the WIN_INIT bytes after the end of the current data have never been
|
| + * written, then zero those bytes in order to avoid memory check reports of
|
| + * the use of uninitialized (or uninitialised as Julian writes) bytes by
|
| + * the longest match routines. Update the high water mark for the next
|
| + * time through here. WIN_INIT is set to MAX_MATCH since the longest match
|
| + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
|
| + */
|
| + if (s->high_water < s->window_size) {
|
| + ulg curr = s->strstart + (ulg)(s->lookahead);
|
| + ulg init;
|
| +
|
| + if (s->high_water < curr) {
|
| + /* Previous high water mark below current data -- zero WIN_INIT
|
| + * bytes or up to end of window, whichever is less.
|
| + */
|
| + init = s->window_size - curr;
|
| + if (init > WIN_INIT)
|
| + init = WIN_INIT;
|
| + zmemzero(s->window + curr, (unsigned)init);
|
| + s->high_water = curr + init;
|
| + }
|
| + else if (s->high_water < (ulg)curr + WIN_INIT) {
|
| + /* High water mark at or above current data, but below current data
|
| + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
|
| + * to end of window, whichever is less.
|
| + */
|
| + init = (ulg)curr + WIN_INIT - s->high_water;
|
| + if (init > s->window_size - s->high_water)
|
| + init = s->window_size - s->high_water;
|
| + zmemzero(s->window + s->high_water, (unsigned)init);
|
| + s->high_water += init;
|
| + }
|
| + }
|
| }
|
|
|
| /* ===========================================================================
|
| * Flush the current block, with given end-of-file flag.
|
| * IN assertion: strstart is set to the end of the current match.
|
| */
|
| -#define FLUSH_BLOCK_ONLY(s, eof) { \
|
| +#define FLUSH_BLOCK_ONLY(s, last) { \
|
| _tr_flush_block(s, (s->block_start >= 0L ? \
|
| (charf *)&s->window[(unsigned)s->block_start] : \
|
| (charf *)Z_NULL), \
|
| (ulg)((long)s->strstart - s->block_start), \
|
| - (eof)); \
|
| + (last)); \
|
| s->block_start = s->strstart; \
|
| flush_pending(s->strm); \
|
| Tracev((stderr,"[FLUSH]")); \
|
| }
|
|
|
| /* Same but force premature exit if necessary. */
|
| -#define FLUSH_BLOCK(s, eof) { \
|
| - FLUSH_BLOCK_ONLY(s, eof); \
|
| - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
|
| +#define FLUSH_BLOCK(s, last) { \
|
| + FLUSH_BLOCK_ONLY(s, last); \
|
| + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
|
| }
|
|
|
| /* ===========================================================================
|
| @@ -1449,7 +1521,7 @@
|
| deflate_state *s;
|
| int flush;
|
| {
|
| - IPos hash_head = NIL; /* head of the hash chain */
|
| + IPos hash_head; /* head of the hash chain */
|
| int bflush; /* set if current block must be flushed */
|
|
|
| for (;;) {
|
| @@ -1469,6 +1541,7 @@
|
| /* Insert the string window[strstart .. strstart+2] in the
|
| * dictionary, and set hash_head to the head of the hash chain:
|
| */
|
| + hash_head = NIL;
|
| if (s->lookahead >= MIN_MATCH) {
|
| INSERT_STRING(s, s->strstart, hash_head);
|
| }
|
| @@ -1481,19 +1554,8 @@
|
| * of window index 0 (in particular we have to avoid a match
|
| * of the string with itself at the start of the input file).
|
| */
|
| -#ifdef FASTEST
|
| - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
|
| - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
|
| - s->match_length = longest_match_fast (s, hash_head);
|
| - }
|
| -#else
|
| - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
|
| - s->match_length = longest_match (s, hash_head);
|
| - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
|
| - s->match_length = longest_match_fast (s, hash_head);
|
| - }
|
| -#endif
|
| - /* longest_match() or longest_match_fast() sets match_start */
|
| + s->match_length = longest_match (s, hash_head);
|
| + /* longest_match() sets match_start */
|
| }
|
| if (s->match_length >= MIN_MATCH) {
|
| check_match(s, s->strstart, s->match_start, s->match_length);
|
| @@ -1555,7 +1617,7 @@
|
| deflate_state *s;
|
| int flush;
|
| {
|
| - IPos hash_head = NIL; /* head of hash chain */
|
| + IPos hash_head; /* head of hash chain */
|
| int bflush; /* set if current block must be flushed */
|
|
|
| /* Process the input block. */
|
| @@ -1576,6 +1638,7 @@
|
| /* Insert the string window[strstart .. strstart+2] in the
|
| * dictionary, and set hash_head to the head of the hash chain:
|
| */
|
| + hash_head = NIL;
|
| if (s->lookahead >= MIN_MATCH) {
|
| INSERT_STRING(s, s->strstart, hash_head);
|
| }
|
| @@ -1591,12 +1654,8 @@
|
| * of window index 0 (in particular we have to avoid a match
|
| * of the string with itself at the start of the input file).
|
| */
|
| - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
|
| - s->match_length = longest_match (s, hash_head);
|
| - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
|
| - s->match_length = longest_match_fast (s, hash_head);
|
| - }
|
| - /* longest_match() or longest_match_fast() sets match_start */
|
| + s->match_length = longest_match (s, hash_head);
|
| + /* longest_match() sets match_start */
|
|
|
| if (s->match_length <= 5 && (s->strategy == Z_FILTERED
|
| #if TOO_FAR <= 32767
|
| @@ -1674,7 +1733,6 @@
|
| }
|
| #endif /* FASTEST */
|
|
|
| -#if 0
|
| /* ===========================================================================
|
| * For Z_RLE, simply look for runs of bytes, generate matches only of distance
|
| * one. Do not maintain a hash table. (It will be regenerated if this run of
|
| @@ -1684,11 +1742,9 @@
|
| deflate_state *s;
|
| int flush;
|
| {
|
| - int bflush; /* set if current block must be flushed */
|
| - uInt run; /* length of run */
|
| - uInt max; /* maximum length of run */
|
| - uInt prev; /* byte at distance one to match */
|
| - Bytef *scan; /* scan for end of run */
|
| + int bflush; /* set if current block must be flushed */
|
| + uInt prev; /* byte at distance one to match */
|
| + Bytef *scan, *strend; /* scan goes up to strend for length of run */
|
|
|
| for (;;) {
|
| /* Make sure that we always have enough lookahead, except
|
| @@ -1704,23 +1760,33 @@
|
| }
|
|
|
| /* See how many times the previous byte repeats */
|
| - run = 0;
|
| - if (s->strstart > 0) { /* if there is a previous byte, that is */
|
| - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
|
| + s->match_length = 0;
|
| + if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
|
| scan = s->window + s->strstart - 1;
|
| - prev = *scan++;
|
| - do {
|
| - if (*scan++ != prev)
|
| - break;
|
| - } while (++run < max);
|
| + prev = *scan;
|
| + if (prev == *++scan && prev == *++scan && prev == *++scan) {
|
| + strend = s->window + s->strstart + MAX_MATCH;
|
| + do {
|
| + } while (prev == *++scan && prev == *++scan &&
|
| + prev == *++scan && prev == *++scan &&
|
| + prev == *++scan && prev == *++scan &&
|
| + prev == *++scan && prev == *++scan &&
|
| + scan < strend);
|
| + s->match_length = MAX_MATCH - (int)(strend - scan);
|
| + if (s->match_length > s->lookahead)
|
| + s->match_length = s->lookahead;
|
| + }
|
| }
|
|
|
| /* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
| - if (run >= MIN_MATCH) {
|
| - check_match(s, s->strstart, s->strstart - 1, run);
|
| - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
|
| - s->lookahead -= run;
|
| - s->strstart += run;
|
| + if (s->match_length >= MIN_MATCH) {
|
| + check_match(s, s->strstart, s->strstart - 1, s->match_length);
|
| +
|
| + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
|
| +
|
| + s->lookahead -= s->match_length;
|
| + s->strstart += s->match_length;
|
| + s->match_length = 0;
|
| } else {
|
| /* No match, output a literal byte */
|
| Tracevv((stderr,"%c", s->window[s->strstart]));
|
| @@ -1733,4 +1799,36 @@
|
| FLUSH_BLOCK(s, flush == Z_FINISH);
|
| return flush == Z_FINISH ? finish_done : block_done;
|
| }
|
| -#endif
|
| +
|
| +/* ===========================================================================
|
| + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
|
| + * (It will be regenerated if this run of deflate switches away from Huffman.)
|
| + */
|
| +local block_state deflate_huff(s, flush)
|
| + deflate_state *s;
|
| + int flush;
|
| +{
|
| + int bflush; /* set if current block must be flushed */
|
| +
|
| + for (;;) {
|
| + /* Make sure that we have a literal to write. */
|
| + if (s->lookahead == 0) {
|
| + fill_window(s);
|
| + if (s->lookahead == 0) {
|
| + if (flush == Z_NO_FLUSH)
|
| + return need_more;
|
| + break; /* flush the current block */
|
| + }
|
| + }
|
| +
|
| + /* Output a literal byte */
|
| + s->match_length = 0;
|
| + Tracevv((stderr,"%c", s->window[s->strstart]));
|
| + _tr_tally_lit (s, s->window[s->strstart], bflush);
|
| + s->lookahead--;
|
| + s->strstart++;
|
| + if (bflush) FLUSH_BLOCK(s, 0);
|
| + }
|
| + FLUSH_BLOCK(s, flush == Z_FINISH);
|
| + return flush == Z_FINISH ? finish_done : block_done;
|
| +}
|
|
|