OLD | NEW |
---|---|
1 /* deflate.c -- compress data using the deflation algorithm | 1 /* deflate.c -- compress data using the deflation algorithm |
2 * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler | 2 * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler |
3 * For conditions of distribution and use, see copyright notice in zlib.h | 3 * For conditions of distribution and use, see copyright notice in zlib.h |
4 */ | 4 */ |
5 | 5 |
6 /* | 6 /* |
7 * ALGORITHM | 7 * ALGORITHM |
8 * | 8 * |
9 * The "deflation" process depends on being able to identify portions | 9 * The "deflation" process depends on being able to identify portions |
10 * of the input text which are identical to earlier input (within a | 10 * of the input text which are identical to earlier input (within a |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 * A description of the Rabin and Karp algorithm is given in the book | 42 * A description of the Rabin and Karp algorithm is given in the book |
43 * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. | 43 * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. |
44 * | 44 * |
45 * Fiala,E.R., and Greene,D.H. | 45 * Fiala,E.R., and Greene,D.H. |
46 * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 | 46 * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 |
47 * | 47 * |
48 */ | 48 */ |
49 | 49 |
50 /* @(#) $Id$ */ | 50 /* @(#) $Id$ */ |
51 | 51 |
52 #include <assert.h> | |
53 | |
52 #include "deflate.h" | 54 #include "deflate.h" |
55 #include "x86.h" | |
53 | 56 |
54 const char deflate_copyright[] = | 57 const char deflate_copyright[] = |
55 " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; | 58 " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; |
56 /* | 59 /* |
57 If you use the zlib library in a product, an acknowledgment is welcome | 60 If you use the zlib library in a product, an acknowledgment is welcome |
58 in the documentation of your product. If for some reason you cannot | 61 in the documentation of your product. If for some reason you cannot |
59 include such an acknowledgment, I would appreciate that you keep this | 62 include such an acknowledgment, I would appreciate that you keep this |
60 copyright string in the executable of your product. | 63 copyright string in the executable of your product. |
61 */ | 64 */ |
62 | 65 |
(...skipping 15 matching lines...) Expand all Loading... | |
78 local block_state deflate_stored OF((deflate_state *s, int flush, int clas)); | 81 local block_state deflate_stored OF((deflate_state *s, int flush, int clas)); |
79 local block_state deflate_fast OF((deflate_state *s, int flush, int clas)); | 82 local block_state deflate_fast OF((deflate_state *s, int flush, int clas)); |
80 #ifndef FASTEST | 83 #ifndef FASTEST |
81 local block_state deflate_slow OF((deflate_state *s, int flush, int clas)); | 84 local block_state deflate_slow OF((deflate_state *s, int flush, int clas)); |
82 #endif | 85 #endif |
83 local block_state deflate_rle OF((deflate_state *s, int flush)); | 86 local block_state deflate_rle OF((deflate_state *s, int flush)); |
84 local block_state deflate_huff OF((deflate_state *s, int flush)); | 87 local block_state deflate_huff OF((deflate_state *s, int flush)); |
85 local void lm_init OF((deflate_state *s)); | 88 local void lm_init OF((deflate_state *s)); |
86 local void putShortMSB OF((deflate_state *s, uInt b)); | 89 local void putShortMSB OF((deflate_state *s, uInt b)); |
87 local void flush_pending OF((z_streamp strm)); | 90 local void flush_pending OF((z_streamp strm)); |
88 local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); | 91 |
89 #ifdef ASMV | 92 #ifdef ASMV |
90 void match_init OF((void)); /* asm code initialization */ | 93 void match_init OF((void)); /* asm code initialization */ |
91 uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); | 94 uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); |
92 #else | 95 #else |
93 local uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); | 96 local uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); |
94 #endif | 97 #endif |
95 | 98 |
96 #ifdef DEBUG | 99 #ifdef DEBUG |
97 local void check_match OF((deflate_state *s, IPos start, IPos match, | 100 local void check_match OF((deflate_state *s, IPos start, IPos match, |
98 int length)); | 101 int length)); |
99 #endif | 102 #endif |
100 | 103 |
104 /* For fill_window_sse.c to use */ | |
105 ZLIB_INTERNAL int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); | |
106 | |
107 /* From crc32.c */ | |
108 extern void ZLIB_INTERNAL crc_reset(deflate_state *const s); | |
109 extern void ZLIB_INTERNAL crc_finalize(deflate_state *const s); | |
110 extern void ZLIB_INTERNAL copy_with_crc(z_streamp strm, Bytef *dst, long size); | |
111 | |
112 #ifdef _MSC_VER | |
113 #define INLINE __inline | |
114 #else | |
115 #define INLINE inline | |
116 #endif | |
117 | |
118 /* Inline optimisation */ | |
119 local INLINE Pos insert_string_sse(deflate_state *const s, const Pos str); | |
120 | |
101 /* =========================================================================== | 121 /* =========================================================================== |
102 * Local data | 122 * Local data |
103 */ | 123 */ |
104 | 124 |
105 #define NIL 0 | 125 #define NIL 0 |
106 /* Tail of hash chains */ | 126 /* Tail of hash chains */ |
107 | 127 |
108 #ifndef TOO_FAR | 128 #ifndef TOO_FAR |
109 # define TOO_FAR 4096 | 129 # define TOO_FAR 4096 |
110 #endif | 130 #endif |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 #endif | 177 #endif |
158 | 178 |
159 /* =========================================================================== | 179 /* =========================================================================== |
160 * Update a hash value with the given input byte | 180 * Update a hash value with the given input byte |
161 * IN assertion: all calls to to UPDATE_HASH are made with consecutive | 181 * IN assertion: all calls to to UPDATE_HASH are made with consecutive |
162 * input characters, so that a running hash key can be computed from the | 182 * input characters, so that a running hash key can be computed from the |
163 * previous key instead of complete recalculation each time. | 183 * previous key instead of complete recalculation each time. |
164 */ | 184 */ |
165 #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) | 185 #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) |
166 | 186 |
167 | |
168 /* =========================================================================== | 187 /* =========================================================================== |
169 * Insert string str in the dictionary and set match_head to the previous head | 188 * Insert string str in the dictionary and set match_head to the previous head |
170 * of the hash chain (the most recent string with same hash key). Return | 189 * of the hash chain (the most recent string with same hash key). Return |
171 * the previous length of the hash chain. | 190 * the previous length of the hash chain. |
172 * If this file is compiled with -DFASTEST, the compression level is forced | 191 * If this file is compiled with -DFASTEST, the compression level is forced |
173 * to 1, and no hash chains are maintained. | 192 * to 1, and no hash chains are maintained. |
174 * IN assertion: all calls to to INSERT_STRING are made with consecutive | 193 * IN assertion: all calls to to INSERT_STRING are made with consecutive |
175 * input characters and the first MIN_MATCH bytes of str are valid | 194 * input characters and the first MIN_MATCH bytes of str are valid |
176 * (except for the last MIN_MATCH-1 bytes of the input file). | 195 * (except for the last MIN_MATCH-1 bytes of the input file). |
177 */ | 196 */ |
197 local INLINE Pos insert_string_c(deflate_state *const s, const Pos str) | |
198 { | |
199 Pos ret; | |
200 | |
201 UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]); | |
178 #ifdef FASTEST | 202 #ifdef FASTEST |
179 #define INSERT_STRING(s, str, match_head) \ | 203 ret = s->head[s->ins_h]; |
180 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ | |
181 match_head = s->head[s->ins_h], \ | |
182 s->head[s->ins_h] = (Pos)(str)) | |
183 #else | 204 #else |
184 #define INSERT_STRING(s, str, match_head) \ | 205 ret = s->prev[str & s->w_mask] = s->head[s->ins_h]; |
185 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ | |
186 match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ | |
187 s->head[s->ins_h] = (Pos)(str)) | |
188 #endif | 206 #endif |
207 s->head[s->ins_h] = str; | |
208 | |
209 return ret; | |
210 } | |
211 | |
212 local INLINE Pos insert_string(deflate_state *const s, const Pos str) | |
213 { | |
214 if (x86_cpu_enable_simd) | |
215 return insert_string_sse(s, str); | |
216 return insert_string_c(s, str); | |
217 } | |
218 | |
189 | 219 |
190 /* =========================================================================== | 220 /* =========================================================================== |
191 * Initialize the hash table (avoiding 64K overflow for 16 bit systems). | 221 * Initialize the hash table (avoiding 64K overflow for 16 bit systems). |
192 * prev[] will be initialized on the fly. | 222 * prev[] will be initialized on the fly. |
193 */ | 223 */ |
194 #define CLEAR_HASH(s) \ | 224 #define CLEAR_HASH(s) \ |
195 s->head[s->hash_size-1] = NIL; \ | 225 s->head[s->hash_size-1] = NIL; \ |
196 zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); | 226 zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); |
197 | 227 |
198 /* ========================================================================= */ | 228 /* ========================================================================= */ |
(...skipping 13 matching lines...) Expand all Loading... | |
212 version, stream_size) | 242 version, stream_size) |
213 z_streamp strm; | 243 z_streamp strm; |
214 int level; | 244 int level; |
215 int method; | 245 int method; |
216 int windowBits; | 246 int windowBits; |
217 int memLevel; | 247 int memLevel; |
218 int strategy; | 248 int strategy; |
219 const char *version; | 249 const char *version; |
220 int stream_size; | 250 int stream_size; |
221 { | 251 { |
252 unsigned window_padding = 8; | |
222 deflate_state *s; | 253 deflate_state *s; |
223 int wrap = 1; | 254 int wrap = 1; |
224 static const char my_version[] = ZLIB_VERSION; | 255 static const char my_version[] = ZLIB_VERSION; |
225 | 256 |
226 ushf *overlay; | 257 ushf *overlay; |
227 /* We overlay pending_buf and d_buf+l_buf. This works since the average | 258 /* We overlay pending_buf and d_buf+l_buf. This works since the average |
228 * output size for (length,distance) codes is <= 24 bits. | 259 * output size for (length,distance) codes is <= 24 bits. |
229 */ | 260 */ |
230 | 261 |
262 x86_check_features(); | |
263 | |
231 if (version == Z_NULL || version[0] != my_version[0] || | 264 if (version == Z_NULL || version[0] != my_version[0] || |
232 stream_size != sizeof(z_stream)) { | 265 stream_size != sizeof(z_stream)) { |
233 return Z_VERSION_ERROR; | 266 return Z_VERSION_ERROR; |
234 } | 267 } |
235 if (strm == Z_NULL) return Z_STREAM_ERROR; | 268 if (strm == Z_NULL) return Z_STREAM_ERROR; |
236 | 269 |
237 strm->msg = Z_NULL; | 270 strm->msg = Z_NULL; |
238 if (strm->zalloc == (alloc_func)0) { | 271 if (strm->zalloc == (alloc_func)0) { |
239 strm->zalloc = zcalloc; | 272 strm->zalloc = zcalloc; |
240 strm->opaque = (voidpf)0; | 273 strm->opaque = (voidpf)0; |
(...skipping 26 matching lines...) Expand all Loading... | |
267 if (s == Z_NULL) return Z_MEM_ERROR; | 300 if (s == Z_NULL) return Z_MEM_ERROR; |
268 strm->state = (struct internal_state FAR *)s; | 301 strm->state = (struct internal_state FAR *)s; |
269 s->strm = strm; | 302 s->strm = strm; |
270 | 303 |
271 s->wrap = wrap; | 304 s->wrap = wrap; |
272 s->gzhead = Z_NULL; | 305 s->gzhead = Z_NULL; |
273 s->w_bits = windowBits; | 306 s->w_bits = windowBits; |
274 s->w_size = 1 << s->w_bits; | 307 s->w_size = 1 << s->w_bits; |
275 s->w_mask = s->w_size - 1; | 308 s->w_mask = s->w_size - 1; |
276 | 309 |
277 s->hash_bits = memLevel + 7; | 310 if (x86_cpu_enable_simd) { |
311 s->hash_bits = 15; | |
312 } else { | |
313 s->hash_bits = memLevel + 7; | |
314 } | |
315 | |
278 s->hash_size = 1 << s->hash_bits; | 316 s->hash_size = 1 << s->hash_bits; |
279 s->hash_mask = s->hash_size - 1; | 317 s->hash_mask = s->hash_size - 1; |
280 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); | 318 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); |
281 | 319 |
282 s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); | 320 s->window = (Bytef *) ZALLOC(strm, s->w_size + window_padding, 2*sizeof(Byte )); |
283 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); | 321 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
284 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); | 322 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); |
285 s->class_bitmap = NULL; | 323 s->class_bitmap = NULL; |
286 zmemzero(&s->cookie_locations, sizeof(s->cookie_locations)); | 324 zmemzero(&s->cookie_locations, sizeof(s->cookie_locations)); |
287 strm->clas = 0; | 325 strm->clas = 0; |
288 | 326 |
289 s->high_water = 0; /* nothing written to s->window yet */ | 327 s->high_water = 0; /* nothing written to s->window yet */ |
290 | 328 |
291 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ | 329 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ |
292 | 330 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 s->strstart = length; | 378 s->strstart = length; |
341 s->block_start = (long)length; | 379 s->block_start = (long)length; |
342 | 380 |
343 /* Insert all strings in the hash table (except for the last two bytes). | 381 /* Insert all strings in the hash table (except for the last two bytes). |
344 * s->lookahead stays null, so s->ins_h will be recomputed at the next | 382 * s->lookahead stays null, so s->ins_h will be recomputed at the next |
345 * call of fill_window. | 383 * call of fill_window. |
346 */ | 384 */ |
347 s->ins_h = s->window[0]; | 385 s->ins_h = s->window[0]; |
348 UPDATE_HASH(s, s->ins_h, s->window[1]); | 386 UPDATE_HASH(s, s->ins_h, s->window[1]); |
349 for (n = 0; n <= length - MIN_MATCH; n++) { | 387 for (n = 0; n <= length - MIN_MATCH; n++) { |
350 INSERT_STRING(s, n, hash_head); | 388 insert_string(s, n); |
351 } | 389 } |
352 if (hash_head) hash_head = 0; /* to make compiler happy */ | 390 if (hash_head) hash_head = 0; /* to make compiler happy */ |
353 return Z_OK; | 391 return Z_OK; |
354 } | 392 } |
355 | 393 |
356 /* ========================================================================= */ | 394 /* ========================================================================= */ |
357 int ZEXPORT deflateReset (strm) | 395 int ZEXPORT deflateReset (strm) |
358 z_streamp strm; | 396 z_streamp strm; |
359 { | 397 { |
360 deflate_state *s; | 398 deflate_state *s; |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); | 644 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); |
607 | 645 |
608 s->strm = strm; /* just in case */ | 646 s->strm = strm; /* just in case */ |
609 old_flush = s->last_flush; | 647 old_flush = s->last_flush; |
610 s->last_flush = flush; | 648 s->last_flush = flush; |
611 | 649 |
612 /* Write the header */ | 650 /* Write the header */ |
613 if (s->status == INIT_STATE) { | 651 if (s->status == INIT_STATE) { |
614 #ifdef GZIP | 652 #ifdef GZIP |
615 if (s->wrap == 2) { | 653 if (s->wrap == 2) { |
616 strm->adler = crc32(0L, Z_NULL, 0); | 654 crc_reset(s); |
617 put_byte(s, 31); | 655 put_byte(s, 31); |
618 put_byte(s, 139); | 656 put_byte(s, 139); |
619 put_byte(s, 8); | 657 put_byte(s, 8); |
620 if (s->gzhead == Z_NULL) { | 658 if (s->gzhead == Z_NULL) { |
621 put_byte(s, 0); | 659 put_byte(s, 0); |
622 put_byte(s, 0); | 660 put_byte(s, 0); |
623 put_byte(s, 0); | 661 put_byte(s, 0); |
624 put_byte(s, 0); | 662 put_byte(s, 0); |
625 put_byte(s, 0); | 663 put_byte(s, 0); |
626 put_byte(s, s->level == 9 ? 2 : | 664 put_byte(s, s->level == 9 ? 2 : |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
884 } | 922 } |
885 } | 923 } |
886 Assert(strm->avail_out > 0, "bug2"); | 924 Assert(strm->avail_out > 0, "bug2"); |
887 | 925 |
888 if (flush != Z_FINISH) return Z_OK; | 926 if (flush != Z_FINISH) return Z_OK; |
889 if (s->wrap <= 0) return Z_STREAM_END; | 927 if (s->wrap <= 0) return Z_STREAM_END; |
890 | 928 |
891 /* Write the trailer */ | 929 /* Write the trailer */ |
892 #ifdef GZIP | 930 #ifdef GZIP |
893 if (s->wrap == 2) { | 931 if (s->wrap == 2) { |
932 crc_finalize(s); | |
894 put_byte(s, (Byte)(strm->adler & 0xff)); | 933 put_byte(s, (Byte)(strm->adler & 0xff)); |
895 put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); | 934 put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); |
896 put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); | 935 put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); |
897 put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); | 936 put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); |
898 put_byte(s, (Byte)(strm->total_in & 0xff)); | 937 put_byte(s, (Byte)(strm->total_in & 0xff)); |
899 put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); | 938 put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); |
900 put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); | 939 put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); |
901 put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); | 940 put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); |
902 } | 941 } |
903 else | 942 else |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1006 #endif /* MAXSEG_64K */ | 1045 #endif /* MAXSEG_64K */ |
1007 } | 1046 } |
1008 | 1047 |
1009 /* =========================================================================== | 1048 /* =========================================================================== |
1010 * Read a new buffer from the current input stream, update the adler32 | 1049 * Read a new buffer from the current input stream, update the adler32 |
1011 * and total number of bytes read. All deflate() input goes through | 1050 * and total number of bytes read. All deflate() input goes through |
1012 * this function so some applications may wish to modify it to avoid | 1051 * this function so some applications may wish to modify it to avoid |
1013 * allocating a large strm->next_in buffer and copying from it. | 1052 * allocating a large strm->next_in buffer and copying from it. |
1014 * (See also flush_pending()). | 1053 * (See also flush_pending()). |
1015 */ | 1054 */ |
1016 local int read_buf(strm, buf, size) | 1055 ZLIB_INTERNAL int read_buf(strm, buf, size) |
1017 z_streamp strm; | 1056 z_streamp strm; |
1018 Bytef *buf; | 1057 Bytef *buf; |
1019 unsigned size; | 1058 unsigned size; |
1020 { | 1059 { |
1021 unsigned len = strm->avail_in; | 1060 unsigned len = strm->avail_in; |
1022 | 1061 |
1023 if (len > size) len = size; | 1062 if (len > size) len = size; |
1024 if (len == 0) return 0; | 1063 if (len == 0) return 0; |
1025 | 1064 |
1026 strm->avail_in -= len; | 1065 strm->avail_in -= len; |
1027 | 1066 |
1028 if (strm->state->wrap == 1) { | 1067 #ifdef GZIP |
1029 strm->adler = adler32(strm->adler, strm->next_in, len); | 1068 if (strm->state->wrap == 2) { |
1069 copy_with_crc(strm, buf, len); | |
1030 } | 1070 } |
1031 #ifdef GZIP | 1071 else |
1032 else if (strm->state->wrap == 2) { | 1072 #endif |
1033 strm->adler = crc32(strm->adler, strm->next_in, len); | 1073 { |
1074 zmemcpy(buf, strm->next_in, len); | |
1075 if (strm->state->wrap == 1) | |
1076 strm->adler = adler32(strm->adler, buf, len); | |
1034 } | 1077 } |
1035 #endif | |
1036 zmemcpy(buf, strm->next_in, len); | |
1037 strm->next_in += len; | 1078 strm->next_in += len; |
1038 strm->total_in += len; | 1079 strm->total_in += len; |
1039 | 1080 |
1040 return (int)len; | 1081 return (int)len; |
1041 } | 1082 } |
1042 | 1083 |
1043 /* =========================================================================== | 1084 /* =========================================================================== |
1044 * Initialize the "longest match" routines for a new zlib stream | 1085 * Initialize the "longest match" routines for a new zlib stream |
1045 */ | 1086 */ |
1046 local void lm_init (s) | 1087 local void lm_init (s) |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1438 /* =========================================================================== | 1479 /* =========================================================================== |
1439 * Fill the window when the lookahead becomes insufficient. | 1480 * Fill the window when the lookahead becomes insufficient. |
1440 * Updates strstart and lookahead. | 1481 * Updates strstart and lookahead. |
1441 * | 1482 * |
1442 * IN assertion: lookahead < MIN_LOOKAHEAD | 1483 * IN assertion: lookahead < MIN_LOOKAHEAD |
1443 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD | 1484 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD |
1444 * At least one byte has been read, or avail_in == 0; reads are | 1485 * At least one byte has been read, or avail_in == 0; reads are |
1445 * performed for at least two bytes (required for the zip translate_eol | 1486 * performed for at least two bytes (required for the zip translate_eol |
1446 * option -- not supported here). | 1487 * option -- not supported here). |
1447 */ | 1488 */ |
1448 local void fill_window(s) | 1489 local void fill_window_c(deflate_state *s); |
1490 | |
1491 local void fill_window(deflate_state *s) | |
1492 { | |
1493 if (x86_cpu_enable_simd) { | |
1494 fill_window_sse(s); | |
1495 return; | |
1496 } | |
1497 | |
1498 fill_window_c(s); | |
1499 } | |
1500 | |
1501 local void fill_window_c(s) | |
1449 deflate_state *s; | 1502 deflate_state *s; |
1450 { | 1503 { |
1451 register unsigned n, m; | 1504 register unsigned n, m; |
1452 register Posf *p; | 1505 register Posf *p; |
1453 unsigned more; /* Amount of free space at the end of the window. */ | 1506 unsigned more; /* Amount of free space at the end of the window. */ |
1454 uInt wsize = s->w_size; | 1507 uInt wsize = s->w_size; |
1455 | 1508 |
1456 do { | 1509 do { |
1457 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); | 1510 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); |
1458 | 1511 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1704 return need_more; | 1757 return need_more; |
1705 } | 1758 } |
1706 if (s->lookahead == 0) break; /* flush the current block */ | 1759 if (s->lookahead == 0) break; /* flush the current block */ |
1707 } | 1760 } |
1708 | 1761 |
1709 /* Insert the string window[strstart .. strstart+2] in the | 1762 /* Insert the string window[strstart .. strstart+2] in the |
1710 * dictionary, and set hash_head to the head of the hash chain: | 1763 * dictionary, and set hash_head to the head of the hash chain: |
1711 */ | 1764 */ |
1712 hash_head = NIL; | 1765 hash_head = NIL; |
1713 if (s->lookahead >= MIN_MATCH) { | 1766 if (s->lookahead >= MIN_MATCH) { |
1714 INSERT_STRING(s, s->strstart, hash_head); | 1767 hash_head = insert_string(s, s->strstart); |
1715 } | 1768 } |
1716 | 1769 |
1717 /* Find the longest match, discarding those <= prev_length. | 1770 /* Find the longest match, discarding those <= prev_length. |
1718 * At this point we have always match_length < MIN_MATCH | 1771 * At this point we have always match_length < MIN_MATCH |
1719 */ | 1772 */ |
1720 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { | 1773 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { |
1721 /* To simplify the code, we prevent matches with the string | 1774 /* To simplify the code, we prevent matches with the string |
1722 * of window index 0 (in particular we have to avoid a match | 1775 * of window index 0 (in particular we have to avoid a match |
1723 * of the string with itself at the start of the input file). | 1776 * of the string with itself at the start of the input file). |
1724 */ | 1777 */ |
(...skipping 10 matching lines...) Expand all Loading... | |
1735 | 1788 |
1736 /* Insert new strings in the hash table only if the match length | 1789 /* Insert new strings in the hash table only if the match length |
1737 * is not too large. This saves time but degrades compression. | 1790 * is not too large. This saves time but degrades compression. |
1738 */ | 1791 */ |
1739 #ifndef FASTEST | 1792 #ifndef FASTEST |
1740 if (s->match_length <= s->max_insert_length && | 1793 if (s->match_length <= s->max_insert_length && |
1741 s->lookahead >= MIN_MATCH) { | 1794 s->lookahead >= MIN_MATCH) { |
1742 s->match_length--; /* string at strstart already in table */ | 1795 s->match_length--; /* string at strstart already in table */ |
1743 do { | 1796 do { |
1744 s->strstart++; | 1797 s->strstart++; |
1745 INSERT_STRING(s, s->strstart, hash_head); | 1798 hash_head = insert_string(s, s->strstart); |
1746 /* strstart never exceeds WSIZE-MAX_MATCH, so there are | 1799 /* strstart never exceeds WSIZE-MAX_MATCH, so there are |
1747 * always MIN_MATCH bytes ahead. | 1800 * always MIN_MATCH bytes ahead. |
1748 */ | 1801 */ |
1749 } while (--s->match_length != 0); | 1802 } while (--s->match_length != 0); |
1750 s->strstart++; | 1803 s->strstart++; |
1751 } else | 1804 } else |
1752 #endif | 1805 #endif |
1753 { | 1806 { |
1754 s->strstart += s->match_length; | 1807 s->strstart += s->match_length; |
1755 s->match_length = 0; | 1808 s->match_length = 0; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1814 return need_more; | 1867 return need_more; |
1815 } | 1868 } |
1816 if (s->lookahead == 0) break; /* flush the current block */ | 1869 if (s->lookahead == 0) break; /* flush the current block */ |
1817 } | 1870 } |
1818 | 1871 |
1819 /* Insert the string window[strstart .. strstart+2] in the | 1872 /* Insert the string window[strstart .. strstart+2] in the |
1820 * dictionary, and set hash_head to the head of the hash chain: | 1873 * dictionary, and set hash_head to the head of the hash chain: |
1821 */ | 1874 */ |
1822 hash_head = NIL; | 1875 hash_head = NIL; |
1823 if (s->lookahead >= MIN_MATCH) { | 1876 if (s->lookahead >= MIN_MATCH) { |
1824 INSERT_STRING(s, s->strstart, hash_head); | 1877 hash_head = insert_string(s, s->strstart); |
1825 } | 1878 } |
1826 | 1879 |
1827 /* Find the longest match, discarding those <= prev_length. | 1880 /* Find the longest match, discarding those <= prev_length. |
1828 */ | 1881 */ |
1829 s->prev_length = s->match_length, s->prev_match = s->match_start; | 1882 s->prev_length = s->match_length, s->prev_match = s->match_start; |
1830 s->match_length = MIN_MATCH-1; | 1883 s->match_length = MIN_MATCH-1; |
1831 | 1884 |
1832 if (clas == Z_CLASS_COOKIE && first) { | 1885 if (clas == Z_CLASS_COOKIE && first) { |
1833 s->match_length = cookie_match(s, s->strstart, input_length); | 1886 s->match_length = cookie_match(s, s->strstart, input_length); |
1834 } else if (clas == Z_CLASS_STANDARD && | 1887 } else if (clas == Z_CLASS_STANDARD && |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1883 | 1936 |
1884 /* Insert in hash table all strings up to the end of the match. | 1937 /* Insert in hash table all strings up to the end of the match. |
1885 * strstart-1 and strstart are already inserted. If there is not | 1938 * strstart-1 and strstart are already inserted. If there is not |
1886 * enough lookahead, the last two strings are not inserted in | 1939 * enough lookahead, the last two strings are not inserted in |
1887 * the hash table. | 1940 * the hash table. |
1888 */ | 1941 */ |
1889 s->lookahead -= s->prev_length-1; | 1942 s->lookahead -= s->prev_length-1; |
1890 s->prev_length -= 2; | 1943 s->prev_length -= 2; |
1891 do { | 1944 do { |
1892 if (++s->strstart <= max_insert) { | 1945 if (++s->strstart <= max_insert) { |
1893 INSERT_STRING(s, s->strstart, hash_head); | 1946 hash_head = insert_string(s, s->strstart); |
1894 } | 1947 } |
1895 } while (--s->prev_length != 0); | 1948 } while (--s->prev_length != 0); |
1896 s->match_available = 0; | 1949 s->match_available = 0; |
1897 s->match_length = MIN_MATCH-1; | 1950 s->match_length = MIN_MATCH-1; |
1898 s->strstart++; | 1951 s->strstart++; |
1899 | 1952 |
1900 if (bflush) FLUSH_BLOCK(s, 0); | 1953 if (bflush) FLUSH_BLOCK(s, 0); |
1901 | 1954 |
1902 } else if (s->match_available) { | 1955 } else if (s->match_available) { |
1903 /* If there was no match at the previous position, output a | 1956 /* If there was no match at the previous position, output a |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2024 s->match_length = 0; | 2077 s->match_length = 0; |
2025 Tracevv((stderr,"%c", s->window[s->strstart])); | 2078 Tracevv((stderr,"%c", s->window[s->strstart])); |
2026 _tr_tally_lit (s, s->window[s->strstart], bflush); | 2079 _tr_tally_lit (s, s->window[s->strstart], bflush); |
2027 s->lookahead--; | 2080 s->lookahead--; |
2028 s->strstart++; | 2081 s->strstart++; |
2029 if (bflush) FLUSH_BLOCK(s, 0); | 2082 if (bflush) FLUSH_BLOCK(s, 0); |
2030 } | 2083 } |
2031 FLUSH_BLOCK(s, flush == Z_FINISH); | 2084 FLUSH_BLOCK(s, flush == Z_FINISH); |
2032 return flush == Z_FINISH ? finish_done : block_done; | 2085 return flush == Z_FINISH ? finish_done : block_done; |
2033 } | 2086 } |
2087 | |
2088 /* Safe to inline this as GCC/clang will use inline asm and Visual Studio will | |
2089 * use intrinsic without extra params | |
2090 */ | |
2091 local INLINE Pos insert_string_sse(deflate_state *const s, const Pos str) | |
2092 { | |
2093 Pos ret; | |
2094 unsigned *ip, val, h = 0; | |
2095 | |
2096 ip = (unsigned *)&s->window[str]; | |
2097 val = *ip; | |
2098 | |
2099 if (s->level >= 6) | |
2100 val &= 0xFFFFFF; | |
2101 | |
2102 /* Windows clang should use inline asm */ | |
2103 #if defined(_MSC_VER) && !defined(__clang__) | |
hans
2014/10/24 17:28:15
Thanks, this should fix the Win-Clang issue I was
| |
2104 h = _mm_crc32_u32(h, val); | |
2105 #elif defined(__i386__) || defined(__amd64__) | |
2106 __asm__ __volatile__ ( | |
2107 "crc32 %1,%0\n\t" | |
2108 : "+r" (h) | |
2109 : "r" (val) | |
2110 ); | |
2111 #else | |
2112 /* This should never happen */ | |
agl
2014/10/24 17:47:16
This is a static error, so can #error be used?
| |
2113 assert(0); | |
2114 #endif | |
2115 | |
2116 ret = s->head[h & s->hash_mask]; | |
2117 s->head[h & s->hash_mask] = str; | |
2118 s->prev[str & s->w_mask] = ret; | |
2119 return ret; | |
2120 } | |
OLD | NEW |