OLD | NEW |
| (Empty) |
1 diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c | |
2 index 6969577..7c95b30 100644 | |
3 --- a/third_party/zlib/deflate.c | |
4 +++ b/third_party/zlib/deflate.c | |
5 @@ -70,14 +70,15 @@ typedef enum { | |
6 finish_done /* finish done, accept no more input or output */ | |
7 } block_state; | |
8 | |
9 -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); | |
10 +typedef block_state (*compress_func) OF((deflate_state *s, int flush, | |
11 + int clas)); | |
12 /* Compression function. Returns the block state after the call. */ | |
13 | |
14 local void fill_window OF((deflate_state *s)); | |
15 -local block_state deflate_stored OF((deflate_state *s, int flush)); | |
16 -local block_state deflate_fast OF((deflate_state *s, int flush)); | |
17 +local block_state deflate_stored OF((deflate_state *s, int flush, int clas)); | |
18 +local block_state deflate_fast OF((deflate_state *s, int flush, int clas)); | |
19 #ifndef FASTEST | |
20 -local block_state deflate_slow OF((deflate_state *s, int flush)); | |
21 +local block_state deflate_slow OF((deflate_state *s, int flush, int clas)); | |
22 #endif | |
23 local block_state deflate_rle OF((deflate_state *s, int flush)); | |
24 local block_state deflate_huff OF((deflate_state *s, int flush)); | |
25 @@ -87,9 +88,9 @@ local void flush_pending OF((z_streamp strm)); | |
26 local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); | |
27 #ifdef ASMV | |
28 void match_init OF((void)); /* asm code initialization */ | |
29 - uInt longest_match OF((deflate_state *s, IPos cur_match)); | |
30 + uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); | |
31 #else | |
32 -local uInt longest_match OF((deflate_state *s, IPos cur_match)); | |
33 +local uInt longest_match OF((deflate_state *s, IPos cur_match, int clas)); | |
34 #endif | |
35 | |
36 #ifdef DEBUG | |
37 @@ -293,6 +294,9 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, m
emLevel, strategy, | |
38 s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); | |
39 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); | |
40 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); | |
41 + s->class_bitmap = NULL; | |
42 + zmemzero(&s->cookie_locations, sizeof(s->cookie_locations)); | |
43 + strm->clas = 0; | |
44 | |
45 s->high_water = 0; /* nothing written to s->window yet */ | |
46 | |
47 @@ -406,6 +410,8 @@ int ZEXPORT deflateResetKeep (strm) | |
48 s = (deflate_state *)strm->state; | |
49 s->pending = 0; | |
50 s->pending_out = s->pending_buf; | |
51 + TRY_FREE(strm, s->class_bitmap); | |
52 + s->class_bitmap = NULL; | |
53 | |
54 if (s->wrap < 0) { | |
55 s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ | |
56 @@ -900,9 +906,26 @@ int ZEXPORT deflate (strm, flush) | |
57 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { | |
58 block_state bstate; | |
59 | |
60 - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : | |
61 - (s->strategy == Z_RLE ? deflate_rle(s, flush) : | |
62 - (*(configuration_table[s->level].func))(s, flush)); | |
63 + if (strm->clas && s->class_bitmap == NULL) { | |
64 + /* This is the first time that we have seen alternative class | |
65 + * data. All data up till this point has been standard class. */ | |
66 + s->class_bitmap = (Bytef*) ZALLOC(strm, s->w_size/4, sizeof(Byte)); | |
67 + zmemzero(s->class_bitmap, s->w_size/4); | |
68 + } | |
69 + | |
70 + if (strm->clas && s->strategy == Z_RLE) { | |
71 + /* We haven't patched deflate_rle. */ | |
72 + ERR_RETURN(strm, Z_BUF_ERROR); | |
73 + } | |
74 + | |
75 + if (s->strategy == Z_HUFFMAN_ONLY) { | |
76 + bstate = deflate_huff(s, flush); | |
77 + } else if (s->strategy == Z_RLE) { | |
78 + bstate = deflate_rle(s, flush); | |
79 + } else { | |
80 + bstate = (*(configuration_table[s->level].func)) | |
81 + (s, flush, strm->clas); | |
82 + } | |
83 | |
84 if (bstate == finish_started || bstate == finish_done) { | |
85 s->status = FINISH_STATE; | |
86 @@ -999,6 +1022,7 @@ int ZEXPORT deflateEnd (strm) | |
87 TRY_FREE(strm, strm->state->head); | |
88 TRY_FREE(strm, strm->state->prev); | |
89 TRY_FREE(strm, strm->state->window); | |
90 + TRY_FREE(strm, strm->state->class_bitmap); | |
91 | |
92 ZFREE(strm, strm->state); | |
93 strm->state = Z_NULL; | |
94 @@ -1131,6 +1155,57 @@ local void lm_init (s) | |
95 #endif | |
96 } | |
97 | |
98 +/* class_set sets bits [offset,offset+len) in s->class_bitmap to either 1 (if | |
99 + * class != 0) or 0 (otherwise). */ | |
100 +local void class_set(s, offset, len, clas) | |
101 + deflate_state *s; | |
102 + IPos offset; | |
103 + uInt len; | |
104 + int clas; | |
105 +{ | |
106 + IPos byte = offset >> 3; | |
107 + IPos bit = offset & 7; | |
108 + Bytef class_byte_value = clas ? 0xff : 0x00; | |
109 + Bytef class_bit_value = clas ? 1 : 0; | |
110 + static const Bytef mask[8] = {0xfe, 0xfd, 0xfb, 0xf7, | |
111 + 0xef, 0xdf, 0xbf, 0x7f}; | |
112 + | |
113 + if (bit) { | |
114 + while (len) { | |
115 + s->class_bitmap[byte] &= mask[bit]; | |
116 + s->class_bitmap[byte] |= class_bit_value << bit; | |
117 + bit++; | |
118 + len--; | |
119 + if (bit == 8) { | |
120 + bit = 0; | |
121 + byte++; | |
122 + break; | |
123 + } | |
124 + } | |
125 + } | |
126 + | |
127 + while (len >= 8) { | |
128 + s->class_bitmap[byte++] = class_byte_value; | |
129 + len -= 8; | |
130 + } | |
131 + | |
132 + while (len) { | |
133 + s->class_bitmap[byte] &= mask[bit]; | |
134 + s->class_bitmap[byte] |= class_bit_value << bit; | |
135 + bit++; | |
136 + len--; | |
137 + } | |
138 +} | |
139 + | |
140 +local int class_at(s, window_offset) | |
141 + deflate_state *s; | |
142 + IPos window_offset; | |
143 +{ | |
144 + IPos byte = window_offset >> 3; | |
145 + IPos bit = window_offset & 7; | |
146 + return (s->class_bitmap[byte] >> bit) & 1; | |
147 +} | |
148 + | |
149 #ifndef FASTEST | |
150 /* =========================================================================== | |
151 * Set match_start to the longest match starting at the given string and | |
152 @@ -1145,9 +1220,10 @@ local void lm_init (s) | |
153 /* For 80x86 and 680x0, an optimized version will be provided in match.asm or | |
154 * match.S. The code will be functionally equivalent. | |
155 */ | |
156 -local uInt longest_match(s, cur_match) | |
157 +local uInt longest_match(s, cur_match, clas) | |
158 deflate_state *s; | |
159 IPos cur_match; /* current match */ | |
160 + int clas; | |
161 { | |
162 unsigned chain_length = s->max_chain_length;/* max hash chain length */ | |
163 register Bytef *scan = s->window + s->strstart; /* current string */ | |
164 @@ -1195,6 +1271,9 @@ local uInt longest_match(s, cur_match) | |
165 do { | |
166 Assert(cur_match < s->strstart, "no future"); | |
167 match = s->window + cur_match; | |
168 + /* If the matched data is in the wrong class, skip it. */ | |
169 + if (s->class_bitmap && class_at(s, cur_match) != clas) | |
170 + continue; | |
171 | |
172 /* Skip to next match if the match length cannot increase | |
173 * or if the match length is less than 2. Note that the checks below | |
174 @@ -1237,6 +1316,8 @@ local uInt longest_match(s, cur_match) | |
175 len = (MAX_MATCH - 1) - (int)(strend-scan); | |
176 scan = strend - (MAX_MATCH-1); | |
177 | |
178 +#error "UNALIGNED_OK hasn't been patched." | |
179 + | |
180 #else /* UNALIGNED_OK */ | |
181 | |
182 if (match[best_len] != scan_end || | |
183 @@ -1253,15 +1334,23 @@ local uInt longest_match(s, cur_match) | |
184 scan += 2, match++; | |
185 Assert(*scan == *match, "match[2]?"); | |
186 | |
187 - /* We check for insufficient lookahead only every 8th comparison; | |
188 - * the 256th check will be made at strstart+258. | |
189 - */ | |
190 - do { | |
191 - } while (*++scan == *++match && *++scan == *++match && | |
192 - *++scan == *++match && *++scan == *++match && | |
193 - *++scan == *++match && *++scan == *++match && | |
194 - *++scan == *++match && *++scan == *++match && | |
195 - scan < strend); | |
196 + if (!s->class_bitmap) { | |
197 + /* We check for insufficient lookahead only every 8th comparison; | |
198 + * the 256th check will be made at strstart+258. | |
199 + */ | |
200 + do { | |
201 + } while (*++scan == *++match && *++scan == *++match && | |
202 + *++scan == *++match && *++scan == *++match && | |
203 + *++scan == *++match && *++scan == *++match && | |
204 + *++scan == *++match && *++scan == *++match && | |
205 + scan < strend); | |
206 + } else { | |
207 + /* We have to be mindful of the class of the data and not stray. */ | |
208 + do { | |
209 + } while (*++scan == *++match && | |
210 + class_at(s, match - s->window) == clas && | |
211 + scan < strend); | |
212 + } | |
213 | |
214 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); | |
215 | |
216 @@ -1289,20 +1378,74 @@ local uInt longest_match(s, cur_match) | |
217 } | |
218 #endif /* ASMV */ | |
219 | |
220 +/* cookie_match is a replacement for longest_match in the case of cookie data. | |
221 + * Here we only wish to match the entire value so trying the partial matches in | |
222 + * longest_match is both wasteful and often fails to find the correct match. | |
223 + * | |
224 + * So we take the djb2 hash of the cookie and look up the last position for a | |
225 + * match in a special hash table. */ | |
226 +local uInt cookie_match(s, start, len) | |
227 + deflate_state *s; | |
228 + IPos start; | |
229 + unsigned len; | |
230 +{ | |
231 + unsigned hash = 5381; | |
232 + Bytef *str = s->window + start; | |
233 + unsigned i; | |
234 + IPos cookie_location; | |
235 + | |
236 + if (len >= MAX_MATCH || len == 0) | |
237 + return 0; | |
238 + | |
239 + for (i = 0; i < len; i++) | |
240 + hash = ((hash << 5) + hash) + str[i]; | |
241 + | |
242 + hash &= Z_COOKIE_HASH_MASK; | |
243 + cookie_location = s->cookie_locations[hash]; | |
244 + s->cookie_locations[hash] = start; | |
245 + s->match_start = 0; | |
246 + if (cookie_location && | |
247 + (start - cookie_location) > len && | |
248 + (start - cookie_location) < MAX_DIST(s) && | |
249 + len <= s->lookahead) { | |
250 + for (i = 0; i < len; i++) { | |
251 + if (s->window[start+i] != s->window[cookie_location+i] || | |
252 + class_at(s, cookie_location+i) != 1) { | |
253 + return 0; | |
254 + } | |
255 + } | |
256 + /* Check that we aren't matching a prefix of another cookie by ensuring | |
257 + * that the final byte is either a semicolon (which cannot appear in a | |
258 + * cookie value), or non-cookie data. */ | |
259 + if (s->window[cookie_location+len-1] != ';' && | |
260 + class_at(s, cookie_location+len) != 0) { | |
261 + return 0; | |
262 + } | |
263 + s->match_start = cookie_location; | |
264 + return len; | |
265 + } | |
266 + | |
267 + return 0; | |
268 +} | |
269 + | |
270 + | |
271 #else /* FASTEST */ | |
272 | |
273 /* --------------------------------------------------------------------------- | |
274 * Optimized version for FASTEST only | |
275 */ | |
276 -local uInt longest_match(s, cur_match) | |
277 +local uInt longest_match(s, cur_match, clas) | |
278 deflate_state *s; | |
279 IPos cur_match; /* current match */ | |
280 + int clas; | |
281 { | |
282 register Bytef *scan = s->window + s->strstart; /* current string */ | |
283 register Bytef *match; /* matched string */ | |
284 register int len; /* length of current match */ | |
285 register Bytef *strend = s->window + s->strstart + MAX_MATCH; | |
286 | |
287 +#error "This code not patched" | |
288 + | |
289 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. | |
290 * It is easy to get rid of this optimization if necessary. | |
291 */ | |
292 @@ -1447,6 +1590,20 @@ local void fill_window(s) | |
293 */ | |
294 } while (--n); | |
295 #endif | |
296 + for (n = 0; n < Z_COOKIE_HASH_SIZE; n++) { | |
297 + if (s->cookie_locations[n] > wsize) { | |
298 + s->cookie_locations[n] -= wsize; | |
299 + } else { | |
300 + s->cookie_locations[n] = 0; | |
301 + } | |
302 + } | |
303 + | |
304 + if (s->class_bitmap) { | |
305 + zmemcpy(s->class_bitmap, s->class_bitmap + s->w_size/8, | |
306 + s->w_size/8); | |
307 + zmemzero(s->class_bitmap + s->w_size/8, s->w_size/8); | |
308 + } | |
309 + | |
310 more += wsize; | |
311 } | |
312 if (s->strm->avail_in == 0) break; | |
313 @@ -1465,6 +1622,9 @@ local void fill_window(s) | |
314 Assert(more >= 2, "more < 2"); | |
315 | |
316 n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); | |
317 + if (s->class_bitmap != NULL) { | |
318 + class_set(s, s->strstart + s->lookahead, n, s->strm->clas); | |
319 + } | |
320 s->lookahead += n; | |
321 | |
322 /* Initialize the hash value now that we have some input: */ | |
323 @@ -1561,9 +1721,10 @@ local void fill_window(s) | |
324 * NOTE: this function should be optimized to avoid extra copying from | |
325 * window to pending_buf. | |
326 */ | |
327 -local block_state deflate_stored(s, flush) | |
328 +local block_state deflate_stored(s, flush, clas) | |
329 deflate_state *s; | |
330 int flush; | |
331 + int clas; | |
332 { | |
333 /* Stored blocks are limited to 0xffff bytes, pending_buf is limited | |
334 * to pending_buf_size, and each stored block has a 5 byte header: | |
335 @@ -1625,13 +1786,19 @@ local block_state deflate_stored(s, flush) | |
336 * new strings in the dictionary only for unmatched strings or for short | |
337 * matches. It is used only for the fast compression options. | |
338 */ | |
339 -local block_state deflate_fast(s, flush) | |
340 +local block_state deflate_fast(s, flush, clas) | |
341 deflate_state *s; | |
342 int flush; | |
343 + int clas; | |
344 { | |
345 IPos hash_head; /* head of the hash chain */ | |
346 int bflush; /* set if current block must be flushed */ | |
347 | |
348 + if (clas != 0) { | |
349 + /* We haven't patched this code for alternative class data. */ | |
350 + return Z_BUF_ERROR; | |
351 + } | |
352 + | |
353 for (;;) { | |
354 /* Make sure that we always have enough lookahead, except | |
355 * at the end of the input file. We need MAX_MATCH bytes | |
356 @@ -1662,7 +1829,7 @@ local block_state deflate_fast(s, flush) | |
357 * of window index 0 (in particular we have to avoid a match | |
358 * of the string with itself at the start of the input file). | |
359 */ | |
360 - s->match_length = longest_match (s, hash_head); | |
361 + s->match_length = longest_match (s, hash_head, clas); | |
362 /* longest_match() sets match_start */ | |
363 } | |
364 if (s->match_length >= MIN_MATCH) { | |
365 @@ -1727,12 +1894,25 @@ local block_state deflate_fast(s, flush) | |
366 * evaluation for matches: a match is finally adopted only if there is | |
367 * no better match at the next window position. | |
368 */ | |
369 -local block_state deflate_slow(s, flush) | |
370 +local block_state deflate_slow(s, flush, clas) | |
371 deflate_state *s; | |
372 int flush; | |
373 + int clas; | |
374 { | |
375 IPos hash_head; /* head of hash chain */ | |
376 int bflush; /* set if current block must be flushed */ | |
377 + uInt input_length ; | |
378 + int first = 1; /* first says whether this is the first iteration | |
379 + of the loop, below. */ | |
380 + | |
381 + if (clas == Z_CLASS_COOKIE) { | |
382 + if (s->lookahead) { | |
383 + /* Alternative class data must always be presented at the beginning | |
384 + * of a block. */ | |
385 + return Z_BUF_ERROR; | |
386 + } | |
387 + input_length = s->strm->avail_in; | |
388 + } | |
389 | |
390 /* Process the input block. */ | |
391 for (;;) { | |
392 @@ -1762,13 +1942,18 @@ local block_state deflate_slow(s, flush) | |
393 s->prev_length = s->match_length, s->prev_match = s->match_start; | |
394 s->match_length = MIN_MATCH-1; | |
395 | |
396 - if (hash_head != NIL && s->prev_length < s->max_lazy_match && | |
397 - s->strstart - hash_head <= MAX_DIST(s)) { | |
398 + if (clas == Z_CLASS_COOKIE && first) { | |
399 + s->match_length = cookie_match(s, s->strstart, input_length); | |
400 + } else if (clas == Z_CLASS_STANDARD && | |
401 + hash_head != NIL && | |
402 + s->prev_length < s->max_lazy_match && | |
403 + s->strstart - hash_head <= MAX_DIST(s)) { | |
404 /* To simplify the code, we prevent matches with the string | |
405 * of window index 0 (in particular we have to avoid a match | |
406 * of the string with itself at the start of the input file). | |
407 */ | |
408 - s->match_length = longest_match (s, hash_head); | |
409 + s->match_length = longest_match (s, hash_head, clas); | |
410 + | |
411 /* longest_match() sets match_start */ | |
412 | |
413 if (s->match_length <= 5 && (s->strategy == Z_FILTERED | |
414 @@ -1787,7 +1972,20 @@ local block_state deflate_slow(s, flush) | |
415 /* If there was a match at the previous step and the current | |
416 * match is not better, output the previous match: | |
417 */ | |
418 - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { | |
419 + first = 0; | |
420 + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length && | |
421 + /* We will only accept an exact match for Z_CLASS_COOKIE data and | |
422 + * we won't match Z_CLASS_HUFFMAN_ONLY data at all. */ | |
423 + (clas == Z_CLASS_STANDARD || (clas == Z_CLASS_COOKIE && | |
424 + s->prev_length == input_length && | |
425 + s->prev_match > 0 && | |
426 + /* We require that a Z_CLASS_COOKIE match be | |
427 + * preceded by either a semicolon (which cannot be | |
428 + * part of a cookie), or non-cookie data. This is | |
429 + * to prevent a cookie from being a suffix of | |
430 + * another. */ | |
431 + (class_at(s, s->prev_match-1) == Z_CLASS_STANDARD |
| | |
432 + *(s->window + s->prev_match-1) == ';')))) { | |
433 uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; | |
434 /* Do not insert strings in hash table beyond this. */ | |
435 | |
436 diff --git a/third_party/zlib/deflate.h b/third_party/zlib/deflate.h | |
437 index ce0299e..c795034 100644 | |
438 --- a/third_party/zlib/deflate.h | |
439 +++ b/third_party/zlib/deflate.h | |
440 @@ -94,6 +94,9 @@ typedef unsigned IPos; | |
441 * save space in the various tables. IPos is used only for parameter passing. | |
442 */ | |
443 | |
444 +#define Z_COOKIE_HASH_SIZE 256 | |
445 +#define Z_COOKIE_HASH_MASK (Z_COOKIE_HASH_SIZE-1) | |
446 + | |
447 typedef struct internal_state { | |
448 z_streamp strm; /* pointer back to this zlib stream */ | |
449 int status; /* as the name implies */ | |
450 @@ -142,6 +145,8 @@ typedef struct internal_state { | |
451 uInt hash_mask; /* hash_size-1 */ | |
452 | |
453 uInt hash_shift; | |
454 + Bytef *class_bitmap; /* bitmap of class for each byte in window */ | |
455 + IPos cookie_locations[Z_COOKIE_HASH_SIZE]; | |
456 /* Number of bits by which ins_h must be shifted at each input | |
457 * step. It must be such that after MIN_MATCH steps, the oldest | |
458 * byte no longer takes part in the hash key, that is: | |
459 diff --git a/third_party/zlib/zlib.h b/third_party/zlib/zlib.h | |
460 index 36c73af..5544c88 100644 | |
461 --- a/third_party/zlib/zlib.h | |
462 +++ b/third_party/zlib/zlib.h | |
463 @@ -101,6 +101,7 @@ typedef struct z_stream_s { | |
464 int data_type; /* best guess about the data type: binary or text */ | |
465 uLong adler; /* adler32 value of the uncompressed data */ | |
466 uLong reserved; /* reserved for future use */ | |
467 + int clas; | |
468 } z_stream; | |
469 | |
470 typedef z_stream FAR *z_streamp; | |
471 @@ -207,6 +208,10 @@ typedef gz_header FAR *gz_headerp; | |
472 | |
473 #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ | |
474 | |
475 +#define Z_CLASS_STANDARD 0 | |
476 +#define Z_CLASS_COOKIE 1 | |
477 +#define Z_CLASS_HUFFMAN_ONLY 2 | |
478 + | |
479 #define zlib_version zlibVersion() | |
480 /* for compatibility with versions < 1.0.2 */ | |
481 | |
482 @@ -1744,6 +1749,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backwa
rd compatibility */ | |
483 ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); | |
484 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); | |
485 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); | |
486 +# else | |
487 + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); | |
488 + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); | |
489 + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); | |
490 + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); | |
491 + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); | |
492 + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); | |
493 # endif | |
494 #else | |
495 ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); | |
496 -- | |
497 2.7.4 | |
498 | |
OLD | NEW |