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(); |