| Index: third_party/zlib/deflate.c
|
| diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c
|
| index 55ec21570a1a99b54bae2ecaefb9ec4a085080e3..795c7fb1b0c8589da384747a7f904ddcf83f1ac5 100644
|
| --- a/third_party/zlib/deflate.c
|
| +++ b/third_party/zlib/deflate.c
|
| @@ -1,5 +1,5 @@
|
| /* deflate.c -- compress data using the deflation algorithm
|
| - * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
| + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
| * For conditions of distribution and use, see copyright notice in zlib.h
|
| */
|
|
|
| @@ -37,7 +37,7 @@
|
| * REFERENCES
|
| *
|
| * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
| - * Available in http://www.ietf.org/rfc/rfc1951.txt
|
| + * Available in http://tools.ietf.org/html/rfc1951
|
| *
|
| * A description of the Rabin and Karp algorithm is given in the book
|
| * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
| @@ -55,7 +55,7 @@
|
| #include "x86.h"
|
|
|
| const char deflate_copyright[] =
|
| - " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
|
| + " deflate 1.2.8 Copyright 1995-2013 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
|
| @@ -176,6 +176,9 @@ local const config configuration_table[10] = {
|
| struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
| #endif
|
|
|
| +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
|
| +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
|
| +
|
| /* ===========================================================================
|
| * Update a hash value with the given input byte
|
| * IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
| @@ -269,10 +272,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|
|
| strm->msg = Z_NULL;
|
| if (strm->zalloc == (alloc_func)0) {
|
| +#ifdef Z_SOLO
|
| + return Z_STREAM_ERROR;
|
| +#else
|
| strm->zalloc = zcalloc;
|
| strm->opaque = (voidpf)0;
|
| +#endif
|
| }
|
| - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
| + if (strm->zfree == (free_func)0)
|
| +#ifdef Z_SOLO
|
| + return Z_STREAM_ERROR;
|
| +#else
|
| + strm->zfree = zcfree;
|
| +#endif
|
|
|
| #ifdef FASTEST
|
| if (level != 0) level = 1;
|
| @@ -335,7 +347,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
| if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
| s->pending_buf == Z_NULL) {
|
| s->status = FINISH_STATE;
|
| - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
|
| + strm->msg = ERR_MSG(Z_MEM_ERROR);
|
| deflateEnd (strm);
|
| return Z_MEM_ERROR;
|
| }
|
| @@ -356,43 +368,71 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
| uInt dictLength;
|
| {
|
| deflate_state *s;
|
| - uInt length = dictLength;
|
| - uInt n;
|
| - IPos hash_head = 0;
|
| + uInt str, n;
|
| + int wrap;
|
| + unsigned avail;
|
| + z_const unsigned char *next;
|
|
|
| - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
| - strm->state->wrap == 2 ||
|
| - (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
|
| + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
|
| return Z_STREAM_ERROR;
|
|
|
| s = strm->state;
|
| - if (s->wrap)
|
| - strm->adler = adler32(strm->adler, dictionary, dictLength);
|
| + wrap = s->wrap;
|
| + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
|
| + return Z_STREAM_ERROR;
|
|
|
| - if (length < MIN_MATCH) return Z_OK;
|
| - if (length > s->w_size) {
|
| - length = s->w_size;
|
| - dictionary += dictLength - length; /* use the tail of the dictionary */
|
| + /* when using zlib wrappers, compute Adler-32 for provided dictionary */
|
| + if (wrap == 1)
|
| + strm->adler = adler32(strm->adler, dictionary, dictLength);
|
| + s->wrap = 0; /* avoid computing Adler-32 in read_buf */
|
| +
|
| + /* if dictionary would fill window, just replace the history */
|
| + if (dictLength >= s->w_size) {
|
| + if (wrap == 0) { /* already empty otherwise */
|
| + CLEAR_HASH(s);
|
| + s->strstart = 0;
|
| + s->block_start = 0L;
|
| + s->insert = 0;
|
| + }
|
| + dictionary += dictLength - s->w_size; /* use the tail */
|
| + dictLength = s->w_size;
|
| }
|
| - zmemcpy(s->window, dictionary, length);
|
| - s->strstart = length;
|
| - s->block_start = (long)length;
|
|
|
| - /* Insert all strings in the hash table (except for the last two bytes).
|
| - * s->lookahead stays null, so s->ins_h will be recomputed at the next
|
| - * call of fill_window.
|
| - */
|
| - s->ins_h = s->window[0];
|
| - UPDATE_HASH(s, s->ins_h, s->window[1]);
|
| - for (n = 0; n <= length - MIN_MATCH; n++) {
|
| - insert_string(s, n);
|
| + /* insert dictionary into window and hash */
|
| + avail = strm->avail_in;
|
| + next = strm->next_in;
|
| + strm->avail_in = dictLength;
|
| + strm->next_in = (z_const Bytef *)dictionary;
|
| + fill_window(s);
|
| + while (s->lookahead >= MIN_MATCH) {
|
| + str = s->strstart;
|
| + n = s->lookahead - (MIN_MATCH-1);
|
| + do {
|
| + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
| +#ifndef FASTEST
|
| + s->prev[str & s->w_mask] = s->head[s->ins_h];
|
| +#endif
|
| + s->head[s->ins_h] = (Pos)str;
|
| + str++;
|
| + } while (--n);
|
| + s->strstart = str;
|
| + s->lookahead = MIN_MATCH-1;
|
| + fill_window(s);
|
| }
|
| - if (hash_head) hash_head = 0; /* to make compiler happy */
|
| + s->strstart += s->lookahead;
|
| + s->block_start = (long)s->strstart;
|
| + s->insert = s->lookahead;
|
| + s->lookahead = 0;
|
| + s->match_length = s->prev_length = MIN_MATCH-1;
|
| + s->match_available = 0;
|
| + strm->next_in = next;
|
| + strm->avail_in = avail;
|
| + s->wrap = wrap;
|
| return Z_OK;
|
| }
|
|
|
| /* ========================================================================= */
|
| -int ZEXPORT deflateReset (strm)
|
| +int ZEXPORT deflateResetKeep (strm)
|
| z_streamp strm;
|
| {
|
| deflate_state *s;
|
| @@ -424,12 +464,23 @@ int ZEXPORT deflateReset (strm)
|
| s->last_flush = Z_NO_FLUSH;
|
|
|
| _tr_init(s);
|
| - lm_init(s);
|
|
|
| return Z_OK;
|
| }
|
|
|
| /* ========================================================================= */
|
| +int ZEXPORT deflateReset (strm)
|
| + z_streamp strm;
|
| +{
|
| + int ret;
|
| +
|
| + ret = deflateResetKeep(strm);
|
| + if (ret == Z_OK)
|
| + lm_init(strm->state);
|
| + return ret;
|
| +}
|
| +
|
| +/* ========================================================================= */
|
| int ZEXPORT deflateSetHeader (strm, head)
|
| z_streamp strm;
|
| gz_headerp head;
|
| @@ -441,14 +492,42 @@ int ZEXPORT deflateSetHeader (strm, head)
|
| }
|
|
|
| /* ========================================================================= */
|
| +int ZEXPORT deflatePending (strm, pending, bits)
|
| + unsigned *pending;
|
| + int *bits;
|
| + z_streamp strm;
|
| +{
|
| + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
| + if (pending != Z_NULL)
|
| + *pending = strm->state->pending;
|
| + if (bits != Z_NULL)
|
| + *bits = strm->state->bi_valid;
|
| + return Z_OK;
|
| +}
|
| +
|
| +/* ========================================================================= */
|
| int ZEXPORT deflatePrime (strm, bits, value)
|
| z_streamp strm;
|
| int bits;
|
| int value;
|
| {
|
| + deflate_state *s;
|
| + int put;
|
| +
|
| if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
| - strm->state->bi_valid = bits;
|
| - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
|
| + s = strm->state;
|
| + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
| + return Z_BUF_ERROR;
|
| + do {
|
| + put = Buf_size - s->bi_valid;
|
| + if (put > bits)
|
| + put = bits;
|
| + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
|
| + s->bi_valid += put;
|
| + _tr_flush_bits(s);
|
| + value >>= put;
|
| + bits -= put;
|
| + } while (bits);
|
| return Z_OK;
|
| }
|
|
|
| @@ -479,6 +558,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
| strm->total_in != 0) {
|
| /* Flush the last buffer: */
|
| err = deflate(strm, Z_BLOCK);
|
| + if (err == Z_BUF_ERROR && s->pending == 0)
|
| + err = Z_OK;
|
| }
|
| if (s->level != level) {
|
| s->level = level;
|
| @@ -606,19 +687,22 @@ local void putShortMSB (s, b)
|
| local void flush_pending(strm)
|
| z_streamp strm;
|
| {
|
| - unsigned len = strm->state->pending;
|
| + unsigned len;
|
| + deflate_state *s = strm->state;
|
|
|
| + _tr_flush_bits(s);
|
| + len = s->pending;
|
| if (len > strm->avail_out) len = strm->avail_out;
|
| if (len == 0) return;
|
|
|
| - zmemcpy(strm->next_out, strm->state->pending_out, len);
|
| + zmemcpy(strm->next_out, s->pending_out, len);
|
| strm->next_out += len;
|
| - strm->state->pending_out += len;
|
| + s->pending_out += len;
|
| strm->total_out += len;
|
| strm->avail_out -= len;
|
| - strm->state->pending -= len;
|
| - if (strm->state->pending == 0) {
|
| - strm->state->pending_out = strm->state->pending_buf;
|
| + s->pending -= len;
|
| + if (s->pending == 0) {
|
| + s->pending_out = s->pending_buf;
|
| }
|
| }
|
|
|
| @@ -845,7 +929,7 @@ int ZEXPORT deflate (strm, flush)
|
| * flushes. For repeated and useless calls with Z_FINISH, we keep
|
| * returning Z_STREAM_END instead of Z_BUF_ERROR.
|
| */
|
| - } else if (strm->avail_in == 0 && flush <= old_flush &&
|
| + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
|
| flush != Z_FINISH) {
|
| ERR_RETURN(strm, Z_BUF_ERROR);
|
| }
|
| @@ -911,6 +995,7 @@ int ZEXPORT deflate (strm, flush)
|
| if (s->lookahead == 0) {
|
| s->strstart = 0;
|
| s->block_start = 0L;
|
| + s->insert = 0;
|
| }
|
| }
|
| }
|
| @@ -1008,12 +1093,12 @@ int ZEXPORT deflateCopy (dest, source)
|
|
|
| ss = source->state;
|
|
|
| - zmemcpy(dest, source, sizeof(z_stream));
|
| + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
|
|
| ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
| if (ds == Z_NULL) return Z_MEM_ERROR;
|
| dest->state = (struct internal_state FAR *) ds;
|
| - zmemcpy(ds, ss, sizeof(deflate_state));
|
| + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
| ds->strm = dest;
|
|
|
| ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
| @@ -1029,8 +1114,8 @@ int ZEXPORT deflateCopy (dest, source)
|
| }
|
| /* following zmemcpy do not work for 16-bit MSDOS */
|
| zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
| - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
| - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
| + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
|
| + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
|
| zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
|
|
| ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
| @@ -1064,17 +1149,15 @@ ZLIB_INTERNAL int read_buf(strm, buf, size)
|
|
|
| strm->avail_in -= len;
|
|
|
| + zmemcpy(buf, strm->next_in, len);
|
| + if (strm->state->wrap == 1) {
|
| + strm->adler = adler32(strm->adler, buf, len);
|
| + }
|
| #ifdef GZIP
|
| if (strm->state->wrap == 2) {
|
| copy_with_crc(strm, buf, len);
|
| }
|
| - else
|
| #endif
|
| - {
|
| - zmemcpy(buf, strm->next_in, len);
|
| - if (strm->state->wrap == 1)
|
| - strm->adler = adler32(strm->adler, buf, len);
|
| - }
|
| strm->next_in += len;
|
| strm->total_in += len;
|
|
|
| @@ -1101,6 +1184,7 @@ local void lm_init (s)
|
| s->strstart = 0;
|
| s->block_start = 0L;
|
| s->lookahead = 0;
|
| + s->insert = 0;
|
| s->match_length = s->prev_length = MIN_MATCH-1;
|
| s->match_available = 0;
|
| s->ins_h = 0;
|
| @@ -1506,6 +1590,8 @@ local void fill_window_c(s)
|
| unsigned more; /* Amount of free space at the end of the window. */
|
| uInt wsize = s->w_size;
|
|
|
| + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
| +
|
| do {
|
| more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
|
|
| @@ -1573,7 +1659,7 @@ local void fill_window_c(s)
|
|
|
| more += wsize;
|
| }
|
| - if (s->strm->avail_in == 0) return;
|
| + if (s->strm->avail_in == 0) break;
|
|
|
| /* If there was no sliding:
|
| * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
| @@ -1595,12 +1681,24 @@ local void fill_window_c(s)
|
| s->lookahead += n;
|
|
|
| /* Initialize the hash value now that we have some input: */
|
| - if (s->lookahead >= MIN_MATCH) {
|
| - s->ins_h = s->window[s->strstart];
|
| - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
| + if (s->lookahead + s->insert >= MIN_MATCH) {
|
| + uInt str = s->strstart - s->insert;
|
| + s->ins_h = s->window[str];
|
| + UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
|
| #if MIN_MATCH != 3
|
| Call UPDATE_HASH() MIN_MATCH-3 more times
|
| #endif
|
| + while (s->insert) {
|
| + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
| +#ifndef FASTEST
|
| + s->prev[str & s->w_mask] = s->head[s->ins_h];
|
| +#endif
|
| + s->head[s->ins_h] = (Pos)str;
|
| + str++;
|
| + s->insert--;
|
| + if (s->lookahead + s->insert < MIN_MATCH)
|
| + break;
|
| + }
|
| }
|
| /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
| * but this is not important since only literal bytes will be emitted.
|
| @@ -1641,6 +1739,9 @@ local void fill_window_c(s)
|
| s->high_water += init;
|
| }
|
| }
|
| +
|
| + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
| + "not enough room for search");
|
| }
|
|
|
| /* ===========================================================================
|
| @@ -1721,8 +1822,14 @@ local block_state deflate_stored(s, flush, clas)
|
| FLUSH_BLOCK(s, 0);
|
| }
|
| }
|
| - FLUSH_BLOCK(s, flush == Z_FINISH);
|
| - return flush == Z_FINISH ? finish_done : block_done;
|
| + s->insert = 0;
|
| + if (flush == Z_FINISH) {
|
| + FLUSH_BLOCK(s, 1);
|
| + return finish_done;
|
| + }
|
| + if ((long)s->strstart > s->block_start)
|
| + FLUSH_BLOCK(s, 0);
|
| + return block_done;
|
| }
|
|
|
| /* ===========================================================================
|
| @@ -1824,8 +1931,14 @@ local block_state deflate_fast(s, flush, clas)
|
| }
|
| if (bflush) FLUSH_BLOCK(s, 0);
|
| }
|
| - FLUSH_BLOCK(s, flush == Z_FINISH);
|
| - return flush == Z_FINISH ? finish_done : block_done;
|
| + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
| + if (flush == Z_FINISH) {
|
| + FLUSH_BLOCK(s, 1);
|
| + return finish_done;
|
| + }
|
| + if (s->last_lit)
|
| + FLUSH_BLOCK(s, 0);
|
| + return block_done;
|
| }
|
|
|
| #ifndef FASTEST
|
| @@ -1980,8 +2093,14 @@ local block_state deflate_slow(s, flush, clas)
|
| _tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
| s->match_available = 0;
|
| }
|
| - FLUSH_BLOCK(s, flush == Z_FINISH);
|
| - return flush == Z_FINISH ? finish_done : block_done;
|
| + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
| + if (flush == Z_FINISH) {
|
| + FLUSH_BLOCK(s, 1);
|
| + return finish_done;
|
| + }
|
| + if (s->last_lit)
|
| + FLUSH_BLOCK(s, 0);
|
| + return block_done;
|
| }
|
| #endif /* FASTEST */
|
|
|
| @@ -2001,11 +2120,11 @@ local block_state deflate_rle(s, flush)
|
| for (;;) {
|
| /* Make sure that we always have enough lookahead, except
|
| * at the end of the input file. We need MAX_MATCH bytes
|
| - * for the longest encodable run.
|
| + * for the longest run, plus one for the unrolled loop.
|
| */
|
| - if (s->lookahead < MAX_MATCH) {
|
| + if (s->lookahead <= MAX_MATCH) {
|
| fill_window(s);
|
| - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
|
| + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
|
| return need_more;
|
| }
|
| if (s->lookahead == 0) break; /* flush the current block */
|
| @@ -2028,6 +2147,7 @@ local block_state deflate_rle(s, flush)
|
| if (s->match_length > s->lookahead)
|
| s->match_length = s->lookahead;
|
| }
|
| + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
| }
|
|
|
| /* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
| @@ -2048,8 +2168,14 @@ local block_state deflate_rle(s, flush)
|
| }
|
| if (bflush) FLUSH_BLOCK(s, 0);
|
| }
|
| - FLUSH_BLOCK(s, flush == Z_FINISH);
|
| - return flush == Z_FINISH ? finish_done : block_done;
|
| + s->insert = 0;
|
| + if (flush == Z_FINISH) {
|
| + FLUSH_BLOCK(s, 1);
|
| + return finish_done;
|
| + }
|
| + if (s->last_lit)
|
| + FLUSH_BLOCK(s, 0);
|
| + return block_done;
|
| }
|
|
|
| /* ===========================================================================
|
| @@ -2081,8 +2207,14 @@ local block_state deflate_huff(s, flush)
|
| s->strstart++;
|
| if (bflush) FLUSH_BLOCK(s, 0);
|
| }
|
| - FLUSH_BLOCK(s, flush == Z_FINISH);
|
| - return flush == Z_FINISH ? finish_done : block_done;
|
| + s->insert = 0;
|
| + if (flush == Z_FINISH) {
|
| + FLUSH_BLOCK(s, 1);
|
| + return finish_done;
|
| + }
|
| + if (s->last_lit)
|
| + FLUSH_BLOCK(s, 0);
|
| + return block_done;
|
| }
|
|
|
| /* Safe to inline this as GCC/clang will use inline asm and Visual Studio will
|
|
|