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