00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "deflate.h"
00053
00054 const char deflate_copyright[] =
00055 " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 typedef enum {
00067 need_more,
00068 block_done,
00069 finish_started,
00070 finish_done
00071 } block_state;
00072
00073 typedef block_state (*compress_func) OF((deflate_state *s, int flush));
00074
00075
00076 local void fill_window OF((deflate_state *s));
00077 local block_state deflate_stored OF((deflate_state *s, int flush));
00078 local block_state deflate_fast OF((deflate_state *s, int flush));
00079 #ifndef FASTEST
00080 local block_state deflate_slow OF((deflate_state *s, int flush));
00081 #endif
00082 local void lm_init OF((deflate_state *s));
00083 local void putShortMSB OF((deflate_state *s, uInt b));
00084 local void flush_pending OF((z_streamp strm));
00085 local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
00086 #ifndef FASTEST
00087 #ifdef ASMV
00088 void match_init OF((void));
00089 uInt longest_match OF((deflate_state *s, IPos cur_match));
00090 #else
00091 local uInt longest_match OF((deflate_state *s, IPos cur_match));
00092 #endif
00093 #endif
00094 local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
00095
00096 #ifdef DEBUG
00097 local void check_match OF((deflate_state *s, IPos start, IPos match,
00098 int length));
00099 #endif
00100
00101
00102
00103
00104
00105 #define NIL 0
00106
00107
00108 #ifndef TOO_FAR
00109 # define TOO_FAR 4096
00110 #endif
00111
00112
00113 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 typedef struct config_s {
00124 ush good_length;
00125 ush max_lazy;
00126 ush nice_length;
00127 ush max_chain;
00128 compress_func func;
00129 } config;
00130
00131 #ifdef FASTEST
00132 local const config configuration_table[2] = {
00133
00134 {0, 0, 0, 0, deflate_stored},
00135 {4, 4, 8, 4, deflate_fast}};
00136 #else
00137 local const config configuration_table[10] = {
00138
00139 {0, 0, 0, 0, deflate_stored},
00140 {4, 4, 8, 4, deflate_fast},
00141 {4, 5, 16, 8, deflate_fast},
00142 {4, 6, 32, 32, deflate_fast},
00143
00144 {4, 4, 16, 16, deflate_slow},
00145 {8, 16, 32, 32, deflate_slow},
00146 {8, 16, 128, 128, deflate_slow},
00147 {8, 32, 128, 256, deflate_slow},
00148 {32, 128, 258, 1024, deflate_slow},
00149 {32, 258, 258, 4096, deflate_slow}};
00150 #endif
00151
00152
00153
00154
00155
00156
00157 #define EQUAL 0
00158
00159
00160 #ifndef NO_DUMMY_DECL
00161 struct static_tree_desc_s {int dummy;};
00162 #endif
00163
00164
00165
00166
00167
00168
00169
00170 #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 #ifdef FASTEST
00184 #define INSERT_STRING(s, str, match_head) \
00185 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
00186 match_head = s->head[s->ins_h], \
00187 s->head[s->ins_h] = (Pos)(str))
00188 #else
00189 #define INSERT_STRING(s, str, match_head) \
00190 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
00191 match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
00192 s->head[s->ins_h] = (Pos)(str))
00193 #endif
00194
00195
00196
00197
00198
00199 #define CLEAR_HASH(s) \
00200 s->head[s->hash_size-1] = NIL; \
00201 zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
00202
00203
00204 int ZEXPORT deflateInit_(strm, level, version, stream_size)
00205 z_streamp strm;
00206 int level;
00207 const char *version;
00208 int stream_size;
00209 {
00210 return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
00211 Z_DEFAULT_STRATEGY, version, stream_size);
00212
00213 }
00214
00215
00216 int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
00217 version, stream_size)
00218 z_streamp strm;
00219 int level;
00220 int method;
00221 int windowBits;
00222 int memLevel;
00223 int strategy;
00224 const char *version;
00225 int stream_size;
00226 {
00227 deflate_state *s;
00228 int wrap = 1;
00229 static const char my_version[] = ZLIB_VERSION;
00230
00231 ushf *overlay;
00232
00233
00234
00235
00236 if (version == Z_NULL || version[0] != my_version[0] ||
00237 stream_size != sizeof(z_stream)) {
00238 return Z_VERSION_ERROR;
00239 }
00240 if (strm == Z_NULL) return Z_STREAM_ERROR;
00241
00242 strm->msg = Z_NULL;
00243 if (strm->zalloc == (alloc_func)0) {
00244 strm->zalloc = zcalloc;
00245 strm->opaque = (voidpf)0;
00246 }
00247 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
00248
00249 #ifdef FASTEST
00250 if (level != 0) level = 1;
00251 #else
00252 if (level == Z_DEFAULT_COMPRESSION) level = 6;
00253 #endif
00254
00255 if (windowBits < 0) {
00256 wrap = 0;
00257 windowBits = -windowBits;
00258 }
00259 #ifdef GZIP
00260 else if (windowBits > 15) {
00261 wrap = 2;
00262 windowBits -= 16;
00263 }
00264 #endif
00265 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
00266 windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
00267 strategy < 0 || strategy > Z_FIXED) {
00268 return Z_STREAM_ERROR;
00269 }
00270 if (windowBits == 8) windowBits = 9;
00271 s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
00272 if (s == Z_NULL) return Z_MEM_ERROR;
00273 strm->state = (struct internal_state FAR *)s;
00274 s->strm = strm;
00275
00276 s->wrap = wrap;
00277 s->gzhead = Z_NULL;
00278 s->w_bits = windowBits;
00279 s->w_size = 1 << s->w_bits;
00280 s->w_mask = s->w_size - 1;
00281
00282 s->hash_bits = memLevel + 7;
00283 s->hash_size = 1 << s->hash_bits;
00284 s->hash_mask = s->hash_size - 1;
00285 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
00286
00287 s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
00288 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
00289 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
00290
00291 s->lit_bufsize = 1 << (memLevel + 6);
00292
00293 overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
00294 s->pending_buf = (uchf *) overlay;
00295 s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
00296
00297 if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
00298 s->pending_buf == Z_NULL) {
00299 s->status = FINISH_STATE;
00300 strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
00301 deflateEnd (strm);
00302 return Z_MEM_ERROR;
00303 }
00304 s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
00305 s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
00306
00307 s->level = level;
00308 s->strategy = strategy;
00309 s->method = (Byte)method;
00310
00311 return deflateReset(strm);
00312 }
00313
00314
00315 int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
00316 z_streamp strm;
00317 const Bytef *dictionary;
00318 uInt dictLength;
00319 {
00320 deflate_state *s;
00321 uInt length = dictLength;
00322 uInt n;
00323 IPos hash_head = 0;
00324
00325 if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
00326 strm->state->wrap == 2 ||
00327 (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
00328 return Z_STREAM_ERROR;
00329
00330 s = strm->state;
00331 if (s->wrap)
00332 strm->adler = adler32(strm->adler, dictionary, dictLength);
00333
00334 if (length < MIN_MATCH) return Z_OK;
00335 if (length > MAX_DIST(s)) {
00336 length = MAX_DIST(s);
00337 dictionary += dictLength - length;
00338 }
00339 zmemcpy(s->window, dictionary, length);
00340 s->strstart = length;
00341 s->block_start = (long)length;
00342
00343
00344
00345
00346
00347 s->ins_h = s->window[0];
00348 UPDATE_HASH(s, s->ins_h, s->window[1]);
00349 for (n = 0; n <= length - MIN_MATCH; n++) {
00350 INSERT_STRING(s, n, hash_head);
00351 }
00352 if (hash_head) hash_head = 0;
00353 return Z_OK;
00354 }
00355
00356
00357 int ZEXPORT deflateReset (strm)
00358 z_streamp strm;
00359 {
00360 deflate_state *s;
00361
00362 if (strm == Z_NULL || strm->state == Z_NULL ||
00363 strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
00364 return Z_STREAM_ERROR;
00365 }
00366
00367 strm->total_in = strm->total_out = 0;
00368 strm->msg = Z_NULL;
00369 strm->data_type = Z_UNKNOWN;
00370
00371 s = (deflate_state *)strm->state;
00372 s->pending = 0;
00373 s->pending_out = s->pending_buf;
00374
00375 if (s->wrap < 0) {
00376 s->wrap = -s->wrap;
00377 }
00378 s->status = s->wrap ? INIT_STATE : BUSY_STATE;
00379 strm->adler =
00380 #ifdef GZIP
00381 s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
00382 #endif
00383 adler32(0L, Z_NULL, 0);
00384 s->last_flush = Z_NO_FLUSH;
00385
00386 _tr_init(s);
00387 lm_init(s);
00388
00389 return Z_OK;
00390 }
00391
00392
00393 int ZEXPORT deflateSetHeader (strm, head)
00394 z_streamp strm;
00395 gz_headerp head;
00396 {
00397 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00398 if (strm->state->wrap != 2) return Z_STREAM_ERROR;
00399 strm->state->gzhead = head;
00400 return Z_OK;
00401 }
00402
00403
00404 int ZEXPORT deflatePrime (strm, bits, value)
00405 z_streamp strm;
00406 int bits;
00407 int value;
00408 {
00409 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00410 strm->state->bi_valid = bits;
00411 strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
00412 return Z_OK;
00413 }
00414
00415
00416 int ZEXPORT deflateParams(strm, level, strategy)
00417 z_streamp strm;
00418 int level;
00419 int strategy;
00420 {
00421 deflate_state *s;
00422 compress_func func;
00423 int err = Z_OK;
00424
00425 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00426 s = strm->state;
00427
00428 #ifdef FASTEST
00429 if (level != 0) level = 1;
00430 #else
00431 if (level == Z_DEFAULT_COMPRESSION) level = 6;
00432 #endif
00433 if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
00434 return Z_STREAM_ERROR;
00435 }
00436 func = configuration_table[s->level].func;
00437
00438 if (func != configuration_table[level].func && strm->total_in != 0) {
00439
00440 err = deflate(strm, Z_PARTIAL_FLUSH);
00441 }
00442 if (s->level != level) {
00443 s->level = level;
00444 s->max_lazy_match = configuration_table[level].max_lazy;
00445 s->good_match = configuration_table[level].good_length;
00446 s->nice_match = configuration_table[level].nice_length;
00447 s->max_chain_length = configuration_table[level].max_chain;
00448 }
00449 s->strategy = strategy;
00450 return err;
00451 }
00452
00453
00454 int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
00455 z_streamp strm;
00456 int good_length;
00457 int max_lazy;
00458 int nice_length;
00459 int max_chain;
00460 {
00461 deflate_state *s;
00462
00463 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00464 s = strm->state;
00465 s->good_match = good_length;
00466 s->max_lazy_match = max_lazy;
00467 s->nice_match = nice_length;
00468 s->max_chain_length = max_chain;
00469 return Z_OK;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 uLong ZEXPORT deflateBound(strm, sourceLen)
00490 z_streamp strm;
00491 uLong sourceLen;
00492 {
00493 deflate_state *s;
00494 uLong destLen;
00495
00496
00497 destLen = sourceLen +
00498 ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
00499
00500
00501 if (strm == Z_NULL || strm->state == Z_NULL)
00502 return destLen;
00503
00504
00505 s = strm->state;
00506 if (s->w_bits != 15 || s->hash_bits != 8 + 7)
00507 return destLen;
00508
00509
00510 return compressBound(sourceLen);
00511 }
00512
00513
00514
00515
00516
00517
00518 local void putShortMSB (s, b)
00519 deflate_state *s;
00520 uInt b;
00521 {
00522 put_byte(s, (Byte)(b >> 8));
00523 put_byte(s, (Byte)(b & 0xff));
00524 }
00525
00526
00527
00528
00529
00530
00531
00532 local void flush_pending(strm)
00533 z_streamp strm;
00534 {
00535 unsigned len = strm->state->pending;
00536
00537 if (len > strm->avail_out) len = strm->avail_out;
00538 if (len == 0) return;
00539
00540 zmemcpy(strm->next_out, strm->state->pending_out, len);
00541 strm->next_out += len;
00542 strm->state->pending_out += len;
00543 strm->total_out += len;
00544 strm->avail_out -= len;
00545 strm->state->pending -= len;
00546 if (strm->state->pending == 0) {
00547 strm->state->pending_out = strm->state->pending_buf;
00548 }
00549 }
00550
00551
00552 int ZEXPORT deflate (strm, flush)
00553 z_streamp strm;
00554 int flush;
00555 {
00556 int old_flush;
00557 deflate_state *s;
00558
00559 if (strm == Z_NULL || strm->state == Z_NULL ||
00560 flush > Z_FINISH || flush < 0) {
00561 return Z_STREAM_ERROR;
00562 }
00563 s = strm->state;
00564
00565 if (strm->next_out == Z_NULL ||
00566 (strm->next_in == Z_NULL && strm->avail_in != 0) ||
00567 (s->status == FINISH_STATE && flush != Z_FINISH)) {
00568 ERR_RETURN(strm, Z_STREAM_ERROR);
00569 }
00570 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
00571
00572 s->strm = strm;
00573 old_flush = s->last_flush;
00574 s->last_flush = flush;
00575
00576
00577 if (s->status == INIT_STATE) {
00578 #ifdef GZIP
00579 if (s->wrap == 2) {
00580 strm->adler = crc32(0L, Z_NULL, 0);
00581 put_byte(s, 31);
00582 put_byte(s, 139);
00583 put_byte(s, 8);
00584 if (s->gzhead == NULL) {
00585 put_byte(s, 0);
00586 put_byte(s, 0);
00587 put_byte(s, 0);
00588 put_byte(s, 0);
00589 put_byte(s, 0);
00590 put_byte(s, s->level == 9 ? 2 :
00591 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
00592 4 : 0));
00593 put_byte(s, OS_CODE);
00594 s->status = BUSY_STATE;
00595 }
00596 else {
00597 put_byte(s, (s->gzhead->text ? 1 : 0) +
00598 (s->gzhead->hcrc ? 2 : 0) +
00599 (s->gzhead->extra == Z_NULL ? 0 : 4) +
00600 (s->gzhead->name == Z_NULL ? 0 : 8) +
00601 (s->gzhead->comment == Z_NULL ? 0 : 16)
00602 );
00603 put_byte(s, (Byte)(s->gzhead->time & 0xff));
00604 put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
00605 put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
00606 put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
00607 put_byte(s, s->level == 9 ? 2 :
00608 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
00609 4 : 0));
00610 put_byte(s, s->gzhead->os & 0xff);
00611 if (s->gzhead->extra != NULL) {
00612 put_byte(s, s->gzhead->extra_len & 0xff);
00613 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
00614 }
00615 if (s->gzhead->hcrc)
00616 strm->adler = crc32(strm->adler, s->pending_buf,
00617 s->pending);
00618 s->gzindex = 0;
00619 s->status = EXTRA_STATE;
00620 }
00621 }
00622 else
00623 #endif
00624 {
00625 uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
00626 uInt level_flags;
00627
00628 if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
00629 level_flags = 0;
00630 else if (s->level < 6)
00631 level_flags = 1;
00632 else if (s->level == 6)
00633 level_flags = 2;
00634 else
00635 level_flags = 3;
00636 header |= (level_flags << 6);
00637 if (s->strstart != 0) header |= PRESET_DICT;
00638 header += 31 - (header % 31);
00639
00640 s->status = BUSY_STATE;
00641 putShortMSB(s, header);
00642
00643
00644 if (s->strstart != 0) {
00645 putShortMSB(s, (uInt)(strm->adler >> 16));
00646 putShortMSB(s, (uInt)(strm->adler & 0xffff));
00647 }
00648 strm->adler = adler32(0L, Z_NULL, 0);
00649 }
00650 }
00651 #ifdef GZIP
00652 if (s->status == EXTRA_STATE) {
00653 if (s->gzhead->extra != NULL) {
00654 uInt beg = s->pending;
00655
00656 while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
00657 if (s->pending == s->pending_buf_size) {
00658 if (s->gzhead->hcrc && s->pending > beg)
00659 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00660 s->pending - beg);
00661 flush_pending(strm);
00662 beg = s->pending;
00663 if (s->pending == s->pending_buf_size)
00664 break;
00665 }
00666 put_byte(s, s->gzhead->extra[s->gzindex]);
00667 s->gzindex++;
00668 }
00669 if (s->gzhead->hcrc && s->pending > beg)
00670 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00671 s->pending - beg);
00672 if (s->gzindex == s->gzhead->extra_len) {
00673 s->gzindex = 0;
00674 s->status = NAME_STATE;
00675 }
00676 }
00677 else
00678 s->status = NAME_STATE;
00679 }
00680 if (s->status == NAME_STATE) {
00681 if (s->gzhead->name != NULL) {
00682 uInt beg = s->pending;
00683 int val;
00684
00685 do {
00686 if (s->pending == s->pending_buf_size) {
00687 if (s->gzhead->hcrc && s->pending > beg)
00688 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00689 s->pending - beg);
00690 flush_pending(strm);
00691 beg = s->pending;
00692 if (s->pending == s->pending_buf_size) {
00693 val = 1;
00694 break;
00695 }
00696 }
00697 val = s->gzhead->name[s->gzindex++];
00698 put_byte(s, val);
00699 } while (val != 0);
00700 if (s->gzhead->hcrc && s->pending > beg)
00701 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00702 s->pending - beg);
00703 if (val == 0) {
00704 s->gzindex = 0;
00705 s->status = COMMENT_STATE;
00706 }
00707 }
00708 else
00709 s->status = COMMENT_STATE;
00710 }
00711 if (s->status == COMMENT_STATE) {
00712 if (s->gzhead->comment != NULL) {
00713 uInt beg = s->pending;
00714 int val;
00715
00716 do {
00717 if (s->pending == s->pending_buf_size) {
00718 if (s->gzhead->hcrc && s->pending > beg)
00719 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00720 s->pending - beg);
00721 flush_pending(strm);
00722 beg = s->pending;
00723 if (s->pending == s->pending_buf_size) {
00724 val = 1;
00725 break;
00726 }
00727 }
00728 val = s->gzhead->comment[s->gzindex++];
00729 put_byte(s, val);
00730 } while (val != 0);
00731 if (s->gzhead->hcrc && s->pending > beg)
00732 strm->adler = crc32(strm->adler, s->pending_buf + beg,
00733 s->pending - beg);
00734 if (val == 0)
00735 s->status = HCRC_STATE;
00736 }
00737 else
00738 s->status = HCRC_STATE;
00739 }
00740 if (s->status == HCRC_STATE) {
00741 if (s->gzhead->hcrc) {
00742 if (s->pending + 2 > s->pending_buf_size)
00743 flush_pending(strm);
00744 if (s->pending + 2 <= s->pending_buf_size) {
00745 put_byte(s, (Byte)(strm->adler & 0xff));
00746 put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
00747 strm->adler = crc32(0L, Z_NULL, 0);
00748 s->status = BUSY_STATE;
00749 }
00750 }
00751 else
00752 s->status = BUSY_STATE;
00753 }
00754 #endif
00755
00756
00757 if (s->pending != 0) {
00758 flush_pending(strm);
00759 if (strm->avail_out == 0) {
00760
00761
00762
00763
00764
00765
00766 s->last_flush = -1;
00767 return Z_OK;
00768 }
00769
00770
00771
00772
00773
00774 } else if (strm->avail_in == 0 && flush <= old_flush &&
00775 flush != Z_FINISH) {
00776 ERR_RETURN(strm, Z_BUF_ERROR);
00777 }
00778
00779
00780 if (s->status == FINISH_STATE && strm->avail_in != 0) {
00781 ERR_RETURN(strm, Z_BUF_ERROR);
00782 }
00783
00784
00785
00786 if (strm->avail_in != 0 || s->lookahead != 0 ||
00787 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
00788 block_state bstate;
00789
00790 bstate = (*(configuration_table[s->level].func))(s, flush);
00791
00792 if (bstate == finish_started || bstate == finish_done) {
00793 s->status = FINISH_STATE;
00794 }
00795 if (bstate == need_more || bstate == finish_started) {
00796 if (strm->avail_out == 0) {
00797 s->last_flush = -1;
00798 }
00799 return Z_OK;
00800
00801
00802
00803
00804
00805
00806
00807 }
00808 if (bstate == block_done) {
00809 if (flush == Z_PARTIAL_FLUSH) {
00810 _tr_align(s);
00811 } else {
00812 _tr_stored_block(s, (char*)0, 0L, 0);
00813
00814
00815
00816 if (flush == Z_FULL_FLUSH) {
00817 CLEAR_HASH(s);
00818 }
00819 }
00820 flush_pending(strm);
00821 if (strm->avail_out == 0) {
00822 s->last_flush = -1;
00823 return Z_OK;
00824 }
00825 }
00826 }
00827 Assert(strm->avail_out > 0, "bug2");
00828
00829 if (flush != Z_FINISH) return Z_OK;
00830 if (s->wrap <= 0) return Z_STREAM_END;
00831
00832
00833 #ifdef GZIP
00834 if (s->wrap == 2) {
00835 put_byte(s, (Byte)(strm->adler & 0xff));
00836 put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
00837 put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
00838 put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
00839 put_byte(s, (Byte)(strm->total_in & 0xff));
00840 put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
00841 put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
00842 put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
00843 }
00844 else
00845 #endif
00846 {
00847 putShortMSB(s, (uInt)(strm->adler >> 16));
00848 putShortMSB(s, (uInt)(strm->adler & 0xffff));
00849 }
00850 flush_pending(strm);
00851
00852
00853
00854 if (s->wrap > 0) s->wrap = -s->wrap;
00855 return s->pending != 0 ? Z_OK : Z_STREAM_END;
00856 }
00857
00858
00859 int ZEXPORT deflateEnd (strm)
00860 z_streamp strm;
00861 {
00862 int status;
00863
00864 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00865
00866 status = strm->state->status;
00867 if (status != INIT_STATE &&
00868 status != EXTRA_STATE &&
00869 status != NAME_STATE &&
00870 status != COMMENT_STATE &&
00871 status != HCRC_STATE &&
00872 status != BUSY_STATE &&
00873 status != FINISH_STATE) {
00874 return Z_STREAM_ERROR;
00875 }
00876
00877
00878 TRY_FREE(strm, strm->state->pending_buf);
00879 TRY_FREE(strm, strm->state->head);
00880 TRY_FREE(strm, strm->state->prev);
00881 TRY_FREE(strm, strm->state->window);
00882
00883 ZFREE(strm, strm->state);
00884 strm->state = Z_NULL;
00885
00886 return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
00887 }
00888
00889
00890
00891
00892
00893
00894 int ZEXPORT deflateCopy (dest, source)
00895 z_streamp dest;
00896 z_streamp source;
00897 {
00898 #ifdef MAXSEG_64K
00899 return Z_STREAM_ERROR;
00900 #else
00901 deflate_state *ds;
00902 deflate_state *ss;
00903 ushf *overlay;
00904
00905
00906 if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
00907 return Z_STREAM_ERROR;
00908 }
00909
00910 ss = source->state;
00911
00912 zmemcpy(dest, source, sizeof(z_stream));
00913
00914 ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
00915 if (ds == Z_NULL) return Z_MEM_ERROR;
00916 dest->state = (struct internal_state FAR *) ds;
00917 zmemcpy(ds, ss, sizeof(deflate_state));
00918 ds->strm = dest;
00919
00920 ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
00921 ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
00922 ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
00923 overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
00924 ds->pending_buf = (uchf *) overlay;
00925
00926 if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
00927 ds->pending_buf == Z_NULL) {
00928 deflateEnd (dest);
00929 return Z_MEM_ERROR;
00930 }
00931
00932 zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
00933 zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
00934 zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
00935 zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
00936
00937 ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
00938 ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
00939 ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
00940
00941 ds->l_desc.dyn_tree = ds->dyn_ltree;
00942 ds->d_desc.dyn_tree = ds->dyn_dtree;
00943 ds->bl_desc.dyn_tree = ds->bl_tree;
00944
00945 return Z_OK;
00946 #endif
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956 local int read_buf(strm, buf, size)
00957 z_streamp strm;
00958 Bytef *buf;
00959 unsigned size;
00960 {
00961 unsigned len = strm->avail_in;
00962
00963 if (len > size) len = size;
00964 if (len == 0) return 0;
00965
00966 strm->avail_in -= len;
00967
00968 if (strm->state->wrap == 1) {
00969 strm->adler = adler32(strm->adler, strm->next_in, len);
00970 }
00971 #ifdef GZIP
00972 else if (strm->state->wrap == 2) {
00973 strm->adler = crc32(strm->adler, strm->next_in, len);
00974 }
00975 #endif
00976 zmemcpy(buf, strm->next_in, len);
00977 strm->next_in += len;
00978 strm->total_in += len;
00979
00980 return (int)len;
00981 }
00982
00983
00984
00985
00986 local void lm_init (s)
00987 deflate_state *s;
00988 {
00989 s->window_size = (ulg)2L*s->w_size;
00990
00991 CLEAR_HASH(s);
00992
00993
00994
00995 s->max_lazy_match = configuration_table[s->level].max_lazy;
00996 s->good_match = configuration_table[s->level].good_length;
00997 s->nice_match = configuration_table[s->level].nice_length;
00998 s->max_chain_length = configuration_table[s->level].max_chain;
00999
01000 s->strstart = 0;
01001 s->block_start = 0L;
01002 s->lookahead = 0;
01003 s->match_length = s->prev_length = MIN_MATCH-1;
01004 s->match_available = 0;
01005 s->ins_h = 0;
01006 #ifndef FASTEST
01007 #ifdef ASMV
01008 match_init();
01009 #endif
01010 #endif
01011 }
01012
01013 #ifndef FASTEST
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 #ifndef ASMV
01024
01025
01026
01027 local uInt longest_match(s, cur_match)
01028 deflate_state *s;
01029 IPos cur_match;
01030 {
01031 unsigned chain_length = s->max_chain_length;
01032 register Bytef *scan = s->window + s->strstart;
01033 register Bytef *match;
01034 register int len;
01035 int best_len = s->prev_length;
01036 int nice_match = s->nice_match;
01037 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
01038 s->strstart - (IPos)MAX_DIST(s) : NIL;
01039
01040
01041
01042 Posf *prev = s->prev;
01043 uInt wmask = s->w_mask;
01044
01045 #ifdef UNALIGNED_OK
01046
01047
01048
01049 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
01050 register ush scan_start = *(ushf*)scan;
01051 register ush scan_end = *(ushf*)(scan+best_len-1);
01052 #else
01053 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
01054 register Byte scan_end1 = scan[best_len-1];
01055 register Byte scan_end = scan[best_len];
01056 #endif
01057
01058
01059
01060
01061 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
01062
01063
01064 if (s->prev_length >= s->good_match) {
01065 chain_length >>= 2;
01066 }
01067
01068
01069
01070 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
01071
01072 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
01073
01074 do {
01075 Assert(cur_match < s->strstart, "no future");
01076 match = s->window + cur_match;
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
01087
01088
01089
01090 if (*(ushf*)(match+best_len-1) != scan_end ||
01091 *(ushf*)match != scan_start) continue;
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 Assert(scan[2] == match[2], "scan[2]?");
01103 scan++, match++;
01104 do {
01105 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
01106 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
01107 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
01108 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
01109 scan < strend);
01110
01111
01112
01113 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
01114 if (*scan == *match) scan++;
01115
01116 len = (MAX_MATCH - 1) - (int)(strend-scan);
01117 scan = strend - (MAX_MATCH-1);
01118
01119 #else
01120
01121 if (match[best_len] != scan_end ||
01122 match[best_len-1] != scan_end1 ||
01123 *match != *scan ||
01124 *++match != scan[1]) continue;
01125
01126
01127
01128
01129
01130
01131
01132 scan += 2, match++;
01133 Assert(*scan == *match, "match[2]?");
01134
01135
01136
01137
01138 do {
01139 } while (*++scan == *++match && *++scan == *++match &&
01140 *++scan == *++match && *++scan == *++match &&
01141 *++scan == *++match && *++scan == *++match &&
01142 *++scan == *++match && *++scan == *++match &&
01143 scan < strend);
01144
01145 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
01146
01147 len = MAX_MATCH - (int)(strend - scan);
01148 scan = strend - MAX_MATCH;
01149
01150 #endif
01151
01152 if (len > best_len) {
01153 s->match_start = cur_match;
01154 best_len = len;
01155 if (len >= nice_match) break;
01156 #ifdef UNALIGNED_OK
01157 scan_end = *(ushf*)(scan+best_len-1);
01158 #else
01159 scan_end1 = scan[best_len-1];
01160 scan_end = scan[best_len];
01161 #endif
01162 }
01163 } while ((cur_match = prev[cur_match & wmask]) > limit
01164 && --chain_length != 0);
01165
01166 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
01167 return s->lookahead;
01168 }
01169 #endif
01170 #endif
01171
01172
01173
01174
01175 local uInt longest_match_fast(s, cur_match)
01176 deflate_state *s;
01177 IPos cur_match;
01178 {
01179 register Bytef *scan = s->window + s->strstart;
01180 register Bytef *match;
01181 register int len;
01182 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
01183
01184
01185
01186
01187 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
01188
01189 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
01190
01191 Assert(cur_match < s->strstart, "no future");
01192
01193 match = s->window + cur_match;
01194
01195
01196
01197 if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
01198
01199
01200
01201
01202
01203
01204
01205 scan += 2, match += 2;
01206 Assert(*scan == *match, "match[2]?");
01207
01208
01209
01210
01211 do {
01212 } while (*++scan == *++match && *++scan == *++match &&
01213 *++scan == *++match && *++scan == *++match &&
01214 *++scan == *++match && *++scan == *++match &&
01215 *++scan == *++match && *++scan == *++match &&
01216 scan < strend);
01217
01218 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
01219
01220 len = MAX_MATCH - (int)(strend - scan);
01221
01222 if (len < MIN_MATCH) return MIN_MATCH - 1;
01223
01224 s->match_start = cur_match;
01225 return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
01226 }
01227
01228 #ifdef DEBUG
01229
01230
01231
01232 local void check_match(s, start, match, length)
01233 deflate_state *s;
01234 IPos start, match;
01235 int length;
01236 {
01237
01238 if (zmemcmp(s->window + match,
01239 s->window + start, length) != EQUAL) {
01240 fprintf(stderr, " start %u, match %u, length %d\n",
01241 start, match, length);
01242 do {
01243 fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
01244 } while (--length != 0);
01245 z_error("invalid match");
01246 }
01247 if (z_verbose > 1) {
01248 fprintf(stderr,"\\[%d,%d]", start-match, length);
01249 do { putc(s->window[start++], stderr); } while (--length != 0);
01250 }
01251 }
01252 #else
01253 # define check_match(s, start, match, length)
01254 #endif
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 local void fill_window(s)
01267 deflate_state *s;
01268 {
01269 register unsigned n, m;
01270 register Posf *p;
01271 unsigned more;
01272 uInt wsize = s->w_size;
01273
01274 do {
01275 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
01276
01277
01278 if (sizeof(int) <= 2) {
01279 if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
01280 more = wsize;
01281
01282 } else if (more == (unsigned)(-1)) {
01283
01284
01285
01286 more--;
01287 }
01288 }
01289
01290
01291
01292
01293 if (s->strstart >= wsize+MAX_DIST(s)) {
01294
01295 zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
01296 s->match_start -= wsize;
01297 s->strstart -= wsize;
01298 s->block_start -= (long) wsize;
01299
01300
01301
01302
01303
01304
01305
01306
01307 n = s->hash_size;
01308 p = &s->head[n];
01309 do {
01310 m = *--p;
01311 *p = (Pos)(m >= wsize ? m-wsize : NIL);
01312 } while (--n);
01313
01314 n = wsize;
01315 #ifndef FASTEST
01316 p = &s->prev[n];
01317 do {
01318 m = *--p;
01319 *p = (Pos)(m >= wsize ? m-wsize : NIL);
01320
01321
01322
01323 } while (--n);
01324 #endif
01325 more += wsize;
01326 }
01327 if (s->strm->avail_in == 0) return;
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 Assert(more >= 2, "more < 2");
01341
01342 n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
01343 s->lookahead += n;
01344
01345
01346 if (s->lookahead >= MIN_MATCH) {
01347 s->ins_h = s->window[s->strstart];
01348 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
01349 #if MIN_MATCH != 3
01350 Call UPDATE_HASH() MIN_MATCH-3 more times
01351 #endif
01352 }
01353
01354
01355
01356
01357 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
01358 }
01359
01360
01361
01362
01363
01364 #define FLUSH_BLOCK_ONLY(s, eof) { \
01365 _tr_flush_block(s, (s->block_start >= 0L ? \
01366 (charf *)&s->window[(unsigned)s->block_start] : \
01367 (charf *)Z_NULL), \
01368 (ulg)((long)s->strstart - s->block_start), \
01369 (eof)); \
01370 s->block_start = s->strstart; \
01371 flush_pending(s->strm); \
01372 Tracev((stderr,"[FLUSH]")); \
01373 }
01374
01375
01376 #define FLUSH_BLOCK(s, eof) { \
01377 FLUSH_BLOCK_ONLY(s, eof); \
01378 if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
01379 }
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390 local block_state deflate_stored(s, flush)
01391 deflate_state *s;
01392 int flush;
01393 {
01394
01395
01396
01397 ulg max_block_size = 0xffff;
01398 ulg max_start;
01399
01400 if (max_block_size > s->pending_buf_size - 5) {
01401 max_block_size = s->pending_buf_size - 5;
01402 }
01403
01404
01405 for (;;) {
01406
01407 if (s->lookahead <= 1) {
01408
01409 Assert(s->strstart < s->w_size+MAX_DIST(s) ||
01410 s->block_start >= (long)s->w_size, "slide too late");
01411
01412 fill_window(s);
01413 if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
01414
01415 if (s->lookahead == 0) break;
01416 }
01417 Assert(s->block_start >= 0L, "block gone");
01418
01419 s->strstart += s->lookahead;
01420 s->lookahead = 0;
01421
01422
01423 max_start = s->block_start + max_block_size;
01424 if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
01425
01426 s->lookahead = (uInt)(s->strstart - max_start);
01427 s->strstart = (uInt)max_start;
01428 FLUSH_BLOCK(s, 0);
01429 }
01430
01431
01432
01433 if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
01434 FLUSH_BLOCK(s, 0);
01435 }
01436 }
01437 FLUSH_BLOCK(s, flush == Z_FINISH);
01438 return flush == Z_FINISH ? finish_done : block_done;
01439 }
01440
01441
01442
01443
01444
01445
01446
01447
01448 local block_state deflate_fast(s, flush)
01449 deflate_state *s;
01450 int flush;
01451 {
01452 IPos hash_head = NIL;
01453 int bflush;
01454
01455 for (;;) {
01456
01457
01458
01459
01460
01461 if (s->lookahead < MIN_LOOKAHEAD) {
01462 fill_window(s);
01463 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
01464 return need_more;
01465 }
01466 if (s->lookahead == 0) break;
01467 }
01468
01469
01470
01471
01472 if (s->lookahead >= MIN_MATCH) {
01473 INSERT_STRING(s, s->strstart, hash_head);
01474 }
01475
01476
01477
01478
01479 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
01480
01481
01482
01483
01484 #ifdef FASTEST
01485 if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
01486 (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
01487 s->match_length = longest_match_fast (s, hash_head);
01488 }
01489 #else
01490 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
01491 s->match_length = longest_match (s, hash_head);
01492 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
01493 s->match_length = longest_match_fast (s, hash_head);
01494 }
01495 #endif
01496
01497 }
01498 if (s->match_length >= MIN_MATCH) {
01499 check_match(s, s->strstart, s->match_start, s->match_length);
01500
01501 _tr_tally_dist(s, s->strstart - s->match_start,
01502 s->match_length - MIN_MATCH, bflush);
01503
01504 s->lookahead -= s->match_length;
01505
01506
01507
01508
01509 #ifndef FASTEST
01510 if (s->match_length <= s->max_insert_length &&
01511 s->lookahead >= MIN_MATCH) {
01512 s->match_length--;
01513 do {
01514 s->strstart++;
01515 INSERT_STRING(s, s->strstart, hash_head);
01516
01517
01518
01519 } while (--s->match_length != 0);
01520 s->strstart++;
01521 } else
01522 #endif
01523 {
01524 s->strstart += s->match_length;
01525 s->match_length = 0;
01526 s->ins_h = s->window[s->strstart];
01527 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
01528 #if MIN_MATCH != 3
01529 Call UPDATE_HASH() MIN_MATCH-3 more times
01530 #endif
01531
01532
01533
01534 }
01535 } else {
01536
01537 Tracevv((stderr,"%c", s->window[s->strstart]));
01538 _tr_tally_lit (s, s->window[s->strstart], bflush);
01539 s->lookahead--;
01540 s->strstart++;
01541 }
01542 if (bflush) FLUSH_BLOCK(s, 0);
01543 }
01544 FLUSH_BLOCK(s, flush == Z_FINISH);
01545 return flush == Z_FINISH ? finish_done : block_done;
01546 }
01547
01548 #ifndef FASTEST
01549
01550
01551
01552
01553
01554 local block_state deflate_slow(s, flush)
01555 deflate_state *s;
01556 int flush;
01557 {
01558 IPos hash_head = NIL;
01559 int bflush;
01560
01561
01562 for (;;) {
01563
01564
01565
01566
01567
01568 if (s->lookahead < MIN_LOOKAHEAD) {
01569 fill_window(s);
01570 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
01571 return need_more;
01572 }
01573 if (s->lookahead == 0) break;
01574 }
01575
01576
01577
01578
01579 if (s->lookahead >= MIN_MATCH) {
01580 INSERT_STRING(s, s->strstart, hash_head);
01581 }
01582
01583
01584
01585 s->prev_length = s->match_length, s->prev_match = s->match_start;
01586 s->match_length = MIN_MATCH-1;
01587
01588 if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
01589 s->strstart - hash_head <= MAX_DIST(s)) {
01590
01591
01592
01593
01594 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
01595 s->match_length = longest_match (s, hash_head);
01596 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
01597 s->match_length = longest_match_fast (s, hash_head);
01598 }
01599
01600
01601 if (s->match_length <= 5 && (s->strategy == Z_FILTERED
01602 #if TOO_FAR <= 32767
01603 || (s->match_length == MIN_MATCH &&
01604 s->strstart - s->match_start > TOO_FAR)
01605 #endif
01606 )) {
01607
01608
01609
01610
01611 s->match_length = MIN_MATCH-1;
01612 }
01613 }
01614
01615
01616
01617 if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
01618 uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
01619
01620
01621 check_match(s, s->strstart-1, s->prev_match, s->prev_length);
01622
01623 _tr_tally_dist(s, s->strstart -1 - s->prev_match,
01624 s->prev_length - MIN_MATCH, bflush);
01625
01626
01627
01628
01629
01630
01631 s->lookahead -= s->prev_length-1;
01632 s->prev_length -= 2;
01633 do {
01634 if (++s->strstart <= max_insert) {
01635 INSERT_STRING(s, s->strstart, hash_head);
01636 }
01637 } while (--s->prev_length != 0);
01638 s->match_available = 0;
01639 s->match_length = MIN_MATCH-1;
01640 s->strstart++;
01641
01642 if (bflush) FLUSH_BLOCK(s, 0);
01643
01644 } else if (s->match_available) {
01645
01646
01647
01648
01649 Tracevv((stderr,"%c", s->window[s->strstart-1]));
01650 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
01651 if (bflush) {
01652 FLUSH_BLOCK_ONLY(s, 0);
01653 }
01654 s->strstart++;
01655 s->lookahead--;
01656 if (s->strm->avail_out == 0) return need_more;
01657 } else {
01658
01659
01660
01661 s->match_available = 1;
01662 s->strstart++;
01663 s->lookahead--;
01664 }
01665 }
01666 Assert (flush != Z_NO_FLUSH, "no flush?");
01667 if (s->match_available) {
01668 Tracevv((stderr,"%c", s->window[s->strstart-1]));
01669 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
01670 s->match_available = 0;
01671 }
01672 FLUSH_BLOCK(s, flush == Z_FINISH);
01673 return flush == Z_FINISH ? finish_done : block_done;
01674 }
01675 #endif
01676
01677 #if 0
01678
01679
01680
01681
01682
01683 local block_state deflate_rle(s, flush)
01684 deflate_state *s;
01685 int flush;
01686 {
01687 int bflush;
01688 uInt run;
01689 uInt max;
01690 uInt prev;
01691 Bytef *scan;
01692
01693 for (;;) {
01694
01695
01696
01697
01698 if (s->lookahead < MAX_MATCH) {
01699 fill_window(s);
01700 if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
01701 return need_more;
01702 }
01703 if (s->lookahead == 0) break;
01704 }
01705
01706
01707 run = 0;
01708 if (s->strstart > 0) {
01709 max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
01710 scan = s->window + s->strstart - 1;
01711 prev = *scan++;
01712 do {
01713 if (*scan++ != prev)
01714 break;
01715 } while (++run < max);
01716 }
01717
01718
01719 if (run >= MIN_MATCH) {
01720 check_match(s, s->strstart, s->strstart - 1, run);
01721 _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
01722 s->lookahead -= run;
01723 s->strstart += run;
01724 } else {
01725
01726 Tracevv((stderr,"%c", s->window[s->strstart]));
01727 _tr_tally_lit (s, s->window[s->strstart], bflush);
01728 s->lookahead--;
01729 s->strstart++;
01730 }
01731 if (bflush) FLUSH_BLOCK(s, 0);
01732 }
01733 FLUSH_BLOCK(s, flush == Z_FINISH);
01734 return flush == Z_FINISH ? finish_done : block_done;
01735 }
01736 #endif