Chromium Code Reviews| Index: third_party/zlib/deflate.c |
| diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c |
| index 8043e5bd30945f03967ede05b09d26375ecb533b..bd12890ceb51e69555ecaa6f64250ceed8d27f9a 100644 |
| --- a/third_party/zlib/deflate.c |
| +++ b/third_party/zlib/deflate.c |
| @@ -50,6 +50,7 @@ |
| /* @(#) $Id$ */ |
| #include "deflate.h" |
| +#include "x86.h" |
| const char deflate_copyright[] = |
| " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; |
| @@ -85,7 +86,7 @@ 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)); |
| + |
| #ifdef ASMV |
| void match_init OF((void)); /* asm code initialization */ |
| uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); |
| @@ -98,6 +99,14 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, |
| int length)); |
| #endif |
| +/* For fill_window_sse.c to use */ |
| +ZLIB_INTERNAL int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); |
| + |
| +/* From crc32.c */ |
| +extern void ZLIB_INTERNAL crc_reset(deflate_state *const s); |
| +extern void ZLIB_INTERNAL crc_finalize(deflate_state *const s); |
| +extern void ZLIB_INTERNAL copy_with_crc(z_streamp strm, Bytef *dst, long size); |
| + |
| /* =========================================================================== |
| * Local data |
| */ |
| @@ -164,6 +173,11 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ |
| */ |
| #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) |
| +#ifdef _MSC_VER |
| +#define INLINE __inline |
| +#else |
| +#define INLINE inline |
| +#endif |
| /* =========================================================================== |
| * Insert string str in the dictionary and set match_head to the previous head |
| @@ -175,17 +189,28 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ |
| * input characters and the first MIN_MATCH bytes of str are valid |
| * (except for the last MIN_MATCH-1 bytes of the input file). |
| */ |
| +local INLINE Pos insert_string_c(deflate_state *const s, const Pos str) |
| +{ |
| + Pos ret; |
| + |
| + UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]); |
| #ifdef FASTEST |
| -#define INSERT_STRING(s, str, match_head) \ |
| - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ |
| - match_head = s->head[s->ins_h], \ |
| - s->head[s->ins_h] = (Pos)(str)) |
| + ret = s->head[s->ins_h]; |
| #else |
| -#define INSERT_STRING(s, str, match_head) \ |
| - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ |
| - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ |
| - s->head[s->ins_h] = (Pos)(str)) |
| + ret = s->prev[str & s->w_mask] = s->head[s->ins_h]; |
| #endif |
| + s->head[s->ins_h] = str; |
| + |
| + return ret; |
| +} |
| + |
| +local INLINE Pos insert_string(deflate_state *const s, const Pos str) |
| +{ |
| + if (x86_cpu_enable_simd) |
| + return insert_string_sse(s, str); |
| + return insert_string_c(s, str); |
| +} |
| + |
| /* =========================================================================== |
| * Initialize the hash table (avoiding 64K overflow for 16 bit systems). |
| @@ -219,6 +244,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
| const char *version; |
| int stream_size; |
| { |
| + unsigned window_padding = 8; |
| deflate_state *s; |
| int wrap = 1; |
| static const char my_version[] = ZLIB_VERSION; |
| @@ -228,6 +254,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
| * output size for (length,distance) codes is <= 24 bits. |
| */ |
| + x86_check_features(); |
| + |
| if (version == Z_NULL || version[0] != my_version[0] || |
| stream_size != sizeof(z_stream)) { |
| return Z_VERSION_ERROR; |
| @@ -274,12 +302,16 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
| s->w_size = 1 << s->w_bits; |
| s->w_mask = s->w_size - 1; |
| + if (x86_cpu_enable_simd) |
| + s->hash_bits = 15; |
| + else |
| s->hash_bits = memLevel + 7; |
|
agl
2014/10/17 00:45:34
indentation. (Also, I think that omitting branches
robert.bradford
2014/10/20 16:45:54
Urgh I agree. Fixed. I'll try and get it fixed in
|
| + |
| s->hash_size = 1 << s->hash_bits; |
| s->hash_mask = s->hash_size - 1; |
| s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); |
| - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); |
| + s->window = (Bytef *) ZALLOC(strm, s->w_size + window_padding, 2*sizeof(Byte)); |
| s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
| s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); |
| s->class_bitmap = NULL; |
| @@ -347,7 +379,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) |
| 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, hash_head); |
| + insert_string(s, n); |
| } |
| if (hash_head) hash_head = 0; /* to make compiler happy */ |
| return Z_OK; |
| @@ -613,7 +645,7 @@ int ZEXPORT deflate (strm, flush) |
| if (s->status == INIT_STATE) { |
| #ifdef GZIP |
| if (s->wrap == 2) { |
| - strm->adler = crc32(0L, Z_NULL, 0); |
| + crc_reset(s); |
| put_byte(s, 31); |
| put_byte(s, 139); |
| put_byte(s, 8); |
| @@ -891,6 +923,7 @@ int ZEXPORT deflate (strm, flush) |
| /* Write the trailer */ |
| #ifdef GZIP |
| if (s->wrap == 2) { |
| + crc_finalize(s); |
| put_byte(s, (Byte)(strm->adler & 0xff)); |
| put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); |
| put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); |
| @@ -1013,7 +1046,7 @@ int ZEXPORT deflateCopy (dest, source) |
| * allocating a large strm->next_in buffer and copying from it. |
| * (See also flush_pending()). |
| */ |
| -local int read_buf(strm, buf, size) |
| +ZLIB_INTERNAL int read_buf(strm, buf, size) |
| z_streamp strm; |
| Bytef *buf; |
| unsigned size; |
| @@ -1025,15 +1058,17 @@ local int read_buf(strm, buf, size) |
| strm->avail_in -= len; |
| - if (strm->state->wrap == 1) { |
| - strm->adler = adler32(strm->adler, strm->next_in, len); |
| - } |
| #ifdef GZIP |
| - else if (strm->state->wrap == 2) { |
| - strm->adler = crc32(strm->adler, strm->next_in, len); |
| + if (strm->state->wrap == 2) { |
| + copy_with_crc(strm, buf, len); |
| } |
| + else |
| #endif |
| - zmemcpy(buf, strm->next_in, len); |
| + { |
| + 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; |
| @@ -1445,7 +1480,19 @@ local void check_match(s, start, match, length) |
| * performed for at least two bytes (required for the zip translate_eol |
| * option -- not supported here). |
| */ |
| -local void fill_window(s) |
| +local void fill_window_c(deflate_state *s); |
| + |
| +local void fill_window(deflate_state *s) |
| +{ |
| + if (x86_cpu_enable_simd) { |
| + fill_window_sse(s); |
| + return; |
| + } |
| + |
| + fill_window_c(s); |
| +} |
| + |
| +local void fill_window_c(s) |
| deflate_state *s; |
| { |
| register unsigned n, m; |
| @@ -1711,7 +1758,7 @@ local block_state deflate_fast(s, flush, clas) |
| */ |
| hash_head = NIL; |
| if (s->lookahead >= MIN_MATCH) { |
| - INSERT_STRING(s, s->strstart, hash_head); |
| + hash_head = insert_string(s, s->strstart); |
| } |
| /* Find the longest match, discarding those <= prev_length. |
| @@ -1742,7 +1789,7 @@ local block_state deflate_fast(s, flush, clas) |
| s->match_length--; /* string at strstart already in table */ |
| do { |
| s->strstart++; |
| - INSERT_STRING(s, s->strstart, hash_head); |
| + hash_head = insert_string(s, s->strstart); |
| /* strstart never exceeds WSIZE-MAX_MATCH, so there are |
| * always MIN_MATCH bytes ahead. |
| */ |
| @@ -1821,7 +1868,7 @@ local block_state deflate_slow(s, flush, clas) |
| */ |
| hash_head = NIL; |
| if (s->lookahead >= MIN_MATCH) { |
| - INSERT_STRING(s, s->strstart, hash_head); |
| + hash_head = insert_string(s, s->strstart); |
| } |
| /* Find the longest match, discarding those <= prev_length. |
| @@ -1890,7 +1937,7 @@ local block_state deflate_slow(s, flush, clas) |
| s->prev_length -= 2; |
| do { |
| if (++s->strstart <= max_insert) { |
| - INSERT_STRING(s, s->strstart, hash_head); |
| + hash_head = insert_string(s, s->strstart); |
| } |
| } while (--s->prev_length != 0); |
| s->match_available = 0; |