diff options
Diffstat (limited to 'deflate.c')
| -rw-r--r-- | deflate.c | 195 |
1 files changed, 104 insertions, 91 deletions
| @@ -47,7 +47,7 @@ | |||
| 47 | * | 47 | * |
| 48 | */ | 48 | */ |
| 49 | 49 | ||
| 50 | /* $Id: deflate.c,v 1.7 1995/05/02 13:28:18 jloup Exp $ */ | 50 | /* $Id: deflate.c,v 1.8 1995/05/03 17:27:08 jloup Exp $ */ |
| 51 | 51 | ||
| 52 | #include "deflate.h" | 52 | #include "deflate.h" |
| 53 | 53 | ||
| @@ -127,7 +127,7 @@ local int read_buf __P((z_stream *strm, char *buf, unsigned size)); | |||
| 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 __P((deflate_state *s, IPos start, IPos match, |
| 130 | int length)); | 130 | int length)); |
| 131 | #endif | 131 | #endif |
| 132 | 132 | ||
| 133 | 133 | ||
| @@ -190,12 +190,12 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) | |||
| 190 | if (level == Z_DEFAULT_COMPRESSION) level = 6; | 190 | if (level == Z_DEFAULT_COMPRESSION) level = 6; |
| 191 | 191 | ||
| 192 | if (windowBits < 0) { /* undocumented feature: suppress zlib header */ | 192 | if (windowBits < 0) { /* undocumented feature: suppress zlib header */ |
| 193 | noheader = 1; | 193 | noheader = 1; |
| 194 | windowBits = -windowBits; | 194 | windowBits = -windowBits; |
| 195 | } | 195 | } |
| 196 | if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || | 196 | if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || |
| 197 | windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { | 197 | windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { |
| 198 | return Z_STREAM_ERROR; | 198 | return Z_STREAM_ERROR; |
| 199 | } | 199 | } |
| 200 | s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); | 200 | s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); |
| 201 | if (s == Z_NULL) return Z_MEM_ERROR; | 201 | if (s == Z_NULL) return Z_MEM_ERROR; |
| @@ -221,10 +221,10 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) | |||
| 221 | s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); | 221 | s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); |
| 222 | 222 | ||
| 223 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || | 223 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || |
| 224 | s->pending_buf == Z_NULL) { | 224 | s->pending_buf == Z_NULL) { |
| 225 | strm->msg = z_errmsg[1-Z_MEM_ERROR]; | 225 | strm->msg = z_errmsg[1-Z_MEM_ERROR]; |
| 226 | deflateEnd (strm); | 226 | deflateEnd (strm); |
| 227 | return Z_MEM_ERROR; | 227 | return Z_MEM_ERROR; |
| 228 | } | 228 | } |
| 229 | s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]); | 229 | s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]); |
| 230 | s->l_buf = (uch*) &(s->pending_buf[3*s->lit_bufsize]); | 230 | s->l_buf = (uch*) &(s->pending_buf[3*s->lit_bufsize]); |
| @@ -247,7 +247,7 @@ int deflateReset (strm) | |||
| 247 | deflate_state *s; | 247 | deflate_state *s; |
| 248 | 248 | ||
| 249 | if (strm == Z_NULL || strm->state == Z_NULL || | 249 | if (strm == Z_NULL || strm->state == Z_NULL || |
| 250 | strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; | 250 | strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; |
| 251 | 251 | ||
| 252 | strm->total_in = strm->total_out = 0; | 252 | strm->total_in = strm->total_out = 0; |
| 253 | strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ | 253 | strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ |
| @@ -297,7 +297,7 @@ local void flush_pending(strm) | |||
| 297 | strm->avail_out -= len; | 297 | strm->avail_out -= len; |
| 298 | strm->state->pending -= len; | 298 | strm->state->pending -= len; |
| 299 | if (strm->state->pending == 0) { | 299 | if (strm->state->pending == 0) { |
| 300 | strm->state->pending_out = strm->state->pending_buf; | 300 | strm->state->pending_out = strm->state->pending_buf; |
| 301 | } | 301 | } |
| 302 | } | 302 | } |
| 303 | 303 | ||
| @@ -309,7 +309,7 @@ int deflate (strm, flush) | |||
| 309 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 309 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
| 310 | 310 | ||
| 311 | if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) { | 311 | if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) { |
| 312 | ERR_RETURN(strm, Z_STREAM_ERROR); | 312 | ERR_RETURN(strm, Z_STREAM_ERROR); |
| 313 | } | 313 | } |
| 314 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); | 314 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); |
| 315 | 315 | ||
| @@ -318,49 +318,49 @@ int deflate (strm, flush) | |||
| 318 | /* Write the zlib header */ | 318 | /* Write the zlib header */ |
| 319 | if (strm->state->status == INIT_STATE) { | 319 | if (strm->state->status == INIT_STATE) { |
| 320 | 320 | ||
| 321 | uInt header = (DEFLATED + ((strm->state->w_bits-8)<<4)) << 8; | 321 | uInt header = (DEFLATED + ((strm->state->w_bits-8)<<4)) << 8; |
| 322 | uInt level_flags = (strm->state->level-1) >> 1; | 322 | uInt level_flags = (strm->state->level-1) >> 1; |
| 323 | 323 | ||
| 324 | if (level_flags > 3) level_flags = 3; | 324 | if (level_flags > 3) level_flags = 3; |
| 325 | header |= (level_flags << 6); | 325 | header |= (level_flags << 6); |
| 326 | header += 31 - (header % 31); | 326 | header += 31 - (header % 31); |
| 327 | 327 | ||
| 328 | strm->state->status = BUSY_STATE; | 328 | strm->state->status = BUSY_STATE; |
| 329 | putShortMSB(strm->state, header); | 329 | putShortMSB(strm->state, header); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /* Flush as much pending output as possible */ | 332 | /* Flush as much pending output as possible */ |
| 333 | if (strm->state->pending != 0) { | 333 | if (strm->state->pending != 0) { |
| 334 | flush_pending(strm); | 334 | flush_pending(strm); |
| 335 | if (strm->avail_out == 0) return Z_OK; | 335 | if (strm->avail_out == 0) return Z_OK; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | /* User must not provide more input after the first FINISH: */ | 338 | /* User must not provide more input after the first FINISH: */ |
| 339 | if (strm->state->status == FINISH_STATE && strm->avail_in != 0) { | 339 | if (strm->state->status == FINISH_STATE && strm->avail_in != 0) { |
| 340 | ERR_RETURN(strm, Z_BUF_ERROR); | 340 | ERR_RETURN(strm, Z_BUF_ERROR); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | /* Start a new block or continue the current one. | 343 | /* Start a new block or continue the current one. |
| 344 | */ | 344 | */ |
| 345 | if (strm->avail_in != 0 || | 345 | if (strm->avail_in != 0 || |
| 346 | (flush == Z_FINISH && strm->state->status != FINISH_STATE)) { | 346 | (flush == Z_FINISH && strm->state->status != FINISH_STATE)) { |
| 347 | int quit; | 347 | int quit; |
| 348 | 348 | ||
| 349 | if (flush == Z_FINISH) { | 349 | if (flush == Z_FINISH) { |
| 350 | strm->state->status = FINISH_STATE; | 350 | strm->state->status = FINISH_STATE; |
| 351 | } | 351 | } |
| 352 | if (strm->state->level <= 3) { | 352 | if (strm->state->level <= 3) { |
| 353 | quit = deflate_fast(strm->state, flush); | 353 | quit = deflate_fast(strm->state, flush); |
| 354 | } else { | 354 | } else { |
| 355 | quit = deflate_slow(strm->state, flush); | 355 | quit = deflate_slow(strm->state, flush); |
| 356 | } | 356 | } |
| 357 | if (flush == Z_FULL_FLUSH) { | 357 | if (flush == Z_FULL_FLUSH) { |
| 358 | ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */ | 358 | ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */ |
| 359 | flush_pending(strm); | 359 | flush_pending(strm); |
| 360 | CLEAR_HASH(strm->state); /* forget history */ | 360 | CLEAR_HASH(strm->state); /* forget history */ |
| 361 | if (strm->avail_out == 0) return Z_OK; | 361 | if (strm->avail_out == 0) return Z_OK; |
| 362 | } | 362 | } |
| 363 | if (quit) return Z_OK; | 363 | if (quit) return Z_OK; |
| 364 | } | 364 | } |
| 365 | Assert(strm->avail_out > 0, "bug2"); | 365 | Assert(strm->avail_out > 0, "bug2"); |
| 366 | 366 | ||
| @@ -401,13 +401,13 @@ int deflateCopy (dest, source) | |||
| 401 | z_stream *source; | 401 | z_stream *source; |
| 402 | { | 402 | { |
| 403 | if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { | 403 | if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { |
| 404 | return Z_STREAM_ERROR; | 404 | return Z_STREAM_ERROR; |
| 405 | } | 405 | } |
| 406 | *dest = *source; | 406 | *dest = *source; |
| 407 | return Z_STREAM_ERROR; /* to be implemented */ | 407 | return Z_STREAM_ERROR; /* to be implemented */ |
| 408 | #if 0 | 408 | #if 0 |
| 409 | dest->state = (struct internal_state *) | 409 | dest->state = (struct internal_state *) |
| 410 | (*dest->zalloc)(1, sizeof(deflate_state)); | 410 | (*dest->zalloc)(1, sizeof(deflate_state)); |
| 411 | if (dest->state == Z_NULL) return Z_MEM_ERROR; | 411 | if (dest->state == Z_NULL) return Z_MEM_ERROR; |
| 412 | 412 | ||
| 413 | *(dest->state) = *(source->state); | 413 | *(dest->state) = *(source->state); |
| @@ -432,7 +432,7 @@ local int read_buf(strm, buf, size) | |||
| 432 | strm->avail_in -= len; | 432 | strm->avail_in -= len; |
| 433 | 433 | ||
| 434 | if (!strm->state->noheader) { | 434 | if (!strm->state->noheader) { |
| 435 | strm->state->adler = adler32(strm->state->adler, strm->next_in, len); | 435 | strm->state->adler = adler32(strm->state->adler, strm->next_in, len); |
| 436 | } | 436 | } |
| 437 | zmemcpy(buf, strm->next_in, len); | 437 | zmemcpy(buf, strm->next_in, len); |
| 438 | strm->next_in += len; | 438 | strm->next_in += len; |
| @@ -488,7 +488,7 @@ local void lm_init (s) | |||
| 488 | /* For 80x86 and 680x0, an optimized version will be provided in match.asm or | 488 | /* For 80x86 and 680x0, an optimized version will be provided in match.asm or |
| 489 | * match.S. The code will be functionally equivalent. | 489 | * match.S. The code will be functionally equivalent. |
| 490 | */ | 490 | */ |
| 491 | local int longest_match(s, cur_match) | 491 | local INLINE int longest_match(s, cur_match) |
| 492 | deflate_state *s; | 492 | deflate_state *s; |
| 493 | IPos cur_match; /* current match */ | 493 | IPos cur_match; /* current match */ |
| 494 | { | 494 | { |
| @@ -498,10 +498,12 @@ local int longest_match(s, cur_match) | |||
| 498 | register int len; /* length of current match */ | 498 | register int len; /* length of current match */ |
| 499 | int best_len = s->prev_length; /* best match length so far */ | 499 | int best_len = s->prev_length; /* best match length so far */ |
| 500 | IPos limit = s->strstart > (IPos)MAX_DIST(s) ? | 500 | IPos limit = s->strstart > (IPos)MAX_DIST(s) ? |
| 501 | s->strstart - (IPos)MAX_DIST(s) : NIL; | 501 | s->strstart - (IPos)MAX_DIST(s) : NIL; |
| 502 | /* Stop when cur_match becomes <= limit. To simplify the code, | 502 | /* Stop when cur_match becomes <= limit. To simplify the code, |
| 503 | * we prevent matches with the string of window index 0. | 503 | * we prevent matches with the string of window index 0. |
| 504 | */ | 504 | */ |
| 505 | Pos *prev = s->prev; | ||
| 506 | uInt wmask = s->w_mask; | ||
| 505 | 507 | ||
| 506 | #ifdef UNALIGNED_OK | 508 | #ifdef UNALIGNED_OK |
| 507 | /* Compare two bytes at a time. Note: this is not always beneficial. | 509 | /* Compare two bytes at a time. Note: this is not always beneficial. |
| @@ -609,7 +611,7 @@ local int longest_match(s, cur_match) | |||
| 609 | scan_end = scan[best_len]; | 611 | scan_end = scan[best_len]; |
| 610 | #endif | 612 | #endif |
| 611 | } | 613 | } |
| 612 | } while ((cur_match = s->prev[cur_match & s->w_mask]) > limit | 614 | } while ((cur_match = prev[cur_match & wmask]) > limit |
| 613 | && --chain_length != 0); | 615 | && --chain_length != 0); |
| 614 | 616 | ||
| 615 | return best_len; | 617 | return best_len; |
| @@ -634,8 +636,8 @@ local void check_match(s, start, match, length) | |||
| 634 | z_error("invalid match"); | 636 | z_error("invalid match"); |
| 635 | } | 637 | } |
| 636 | if (verbose > 1) { | 638 | if (verbose > 1) { |
| 637 | fprintf(stderr,"\\[%d,%d]", start-match, length); | 639 | fprintf(stderr,"\\[%d,%d]", start-match, length); |
| 638 | do { putc(s->window[start++], stderr); } while (--length != 0); | 640 | do { putc(s->window[start++], stderr); } while (--length != 0); |
| 639 | } | 641 | } |
| 640 | } | 642 | } |
| 641 | #else | 643 | #else |
| @@ -656,14 +658,16 @@ local void fill_window(s) | |||
| 656 | deflate_state *s; | 658 | deflate_state *s; |
| 657 | { | 659 | { |
| 658 | register unsigned n, m; | 660 | register unsigned n, m; |
| 661 | register Pos *p; | ||
| 659 | unsigned more; /* Amount of free space at the end of the window. */ | 662 | unsigned more; /* Amount of free space at the end of the window. */ |
| 663 | uInt wsize = s->w_size; | ||
| 660 | 664 | ||
| 661 | do { | 665 | do { |
| 662 | more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); | 666 | more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); |
| 663 | 667 | ||
| 664 | /* Deal with !@#$% 64K limit: */ | 668 | /* Deal with !@#$% 64K limit: */ |
| 665 | if (more == 0 && s->strstart == 0 && s->lookahead == 0) { | 669 | if (more == 0 && s->strstart == 0 && s->lookahead == 0) { |
| 666 | more = s->w_size; | 670 | more = wsize; |
| 667 | } else if (more == (unsigned)(-1)) { | 671 | } else if (more == (unsigned)(-1)) { |
| 668 | /* Very unlikely, but possible on 16 bit machine if strstart == 0 | 672 | /* Very unlikely, but possible on 16 bit machine if strstart == 0 |
| 669 | * and lookahead == 1 (input done one byte at time) | 673 | * and lookahead == 1 (input done one byte at time) |
| @@ -673,30 +677,39 @@ local void fill_window(s) | |||
| 673 | /* If the window is almost full and there is insufficient lookahead, | 677 | /* If the window is almost full and there is insufficient lookahead, |
| 674 | * move the upper half to the lower one to make room in the upper half. | 678 | * move the upper half to the lower one to make room in the upper half. |
| 675 | */ | 679 | */ |
| 676 | } else if (s->strstart >= s->w_size+MAX_DIST(s)) { | 680 | } else if (s->strstart >= wsize+MAX_DIST(s)) { |
| 677 | 681 | ||
| 678 | /* By the IN assertion, the window is not empty so we can't confuse | 682 | /* By the IN assertion, the window is not empty so we can't confuse |
| 679 | * more == 0 with more == 64K on a 16 bit machine. | 683 | * more == 0 with more == 64K on a 16 bit machine. |
| 680 | */ | 684 | */ |
| 681 | memcpy((char*)s->window, (char*)s->window+s->w_size, | 685 | zmemcpy((char*)s->window, (char*)s->window+wsize, |
| 682 | (unsigned)s->w_size); | 686 | (unsigned)wsize); |
| 683 | s->match_start -= s->w_size; | 687 | s->match_start -= wsize; |
| 684 | s->strstart -= s->w_size; /* we now have strstart >= MAX_DIST */ | 688 | s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
| 685 | 689 | ||
| 686 | s->block_start -= (long) s->w_size; | 690 | s->block_start -= (long) wsize; |
| 687 | 691 | ||
| 688 | for (n = 0; n < s->hash_size; n++) { | 692 | /* Slide the hash table (could be avoided with 32 bit values |
| 689 | m = s->head[n]; | 693 | at the expense of memory usage): |
| 690 | s->head[n] = (Pos)(m >= s->w_size ? m-s->w_size : NIL); | 694 | */ |
| 691 | } | 695 | n = s->hash_size; |
| 692 | for (n = 0; n < s->w_size; n++) { | 696 | p = &s->head[n-1]; |
| 693 | m = s->prev[n]; | 697 | do { |
| 694 | s->prev[n] = (Pos)(m >= s->w_size ? m-s->w_size : NIL); | 698 | m = *p; |
| 699 | *p-- = (Pos)(m >= wsize ? m-wsize : NIL); | ||
| 700 | } while (--n); | ||
| 701 | |||
| 702 | n = wsize; | ||
| 703 | p = &s->prev[n-1]; | ||
| 704 | do { | ||
| 705 | m = *p; | ||
| 706 | *p-- = (Pos)(m >= wsize ? m-wsize : NIL); | ||
| 695 | /* If n is not on any hash chain, prev[n] is garbage but | 707 | /* If n is not on any hash chain, prev[n] is garbage but |
| 696 | * its value will never be used. | 708 | * its value will never be used. |
| 697 | */ | 709 | */ |
| 698 | } | 710 | } while (--n); |
| 699 | more += s->w_size; | 711 | |
| 712 | more += wsize; | ||
| 700 | } | 713 | } |
| 701 | if (s->strm->avail_in == 0) return; | 714 | if (s->strm->avail_in == 0) return; |
| 702 | 715 | ||
| @@ -714,8 +727,8 @@ local void fill_window(s) | |||
| 714 | Assert(more >= 2, "more < 2"); | 727 | Assert(more >= 2, "more < 2"); |
| 715 | 728 | ||
| 716 | n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead, | 729 | n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead, |
| 717 | more); | 730 | more); |
| 718 | s->lookahead += n; | 731 | s->lookahead += n; |
| 719 | 732 | ||
| 720 | } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); | 733 | } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); |
| 721 | } | 734 | } |
| @@ -726,7 +739,7 @@ local void fill_window(s) | |||
| 726 | */ | 739 | */ |
| 727 | #define FLUSH_BLOCK_ONLY(s, eof) { \ | 740 | #define FLUSH_BLOCK_ONLY(s, eof) { \ |
| 728 | ct_flush_block(s, (s->block_start >= 0L ? \ | 741 | ct_flush_block(s, (s->block_start >= 0L ? \ |
| 729 | (char*)&s->window[(unsigned)s->block_start] : \ | 742 | (char*)&s->window[(unsigned)s->block_start] : \ |
| 730 | (char*)Z_NULL), (long)s->strstart - s->block_start, (eof)); \ | 743 | (char*)Z_NULL), (long)s->strstart - s->block_start, (eof)); \ |
| 731 | s->block_start = s->strstart; \ | 744 | s->block_start = s->strstart; \ |
| 732 | flush_pending(s->strm); \ | 745 | flush_pending(s->strm); \ |
| @@ -761,11 +774,11 @@ local int deflate_fast(s, flush) | |||
| 761 | * string following the next match. | 774 | * string following the next match. |
| 762 | */ | 775 | */ |
| 763 | if (s->lookahead < MIN_LOOKAHEAD) { | 776 | if (s->lookahead < MIN_LOOKAHEAD) { |
| 764 | fill_window(s); | 777 | fill_window(s); |
| 765 | if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; | 778 | if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; |
| 766 | 779 | ||
| 767 | if (s->lookahead == 0) break; /* flush the current block */ | 780 | if (s->lookahead == 0) break; /* flush the current block */ |
| 768 | } | 781 | } |
| 769 | 782 | ||
| 770 | /* Insert the string window[strstart .. strstart+2] in the | 783 | /* Insert the string window[strstart .. strstart+2] in the |
| 771 | * dictionary, and set hash_head to the head of the hash chain: | 784 | * dictionary, and set hash_head to the head of the hash chain: |
| @@ -780,9 +793,9 @@ local int deflate_fast(s, flush) | |||
| 780 | * of window index 0 (in particular we have to avoid a match | 793 | * of window index 0 (in particular we have to avoid a match |
| 781 | * of the string with itself at the start of the input file). | 794 | * of the string with itself at the start of the input file). |
| 782 | */ | 795 | */ |
| 783 | if (s->strategy != Z_HUFFMAN_ONLY) { | 796 | if (s->strategy != Z_HUFFMAN_ONLY) { |
| 784 | s->match_length = longest_match (s, hash_head); | 797 | s->match_length = longest_match (s, hash_head); |
| 785 | } | 798 | } |
| 786 | /* longest_match() sets match_start */ | 799 | /* longest_match() sets match_start */ |
| 787 | 800 | ||
| 788 | if (s->match_length > s->lookahead) s->match_length = s->lookahead; | 801 | if (s->match_length > s->lookahead) s->match_length = s->lookahead; |
| @@ -791,7 +804,7 @@ local int deflate_fast(s, flush) | |||
| 791 | check_match(s, s->strstart, s->match_start, s->match_length); | 804 | check_match(s, s->strstart, s->match_start, s->match_length); |
| 792 | 805 | ||
| 793 | bflush = ct_tally(s, s->strstart - s->match_start, | 806 | bflush = ct_tally(s, s->strstart - s->match_start, |
| 794 | s->match_length - MIN_MATCH); | 807 | s->match_length - MIN_MATCH); |
| 795 | 808 | ||
| 796 | s->lookahead -= s->match_length; | 809 | s->lookahead -= s->match_length; |
| 797 | 810 | ||
| @@ -852,11 +865,11 @@ local int deflate_slow(s, flush) | |||
| 852 | * string following the next match. | 865 | * string following the next match. |
| 853 | */ | 866 | */ |
| 854 | if (s->lookahead < MIN_LOOKAHEAD) { | 867 | if (s->lookahead < MIN_LOOKAHEAD) { |
| 855 | fill_window(s); | 868 | fill_window(s); |
| 856 | if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; | 869 | if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; |
| 857 | 870 | ||
| 858 | if (s->lookahead == 0) break; /* flush the current block */ | 871 | if (s->lookahead == 0) break; /* flush the current block */ |
| 859 | } | 872 | } |
| 860 | 873 | ||
| 861 | /* Insert the string window[strstart .. strstart+2] in the | 874 | /* Insert the string window[strstart .. strstart+2] in the |
| 862 | * dictionary, and set hash_head to the head of the hash chain: | 875 | * dictionary, and set hash_head to the head of the hash chain: |
| @@ -874,15 +887,15 @@ local int deflate_slow(s, flush) | |||
| 874 | * of window index 0 (in particular we have to avoid a match | 887 | * of window index 0 (in particular we have to avoid a match |
| 875 | * of the string with itself at the start of the input file). | 888 | * of the string with itself at the start of the input file). |
| 876 | */ | 889 | */ |
| 877 | if (s->strategy != Z_HUFFMAN_ONLY) { | 890 | if (s->strategy != Z_HUFFMAN_ONLY) { |
| 878 | s->match_length = longest_match (s, hash_head); | 891 | s->match_length = longest_match (s, hash_head); |
| 879 | } | 892 | } |
| 880 | /* longest_match() sets match_start */ | 893 | /* longest_match() sets match_start */ |
| 881 | if (s->match_length > s->lookahead) s->match_length = s->lookahead; | 894 | if (s->match_length > s->lookahead) s->match_length = s->lookahead; |
| 882 | 895 | ||
| 883 | if (s->match_length <= 5 && (s->strategy == Z_FILTERED || | 896 | if (s->match_length <= 5 && (s->strategy == Z_FILTERED || |
| 884 | (s->match_length == MIN_MATCH && | 897 | (s->match_length == MIN_MATCH && |
| 885 | s->strstart - s->match_start > TOO_FAR))) { | 898 | s->strstart - s->match_start > TOO_FAR))) { |
| 886 | 899 | ||
| 887 | /* If prev_match is also MIN_MATCH, match_start is garbage | 900 | /* If prev_match is also MIN_MATCH, match_start is garbage |
| 888 | * but we will ignore the current match anyway. | 901 | * but we will ignore the current match anyway. |
| @@ -898,7 +911,7 @@ local int deflate_slow(s, flush) | |||
| 898 | check_match(s, s->strstart-1, s->prev_match, s->prev_length); | 911 | check_match(s, s->strstart-1, s->prev_match, s->prev_length); |
| 899 | 912 | ||
| 900 | bflush = ct_tally(s, s->strstart -1 - s->prev_match, | 913 | bflush = ct_tally(s, s->strstart -1 - s->prev_match, |
| 901 | s->prev_length - MIN_MATCH); | 914 | s->prev_length - MIN_MATCH); |
| 902 | 915 | ||
| 903 | /* Insert in hash table all strings up to the end of the match. | 916 | /* Insert in hash table all strings up to the end of the match. |
| 904 | * strstart-1 and strstart are already inserted. | 917 | * strstart-1 and strstart are already inserted. |
| @@ -927,11 +940,11 @@ local int deflate_slow(s, flush) | |||
| 927 | */ | 940 | */ |
| 928 | Tracevv((stderr,"%c", s->window[s->strstart-1])); | 941 | Tracevv((stderr,"%c", s->window[s->strstart-1])); |
| 929 | if (ct_tally (s, 0, s->window[s->strstart-1])) { | 942 | if (ct_tally (s, 0, s->window[s->strstart-1])) { |
| 930 | FLUSH_BLOCK_ONLY(s, 0); | 943 | FLUSH_BLOCK_ONLY(s, 0); |
| 931 | } | 944 | } |
| 932 | s->strstart++; | 945 | s->strstart++; |
| 933 | s->lookahead--; | 946 | s->lookahead--; |
| 934 | if (s->strm->avail_out == 0) return 1; | 947 | if (s->strm->avail_out == 0) return 1; |
| 935 | } else { | 948 | } else { |
| 936 | /* There is no previous match to compare with, wait for | 949 | /* There is no previous match to compare with, wait for |
| 937 | * the next step to decide. | 950 | * the next step to decide. |
| @@ -942,8 +955,8 @@ local int deflate_slow(s, flush) | |||
| 942 | } | 955 | } |
| 943 | } | 956 | } |
| 944 | if (s->match_available) { | 957 | if (s->match_available) { |
| 945 | ct_tally (s, 0, s->window[s->strstart-1]); | 958 | ct_tally (s, 0, s->window[s->strstart-1]); |
| 946 | s->match_available = 0; | 959 | s->match_available = 0; |
| 947 | } | 960 | } |
| 948 | FLUSH_BLOCK(s, flush == Z_FINISH); | 961 | FLUSH_BLOCK(s, flush == Z_FINISH); |
| 949 | return 0; | 962 | return 0; |
