diff options
Diffstat (limited to '')
| -rw-r--r-- | deflate.c | 187 |
1 files changed, 110 insertions, 77 deletions
| @@ -113,21 +113,21 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ | |||
| 113 | * Prototypes for local functions. | 113 | * Prototypes for local functions. |
| 114 | */ | 114 | */ |
| 115 | 115 | ||
| 116 | local void fill_window __P((deflate_state *s)); | 116 | local void fill_window OF((deflate_state *s)); |
| 117 | local int deflate_fast __P((deflate_state *s, int flush)); | 117 | local int deflate_fast OF((deflate_state *s, int flush)); |
| 118 | local int deflate_slow __P((deflate_state *s, int flush)); | 118 | local int deflate_slow OF((deflate_state *s, int flush)); |
| 119 | local void lm_init __P((deflate_state *s)); | 119 | local void lm_init OF((deflate_state *s)); |
| 120 | local inline int longest_match __P((deflate_state *s, IPos cur_match)); | 120 | local int longest_match OF((deflate_state *s, IPos cur_match)); |
| 121 | local void putShortMSB __P((deflate_state *s, uInt b)); | 121 | local void putShortMSB OF((deflate_state *s, uInt b)); |
| 122 | local void flush_pending __P((z_stream *strm)); | 122 | local void flush_pending OF((z_stream *strm)); |
| 123 | local int read_buf __P((z_stream *strm, char *buf, unsigned size)); | 123 | local int read_buf OF((z_stream *strm, charf *buf, unsigned size)); |
| 124 | #ifdef ASMV | 124 | #ifdef ASMV |
| 125 | void match_init __P((void)); /* asm code initialization */ | 125 | void match_init OF((void)); /* asm code initialization */ |
| 126 | #endif | 126 | #endif |
| 127 | 127 | ||
| 128 | #ifdef DEBUG | 128 | #ifdef DEBUG |
| 129 | local void check_match __P((deflate_state *s, IPos start, IPos match, | 129 | local void check_match OF((deflate_state *s, IPos start, IPos match, |
| 130 | int length)); | 130 | int length)); |
| 131 | #endif | 131 | #endif |
| 132 | 132 | ||
| 133 | 133 | ||
| @@ -139,6 +139,7 @@ local void check_match __P((deflate_state *s, IPos start, IPos match, | |||
| 139 | */ | 139 | */ |
| 140 | #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) | 140 | #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) |
| 141 | 141 | ||
| 142 | |||
| 142 | /* =========================================================================== | 143 | /* =========================================================================== |
| 143 | * Insert string str in the dictionary and set match_head to the previous head | 144 | * Insert string str in the dictionary and set match_head to the previous head |
| 144 | * of the hash chain (the most recent string with same hash key). Return | 145 | * of the hash chain (the most recent string with same hash key). Return |
| @@ -148,7 +149,7 @@ local void check_match __P((deflate_state *s, IPos start, IPos match, | |||
| 148 | * (except for the last MIN_MATCH-1 bytes of the input file). | 149 | * (except for the last MIN_MATCH-1 bytes of the input file). |
| 149 | */ | 150 | */ |
| 150 | #define INSERT_STRING(s, str, match_head) \ | 151 | #define INSERT_STRING(s, str, match_head) \ |
| 151 | (UPDATE_HASH(s, s->ins_h, s->window[(str) + MIN_MATCH-1]), \ | 152 | (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ |
| 152 | s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ | 153 | s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ |
| 153 | s->head[s->ins_h] = (str)) | 154 | s->head[s->ins_h] = (str)) |
| 154 | 155 | ||
| @@ -158,7 +159,7 @@ local void check_match __P((deflate_state *s, IPos start, IPos match, | |||
| 158 | */ | 159 | */ |
| 159 | #define CLEAR_HASH(s) \ | 160 | #define CLEAR_HASH(s) \ |
| 160 | s->head[s->hash_size-1] = NIL; \ | 161 | s->head[s->hash_size-1] = NIL; \ |
| 161 | zmemzero((char*)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); | 162 | zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); |
| 162 | 163 | ||
| 163 | /* ========================================================================= */ | 164 | /* ========================================================================= */ |
| 164 | int deflateInit (strm, level) | 165 | int deflateInit (strm, level) |
| @@ -199,7 +200,7 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) | |||
| 199 | } | 200 | } |
| 200 | s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); | 201 | s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); |
| 201 | if (s == Z_NULL) return Z_MEM_ERROR; | 202 | if (s == Z_NULL) return Z_MEM_ERROR; |
| 202 | strm->state = (struct internal_state *)s; | 203 | strm->state = (struct internal_state FAR *)s; |
| 203 | s->strm = strm; | 204 | s->strm = strm; |
| 204 | 205 | ||
| 205 | s->noheader = noheader; | 206 | s->noheader = noheader; |
| @@ -212,13 +213,13 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) | |||
| 212 | s->hash_mask = s->hash_size - 1; | 213 | s->hash_mask = s->hash_size - 1; |
| 213 | s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); | 214 | s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); |
| 214 | 215 | ||
| 215 | s->window = (Byte*) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); | 216 | s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); |
| 216 | s->prev = (Pos*) ZALLOC(strm, s->w_size, sizeof(Pos)); | 217 | s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
| 217 | s->head = (Pos*) ZALLOC(strm, s->hash_size, sizeof(Pos)); | 218 | s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); |
| 218 | 219 | ||
| 219 | s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ | 220 | s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ |
| 220 | 221 | ||
| 221 | s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); | 222 | s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); |
| 222 | 223 | ||
| 223 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || | 224 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || |
| 224 | s->pending_buf == Z_NULL) { | 225 | s->pending_buf == Z_NULL) { |
| @@ -226,8 +227,8 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) | |||
| 226 | deflateEnd (strm); | 227 | deflateEnd (strm); |
| 227 | return Z_MEM_ERROR; | 228 | return Z_MEM_ERROR; |
| 228 | } | 229 | } |
| 229 | s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]); | 230 | s->d_buf = (ushf *) &(s->pending_buf[s->lit_bufsize]); |
| 230 | s->l_buf = (uch*) &(s->pending_buf[3*s->lit_bufsize]); | 231 | s->l_buf = (uchf *) &(s->pending_buf[3*s->lit_bufsize]); |
| 231 | /* We overlay pending_buf and d_buf+l_buf. This works since the average | 232 | /* We overlay pending_buf and d_buf+l_buf. This works since the average |
| 232 | * output size for (length,distance) codes is <= 32 bits (worst case | 233 | * output size for (length,distance) codes is <= 32 bits (worst case |
| 233 | * is 15+15+13=33). | 234 | * is 15+15+13=33). |
| @@ -257,6 +258,9 @@ int deflateReset (strm) | |||
| 257 | s->pending = 0; | 258 | s->pending = 0; |
| 258 | s->pending_out = s->pending_buf; | 259 | s->pending_out = s->pending_buf; |
| 259 | 260 | ||
| 261 | if (s->noheader < 0) { | ||
| 262 | s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ | ||
| 263 | } | ||
| 260 | s->status = s->noheader ? BUSY_STATE : INIT_STATE; | 264 | s->status = s->noheader ? BUSY_STATE : INIT_STATE; |
| 261 | s->adler = 1; | 265 | s->adler = 1; |
| 262 | 266 | ||
| @@ -267,9 +271,9 @@ int deflateReset (strm) | |||
| 267 | } | 271 | } |
| 268 | 272 | ||
| 269 | /* ========================================================================= | 273 | /* ========================================================================= |
| 270 | * Put a short the pending_out buffer. The 16-bit value is put in MSB order. | 274 | * Put a short in the pending buffer. The 16-bit value is put in MSB order. |
| 271 | * IN assertion: the stream state is correct and there is enough room in | 275 | * IN assertion: the stream state is correct and there is enough room in |
| 272 | * the pending_out buffer. | 276 | * pending_buf. |
| 273 | */ | 277 | */ |
| 274 | local void putShortMSB (s, b) | 278 | local void putShortMSB (s, b) |
| 275 | deflate_state *s; | 279 | deflate_state *s; |
| @@ -308,7 +312,8 @@ int deflate (strm, flush) | |||
| 308 | { | 312 | { |
| 309 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 313 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
| 310 | 314 | ||
| 311 | if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) { | 315 | if (strm->next_out == Z_NULL || |
| 316 | (strm->next_in == Z_NULL && strm->avail_in != 0)) { | ||
| 312 | ERR_RETURN(strm, Z_STREAM_ERROR); | 317 | ERR_RETURN(strm, Z_STREAM_ERROR); |
| 313 | } | 318 | } |
| 314 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); | 319 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); |
| @@ -342,10 +347,10 @@ int deflate (strm, flush) | |||
| 342 | 347 | ||
| 343 | /* Start a new block or continue the current one. | 348 | /* Start a new block or continue the current one. |
| 344 | */ | 349 | */ |
| 345 | if (strm->avail_in != 0 || | 350 | if (strm->avail_in != 0 || strm->state->lookahead != 0 || |
| 346 | (flush == Z_FINISH && strm->state->status != FINISH_STATE)) { | 351 | (flush != Z_NO_FLUSH && strm->state->status != FINISH_STATE)) { |
| 347 | int quit; | 352 | int quit; |
| 348 | 353 | ||
| 349 | if (flush == Z_FINISH) { | 354 | if (flush == Z_FINISH) { |
| 350 | strm->state->status = FINISH_STATE; | 355 | strm->state->status = FINISH_STATE; |
| 351 | } | 356 | } |
| @@ -354,17 +359,29 @@ int deflate (strm, flush) | |||
| 354 | } else { | 359 | } else { |
| 355 | quit = deflate_slow(strm->state, flush); | 360 | quit = deflate_slow(strm->state, flush); |
| 356 | } | 361 | } |
| 357 | if (flush == Z_FULL_FLUSH || flush == Z_SYNC_FLUSH) { | 362 | if (quit || strm->avail_out == 0) return Z_OK; |
| 358 | ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */ | 363 | /* If flush != Z_NO_FLUSH && avail_out == 0, the next call |
| 359 | flush_pending(strm); | 364 | * of deflate should use the same flush parameter to make sure |
| 360 | if (flush == Z_FULL_FLUSH) { | 365 | * that the flush is complete. So we don't have to output an |
| 361 | CLEAR_HASH(strm->state); /* forget history */ | 366 | * empty block here, this will be done at next call. This also |
| 362 | } | 367 | * ensures that for a very small output buffer, we emit at most |
| 363 | } else if (flush == Z_PARTIAL_FLUSH) { | 368 | * one empty block. |
| 364 | ct_align(strm->state); | 369 | */ |
| 370 | if (flush != Z_OK && flush != Z_FINISH) { | ||
| 371 | if (flush == Z_PARTIAL_FLUSH) { | ||
| 372 | ct_align(strm->state); | ||
| 373 | } else { /* FULL_FLUSH or SYNC_FLUSH */ | ||
| 374 | ct_stored_block(strm->state, (char*)0, 0L, 0); | ||
| 375 | /* For a full flush, this empty block will be recognized | ||
| 376 | * as a special marker by inflate_sync(). | ||
| 377 | */ | ||
| 378 | if (flush == Z_FULL_FLUSH) { | ||
| 379 | CLEAR_HASH(strm->state); /* forget history */ | ||
| 380 | } | ||
| 381 | } | ||
| 365 | flush_pending(strm); | 382 | flush_pending(strm); |
| 383 | if (strm->avail_out == 0) return Z_OK; | ||
| 366 | } | 384 | } |
| 367 | if (quit || strm->avail_out == 0) return Z_OK; | ||
| 368 | } | 385 | } |
| 369 | Assert(strm->avail_out > 0, "bug2"); | 386 | Assert(strm->avail_out > 0, "bug2"); |
| 370 | 387 | ||
| @@ -378,7 +395,7 @@ int deflate (strm, flush) | |||
| 378 | /* If avail_out is zero, the application will call deflate again | 395 | /* If avail_out is zero, the application will call deflate again |
| 379 | * to flush the rest. | 396 | * to flush the rest. |
| 380 | */ | 397 | */ |
| 381 | strm->state->noheader = 1; /* write the trailer only once! */ | 398 | strm->state->noheader = -1; /* write the trailer only once! */ |
| 382 | return strm->state->pending != 0 ? Z_OK : Z_STREAM_END; | 399 | return strm->state->pending != 0 ? Z_OK : Z_STREAM_END; |
| 383 | } | 400 | } |
| 384 | 401 | ||
| @@ -410,7 +427,7 @@ int deflateCopy (dest, source) | |||
| 410 | *dest = *source; | 427 | *dest = *source; |
| 411 | return Z_STREAM_ERROR; /* to be implemented */ | 428 | return Z_STREAM_ERROR; /* to be implemented */ |
| 412 | #if 0 | 429 | #if 0 |
| 413 | dest->state = (struct internal_state *) | 430 | dest->state = (struct internal_state FAR *) |
| 414 | (*dest->zalloc)(1, sizeof(deflate_state)); | 431 | (*dest->zalloc)(1, sizeof(deflate_state)); |
| 415 | if (dest->state == Z_NULL) return Z_MEM_ERROR; | 432 | if (dest->state == Z_NULL) return Z_MEM_ERROR; |
| 416 | 433 | ||
| @@ -425,7 +442,7 @@ int deflateCopy (dest, source) | |||
| 425 | */ | 442 | */ |
| 426 | local int read_buf(strm, buf, size) | 443 | local int read_buf(strm, buf, size) |
| 427 | z_stream *strm; | 444 | z_stream *strm; |
| 428 | char *buf; | 445 | charf *buf; |
| 429 | unsigned size; | 446 | unsigned size; |
| 430 | { | 447 | { |
| 431 | unsigned len = strm->avail_in; | 448 | unsigned len = strm->avail_in; |
| @@ -485,13 +502,13 @@ local void lm_init (s) | |||
| 485 | /* For 80x86 and 680x0, an optimized version will be provided in match.asm or | 502 | /* For 80x86 and 680x0, an optimized version will be provided in match.asm or |
| 486 | * match.S. The code will be functionally equivalent. | 503 | * match.S. The code will be functionally equivalent. |
| 487 | */ | 504 | */ |
| 488 | local inline int longest_match(s, cur_match) | 505 | local int longest_match(s, cur_match) |
| 489 | deflate_state *s; | 506 | deflate_state *s; |
| 490 | IPos cur_match; /* current match */ | 507 | IPos cur_match; /* current match */ |
| 491 | { | 508 | { |
| 492 | unsigned chain_length = s->max_chain_length;/* max hash chain length */ | 509 | unsigned chain_length = s->max_chain_length;/* max hash chain length */ |
| 493 | register Byte *scan = s->window + s->strstart; /* current string */ | 510 | register Bytef *scan = s->window + s->strstart; /* current string */ |
| 494 | register Byte *match; /* matched string */ | 511 | register Bytef *match; /* matched string */ |
| 495 | register int len; /* length of current match */ | 512 | register int len; /* length of current match */ |
| 496 | int best_len = s->prev_length; /* best match length so far */ | 513 | int best_len = s->prev_length; /* best match length so far */ |
| 497 | IPos limit = s->strstart > (IPos)MAX_DIST(s) ? | 514 | IPos limit = s->strstart > (IPos)MAX_DIST(s) ? |
| @@ -499,18 +516,18 @@ local inline int longest_match(s, cur_match) | |||
| 499 | /* Stop when cur_match becomes <= limit. To simplify the code, | 516 | /* Stop when cur_match becomes <= limit. To simplify the code, |
| 500 | * we prevent matches with the string of window index 0. | 517 | * we prevent matches with the string of window index 0. |
| 501 | */ | 518 | */ |
| 502 | Pos *prev = s->prev; | 519 | Posf *prev = s->prev; |
| 503 | uInt wmask = s->w_mask; | 520 | uInt wmask = s->w_mask; |
| 504 | 521 | ||
| 505 | #ifdef UNALIGNED_OK | 522 | #ifdef UNALIGNED_OK |
| 506 | /* Compare two bytes at a time. Note: this is not always beneficial. | 523 | /* Compare two bytes at a time. Note: this is not always beneficial. |
| 507 | * Try with and without -DUNALIGNED_OK to check. | 524 | * Try with and without -DUNALIGNED_OK to check. |
| 508 | */ | 525 | */ |
| 509 | register Byte *strend = s->window + s->strstart + MAX_MATCH - 1; | 526 | register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; |
| 510 | register ush scan_start = *(ush*)scan; | 527 | register ush scan_start = *(ush*)scan; |
| 511 | register ush scan_end = *(ush*)(scan+best_len-1); | 528 | register ush scan_end = *(ush*)(scan+best_len-1); |
| 512 | #else | 529 | #else |
| 513 | register Byte *strend = s->window + s->strstart + MAX_MATCH; | 530 | register Bytef *strend = s->window + s->strstart + MAX_MATCH; |
| 514 | register Byte scan_end1 = scan[best_len-1]; | 531 | register Byte scan_end1 = scan[best_len-1]; |
| 515 | register Byte scan_end = scan[best_len]; | 532 | register Byte scan_end = scan[best_len]; |
| 516 | #endif | 533 | #endif |
| @@ -524,7 +541,7 @@ local inline int longest_match(s, cur_match) | |||
| 524 | if (s->prev_length >= s->good_match) { | 541 | if (s->prev_length >= s->good_match) { |
| 525 | chain_length >>= 2; | 542 | chain_length >>= 2; |
| 526 | } | 543 | } |
| 527 | Assert(s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); | 544 | Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
| 528 | 545 | ||
| 529 | do { | 546 | do { |
| 530 | Assert(cur_match < s->strstart, "no future"); | 547 | Assert(cur_match < s->strstart, "no future"); |
| @@ -549,6 +566,7 @@ local inline int longest_match(s, cur_match) | |||
| 549 | * necessary to put more guard bytes at the end of the window, or | 566 | * necessary to put more guard bytes at the end of the window, or |
| 550 | * to check more often for insufficient lookahead. | 567 | * to check more often for insufficient lookahead. |
| 551 | */ | 568 | */ |
| 569 | Assert(scan[2] == match[2], "scan[2]?"); | ||
| 552 | scan++, match++; | 570 | scan++, match++; |
| 553 | do { | 571 | do { |
| 554 | } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && | 572 | } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && |
| @@ -579,6 +597,7 @@ local inline int longest_match(s, cur_match) | |||
| 579 | * the hash keys are equal and that HASH_BITS >= 8. | 597 | * the hash keys are equal and that HASH_BITS >= 8. |
| 580 | */ | 598 | */ |
| 581 | scan += 2, match++; | 599 | scan += 2, match++; |
| 600 | Assert(*scan == *match, "match[2]?"); | ||
| 582 | 601 | ||
| 583 | /* We check for insufficient lookahead only every 8th comparison; | 602 | /* We check for insufficient lookahead only every 8th comparison; |
| 584 | * the 256th check will be made at strstart+258. | 603 | * the 256th check will be made at strstart+258. |
| @@ -625,11 +644,13 @@ local void check_match(s, start, match, length) | |||
| 625 | int length; | 644 | int length; |
| 626 | { | 645 | { |
| 627 | /* check that the match is indeed a match */ | 646 | /* check that the match is indeed a match */ |
| 628 | if (memcmp((char*)s->window + match, | 647 | if (memcmp((charf *)s->window + match, |
| 629 | (char*)s->window + start, length) != EQUAL) { | 648 | (charf *)s->window + start, length) != EQUAL) { |
| 630 | fprintf(stderr, | 649 | fprintf(stderr, |
| 631 | " start %d, match %d, length %d\n", | 650 | " start %u, match %u, length %d\n", |
| 632 | start, match, length); | 651 | start, match, length); |
| 652 | do { fprintf(stderr, "%c%c", s->window[match++], | ||
| 653 | s->window[start++]); } while (--length != 0); | ||
| 633 | z_error("invalid match"); | 654 | z_error("invalid match"); |
| 634 | } | 655 | } |
| 635 | if (verbose > 1) { | 656 | if (verbose > 1) { |
| @@ -655,7 +676,7 @@ local void fill_window(s) | |||
| 655 | deflate_state *s; | 676 | deflate_state *s; |
| 656 | { | 677 | { |
| 657 | register unsigned n, m; | 678 | register unsigned n, m; |
| 658 | register Pos *p; | 679 | register Posf *p; |
| 659 | unsigned more; /* Amount of free space at the end of the window. */ | 680 | unsigned more; /* Amount of free space at the end of the window. */ |
| 660 | uInt wsize = s->w_size; | 681 | uInt wsize = s->w_size; |
| 661 | 682 | ||
| @@ -679,7 +700,7 @@ local void fill_window(s) | |||
| 679 | /* By the IN assertion, the window is not empty so we can't confuse | 700 | /* By the IN assertion, the window is not empty so we can't confuse |
| 680 | * more == 0 with more == 64K on a 16 bit machine. | 701 | * more == 0 with more == 64K on a 16 bit machine. |
| 681 | */ | 702 | */ |
| 682 | zmemcpy((char*)s->window, (char*)s->window+wsize, | 703 | zmemcpy((charf *)s->window, (charf *)s->window+wsize, |
| 683 | (unsigned)wsize); | 704 | (unsigned)wsize); |
| 684 | s->match_start -= wsize; | 705 | s->match_start -= wsize; |
| 685 | s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ | 706 | s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
| @@ -690,17 +711,17 @@ local void fill_window(s) | |||
| 690 | at the expense of memory usage): | 711 | at the expense of memory usage): |
| 691 | */ | 712 | */ |
| 692 | n = s->hash_size; | 713 | n = s->hash_size; |
| 693 | p = &s->head[n-1]; | 714 | p = &s->head[n]; |
| 694 | do { | 715 | do { |
| 695 | m = *p; | 716 | m = *--p; |
| 696 | *p-- = (Pos)(m >= wsize ? m-wsize : NIL); | 717 | *p = (Pos)(m >= wsize ? m-wsize : NIL); |
| 697 | } while (--n); | 718 | } while (--n); |
| 698 | 719 | ||
| 699 | n = wsize; | 720 | n = wsize; |
| 700 | p = &s->prev[n-1]; | 721 | p = &s->prev[n]; |
| 701 | do { | 722 | do { |
| 702 | m = *p; | 723 | m = *--p; |
| 703 | *p-- = (Pos)(m >= wsize ? m-wsize : NIL); | 724 | *p = (Pos)(m >= wsize ? m-wsize : NIL); |
| 704 | /* If n is not on any hash chain, prev[n] is garbage but | 725 | /* If n is not on any hash chain, prev[n] is garbage but |
| 705 | * its value will never be used. | 726 | * its value will never be used. |
| 706 | */ | 727 | */ |
| @@ -723,15 +744,17 @@ local void fill_window(s) | |||
| 723 | */ | 744 | */ |
| 724 | Assert(more >= 2, "more < 2"); | 745 | Assert(more >= 2, "more < 2"); |
| 725 | 746 | ||
| 726 | n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead, | 747 | n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, |
| 727 | more); | 748 | more); |
| 728 | s->lookahead += n; | 749 | s->lookahead += n; |
| 729 | 750 | ||
| 730 | /* Initialize the hash value now that we have some input: */ | 751 | /* Initialize the hash value now that we have some input: */ |
| 731 | if (s->strstart == 0 && s->lookahead >= MIN_MATCH-1) { | 752 | if (s->lookahead >= MIN_MATCH) { |
| 732 | for (n=0; n<MIN_MATCH-1; n++) { | 753 | s->ins_h = s->window[s->strstart]; |
| 733 | UPDATE_HASH(s, s->ins_h, s->window[n]); | 754 | UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); |
| 734 | } | 755 | #if MIN_MATCH != 3 |
| 756 | Call UPDATE_HASH() MIN_MATCH-3 more times | ||
| 757 | #endif | ||
| 735 | } | 758 | } |
| 736 | /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, | 759 | /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, |
| 737 | * but this is not important since only literal bytes will be emitted. | 760 | * but this is not important since only literal bytes will be emitted. |
| @@ -746,10 +769,11 @@ local void fill_window(s) | |||
| 746 | */ | 769 | */ |
| 747 | #define FLUSH_BLOCK_ONLY(s, eof) { \ | 770 | #define FLUSH_BLOCK_ONLY(s, eof) { \ |
| 748 | ct_flush_block(s, (s->block_start >= 0L ? \ | 771 | ct_flush_block(s, (s->block_start >= 0L ? \ |
| 749 | (char*)&s->window[(unsigned)s->block_start] : \ | 772 | (charf *)&s->window[(unsigned)s->block_start] : \ |
| 750 | (char*)Z_NULL), (long)s->strstart - s->block_start, (eof)); \ | 773 | (charf *)Z_NULL), (long)s->strstart - s->block_start, (eof)); \ |
| 751 | s->block_start = s->strstart; \ | 774 | s->block_start = s->strstart; \ |
| 752 | flush_pending(s->strm); \ | 775 | flush_pending(s->strm); \ |
| 776 | Tracev((stderr,"[FLUSH]")); \ | ||
| 753 | } | 777 | } |
| 754 | 778 | ||
| 755 | /* Same but force premature exit if necessary. */ | 779 | /* Same but force premature exit if necessary. */ |
| @@ -790,7 +814,9 @@ local int deflate_fast(s, flush) | |||
| 790 | /* Insert the string window[strstart .. strstart+2] in the | 814 | /* Insert the string window[strstart .. strstart+2] in the |
| 791 | * dictionary, and set hash_head to the head of the hash chain: | 815 | * dictionary, and set hash_head to the head of the hash chain: |
| 792 | */ | 816 | */ |
| 793 | INSERT_STRING(s, s->strstart, hash_head); | 817 | if (s->lookahead >= MIN_MATCH) { |
| 818 | INSERT_STRING(s, s->strstart, hash_head); | ||
| 819 | } | ||
| 794 | 820 | ||
| 795 | /* Find the longest match, discarding those <= prev_length. | 821 | /* Find the longest match, discarding those <= prev_length. |
| 796 | * At this point we have always match_length < MIN_MATCH | 822 | * At this point we have always match_length < MIN_MATCH |
| @@ -818,15 +844,14 @@ local int deflate_fast(s, flush) | |||
| 818 | /* Insert new strings in the hash table only if the match length | 844 | /* Insert new strings in the hash table only if the match length |
| 819 | * is not too large. This saves time but degrades compression. | 845 | * is not too large. This saves time but degrades compression. |
| 820 | */ | 846 | */ |
| 821 | if (s->match_length <= s->max_insert_length) { | 847 | if (s->match_length <= s->max_insert_length && |
| 848 | s->lookahead >= MIN_MATCH) { | ||
| 822 | s->match_length--; /* string at strstart already in hash table */ | 849 | s->match_length--; /* string at strstart already in hash table */ |
| 823 | do { | 850 | do { |
| 824 | s->strstart++; | 851 | s->strstart++; |
| 825 | INSERT_STRING(s, s->strstart, hash_head); | 852 | INSERT_STRING(s, s->strstart, hash_head); |
| 826 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are | 853 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are |
| 827 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | 854 | * always MIN_MATCH bytes ahead. |
| 828 | * these bytes are garbage, but it does not matter since | ||
| 829 | * the next lookahead bytes will be emitted as literals. | ||
| 830 | */ | 855 | */ |
| 831 | } while (--s->match_length != 0); | 856 | } while (--s->match_length != 0); |
| 832 | s->strstart++; | 857 | s->strstart++; |
| @@ -838,6 +863,9 @@ local int deflate_fast(s, flush) | |||
| 838 | #if MIN_MATCH != 3 | 863 | #if MIN_MATCH != 3 |
| 839 | Call UPDATE_HASH() MIN_MATCH-3 more times | 864 | Call UPDATE_HASH() MIN_MATCH-3 more times |
| 840 | #endif | 865 | #endif |
| 866 | /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not | ||
| 867 | * matter since it will be recomputed at next deflate call. | ||
| 868 | */ | ||
| 841 | } | 869 | } |
| 842 | } else { | 870 | } else { |
| 843 | /* No match, output a literal byte */ | 871 | /* No match, output a literal byte */ |
| @@ -881,7 +909,9 @@ local int deflate_slow(s, flush) | |||
| 881 | /* Insert the string window[strstart .. strstart+2] in the | 909 | /* Insert the string window[strstart .. strstart+2] in the |
| 882 | * dictionary, and set hash_head to the head of the hash chain: | 910 | * dictionary, and set hash_head to the head of the hash chain: |
| 883 | */ | 911 | */ |
| 884 | INSERT_STRING(s, s->strstart, hash_head); | 912 | if (s->lookahead >= MIN_MATCH) { |
| 913 | INSERT_STRING(s, s->strstart, hash_head); | ||
| 914 | } | ||
| 885 | 915 | ||
| 886 | /* Find the longest match, discarding those <= prev_length. | 916 | /* Find the longest match, discarding those <= prev_length. |
| 887 | */ | 917 | */ |
| @@ -914,6 +944,8 @@ local int deflate_slow(s, flush) | |||
| 914 | * match is not better, output the previous match: | 944 | * match is not better, output the previous match: |
| 915 | */ | 945 | */ |
| 916 | if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { | 946 | if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { |
| 947 | uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; | ||
| 948 | /* Do not insert strings in hash table beyond this. */ | ||
| 917 | 949 | ||
| 918 | check_match(s, s->strstart-1, s->prev_match, s->prev_length); | 950 | check_match(s, s->strstart-1, s->prev_match, s->prev_length); |
| 919 | 951 | ||
| @@ -921,18 +953,16 @@ local int deflate_slow(s, flush) | |||
| 921 | s->prev_length - MIN_MATCH); | 953 | s->prev_length - MIN_MATCH); |
| 922 | 954 | ||
| 923 | /* Insert in hash table all strings up to the end of the match. | 955 | /* Insert in hash table all strings up to the end of the match. |
| 924 | * strstart-1 and strstart are already inserted. | 956 | * strstart-1 and strstart are already inserted. If there is not |
| 957 | * enough lookahead, the last two strings are not inserted in | ||
| 958 | * the hash table. | ||
| 925 | */ | 959 | */ |
| 926 | s->lookahead -= s->prev_length-1; | 960 | s->lookahead -= s->prev_length-1; |
| 927 | s->prev_length -= 2; | 961 | s->prev_length -= 2; |
| 928 | do { | 962 | do { |
| 929 | s->strstart++; | 963 | if (++s->strstart <= max_insert) { |
| 930 | INSERT_STRING(s, s->strstart, hash_head); | 964 | INSERT_STRING(s, s->strstart, hash_head); |
| 931 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are | 965 | } |
| 932 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | ||
| 933 | * these bytes are garbage, but it does not matter since the | ||
| 934 | * next lookahead bytes will always be emitted as literals. | ||
| 935 | */ | ||
| 936 | } while (--s->prev_length != 0); | 966 | } while (--s->prev_length != 0); |
| 937 | s->match_available = 0; | 967 | s->match_available = 0; |
| 938 | s->match_length = MIN_MATCH-1; | 968 | s->match_length = MIN_MATCH-1; |
| @@ -961,10 +991,13 @@ local int deflate_slow(s, flush) | |||
| 961 | s->lookahead--; | 991 | s->lookahead--; |
| 962 | } | 992 | } |
| 963 | } | 993 | } |
| 994 | Assert (flush != Z_NO_FLUSH, "no flush?"); | ||
| 964 | if (s->match_available) { | 995 | if (s->match_available) { |
| 996 | Tracevv((stderr,"%c", s->window[s->strstart-1])); | ||
| 965 | ct_tally (s, 0, s->window[s->strstart-1]); | 997 | ct_tally (s, 0, s->window[s->strstart-1]); |
| 966 | s->match_available = 0; | 998 | s->match_available = 0; |
| 967 | } | 999 | } |
| 968 | FLUSH_BLOCK(s, flush == Z_FINISH); | 1000 | FLUSH_BLOCK(s, flush == Z_FINISH); |
| 969 | return 0; | 1001 | return 0; |
| 970 | } | 1002 | } |
| 1003 | |||
