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.1.4 Copyright 1995-2002 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 local block_state deflate_slow OF((deflate_state *s, int flush));
00080 local void lm_init OF((deflate_state *s));
00081 local void putShortMSB OF((deflate_state *s, uInt b));
00082 local void flush_pending OF((z_streamp strm));
00083 local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
00084 #ifdef ASMV
00085 void match_init OF((void));
00086 uInt longest_match OF((deflate_state *s, IPos cur_match));
00087 #else
00088 local uInt longest_match OF((deflate_state *s, IPos cur_match));
00089 #endif
00090
00091 #ifdef DEBUG
00092 local void check_match OF((deflate_state *s, IPos start, IPos match,
00093 int length));
00094 #endif
00095
00096
00097
00098
00099
00100 #define NIL 0
00101
00102
00103 #ifndef TOO_FAR
00104 # define TOO_FAR 4096
00105 #endif
00106
00107
00108 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 typedef struct config_s {
00119 ush good_length;
00120 ush max_lazy;
00121 ush nice_length;
00122 ush max_chain;
00123 compress_func func;
00124 } config;
00125
00126 local const config configuration_table[10] = {
00127
00128 {0, 0, 0, 0, deflate_stored},
00129 {4, 4, 8, 4, deflate_fast},
00130 {4, 5, 16, 8, deflate_fast},
00131 {4, 6, 32, 32, deflate_fast},
00132
00133 {4, 4, 16, 16, deflate_slow},
00134 {8, 16, 32, 32, deflate_slow},
00135 {8, 16, 128, 128, deflate_slow},
00136 {8, 32, 128, 256, deflate_slow},
00137 {32, 128, 258, 1024, deflate_slow},
00138 {32, 258, 258, 4096, deflate_slow}};
00139
00140
00141
00142
00143
00144
00145 #define EQUAL 0
00146
00147
00148 struct static_tree_desc_s {int dummy;};
00149
00150
00151
00152
00153
00154
00155
00156 #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 #ifdef FASTEST
00170 #define INSERT_STRING(s, str, match_head) \
00171 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
00172 match_head = s->head[s->ins_h], \
00173 s->head[s->ins_h] = (Pos)(str))
00174 #else
00175 #define INSERT_STRING(s, str, match_head) \
00176 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
00177 s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
00178 s->head[s->ins_h] = (Pos)(str))
00179 #endif
00180
00181
00182
00183
00184
00185 #define CLEAR_HASH(s) \
00186 s->head[s->hash_size-1] = NIL; \
00187 zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
00188
00189
00190 int ZEXPORT deflateInit_(strm, level, version, stream_size)
00191 z_streamp strm;
00192 int level;
00193 const char *version;
00194 int stream_size;
00195 {
00196 return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
00197 Z_DEFAULT_STRATEGY, version, stream_size);
00198
00199 }
00200
00201
00202 int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
00203 version, stream_size)
00204 z_streamp strm;
00205 int level;
00206 int method;
00207 int windowBits;
00208 int memLevel;
00209 int strategy;
00210 const char *version;
00211 int stream_size;
00212 {
00213 deflate_state *s;
00214 int noheader = 0;
00215 static const char* my_version = ZLIB_VERSION;
00216
00217 ushf *overlay;
00218
00219
00220
00221
00222 if (version == Z_NULL || version[0] != my_version[0] ||
00223 stream_size != sizeof(z_stream)) {
00224 return Z_VERSION_ERROR;
00225 }
00226 if (strm == Z_NULL) return Z_STREAM_ERROR;
00227
00228 strm->msg = Z_NULL;
00229 if (strm->zalloc == Z_NULL) {
00230 strm->zalloc = zcalloc;
00231 strm->opaque = (voidpf)0;
00232 }
00233 if (strm->zfree == Z_NULL) strm->zfree = zcfree;
00234
00235 if (level == Z_DEFAULT_COMPRESSION) level = 6;
00236 #ifdef FASTEST
00237 level = 1;
00238 #endif
00239
00240 if (windowBits < 0) {
00241 noheader = 1;
00242 windowBits = -windowBits;
00243 }
00244 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
00245 windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
00246 strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
00247 return Z_STREAM_ERROR;
00248 }
00249 s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
00250 if (s == Z_NULL) return Z_MEM_ERROR;
00251 strm->state = (struct internal_state FAR *)s;
00252 s->strm = strm;
00253
00254 s->noheader = noheader;
00255 s->w_bits = windowBits;
00256 s->w_size = 1 << s->w_bits;
00257 s->w_mask = s->w_size - 1;
00258
00259 s->hash_bits = memLevel + 7;
00260 s->hash_size = 1 << s->hash_bits;
00261 s->hash_mask = s->hash_size - 1;
00262 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
00263
00264 s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
00265 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
00266 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
00267
00268 s->lit_bufsize = 1 << (memLevel + 6);
00269
00270 overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
00271 s->pending_buf = (uchf *) overlay;
00272 s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
00273
00274 if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
00275 s->pending_buf == Z_NULL) {
00276 strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
00277 deflateEnd (strm);
00278 return Z_MEM_ERROR;
00279 }
00280 s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
00281 s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
00282
00283 s->level = level;
00284 s->strategy = strategy;
00285 s->method = (Byte)method;
00286
00287 return deflateReset(strm);
00288 }
00289
00290
00291 int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
00292 z_streamp strm;
00293 const Bytef *dictionary;
00294 uInt dictLength;
00295 {
00296 deflate_state *s;
00297 uInt length = dictLength;
00298 uInt n;
00299 IPos hash_head = 0;
00300
00301 if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
00302 strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
00303
00304 s = strm->state;
00305 strm->adler = adler32(strm->adler, dictionary, dictLength);
00306
00307 if (length < MIN_MATCH) return Z_OK;
00308 if (length > MAX_DIST(s)) {
00309 length = MAX_DIST(s);
00310 #ifndef USE_DICT_HEAD
00311 dictionary += dictLength - length;
00312 #endif
00313 }
00314 zmemcpy(s->window, dictionary, length);
00315 s->strstart = length;
00316 s->block_start = (long)length;
00317
00318
00319
00320
00321
00322 s->ins_h = s->window[0];
00323 UPDATE_HASH(s, s->ins_h, s->window[1]);
00324 for (n = 0; n <= length - MIN_MATCH; n++) {
00325 INSERT_STRING(s, n, hash_head);
00326 }
00327 if (hash_head) hash_head = 0;
00328 return Z_OK;
00329 }
00330
00331
00332 int ZEXPORT deflateReset (strm)
00333 z_streamp strm;
00334 {
00335 deflate_state *s;
00336
00337 if (strm == Z_NULL || strm->state == Z_NULL ||
00338 strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
00339
00340 strm->total_in = strm->total_out = 0;
00341 strm->msg = Z_NULL;
00342 strm->data_type = Z_UNKNOWN;
00343
00344 s = (deflate_state *)strm->state;
00345 s->pending = 0;
00346 s->pending_out = s->pending_buf;
00347
00348 if (s->noheader < 0) {
00349 s->noheader = 0;
00350 }
00351 s->status = s->noheader ? BUSY_STATE : INIT_STATE;
00352 strm->adler = 1;
00353 s->last_flush = Z_NO_FLUSH;
00354
00355 _tr_init(s);
00356 lm_init(s);
00357
00358 return Z_OK;
00359 }
00360
00361
00362 int ZEXPORT deflateParams(strm, level, strategy)
00363 z_streamp strm;
00364 int level;
00365 int strategy;
00366 {
00367 deflate_state *s;
00368 compress_func func;
00369 int err = Z_OK;
00370
00371 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00372 s = strm->state;
00373
00374 if (level == Z_DEFAULT_COMPRESSION) {
00375 level = 6;
00376 }
00377 if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
00378 return Z_STREAM_ERROR;
00379 }
00380 func = configuration_table[s->level].func;
00381
00382 if (func != configuration_table[level].func && strm->total_in != 0) {
00383
00384 err = deflate(strm, Z_PARTIAL_FLUSH);
00385 }
00386 if (s->level != level) {
00387 s->level = level;
00388 s->max_lazy_match = configuration_table[level].max_lazy;
00389 s->good_match = configuration_table[level].good_length;
00390 s->nice_match = configuration_table[level].nice_length;
00391 s->max_chain_length = configuration_table[level].max_chain;
00392 }
00393 s->strategy = strategy;
00394 return err;
00395 }
00396
00397
00398
00399
00400
00401
00402 local void putShortMSB (s, b)
00403 deflate_state *s;
00404 uInt b;
00405 {
00406 put_byte(s, (Byte)(b >> 8));
00407 put_byte(s, (Byte)(b & 0xff));
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 local void flush_pending(strm)
00417 z_streamp strm;
00418 {
00419 unsigned len = strm->state->pending;
00420
00421 if (len > strm->avail_out) len = strm->avail_out;
00422 if (len == 0) return;
00423
00424 zmemcpy(strm->next_out, strm->state->pending_out, len);
00425 strm->next_out += len;
00426 strm->state->pending_out += len;
00427 strm->total_out += len;
00428 strm->avail_out -= len;
00429 strm->state->pending -= len;
00430 if (strm->state->pending == 0) {
00431 strm->state->pending_out = strm->state->pending_buf;
00432 }
00433 }
00434
00435
00436 int ZEXPORT deflate (strm, flush)
00437 z_streamp strm;
00438 int flush;
00439 {
00440 int old_flush;
00441 deflate_state *s;
00442
00443 if (strm == Z_NULL || strm->state == Z_NULL ||
00444 flush > Z_FINISH || flush < 0) {
00445 return Z_STREAM_ERROR;
00446 }
00447 s = strm->state;
00448
00449 if (strm->next_out == Z_NULL ||
00450 (strm->next_in == Z_NULL && strm->avail_in != 0) ||
00451 (s->status == FINISH_STATE && flush != Z_FINISH)) {
00452 ERR_RETURN(strm, Z_STREAM_ERROR);
00453 }
00454 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
00455
00456 s->strm = strm;
00457 old_flush = s->last_flush;
00458 s->last_flush = flush;
00459
00460
00461 if (s->status == INIT_STATE) {
00462
00463 uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
00464 uInt level_flags = (s->level-1) >> 1;
00465
00466 if (level_flags > 3) level_flags = 3;
00467 header |= (level_flags << 6);
00468 if (s->strstart != 0) header |= PRESET_DICT;
00469 header += 31 - (header % 31);
00470
00471 s->status = BUSY_STATE;
00472 putShortMSB(s, header);
00473
00474
00475 if (s->strstart != 0) {
00476 putShortMSB(s, (uInt)(strm->adler >> 16));
00477 putShortMSB(s, (uInt)(strm->adler & 0xffff));
00478 }
00479 strm->adler = 1L;
00480 }
00481
00482
00483 if (s->pending != 0) {
00484 flush_pending(strm);
00485 if (strm->avail_out == 0) {
00486
00487
00488
00489
00490
00491
00492 s->last_flush = -1;
00493 return Z_OK;
00494 }
00495
00496
00497
00498
00499
00500 } else if (strm->avail_in == 0 && flush <= old_flush &&
00501 flush != Z_FINISH) {
00502 ERR_RETURN(strm, Z_BUF_ERROR);
00503 }
00504
00505
00506 if (s->status == FINISH_STATE && strm->avail_in != 0) {
00507 ERR_RETURN(strm, Z_BUF_ERROR);
00508 }
00509
00510
00511
00512 if (strm->avail_in != 0 || s->lookahead != 0 ||
00513 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
00514 block_state bstate;
00515
00516 bstate = (*(configuration_table[s->level].func))(s, flush);
00517
00518 if (bstate == finish_started || bstate == finish_done) {
00519 s->status = FINISH_STATE;
00520 }
00521 if (bstate == need_more || bstate == finish_started) {
00522 if (strm->avail_out == 0) {
00523 s->last_flush = -1;
00524 }
00525 return Z_OK;
00526
00527
00528
00529
00530
00531
00532
00533 }
00534 if (bstate == block_done) {
00535 if (flush == Z_PARTIAL_FLUSH) {
00536 _tr_align(s);
00537 } else {
00538 _tr_stored_block(s, (char*)0, 0L, 0);
00539
00540
00541
00542 if (flush == Z_FULL_FLUSH) {
00543 CLEAR_HASH(s);
00544 }
00545 }
00546 flush_pending(strm);
00547 if (strm->avail_out == 0) {
00548 s->last_flush = -1;
00549 return Z_OK;
00550 }
00551 }
00552 }
00553 Assert(strm->avail_out > 0, "bug2");
00554
00555 if (flush != Z_FINISH) return Z_OK;
00556 if (s->noheader) return Z_STREAM_END;
00557
00558
00559 putShortMSB(s, (uInt)(strm->adler >> 16));
00560 putShortMSB(s, (uInt)(strm->adler & 0xffff));
00561 flush_pending(strm);
00562
00563
00564
00565 s->noheader = -1;
00566 return s->pending != 0 ? Z_OK : Z_STREAM_END;
00567 }
00568
00569
00570 int ZEXPORT deflateEnd (strm)
00571 z_streamp strm;
00572 {
00573 int status;
00574
00575 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
00576
00577 status = strm->state->status;
00578 if (status != INIT_STATE && status != BUSY_STATE &&
00579 status != FINISH_STATE) {
00580 return Z_STREAM_ERROR;
00581 }
00582
00583
00584 TRY_FREE(strm, strm->state->pending_buf);
00585 TRY_FREE(strm, strm->state->head);
00586 TRY_FREE(strm, strm->state->prev);
00587 TRY_FREE(strm, strm->state->window);
00588
00589 ZFREE(strm, strm->state);
00590 strm->state = Z_NULL;
00591
00592 return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
00593 }
00594
00595
00596
00597
00598
00599
00600 int ZEXPORT deflateCopy (dest, source)
00601 z_streamp dest;
00602 z_streamp source;
00603 {
00604 #ifdef MAXSEG_64K
00605 return Z_STREAM_ERROR;
00606 #else
00607 deflate_state *ds;
00608 deflate_state *ss;
00609 ushf *overlay;
00610
00611
00612 if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
00613 return Z_STREAM_ERROR;
00614 }
00615
00616 ss = source->state;
00617
00618 *dest = *source;
00619
00620 ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
00621 if (ds == Z_NULL) return Z_MEM_ERROR;
00622 dest->state = (struct internal_state FAR *) ds;
00623 *ds = *ss;
00624 ds->strm = dest;
00625
00626 ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
00627 ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
00628 ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
00629 overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
00630 ds->pending_buf = (uchf *) overlay;
00631
00632 if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
00633 ds->pending_buf == Z_NULL) {
00634 deflateEnd (dest);
00635 return Z_MEM_ERROR;
00636 }
00637
00638 zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
00639 zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
00640 zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
00641 zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
00642
00643 ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
00644 ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
00645 ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
00646
00647 ds->l_desc.dyn_tree = ds->dyn_ltree;
00648 ds->d_desc.dyn_tree = ds->dyn_dtree;
00649 ds->bl_desc.dyn_tree = ds->bl_tree;
00650
00651 return Z_OK;
00652 #endif
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662 local int read_buf(strm, buf, size)
00663 z_streamp strm;
00664 Bytef *buf;
00665 unsigned size;
00666 {
00667 unsigned len = strm->avail_in;
00668
00669 if (len > size) len = size;
00670 if (len == 0) return 0;
00671
00672 strm->avail_in -= len;
00673
00674 if (!strm->state->noheader) {
00675 strm->adler = adler32(strm->adler, strm->next_in, len);
00676 }
00677 zmemcpy(buf, strm->next_in, len);
00678 strm->next_in += len;
00679 strm->total_in += len;
00680
00681 return (int)len;
00682 }
00683
00684
00685
00686
00687 local void lm_init (s)
00688 deflate_state *s;
00689 {
00690 s->window_size = (ulg)2L*s->w_size;
00691
00692 CLEAR_HASH(s);
00693
00694
00695
00696 s->max_lazy_match = configuration_table[s->level].max_lazy;
00697 s->good_match = configuration_table[s->level].good_length;
00698 s->nice_match = configuration_table[s->level].nice_length;
00699 s->max_chain_length = configuration_table[s->level].max_chain;
00700
00701 s->strstart = 0;
00702 s->block_start = 0L;
00703 s->lookahead = 0;
00704 s->match_length = s->prev_length = MIN_MATCH-1;
00705 s->match_available = 0;
00706 s->ins_h = 0;
00707 #ifdef ASMV
00708 match_init();
00709 #endif
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 #ifndef ASMV
00722
00723
00724
00725 #ifndef FASTEST
00726 local uInt longest_match(s, cur_match)
00727 deflate_state *s;
00728 IPos cur_match;
00729 {
00730 unsigned chain_length = s->max_chain_length;
00731 register Bytef *scan = s->window + s->strstart;
00732 register Bytef *match;
00733 register int len;
00734 int best_len = s->prev_length;
00735 int nice_match = s->nice_match;
00736 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
00737 s->strstart - (IPos)MAX_DIST(s) : NIL;
00738
00739
00740
00741 Posf *prev = s->prev;
00742 uInt wmask = s->w_mask;
00743
00744 #ifdef UNALIGNED_OK
00745
00746
00747
00748 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
00749 register ush scan_start = *(ushf*)scan;
00750 register ush scan_end = *(ushf*)(scan+best_len-1);
00751 #else
00752 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
00753 register Byte scan_end1 = scan[best_len-1];
00754 register Byte scan_end = scan[best_len];
00755 #endif
00756
00757
00758
00759
00760 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
00761
00762
00763 if (s->prev_length >= s->good_match) {
00764 chain_length >>= 2;
00765 }
00766
00767
00768
00769 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
00770
00771 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
00772
00773 do {
00774 Assert(cur_match < s->strstart, "no future");
00775 match = s->window + cur_match;
00776
00777
00778
00779
00780 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
00781
00782
00783
00784 if (*(ushf*)(match+best_len-1) != scan_end ||
00785 *(ushf*)match != scan_start) continue;
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 Assert(scan[2] == match[2], "scan[2]?");
00797 scan++, match++;
00798 do {
00799 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
00800 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
00801 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
00802 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
00803 scan < strend);
00804
00805
00806
00807 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
00808 if (*scan == *match) scan++;
00809
00810 len = (MAX_MATCH - 1) - (int)(strend-scan);
00811 scan = strend - (MAX_MATCH-1);
00812
00813 #else
00814
00815 if (match[best_len] != scan_end ||
00816 match[best_len-1] != scan_end1 ||
00817 *match != *scan ||
00818 *++match != scan[1]) continue;
00819
00820
00821
00822
00823
00824
00825
00826 scan += 2, match++;
00827 Assert(*scan == *match, "match[2]?");
00828
00829
00830
00831
00832 do {
00833 } while (*++scan == *++match && *++scan == *++match &&
00834 *++scan == *++match && *++scan == *++match &&
00835 *++scan == *++match && *++scan == *++match &&
00836 *++scan == *++match && *++scan == *++match &&
00837 scan < strend);
00838
00839 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
00840
00841 len = MAX_MATCH - (int)(strend - scan);
00842 scan = strend - MAX_MATCH;
00843
00844 #endif
00845
00846 if (len > best_len) {
00847 s->match_start = cur_match;
00848 best_len = len;
00849 if (len >= nice_match) break;
00850 #ifdef UNALIGNED_OK
00851 scan_end = *(ushf*)(scan+best_len-1);
00852 #else
00853 scan_end1 = scan[best_len-1];
00854 scan_end = scan[best_len];
00855 #endif
00856 }
00857 } while ((cur_match = prev[cur_match & wmask]) > limit
00858 && --chain_length != 0);
00859
00860 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
00861 return s->lookahead;
00862 }
00863
00864 #else
00865
00866
00867
00868 local uInt longest_match(s, cur_match)
00869 deflate_state *s;
00870 IPos cur_match;
00871 {
00872 register Bytef *scan = s->window + s->strstart;
00873 register Bytef *match;
00874 register int len;
00875 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
00876
00877
00878
00879
00880 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
00881
00882 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
00883
00884 Assert(cur_match < s->strstart, "no future");
00885
00886 match = s->window + cur_match;
00887
00888
00889
00890 if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
00891
00892
00893
00894
00895
00896
00897
00898 scan += 2, match += 2;
00899 Assert(*scan == *match, "match[2]?");
00900
00901
00902
00903
00904 do {
00905 } while (*++scan == *++match && *++scan == *++match &&
00906 *++scan == *++match && *++scan == *++match &&
00907 *++scan == *++match && *++scan == *++match &&
00908 *++scan == *++match && *++scan == *++match &&
00909 scan < strend);
00910
00911 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
00912
00913 len = MAX_MATCH - (int)(strend - scan);
00914
00915 if (len < MIN_MATCH) return MIN_MATCH - 1;
00916
00917 s->match_start = cur_match;
00918 return len <= s->lookahead ? len : s->lookahead;
00919 }
00920 #endif
00921 #endif
00922
00923 #ifdef DEBUG
00924
00925
00926
00927 local void check_match(s, start, match, length)
00928 deflate_state *s;
00929 IPos start, match;
00930 int length;
00931 {
00932
00933 if (zmemcmp(s->window + match,
00934 s->window + start, length) != EQUAL) {
00935 fprintf(stderr, " start %u, match %u, length %d\n",
00936 start, match, length);
00937 do {
00938 fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
00939 } while (--length != 0);
00940 z_error("invalid match");
00941 }
00942 if (z_verbose > 1) {
00943 fprintf(stderr,"\\[%d,%d]", start-match, length);
00944 do { putc(s->window[start++], stderr); } while (--length != 0);
00945 }
00946 }
00947 #else
00948 # define check_match(s, start, match, length)
00949 #endif
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 local void fill_window(s)
00962 deflate_state *s;
00963 {
00964 register unsigned n, m;
00965 register Posf *p;
00966 unsigned more;
00967 uInt wsize = s->w_size;
00968
00969 do {
00970 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
00971
00972
00973 if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
00974 more = wsize;
00975
00976 } else if (more == (unsigned)(-1)) {
00977
00978
00979
00980 more--;
00981
00982
00983
00984
00985 } else if (s->strstart >= wsize+MAX_DIST(s)) {
00986
00987 zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
00988 s->match_start -= wsize;
00989 s->strstart -= wsize;
00990 s->block_start -= (long) wsize;
00991
00992
00993
00994
00995
00996
00997
00998 n = s->hash_size;
00999 p = &s->head[n];
01000 do {
01001 m = *--p;
01002 *p = (Pos)(m >= wsize ? m-wsize : NIL);
01003 } while (--n);
01004
01005 n = wsize;
01006 #ifndef FASTEST
01007 p = &s->prev[n];
01008 do {
01009 m = *--p;
01010 *p = (Pos)(m >= wsize ? m-wsize : NIL);
01011
01012
01013
01014 } while (--n);
01015 #endif
01016 more += wsize;
01017 }
01018 if (s->strm->avail_in == 0) return;
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 Assert(more >= 2, "more < 2");
01032
01033 n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
01034 s->lookahead += n;
01035
01036
01037 if (s->lookahead >= MIN_MATCH) {
01038 s->ins_h = s->window[s->strstart];
01039 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
01040 #if MIN_MATCH != 3
01041 Call UPDATE_HASH() MIN_MATCH-3 more times
01042 #endif
01043 }
01044
01045
01046
01047
01048 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
01049 }
01050
01051
01052
01053
01054
01055 #define FLUSH_BLOCK_ONLY(s, eof) { \
01056 _tr_flush_block(s, (s->block_start >= 0L ? \
01057 (charf *)&s->window[(unsigned)s->block_start] : \
01058 (charf *)Z_NULL), \
01059 (ulg)((long)s->strstart - s->block_start), \
01060 (eof)); \
01061 s->block_start = s->strstart; \
01062 flush_pending(s->strm); \
01063 Tracev((stderr,"[FLUSH]")); \
01064 }
01065
01066
01067 #define FLUSH_BLOCK(s, eof) { \
01068 FLUSH_BLOCK_ONLY(s, eof); \
01069 if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 local block_state deflate_stored(s, flush)
01082 deflate_state *s;
01083 int flush;
01084 {
01085
01086
01087
01088 ulg max_block_size = 0xffff;
01089 ulg max_start;
01090
01091 if (max_block_size > s->pending_buf_size - 5) {
01092 max_block_size = s->pending_buf_size - 5;
01093 }
01094
01095
01096 for (;;) {
01097
01098 if (s->lookahead <= 1) {
01099
01100 Assert(s->strstart < s->w_size+MAX_DIST(s) ||
01101 s->block_start >= (long)s->w_size, "slide too late");
01102
01103 fill_window(s);
01104 if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
01105
01106 if (s->lookahead == 0) break;
01107 }
01108 Assert(s->block_start >= 0L, "block gone");
01109
01110 s->strstart += s->lookahead;
01111 s->lookahead = 0;
01112
01113
01114 max_start = s->block_start + max_block_size;
01115 if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
01116
01117 s->lookahead = (uInt)(s->strstart - max_start);
01118 s->strstart = (uInt)max_start;
01119 FLUSH_BLOCK(s, 0);
01120 }
01121
01122
01123
01124 if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
01125 FLUSH_BLOCK(s, 0);
01126 }
01127 }
01128 FLUSH_BLOCK(s, flush == Z_FINISH);
01129 return flush == Z_FINISH ? finish_done : block_done;
01130 }
01131
01132
01133
01134
01135
01136
01137
01138
01139 local block_state deflate_fast(s, flush)
01140 deflate_state *s;
01141 int flush;
01142 {
01143 IPos hash_head = NIL;
01144 int bflush;
01145
01146 for (;;) {
01147
01148
01149
01150
01151
01152 if (s->lookahead < MIN_LOOKAHEAD) {
01153 fill_window(s);
01154 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
01155 return need_more;
01156 }
01157 if (s->lookahead == 0) break;
01158 }
01159
01160
01161
01162
01163 if (s->lookahead >= MIN_MATCH) {
01164 INSERT_STRING(s, s->strstart, hash_head);
01165 }
01166
01167
01168
01169
01170 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
01171
01172
01173
01174
01175 if (s->strategy != Z_HUFFMAN_ONLY) {
01176 s->match_length = longest_match (s, hash_head);
01177 }
01178
01179 }
01180 if (s->match_length >= MIN_MATCH) {
01181 check_match(s, s->strstart, s->match_start, s->match_length);
01182
01183 _tr_tally_dist(s, s->strstart - s->match_start,
01184 s->match_length - MIN_MATCH, bflush);
01185
01186 s->lookahead -= s->match_length;
01187
01188
01189
01190
01191 #ifndef FASTEST
01192 if (s->match_length <= s->max_insert_length &&
01193 s->lookahead >= MIN_MATCH) {
01194 s->match_length--;
01195 do {
01196 s->strstart++;
01197 INSERT_STRING(s, s->strstart, hash_head);
01198
01199
01200
01201 } while (--s->match_length != 0);
01202 s->strstart++;
01203 } else
01204 #endif
01205 {
01206 s->strstart += s->match_length;
01207 s->match_length = 0;
01208 s->ins_h = s->window[s->strstart];
01209 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
01210 #if MIN_MATCH != 3
01211 Call UPDATE_HASH() MIN_MATCH-3 more times
01212 #endif
01213
01214
01215
01216 }
01217 } else {
01218
01219 Tracevv((stderr,"%c", s->window[s->strstart]));
01220 _tr_tally_lit (s, s->window[s->strstart], bflush);
01221 s->lookahead--;
01222 s->strstart++;
01223 }
01224 if (bflush) FLUSH_BLOCK(s, 0);
01225 }
01226 FLUSH_BLOCK(s, flush == Z_FINISH);
01227 return flush == Z_FINISH ? finish_done : block_done;
01228 }
01229
01230
01231
01232
01233
01234
01235 local block_state deflate_slow(s, flush)
01236 deflate_state *s;
01237 int flush;
01238 {
01239 IPos hash_head = NIL;
01240 int bflush;
01241
01242
01243 for (;;) {
01244
01245
01246
01247
01248
01249 if (s->lookahead < MIN_LOOKAHEAD) {
01250 fill_window(s);
01251 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
01252 return need_more;
01253 }
01254 if (s->lookahead == 0) break;
01255 }
01256
01257
01258
01259
01260 if (s->lookahead >= MIN_MATCH) {
01261 INSERT_STRING(s, s->strstart, hash_head);
01262 }
01263
01264
01265
01266 s->prev_length = s->match_length, s->prev_match = s->match_start;
01267 s->match_length = MIN_MATCH-1;
01268
01269 if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
01270 s->strstart - hash_head <= MAX_DIST(s)) {
01271
01272
01273
01274
01275 if (s->strategy != Z_HUFFMAN_ONLY) {
01276 s->match_length = longest_match (s, hash_head);
01277 }
01278
01279
01280 if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
01281 (s->match_length == MIN_MATCH &&
01282 s->strstart - s->match_start > TOO_FAR))) {
01283
01284
01285
01286
01287 s->match_length = MIN_MATCH-1;
01288 }
01289 }
01290
01291
01292
01293 if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
01294 uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
01295
01296
01297 check_match(s, s->strstart-1, s->prev_match, s->prev_length);
01298
01299 _tr_tally_dist(s, s->strstart -1 - s->prev_match,
01300 s->prev_length - MIN_MATCH, bflush);
01301
01302
01303
01304
01305
01306
01307 s->lookahead -= s->prev_length-1;
01308 s->prev_length -= 2;
01309 do {
01310 if (++s->strstart <= max_insert) {
01311 INSERT_STRING(s, s->strstart, hash_head);
01312 }
01313 } while (--s->prev_length != 0);
01314 s->match_available = 0;
01315 s->match_length = MIN_MATCH-1;
01316 s->strstart++;
01317
01318 if (bflush) FLUSH_BLOCK(s, 0);
01319
01320 } else if (s->match_available) {
01321
01322
01323
01324
01325 Tracevv((stderr,"%c", s->window[s->strstart-1]));
01326 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
01327 if (bflush) {
01328 FLUSH_BLOCK_ONLY(s, 0);
01329 }
01330 s->strstart++;
01331 s->lookahead--;
01332 if (s->strm->avail_out == 0) return need_more;
01333 } else {
01334
01335
01336
01337 s->match_available = 1;
01338 s->strstart++;
01339 s->lookahead--;
01340 }
01341 }
01342 Assert (flush != Z_NO_FLUSH, "no flush?");
01343 if (s->match_available) {
01344 Tracevv((stderr,"%c", s->window[s->strstart-1]));
01345 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
01346 s->match_available = 0;
01347 }
01348 FLUSH_BLOCK(s, flush == Z_FINISH);
01349 return flush == Z_FINISH ? finish_done : block_done;
01350 }