diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-07 19:39:02 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-07 19:39:02 +0000 |
| commit | da31fbc1b1dec08a18fc94d728b8d080f4a503d3 (patch) | |
| tree | 4c1d83e0642db1a4d4241826901c440182adccd8 | |
| parent | f824136f6b21558ac023bc53bcb69294e0676103 (diff) | |
| download | busybox-w32-da31fbc1b1dec08a18fc94d728b8d080f4a503d3.tar.gz busybox-w32-da31fbc1b1dec08a18fc94d728b8d080f4a503d3.tar.bz2 busybox-w32-da31fbc1b1dec08a18fc94d728b8d080f4a503d3.zip | |
gzip cleanup part #5
| -rw-r--r-- | archival/gzip.c | 416 |
1 files changed, 212 insertions, 204 deletions
diff --git a/archival/gzip.c b/archival/gzip.c index 4f47a2782..0ef25727d 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
| @@ -23,11 +23,36 @@ gzip: bogus: No such file or directory | |||
| 23 | aa: 85.1% -- replaced with aa.gz | 23 | aa: 85.1% -- replaced with aa.gz |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #define SMALL_MEM | ||
| 27 | 26 | ||
| 28 | //#include <dirent.h> | 27 | //#include <dirent.h> |
| 29 | #include "busybox.h" | 28 | #include "busybox.h" |
| 30 | 29 | ||
| 30 | |||
| 31 | /* =========================================================================== | ||
| 32 | */ | ||
| 33 | //#define DEBUG 1 | ||
| 34 | /* Diagnostic functions */ | ||
| 35 | #ifdef DEBUG | ||
| 36 | # define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);} | ||
| 37 | # define Trace(x) fprintf x | ||
| 38 | # define Tracev(x) {if (verbose) fprintf x ;} | ||
| 39 | # define Tracevv(x) {if (verbose > 1) fprintf x ;} | ||
| 40 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} | ||
| 41 | # define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x ;} | ||
| 42 | #else | ||
| 43 | # define Assert(cond,msg) | ||
| 44 | # define Trace(x) | ||
| 45 | # define Tracev(x) | ||
| 46 | # define Tracevv(x) | ||
| 47 | # define Tracec(c,x) | ||
| 48 | # define Tracecv(c,x) | ||
| 49 | #endif | ||
| 50 | |||
| 51 | |||
| 52 | /* =========================================================================== | ||
| 53 | */ | ||
| 54 | #define SMALL_MEM | ||
| 55 | |||
| 31 | /* Compression methods (see algorithm.doc) */ | 56 | /* Compression methods (see algorithm.doc) */ |
| 32 | /* Only STORED and DEFLATED are supported by this BusyBox module */ | 57 | /* Only STORED and DEFLATED are supported by this BusyBox module */ |
| 33 | #define STORED 0 | 58 | #define STORED 0 |
| @@ -121,36 +146,170 @@ aa: 85.1% -- replaced with aa.gz | |||
| 121 | #endif | 146 | #endif |
| 122 | 147 | ||
| 123 | 148 | ||
| 149 | /* =========================================================================== | ||
| 150 | * Compile with MEDIUM_MEM to reduce the memory requirements or | ||
| 151 | * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the | ||
| 152 | * entire input file can be held in memory (not possible on 16 bit systems). | ||
| 153 | * Warning: defining these symbols affects HASH_BITS (see below) and thus | ||
| 154 | * affects the compression ratio. The compressed output | ||
| 155 | * is still correct, and might even be smaller in some cases. | ||
| 156 | */ | ||
| 157 | |||
| 158 | #ifdef SMALL_MEM | ||
| 159 | # define HASH_BITS 13 /* Number of bits used to hash strings */ | ||
| 160 | #endif | ||
| 161 | #ifdef MEDIUM_MEM | ||
| 162 | # define HASH_BITS 14 | ||
| 163 | #endif | ||
| 164 | #ifndef HASH_BITS | ||
| 165 | # define HASH_BITS 15 | ||
| 166 | /* For portability to 16 bit machines, do not use values above 15. */ | ||
| 167 | #endif | ||
| 168 | |||
| 169 | /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and | ||
| 170 | * window with tab_suffix. Check that we can do this: | ||
| 171 | */ | ||
| 172 | #if (WSIZE<<1) > (1<<BITS) | ||
| 173 | # error cannot overlay window with tab_suffix and prev with tab_prefix0 | ||
| 174 | #endif | ||
| 175 | #if HASH_BITS > BITS-1 | ||
| 176 | # error cannot overlay head with tab_prefix1 | ||
| 177 | #endif | ||
| 178 | #define HASH_SIZE (unsigned)(1<<HASH_BITS) | ||
| 179 | #define HASH_MASK (HASH_SIZE-1) | ||
| 180 | #define WMASK (WSIZE-1) | ||
| 181 | /* HASH_SIZE and WSIZE must be powers of two */ | ||
| 182 | #ifndef TOO_FAR | ||
| 183 | # define TOO_FAR 4096 | ||
| 184 | #endif | ||
| 185 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ | ||
| 186 | |||
| 187 | |||
| 188 | /* =========================================================================== | ||
| 189 | */ | ||
| 190 | typedef unsigned char uch; | ||
| 191 | typedef unsigned short ush; | ||
| 192 | typedef unsigned long ulg; | ||
| 193 | |||
| 194 | |||
| 195 | /* =========================================================================== | ||
| 196 | * Local data used by the "longest match" routines. | ||
| 197 | */ | ||
| 198 | typedef ush Pos; | ||
| 199 | typedef unsigned IPos; | ||
| 200 | |||
| 201 | /* A Pos is an index in the character window. We use short instead of int to | ||
| 202 | * save space in the various tables. IPos is used only for parameter passing. | ||
| 203 | */ | ||
| 204 | |||
| 124 | #define DECLARE(type, array, size)\ | 205 | #define DECLARE(type, array, size)\ |
| 125 | static type * array | 206 | static type * array |
| 126 | #define ALLOC(type, array, size) { \ | 207 | #define ALLOC(type, array, size) { \ |
| 127 | array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \ | 208 | array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type)); \ |
| 128 | } | 209 | } |
| 210 | |||
| 129 | #define FREE(array) { \ | 211 | #define FREE(array) { \ |
| 130 | free(array); \ | 212 | free(array); \ |
| 131 | array = NULL; \ | 213 | array = NULL; \ |
| 132 | } | 214 | } |
| 133 | 215 | ||
| 134 | /* Diagnostic functions */ | 216 | /* DECLARE(uch, window, 2L*WSIZE); */ |
| 217 | /* Sliding window. Input bytes are read into the second half of the window, | ||
| 218 | * and move to the first half later to keep a dictionary of at least WSIZE | ||
| 219 | * bytes. With this organization, matches are limited to a distance of | ||
| 220 | * WSIZE-MAX_MATCH bytes, but this ensures that IO is always | ||
| 221 | * performed with a length multiple of the block size. Also, it limits | ||
| 222 | * the window size to 64K, which is quite useful on MSDOS. | ||
| 223 | * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would | ||
| 224 | * be less efficient). | ||
| 225 | */ | ||
| 226 | |||
| 227 | /* DECLARE(Pos, prev, WSIZE); */ | ||
| 228 | /* Link to older string with same hash index. To limit the size of this | ||
| 229 | * array to 64K, this link is maintained only for the last 32K strings. | ||
| 230 | * An index in this array is thus a window index modulo 32K. | ||
| 231 | */ | ||
| 232 | |||
| 233 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | ||
| 234 | /* Heads of the hash chains or 0. */ | ||
| 235 | |||
| 236 | static long block_start; | ||
| 237 | |||
| 238 | /* window position at the beginning of the current output block. Gets | ||
| 239 | * negative when the window is moved backwards. | ||
| 240 | */ | ||
| 241 | |||
| 242 | static unsigned ins_h; /* hash index of string to be inserted */ | ||
| 243 | |||
| 244 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH) | ||
| 245 | /* Number of bits by which ins_h and del_h must be shifted at each | ||
| 246 | * input step. It must be such that after MIN_MATCH steps, the oldest | ||
| 247 | * byte no longer takes part in the hash key, that is: | ||
| 248 | * H_SHIFT * MIN_MATCH >= HASH_BITS | ||
| 249 | */ | ||
| 250 | |||
| 251 | static unsigned int prev_length; | ||
| 252 | |||
| 253 | /* Length of the best match at previous step. Matches not greater than this | ||
| 254 | * are discarded. This is used in the lazy match evaluation. | ||
| 255 | */ | ||
| 256 | |||
| 257 | static unsigned strstart; /* start of string to insert */ | ||
| 258 | static unsigned match_start; /* start of matching string */ | ||
| 259 | static int eofile; /* flag set at end of input file */ | ||
| 260 | static unsigned lookahead; /* number of valid bytes ahead in window */ | ||
| 261 | |||
| 262 | enum { | ||
| 263 | WINDOW_SIZE = 2 * WSIZE, | ||
| 264 | /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the | ||
| 265 | * input file length plus MIN_LOOKAHEAD. | ||
| 266 | */ | ||
| 267 | |||
| 268 | max_chain_length = 4096, | ||
| 269 | /* To speed up deflation, hash chains are never searched beyond this length. | ||
| 270 | * A higher limit improves compression ratio but degrades the speed. | ||
| 271 | */ | ||
| 272 | |||
| 273 | max_lazy_match = 258, | ||
| 274 | /* Attempt to find a better match only when the current match is strictly | ||
| 275 | * smaller than this value. This mechanism is used only for compression | ||
| 276 | * levels >= 4. | ||
| 277 | */ | ||
| 278 | |||
| 279 | max_insert_length = max_lazy_match, | ||
| 280 | /* Insert new strings in the hash table only if the match length | ||
| 281 | * is not greater than this length. This saves time but degrades compression. | ||
| 282 | * max_insert_length is used only for compression levels <= 3. | ||
| 283 | */ | ||
| 284 | |||
| 285 | good_match = 32, | ||
| 286 | /* Use a faster search when the previous match is longer than this */ | ||
| 287 | |||
| 288 | /* Values for max_lazy_match, good_match and max_chain_length, depending on | ||
| 289 | * the desired pack level (0..9). The values given below have been tuned to | ||
| 290 | * exclude worst case performance for pathological files. Better values may be | ||
| 291 | * found for specific files. | ||
| 292 | */ | ||
| 293 | |||
| 294 | nice_match = 258 /* Stop searching when current match exceeds this */ | ||
| 295 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 | ||
| 296 | * For deflate_fast() (levels <= 3) good is ignored and lazy has a different | ||
| 297 | * meaning. | ||
| 298 | */ | ||
| 299 | }; | ||
| 300 | |||
| 301 | |||
| 302 | /* =========================================================================== | ||
| 303 | * Prototypes for local functions. | ||
| 304 | */ | ||
| 305 | static void fill_window(void); | ||
| 306 | |||
| 307 | static int longest_match(IPos cur_match); | ||
| 308 | |||
| 135 | #ifdef DEBUG | 309 | #ifdef DEBUG |
| 136 | # define Assert(cond,msg) {if(!(cond)) bb_error_msg(msg);} | 310 | static void check_match(IPos start, IPos match, int length); |
| 137 | # define Trace(x) fprintf x | ||
| 138 | # define Tracev(x) {if (verbose) fprintf x ;} | ||
| 139 | # define Tracevv(x) {if (verbose > 1) fprintf x ;} | ||
| 140 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} | ||
| 141 | # define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x ;} | ||
| 142 | #else | ||
| 143 | # define Assert(cond,msg) | ||
| 144 | # define Trace(x) | ||
| 145 | # define Tracev(x) | ||
| 146 | # define Tracevv(x) | ||
| 147 | # define Tracec(c,x) | ||
| 148 | # define Tracecv(c,x) | ||
| 149 | #endif | 311 | #endif |
| 150 | 312 | ||
| 151 | typedef unsigned char uch; | ||
| 152 | typedef unsigned short ush; | ||
| 153 | typedef unsigned long ulg; | ||
| 154 | 313 | ||
| 155 | 314 | ||
| 156 | /* from zip.c: */ | 315 | /* from zip.c: */ |
| @@ -183,7 +342,6 @@ static void copy_block(char *buf, unsigned len, int header); | |||
| 183 | * is done in window except for unlzw. | 342 | * is done in window except for unlzw. |
| 184 | */ | 343 | */ |
| 185 | 344 | ||
| 186 | |||
| 187 | #define tab_suffix window | 345 | #define tab_suffix window |
| 188 | #define tab_prefix prev /* hash link (see deflate.c) */ | 346 | #define tab_prefix prev /* hash link (see deflate.c) */ |
| 189 | #define head (prev+WSIZE) /* hash head (see deflate.c) */ | 347 | #define head (prev+WSIZE) /* hash head (see deflate.c) */ |
| @@ -310,16 +468,10 @@ static void clear_bufs(void) | |||
| 310 | static uint32_t crc; /* shift register contents */ | 468 | static uint32_t crc; /* shift register contents */ |
| 311 | static uint32_t updcrc(uch * s, unsigned n) | 469 | static uint32_t updcrc(uch * s, unsigned n) |
| 312 | { | 470 | { |
| 313 | uint32_t c; /* temporary variable */ | 471 | uint32_t c = crc; |
| 314 | 472 | while (n) { | |
| 315 | if (s == NULL) { | 473 | c = crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8); |
| 316 | c = ~0; | 474 | n--; |
| 317 | } else { | ||
| 318 | c = crc; | ||
| 319 | while (n) { | ||
| 320 | c = crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8); | ||
| 321 | n--; | ||
| 322 | } | ||
| 323 | } | 475 | } |
| 324 | crc = c; | 476 | crc = c; |
| 325 | return c; | 477 | return c; |
| @@ -387,6 +539,7 @@ static void send_bits(int value, int length) | |||
| 387 | } | 539 | } |
| 388 | } | 540 | } |
| 389 | 541 | ||
| 542 | |||
| 390 | /* =========================================================================== | 543 | /* =========================================================================== |
| 391 | * Reverse the first len bits of a code, using straightforward code (a faster | 544 | * Reverse the first len bits of a code, using straightforward code (a faster |
| 392 | * method would use a table) | 545 | * method would use a table) |
| @@ -403,6 +556,7 @@ static unsigned bi_reverse(unsigned code, int len) | |||
| 403 | return res >> 1; | 556 | return res >> 1; |
| 404 | } | 557 | } |
| 405 | 558 | ||
| 559 | |||
| 406 | /* =========================================================================== | 560 | /* =========================================================================== |
| 407 | * Write out any remaining bits in an incomplete byte. | 561 | * Write out any remaining bits in an incomplete byte. |
| 408 | */ | 562 | */ |
| @@ -420,6 +574,7 @@ static void bi_windup(void) | |||
| 420 | #endif | 574 | #endif |
| 421 | } | 575 | } |
| 422 | 576 | ||
| 577 | |||
| 423 | /* =========================================================================== | 578 | /* =========================================================================== |
| 424 | * Copy a stored block to the zip file, storing first the length and its | 579 | * Copy a stored block to the zip file, storing first the length and its |
| 425 | * one's complement if requested. | 580 | * one's complement if requested. |
| @@ -443,164 +598,6 @@ static void copy_block(char *buf, unsigned len, int header) | |||
| 443 | } | 598 | } |
| 444 | } | 599 | } |
| 445 | 600 | ||
| 446 | /* =========================================================================== | ||
| 447 | * Configuration parameters | ||
| 448 | */ | ||
| 449 | |||
| 450 | /* Compile with MEDIUM_MEM to reduce the memory requirements or | ||
| 451 | * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the | ||
| 452 | * entire input file can be held in memory (not possible on 16 bit systems). | ||
| 453 | * Warning: defining these symbols affects HASH_BITS (see below) and thus | ||
| 454 | * affects the compression ratio. The compressed output | ||
| 455 | * is still correct, and might even be smaller in some cases. | ||
| 456 | */ | ||
| 457 | |||
| 458 | #ifdef SMALL_MEM | ||
| 459 | # define HASH_BITS 13 /* Number of bits used to hash strings */ | ||
| 460 | #endif | ||
| 461 | #ifdef MEDIUM_MEM | ||
| 462 | # define HASH_BITS 14 | ||
| 463 | #endif | ||
| 464 | #ifndef HASH_BITS | ||
| 465 | # define HASH_BITS 15 | ||
| 466 | /* For portability to 16 bit machines, do not use values above 15. */ | ||
| 467 | #endif | ||
| 468 | |||
| 469 | /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and | ||
| 470 | * window with tab_suffix. Check that we can do this: | ||
| 471 | */ | ||
| 472 | #if (WSIZE<<1) > (1<<BITS) | ||
| 473 | # error cannot overlay window with tab_suffix and prev with tab_prefix0 | ||
| 474 | #endif | ||
| 475 | #if HASH_BITS > BITS-1 | ||
| 476 | # error cannot overlay head with tab_prefix1 | ||
| 477 | #endif | ||
| 478 | #define HASH_SIZE (unsigned)(1<<HASH_BITS) | ||
| 479 | #define HASH_MASK (HASH_SIZE-1) | ||
| 480 | #define WMASK (WSIZE-1) | ||
| 481 | /* HASH_SIZE and WSIZE must be powers of two */ | ||
| 482 | #define NIL 0 | ||
| 483 | /* Tail of hash chains */ | ||
| 484 | #define FAST 4 | ||
| 485 | #define SLOW 2 | ||
| 486 | /* speed options for the general purpose bit flag */ | ||
| 487 | #ifndef TOO_FAR | ||
| 488 | # define TOO_FAR 4096 | ||
| 489 | #endif | ||
| 490 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ | ||
| 491 | /* =========================================================================== | ||
| 492 | * Local data used by the "longest match" routines. | ||
| 493 | */ | ||
| 494 | typedef ush Pos; | ||
| 495 | typedef unsigned IPos; | ||
| 496 | |||
| 497 | /* A Pos is an index in the character window. We use short instead of int to | ||
| 498 | * save space in the various tables. IPos is used only for parameter passing. | ||
| 499 | */ | ||
| 500 | |||
| 501 | /* DECLARE(uch, window, 2L*WSIZE); */ | ||
| 502 | /* Sliding window. Input bytes are read into the second half of the window, | ||
| 503 | * and move to the first half later to keep a dictionary of at least WSIZE | ||
| 504 | * bytes. With this organization, matches are limited to a distance of | ||
| 505 | * WSIZE-MAX_MATCH bytes, but this ensures that IO is always | ||
| 506 | * performed with a length multiple of the block size. Also, it limits | ||
| 507 | * the window size to 64K, which is quite useful on MSDOS. | ||
| 508 | * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would | ||
| 509 | * be less efficient). | ||
| 510 | */ | ||
| 511 | |||
| 512 | /* DECLARE(Pos, prev, WSIZE); */ | ||
| 513 | /* Link to older string with same hash index. To limit the size of this | ||
| 514 | * array to 64K, this link is maintained only for the last 32K strings. | ||
| 515 | * An index in this array is thus a window index modulo 32K. | ||
| 516 | */ | ||
| 517 | |||
| 518 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | ||
| 519 | /* Heads of the hash chains or NIL. */ | ||
| 520 | |||
| 521 | static const ulg window_size = (ulg) 2 * WSIZE; | ||
| 522 | |||
| 523 | /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the | ||
| 524 | * input file length plus MIN_LOOKAHEAD. | ||
| 525 | */ | ||
| 526 | |||
| 527 | static long block_start; | ||
| 528 | |||
| 529 | /* window position at the beginning of the current output block. Gets | ||
| 530 | * negative when the window is moved backwards. | ||
| 531 | */ | ||
| 532 | |||
| 533 | static unsigned ins_h; /* hash index of string to be inserted */ | ||
| 534 | |||
| 535 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH) | ||
| 536 | /* Number of bits by which ins_h and del_h must be shifted at each | ||
| 537 | * input step. It must be such that after MIN_MATCH steps, the oldest | ||
| 538 | * byte no longer takes part in the hash key, that is: | ||
| 539 | * H_SHIFT * MIN_MATCH >= HASH_BITS | ||
| 540 | */ | ||
| 541 | |||
| 542 | static unsigned int prev_length; | ||
| 543 | |||
| 544 | /* Length of the best match at previous step. Matches not greater than this | ||
| 545 | * are discarded. This is used in the lazy match evaluation. | ||
| 546 | */ | ||
| 547 | |||
| 548 | static unsigned strstart; /* start of string to insert */ | ||
| 549 | static unsigned match_start; /* start of matching string */ | ||
| 550 | static int eofile; /* flag set at end of input file */ | ||
| 551 | static unsigned lookahead; /* number of valid bytes ahead in window */ | ||
| 552 | |||
| 553 | enum { | ||
| 554 | max_chain_length = 4096, | ||
| 555 | |||
| 556 | /* To speed up deflation, hash chains are never searched beyond this length. | ||
| 557 | * A higher limit improves compression ratio but degrades the speed. | ||
| 558 | */ | ||
| 559 | |||
| 560 | max_lazy_match = 258, | ||
| 561 | |||
| 562 | /* Attempt to find a better match only when the current match is strictly | ||
| 563 | * smaller than this value. This mechanism is used only for compression | ||
| 564 | * levels >= 4. | ||
| 565 | */ | ||
| 566 | max_insert_length = max_lazy_match, | ||
| 567 | /* Insert new strings in the hash table only if the match length | ||
| 568 | * is not greater than this length. This saves time but degrades compression. | ||
| 569 | * max_insert_length is used only for compression levels <= 3. | ||
| 570 | */ | ||
| 571 | |||
| 572 | good_match = 32, | ||
| 573 | |||
| 574 | /* Use a faster search when the previous match is longer than this */ | ||
| 575 | |||
| 576 | |||
| 577 | /* Values for max_lazy_match, good_match and max_chain_length, depending on | ||
| 578 | * the desired pack level (0..9). The values given below have been tuned to | ||
| 579 | * exclude worst case performance for pathological files. Better values may be | ||
| 580 | * found for specific files. | ||
| 581 | */ | ||
| 582 | |||
| 583 | nice_match = 258 /* Stop searching when current match exceeds this */ | ||
| 584 | |||
| 585 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 | ||
| 586 | * For deflate_fast() (levels <= 3) good is ignored and lazy has a different | ||
| 587 | * meaning. | ||
| 588 | */ | ||
| 589 | }; | ||
| 590 | |||
| 591 | #define EQUAL 0 | ||
| 592 | /* result of memcmp for equal strings */ | ||
| 593 | |||
| 594 | /* =========================================================================== | ||
| 595 | * Prototypes for local functions. | ||
| 596 | */ | ||
| 597 | static void fill_window(void); | ||
| 598 | |||
| 599 | static int longest_match(IPos cur_match); | ||
| 600 | |||
| 601 | #ifdef DEBUG | ||
| 602 | static void check_match(IPos start, IPos match, int length); | ||
| 603 | #endif | ||
| 604 | 601 | ||
| 605 | /* =========================================================================== | 602 | /* =========================================================================== |
| 606 | * Update a hash value with the given input byte | 603 | * Update a hash value with the given input byte |
| @@ -634,7 +631,8 @@ static void lm_init(ush * flags) | |||
| 634 | memset(head, 0, HASH_SIZE * sizeof(*head)); | 631 | memset(head, 0, HASH_SIZE * sizeof(*head)); |
| 635 | /* prev will be initialized on the fly */ | 632 | /* prev will be initialized on the fly */ |
| 636 | 633 | ||
| 637 | *flags |= SLOW; | 634 | /*speed options for the general purpose bit flag */ |
| 635 | *flags |= 2; /* FAST 4, SLOW 2 */ | ||
| 638 | /* ??? reduce max_chain_length for binary files */ | 636 | /* ??? reduce max_chain_length for binary files */ |
| 639 | 637 | ||
| 640 | strstart = 0; | 638 | strstart = 0; |
| @@ -702,7 +700,7 @@ static int longest_match(IPos cur_match) | |||
| 702 | if (prev_length >= good_match) { | 700 | if (prev_length >= good_match) { |
| 703 | chain_length >>= 2; | 701 | chain_length >>= 2; |
| 704 | } | 702 | } |
| 705 | Assert(strstart <= window_size - MIN_LOOKAHEAD, "insufficient lookahead"); | 703 | Assert(strstart <= WINDOW_SIZE - MIN_LOOKAHEAD, "insufficient lookahead"); |
| 706 | 704 | ||
| 707 | do { | 705 | do { |
| 708 | Assert(cur_match < strstart, "no future"); | 706 | Assert(cur_match < strstart, "no future"); |
| @@ -750,6 +748,7 @@ static int longest_match(IPos cur_match) | |||
| 750 | return best_len; | 748 | return best_len; |
| 751 | } | 749 | } |
| 752 | 750 | ||
| 751 | |||
| 753 | #ifdef DEBUG | 752 | #ifdef DEBUG |
| 754 | /* =========================================================================== | 753 | /* =========================================================================== |
| 755 | * Check that the match at match_start is indeed a match. | 754 | * Check that the match at match_start is indeed a match. |
| @@ -757,7 +756,7 @@ static int longest_match(IPos cur_match) | |||
| 757 | static void check_match(IPos start, IPos match, int length) | 756 | static void check_match(IPos start, IPos match, int length) |
| 758 | { | 757 | { |
| 759 | /* check that the match is indeed a match */ | 758 | /* check that the match is indeed a match */ |
| 760 | if (memcmp(window + match, window + start, length) != EQUAL) { | 759 | if (memcmp(window + match, window + start, length) != 0) { |
| 761 | bb_error_msg(" start %d, match %d, length %d", start, match, length); | 760 | bb_error_msg(" start %d, match %d, length %d", start, match, length); |
| 762 | bb_error_msg("invalid match"); | 761 | bb_error_msg("invalid match"); |
| 763 | } | 762 | } |
| @@ -769,9 +768,10 @@ static void check_match(IPos start, IPos match, int length) | |||
| 769 | } | 768 | } |
| 770 | } | 769 | } |
| 771 | #else | 770 | #else |
| 772 | # define check_match(start, match, length) | 771 | # define check_match(start, match, length) ((void)0) |
| 773 | #endif | 772 | #endif |
| 774 | 773 | ||
| 774 | |||
| 775 | /* =========================================================================== | 775 | /* =========================================================================== |
| 776 | * Fill the window when the lookahead becomes insufficient. | 776 | * Fill the window when the lookahead becomes insufficient. |
| 777 | * Updates strstart and lookahead, and sets eofile if end of input file. | 777 | * Updates strstart and lookahead, and sets eofile if end of input file. |
| @@ -783,7 +783,7 @@ static void check_match(IPos start, IPos match, int length) | |||
| 783 | static void fill_window(void) | 783 | static void fill_window(void) |
| 784 | { | 784 | { |
| 785 | unsigned n, m; | 785 | unsigned n, m; |
| 786 | unsigned more = window_size - lookahead - strstart; | 786 | unsigned more = WINDOW_SIZE - lookahead - strstart; |
| 787 | /* Amount of free space at the end of the window. */ | 787 | /* Amount of free space at the end of the window. */ |
| 788 | 788 | ||
| 789 | /* If the window is almost full and there is insufficient lookahead, | 789 | /* If the window is almost full and there is insufficient lookahead, |
| @@ -798,21 +798,21 @@ static void fill_window(void) | |||
| 798 | /* By the IN assertion, the window is not empty so we can't confuse | 798 | /* By the IN assertion, the window is not empty so we can't confuse |
| 799 | * more == 0 with more == 64K on a 16 bit machine. | 799 | * more == 0 with more == 64K on a 16 bit machine. |
| 800 | */ | 800 | */ |
| 801 | Assert(window_size == (ulg) 2 * WSIZE, "no sliding with BIG_MEM"); | 801 | Assert(WINDOW_SIZE == 2 * WSIZE, "no sliding with BIG_MEM"); |
| 802 | 802 | ||
| 803 | memcpy(window, window + WSIZE, WSIZE); | 803 | memcpy(window, window + WSIZE, WSIZE); |
| 804 | match_start -= WSIZE; | 804 | match_start -= WSIZE; |
| 805 | strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ | 805 | strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ |
| 806 | 806 | ||
| 807 | block_start -= (long) WSIZE; | 807 | block_start -= WSIZE; |
| 808 | 808 | ||
| 809 | for (n = 0; n < HASH_SIZE; n++) { | 809 | for (n = 0; n < HASH_SIZE; n++) { |
| 810 | m = head[n]; | 810 | m = head[n]; |
| 811 | head[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); | 811 | head[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0); |
| 812 | } | 812 | } |
| 813 | for (n = 0; n < WSIZE; n++) { | 813 | for (n = 0; n < WSIZE; n++) { |
| 814 | m = prev[n]; | 814 | m = prev[n]; |
| 815 | prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : NIL); | 815 | prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0); |
| 816 | /* If n is not on any hash chain, prev[n] is garbage but | 816 | /* If n is not on any hash chain, prev[n] is garbage but |
| 817 | * its value will never be used. | 817 | * its value will never be used. |
| 818 | */ | 818 | */ |
| @@ -830,15 +830,20 @@ static void fill_window(void) | |||
| 830 | } | 830 | } |
| 831 | } | 831 | } |
| 832 | 832 | ||
| 833 | |||
| 833 | /* =========================================================================== | 834 | /* =========================================================================== |
| 834 | * Flush the current block, with given end-of-file flag. | 835 | * Flush the current block, with given end-of-file flag. |
| 835 | * IN assertion: strstart is set to the end of the current match. | 836 | * IN assertion: strstart is set to the end of the current match. |
| 836 | */ | 837 | */ |
| 837 | #define FLUSH_BLOCK(eof) \ | 838 | #define FLUSH_BLOCK(eof) \ |
| 838 | flush_block(block_start >= 0L \ | 839 | flush_block( \ |
| 839 | ? (char*)&window[(unsigned)block_start] \ | 840 | block_start >= 0L \ |
| 840 | : (char*)NULL, \ | 841 | ? (char*)&window[(unsigned)block_start] \ |
| 841 | (long)strstart - block_start, (eof)) | 842 | : (char*)NULL, \ |
| 843 | (long)strstart - block_start, \ | ||
| 844 | (eof) \ | ||
| 845 | ) | ||
| 846 | |||
| 842 | 847 | ||
| 843 | /* =========================================================================== | 848 | /* =========================================================================== |
| 844 | * Same as above, but achieves better compression. We use a lazy | 849 | * Same as above, but achieves better compression. We use a lazy |
| @@ -915,8 +920,10 @@ static ulg deflate(void) | |||
| 915 | match_available = 0; | 920 | match_available = 0; |
| 916 | match_length = MIN_MATCH - 1; | 921 | match_length = MIN_MATCH - 1; |
| 917 | strstart++; | 922 | strstart++; |
| 918 | if (flush) | 923 | if (flush) { |
| 919 | FLUSH_BLOCK(0), block_start = strstart; | 924 | FLUSH_BLOCK(0); |
| 925 | block_start = strstart; | ||
| 926 | } | ||
| 920 | } else if (match_available) { | 927 | } else if (match_available) { |
| 921 | /* If there was no match at the previous position, output a | 928 | /* If there was no match at the previous position, output a |
| 922 | * single literal. If there was a match but the current match | 929 | * single literal. If there was a match but the current match |
| @@ -924,7 +931,8 @@ static ulg deflate(void) | |||
| 924 | */ | 931 | */ |
| 925 | Tracevv((stderr, "%c", window[strstart - 1])); | 932 | Tracevv((stderr, "%c", window[strstart - 1])); |
| 926 | if (ct_tally(0, window[strstart - 1])) { | 933 | if (ct_tally(0, window[strstart - 1])) { |
| 927 | FLUSH_BLOCK(0), block_start = strstart; | 934 | FLUSH_BLOCK(0); |
| 935 | block_start = strstart; | ||
| 928 | } | 936 | } |
| 929 | strstart++; | 937 | strstart++; |
| 930 | lookahead--; | 938 | lookahead--; |
| @@ -2246,7 +2254,7 @@ static int zip(int in, int out) | |||
| 2246 | ct_init(&attr, &method); | 2254 | ct_init(&attr, &method); |
| 2247 | lm_init(&deflate_flags); | 2255 | lm_init(&deflate_flags); |
| 2248 | 2256 | ||
| 2249 | put_8bit((uch) deflate_flags); /* extra flags */ | 2257 | put_8bit(deflate_flags); /* extra flags */ |
| 2250 | put_8bit(3); /* OS identifier = 3 (Unix) */ | 2258 | put_8bit(3); /* OS identifier = 3 (Unix) */ |
| 2251 | 2259 | ||
| 2252 | deflate(); | 2260 | deflate(); |
