diff options
author | Ron Yorston <rmy@pobox.com> | 2018-02-13 09:44:44 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-02-13 09:44:44 +0000 |
commit | dc19a361bd6c6df30338371532691bbc7f7126bb (patch) | |
tree | 1fb2cd646d54b5f8e425c4f11f3e09fc21d1966b /archival | |
parent | 096aee2bb468d1ab044de36e176ed1f6c7e3674d (diff) | |
parent | 3459024bf404af814cacfe90a0deb719e282ae62 (diff) | |
download | busybox-w32-dc19a361bd6c6df30338371532691bbc7f7126bb.tar.gz busybox-w32-dc19a361bd6c6df30338371532691bbc7f7126bb.tar.bz2 busybox-w32-dc19a361bd6c6df30338371532691bbc7f7126bb.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'archival')
-rw-r--r-- | archival/bbunzip.c | 57 | ||||
-rw-r--r-- | archival/bzip2.c | 60 | ||||
-rw-r--r-- | archival/gzip.c | 425 | ||||
-rw-r--r-- | archival/libarchive/bz/blocksort.c | 311 | ||||
-rw-r--r-- | archival/libarchive/bz/bzlib.c | 20 | ||||
-rw-r--r-- | archival/libarchive/bz/bzlib_private.h | 28 | ||||
-rw-r--r-- | archival/libarchive/bz/compress.c | 329 | ||||
-rw-r--r-- | archival/libarchive/bz/huffman.c | 4 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 17 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 2 | ||||
-rw-r--r-- | archival/libarchive/get_header_ar.c | 4 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 49 | ||||
-rw-r--r-- | archival/libarchive/lzo1x_d.c | 3 | ||||
-rw-r--r-- | archival/lzop.c | 13 | ||||
-rw-r--r-- | archival/unzip.c | 4 |
15 files changed, 712 insertions, 614 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 301170fd4..2d810d131 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -21,19 +21,6 @@ | |||
21 | #include "libbb.h" | 21 | #include "libbb.h" |
22 | #include "bb_archive.h" | 22 | #include "bb_archive.h" |
23 | 23 | ||
24 | /* Note: must be kept in sync with archival/lzop.c */ | ||
25 | enum { | ||
26 | OPT_STDOUT = 1 << 0, | ||
27 | OPT_FORCE = 1 << 1, | ||
28 | /* only some decompressors: */ | ||
29 | OPT_KEEP = 1 << 2, | ||
30 | OPT_VERBOSE = 1 << 3, | ||
31 | OPT_QUIET = 1 << 4, | ||
32 | OPT_DECOMPRESS = 1 << 5, | ||
33 | OPT_TEST = 1 << 6, | ||
34 | SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION, | ||
35 | }; | ||
36 | |||
37 | static | 24 | static |
38 | int open_to_or_warn(int to_fd, const char *filename, int flags, int mode) | 25 | int open_to_or_warn(int to_fd, const char *filename, int flags, int mode) |
39 | { | 26 | { |
@@ -72,7 +59,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
72 | 59 | ||
73 | /* Open src */ | 60 | /* Open src */ |
74 | if (filename) { | 61 | if (filename) { |
75 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 62 | if (!(option_mask32 & BBUNPK_SEAMLESS_MAGIC)) { |
76 | if (stat(filename, &stat_buf) != 0) { | 63 | if (stat(filename, &stat_buf) != 0) { |
77 | err_name: | 64 | err_name: |
78 | bb_simple_perror_msg(filename); | 65 | bb_simple_perror_msg(filename); |
@@ -91,15 +78,15 @@ int FAST_FUNC bbunpack(char **argv, | |||
91 | xmove_fd(fd, STDIN_FILENO); | 78 | xmove_fd(fd, STDIN_FILENO); |
92 | } | 79 | } |
93 | } else | 80 | } else |
94 | if (option_mask32 & SEAMLESS_MAGIC) { | 81 | if (option_mask32 & BBUNPK_SEAMLESS_MAGIC) { |
95 | /* "clever zcat" on stdin */ | 82 | /* "clever zcat" on stdin */ |
96 | if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1)) | 83 | if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1)) |
97 | goto err; | 84 | goto err; |
98 | } | 85 | } |
99 | 86 | ||
100 | /* Special cases: test, stdout */ | 87 | /* Special cases: test, stdout */ |
101 | if (option_mask32 & (OPT_STDOUT|OPT_TEST)) { | 88 | if (option_mask32 & (BBUNPK_OPT_STDOUT|BBUNPK_OPT_TEST)) { |
102 | if (option_mask32 & OPT_TEST) | 89 | if (option_mask32 & BBUNPK_OPT_TEST) |
103 | if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0)) | 90 | if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0)) |
104 | xfunc_die(); | 91 | xfunc_die(); |
105 | filename = NULL; | 92 | filename = NULL; |
@@ -114,7 +101,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
114 | } | 101 | } |
115 | 102 | ||
116 | /* -f: overwrite existing output files */ | 103 | /* -f: overwrite existing output files */ |
117 | if (option_mask32 & OPT_FORCE) { | 104 | if (option_mask32 & BBUNPK_OPT_FORCE) { |
118 | unlink(new_name); | 105 | unlink(new_name); |
119 | } | 106 | } |
120 | 107 | ||
@@ -126,12 +113,12 @@ int FAST_FUNC bbunpack(char **argv, | |||
126 | } | 113 | } |
127 | 114 | ||
128 | /* Check that the input is sane */ | 115 | /* Check that the input is sane */ |
129 | if (!(option_mask32 & OPT_FORCE) && isatty(STDIN_FILENO)) { | 116 | if (!(option_mask32 & BBUNPK_OPT_FORCE) && isatty(STDIN_FILENO)) { |
130 | bb_error_msg_and_die("compressed data not read from terminal, " | 117 | bb_error_msg_and_die("compressed data not read from terminal, " |
131 | "use -f to force it"); | 118 | "use -f to force it"); |
132 | } | 119 | } |
133 | 120 | ||
134 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 121 | if (!(option_mask32 & BBUNPK_SEAMLESS_MAGIC)) { |
135 | init_transformer_state(&xstate); | 122 | init_transformer_state(&xstate); |
136 | /*xstate.signature_skipped = 0; - already is */ | 123 | /*xstate.signature_skipped = 0; - already is */ |
137 | /*xstate.src_fd = STDIN_FILENO; - already is */ | 124 | /*xstate.src_fd = STDIN_FILENO; - already is */ |
@@ -145,7 +132,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
145 | xfunc_die(); | 132 | xfunc_die(); |
146 | } | 133 | } |
147 | 134 | ||
148 | if (!(option_mask32 & OPT_STDOUT)) | 135 | if (!(option_mask32 & BBUNPK_OPT_STDOUT)) |
149 | xclose(STDOUT_FILENO); /* with error check! */ | 136 | xclose(STDOUT_FILENO); /* with error check! */ |
150 | 137 | ||
151 | if (filename) { | 138 | if (filename) { |
@@ -176,7 +163,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
176 | } | 163 | } |
177 | /* Extreme bloat for gunzip compat */ | 164 | /* Extreme bloat for gunzip compat */ |
178 | /* Some users do want this info... */ | 165 | /* Some users do want this info... */ |
179 | if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE)) { | 166 | if (ENABLE_DESKTOP && (option_mask32 & BBUNPK_OPT_VERBOSE)) { |
180 | unsigned percent = status | 167 | unsigned percent = status |
181 | ? ((uoff_t)stat_buf.st_size * 100u / (unsigned long long)status) | 168 | ? ((uoff_t)stat_buf.st_size * 100u / (unsigned long long)status) |
182 | : 0; | 169 | : 0; |
@@ -188,7 +175,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
188 | } | 175 | } |
189 | /* Delete _source_ file */ | 176 | /* Delete _source_ file */ |
190 | del = filename; | 177 | del = filename; |
191 | if (option_mask32 & OPT_KEEP) /* ... unless -k */ | 178 | if (option_mask32 & BBUNPK_OPT_KEEP) /* ... unless -k */ |
192 | del = NULL; | 179 | del = NULL; |
193 | } | 180 | } |
194 | if (ENABLE_PLATFORM_MINGW32) | 181 | if (ENABLE_PLATFORM_MINGW32) |
@@ -201,7 +188,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
201 | } | 188 | } |
202 | } while (*argv && *++argv); | 189 | } while (*argv && *++argv); |
203 | 190 | ||
204 | if (option_mask32 & OPT_STDOUT) | 191 | if (option_mask32 & BBUNPK_OPT_STDOUT) |
205 | xclose(STDOUT_FILENO); /* with error check! */ | 192 | xclose(STDOUT_FILENO); /* with error check! */ |
206 | 193 | ||
207 | return exitcode; | 194 | return exitcode; |
@@ -391,9 +378,9 @@ int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
391 | int gunzip_main(int argc UNUSED_PARAM, char **argv) | 378 | int gunzip_main(int argc UNUSED_PARAM, char **argv) |
392 | { | 379 | { |
393 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS | 380 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS |
394 | getopt32long(argv, "cfkvqdtn", gunzip_longopts); | 381 | getopt32long(argv, BBUNPK_OPTSTR "dtn", gunzip_longopts); |
395 | #else | 382 | #else |
396 | getopt32(argv, "cfkvqdtn"); | 383 | getopt32(argv, BBUNPK_OPTSTR "dtn"); |
397 | #endif | 384 | #endif |
398 | argv += optind; | 385 | argv += optind; |
399 | 386 | ||
@@ -402,7 +389,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
402 | * But if seamless magic is enabled, then we are much more clever. | 389 | * But if seamless magic is enabled, then we are much more clever. |
403 | */ | 390 | */ |
404 | if (ENABLE_ZCAT && (!ENABLE_GUNZIP || applet_name[1] == 'c')) | 391 | if (ENABLE_ZCAT && (!ENABLE_GUNZIP || applet_name[1] == 'c')) |
405 | option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC; | 392 | option_mask32 |= BBUNPK_OPT_STDOUT | BBUNPK_SEAMLESS_MAGIC; |
406 | 393 | ||
407 | return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); | 394 | return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); |
408 | } | 395 | } |
@@ -455,10 +442,10 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
455 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 442 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
456 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 443 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
457 | { | 444 | { |
458 | getopt32(argv, "cfkvqdt"); | 445 | getopt32(argv, BBUNPK_OPTSTR "dt"); |
459 | argv += optind; | 446 | argv += optind; |
460 | if (ENABLE_BZCAT && (!ENABLE_BUNZIP2 || applet_name[2] == 'c')) /* bzcat */ | 447 | if (ENABLE_BZCAT && (!ENABLE_BUNZIP2 || applet_name[2] == 'c')) /* bzcat */ |
461 | option_mask32 |= OPT_STDOUT; | 448 | option_mask32 |= BBUNPK_OPT_STDOUT; |
462 | 449 | ||
463 | return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2"); | 450 | return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2"); |
464 | } | 451 | } |
@@ -528,15 +515,15 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
528 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 515 | int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
529 | int unlzma_main(int argc UNUSED_PARAM, char **argv) | 516 | int unlzma_main(int argc UNUSED_PARAM, char **argv) |
530 | { | 517 | { |
531 | IF_LZMA(int opts =) getopt32(argv, "cfkvqdt"); | 518 | IF_LZMA(int opts =) getopt32(argv, BBUNPK_OPTSTR "dt"); |
532 | # if ENABLE_LZMA | 519 | # if ENABLE_LZMA |
533 | /* lzma without -d or -t? */ | 520 | /* lzma without -d or -t? */ |
534 | if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) | 521 | if (applet_name[2] == 'm' && !(opts & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST))) |
535 | bb_show_usage(); | 522 | bb_show_usage(); |
536 | # endif | 523 | # endif |
537 | /* lzcat? */ | 524 | /* lzcat? */ |
538 | if (ENABLE_LZCAT && applet_name[2] == 'c') | 525 | if (ENABLE_LZCAT && applet_name[2] == 'c') |
539 | option_mask32 |= OPT_STDOUT; | 526 | option_mask32 |= BBUNPK_OPT_STDOUT; |
540 | 527 | ||
541 | argv += optind; | 528 | argv += optind; |
542 | return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma"); | 529 | return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma"); |
@@ -596,15 +583,15 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
596 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 583 | int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
597 | int unxz_main(int argc UNUSED_PARAM, char **argv) | 584 | int unxz_main(int argc UNUSED_PARAM, char **argv) |
598 | { | 585 | { |
599 | IF_XZ(int opts =) getopt32(argv, "cfkvqdt"); | 586 | IF_XZ(int opts =) getopt32(argv, BBUNPK_OPTSTR "dt"); |
600 | # if ENABLE_XZ | 587 | # if ENABLE_XZ |
601 | /* xz without -d or -t? */ | 588 | /* xz without -d or -t? */ |
602 | if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) | 589 | if (applet_name[2] == '\0' && !(opts & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST))) |
603 | bb_show_usage(); | 590 | bb_show_usage(); |
604 | # endif | 591 | # endif |
605 | /* xzcat? */ | 592 | /* xzcat? */ |
606 | if (ENABLE_XZCAT && applet_name[2] == 'c') | 593 | if (ENABLE_XZCAT && applet_name[2] == 'c') |
607 | option_mask32 |= OPT_STDOUT; | 594 | option_mask32 |= BBUNPK_OPT_STDOUT; |
608 | 595 | ||
609 | argv += optind; | 596 | argv += optind; |
610 | return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz"); | 597 | return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz"); |
diff --git a/archival/bzip2.c b/archival/bzip2.c index d6fd9296d..357891ca3 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -19,6 +19,23 @@ | |||
19 | //config: Unless you have a specific application which requires bzip2, you | 19 | //config: Unless you have a specific application which requires bzip2, you |
20 | //config: should probably say N here. | 20 | //config: should probably say N here. |
21 | //config: | 21 | //config: |
22 | //config:config BZIP2_SMALL | ||
23 | //config: int "Trade bytes for speed (0:fast, 9:small)" | ||
24 | //config: default 8 # all "fast or small" options default to small | ||
25 | //config: range 0 9 | ||
26 | //config: depends on BZIP2 | ||
27 | //config: help | ||
28 | //config: Trade code size versus speed. | ||
29 | //config: Approximate values with gcc-6.3.0 "bzip -9" compressing | ||
30 | //config: linux-4.15.tar were: | ||
31 | //config: value time (sec) code size (386) | ||
32 | //config: 9 (smallest) 70.11 7687 | ||
33 | //config: 8 67.93 8091 | ||
34 | //config: 7 67.88 8405 | ||
35 | //config: 6 67.78 8624 | ||
36 | //config: 5 67.05 9427 | ||
37 | //config: 4-0 (fastest) 64.14 12083 | ||
38 | //config: | ||
22 | //config:config FEATURE_BZIP2_DECOMPRESS | 39 | //config:config FEATURE_BZIP2_DECOMPRESS |
23 | //config: bool "Enable decompression" | 40 | //config: bool "Enable decompression" |
24 | //config: default y | 41 | //config: default y |
@@ -48,7 +65,11 @@ | |||
48 | #include "libbb.h" | 65 | #include "libbb.h" |
49 | #include "bb_archive.h" | 66 | #include "bb_archive.h" |
50 | 67 | ||
51 | #define CONFIG_BZIP2_FAST 1 | 68 | #if CONFIG_BZIP2_SMALL >= 4 |
69 | #define BZIP2_SPEED (9 - CONFIG_BZIP2_SMALL) | ||
70 | #else | ||
71 | #define BZIP2_SPEED 5 | ||
72 | #endif | ||
52 | 73 | ||
53 | /* Speed test: | 74 | /* Speed test: |
54 | * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). | 75 | * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). |
@@ -56,7 +77,7 @@ | |||
56 | * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). | 77 | * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). |
57 | * At SPEED 5 difference is 32.7%. | 78 | * At SPEED 5 difference is 32.7%. |
58 | * | 79 | * |
59 | * Test run of all CONFIG_BZIP2_FAST values on a 11Mb text file: | 80 | * Test run of all BZIP2_SPEED values on a 11Mb text file: |
60 | * Size Time (3 runs) | 81 | * Size Time (3 runs) |
61 | * 0: 10828 4.145 4.146 4.148 | 82 | * 0: 10828 4.145 4.146 4.148 |
62 | * 1: 11097 3.845 3.860 3.861 | 83 | * 1: 11097 3.845 3.860 3.861 |
@@ -83,15 +104,13 @@ | |||
83 | /* No point in being shy and having very small buffer here. | 104 | /* No point in being shy and having very small buffer here. |
84 | * bzip2 internal buffers are much bigger anyway, hundreds of kbytes. | 105 | * bzip2 internal buffers are much bigger anyway, hundreds of kbytes. |
85 | * If iobuf is several pages long, malloc() may use mmap, | 106 | * If iobuf is several pages long, malloc() may use mmap, |
86 | * making iobuf is page aligned and thus (maybe) have one memcpy less | 107 | * making iobuf page aligned and thus (maybe) have one memcpy less |
87 | * if kernel is clever enough. | 108 | * if kernel is clever enough. |
88 | */ | 109 | */ |
89 | enum { | 110 | enum { |
90 | IOBUF_SIZE = 8 * 1024 | 111 | IOBUF_SIZE = 8 * 1024 |
91 | }; | 112 | }; |
92 | 113 | ||
93 | static uint8_t level; | ||
94 | |||
95 | /* NB: compressStream() has to return -1 on errors, not die. | 114 | /* NB: compressStream() has to return -1 on errors, not die. |
96 | * bbunpack() will correctly clean up in this case | 115 | * bbunpack() will correctly clean up in this case |
97 | * (delete incomplete .bz2 file) | 116 | * (delete incomplete .bz2 file) |
@@ -143,6 +162,7 @@ static | |||
143 | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate UNUSED_PARAM) | 162 | IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate UNUSED_PARAM) |
144 | { | 163 | { |
145 | IF_DESKTOP(long long) int total; | 164 | IF_DESKTOP(long long) int total; |
165 | unsigned opt, level; | ||
146 | ssize_t count; | 166 | ssize_t count; |
147 | bz_stream bzs; /* it's small */ | 167 | bz_stream bzs; /* it's small */ |
148 | #define strm (&bzs) | 168 | #define strm (&bzs) |
@@ -151,6 +171,17 @@ IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate U | |||
151 | #define wbuf (iobuf + IOBUF_SIZE) | 171 | #define wbuf (iobuf + IOBUF_SIZE) |
152 | 172 | ||
153 | iobuf = xmalloc(2 * IOBUF_SIZE); | 173 | iobuf = xmalloc(2 * IOBUF_SIZE); |
174 | |||
175 | opt = option_mask32 >> (BBUNPK_OPTSTRLEN IF_FEATURE_BZIP2_DECOMPRESS(+ 2) + 2); | ||
176 | /* skipped BBUNPK_OPTSTR, "dt" and "zs" bits */ | ||
177 | opt |= 0x100; /* if nothing else, assume -9 */ | ||
178 | level = 0; | ||
179 | for (;;) { | ||
180 | level++; | ||
181 | if (opt & 1) break; | ||
182 | opt >>= 1; | ||
183 | } | ||
184 | |||
154 | BZ2_bzCompressInit(strm, level); | 185 | BZ2_bzCompressInit(strm, level); |
155 | 186 | ||
156 | while (1) { | 187 | while (1) { |
@@ -196,26 +227,19 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv) | |||
196 | */ | 227 | */ |
197 | 228 | ||
198 | opt = getopt32(argv, "^" | 229 | opt = getopt32(argv, "^" |
199 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | 230 | /* Must match BBUNPK_foo constants! */ |
200 | "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs" | 231 | BBUNPK_OPTSTR IF_FEATURE_BZIP2_DECOMPRESS("dt") "zs123456789" |
201 | "\0" "s2" /* -s means -2 (compatibility) */ | 232 | "\0" "s2" /* -s means -2 (compatibility) */ |
202 | ); | 233 | ); |
203 | #if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ | 234 | #if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ |
204 | if (opt & 0x30) // -d and/or -t | 235 | if (opt & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST)) /* -d and/or -t */ |
205 | return bunzip2_main(argc, argv); | 236 | return bunzip2_main(argc, argv); |
206 | opt >>= 6; | ||
207 | #else | 237 | #else |
208 | opt >>= 4; | 238 | /* clear "decompress" and "test" bits (or bbunpack() can get confused) */ |
239 | /* in !BZIP2_DECOMPRESS config, these bits are -zs and are unused */ | ||
240 | option_mask32 = opt & ~(BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST); | ||
209 | #endif | 241 | #endif |
210 | opt = (uint8_t)opt; /* isolate bits for -1..-8 */ | ||
211 | opt |= 0x100; /* if nothing else, assume -9 */ | ||
212 | level = 1; | ||
213 | while (!(opt & 1)) { | ||
214 | level++; | ||
215 | opt >>= 1; | ||
216 | } | ||
217 | 242 | ||
218 | argv += optind; | 243 | argv += optind; |
219 | option_mask32 &= 0xf; /* ignore all except -cfkv */ | ||
220 | return bbunpack(argv, compressStream, append_ext, "bz2"); | 244 | return bbunpack(argv, compressStream, append_ext, "bz2"); |
221 | } | 245 | } |
diff --git a/archival/gzip.c b/archival/gzip.c index ac6633044..c5a1fe9b4 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -15,21 +15,6 @@ | |||
15 | * | 15 | * |
16 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 16 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
17 | */ | 17 | */ |
18 | /* big objects in bss: | ||
19 | * 00000020 b bl_count | ||
20 | * 00000074 b base_length | ||
21 | * 00000078 b base_dist | ||
22 | * 00000078 b static_dtree | ||
23 | * 0000009c b bl_tree | ||
24 | * 000000f4 b dyn_dtree | ||
25 | * 00000100 b length_code | ||
26 | * 00000200 b dist_code | ||
27 | * 0000023d b depth | ||
28 | * 00000400 b flag_buf | ||
29 | * 0000047a b heap | ||
30 | * 00000480 b static_ltree | ||
31 | * 000008f4 b dyn_ltree | ||
32 | */ | ||
33 | /* TODO: full support for -v for DESKTOP | 18 | /* TODO: full support for -v for DESKTOP |
34 | * "/usr/bin/gzip -v a bogus aa" should say: | 19 | * "/usr/bin/gzip -v a bogus aa" should say: |
35 | a: 85.1% -- replaced with a.gz | 20 | a: 85.1% -- replaced with a.gz |
@@ -108,12 +93,12 @@ aa: 85.1% -- replaced with aa.gz | |||
108 | #include "libbb.h" | 93 | #include "libbb.h" |
109 | #include "bb_archive.h" | 94 | #include "bb_archive.h" |
110 | 95 | ||
111 | |||
112 | /* =========================================================================== | 96 | /* =========================================================================== |
113 | */ | 97 | */ |
114 | //#define DEBUG 1 | 98 | //#define DEBUG 1 |
115 | /* Diagnostic functions */ | 99 | /* Diagnostic functions */ |
116 | #ifdef DEBUG | 100 | #ifdef DEBUG |
101 | static int verbose; | ||
117 | # define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); } | 102 | # define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); } |
118 | # define Trace(x) fprintf x | 103 | # define Trace(x) fprintf x |
119 | # define Tracev(x) {if (verbose) fprintf x; } | 104 | # define Tracev(x) {if (verbose) fprintf x; } |
@@ -129,7 +114,6 @@ aa: 85.1% -- replaced with aa.gz | |||
129 | # define Tracecv(c,x) | 114 | # define Tracecv(c,x) |
130 | #endif | 115 | #endif |
131 | 116 | ||
132 | |||
133 | /* =========================================================================== | 117 | /* =========================================================================== |
134 | */ | 118 | */ |
135 | #if CONFIG_GZIP_FAST == 0 | 119 | #if CONFIG_GZIP_FAST == 0 |
@@ -225,7 +209,6 @@ aa: 85.1% -- replaced with aa.gz | |||
225 | # define MAX_SUFFIX 30 | 209 | # define MAX_SUFFIX 30 |
226 | #endif | 210 | #endif |
227 | 211 | ||
228 | |||
229 | /* =========================================================================== | 212 | /* =========================================================================== |
230 | * Compile with MEDIUM_MEM to reduce the memory requirements or | 213 | * Compile with MEDIUM_MEM to reduce the memory requirements or |
231 | * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the | 214 | * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the |
@@ -234,15 +217,14 @@ aa: 85.1% -- replaced with aa.gz | |||
234 | * affects the compression ratio. The compressed output | 217 | * affects the compression ratio. The compressed output |
235 | * is still correct, and might even be smaller in some cases. | 218 | * is still correct, and might even be smaller in some cases. |
236 | */ | 219 | */ |
237 | |||
238 | #ifdef SMALL_MEM | 220 | #ifdef SMALL_MEM |
239 | # define HASH_BITS 13 /* Number of bits used to hash strings */ | 221 | # define HASH_BITS 13 /* Number of bits used to hash strings */ |
240 | #endif | 222 | #endif |
241 | #ifdef MEDIUM_MEM | 223 | #ifdef MEDIUM_MEM |
242 | # define HASH_BITS 14 | 224 | # define HASH_BITS 14 |
243 | #endif | 225 | #endif |
244 | #ifndef HASH_BITS | 226 | #ifndef HASH_BITS |
245 | # define HASH_BITS 15 | 227 | # define HASH_BITS 15 |
246 | /* For portability to 16 bit machines, do not use values above 15. */ | 228 | /* For portability to 16 bit machines, do not use values above 15. */ |
247 | #endif | 229 | #endif |
248 | 230 | ||
@@ -255,7 +237,6 @@ aa: 85.1% -- replaced with aa.gz | |||
255 | #endif | 237 | #endif |
256 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ | 238 | /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ |
257 | 239 | ||
258 | |||
259 | /* =========================================================================== | 240 | /* =========================================================================== |
260 | * These types are not really 'char', 'short' and 'long' | 241 | * These types are not really 'char', 'short' and 'long' |
261 | */ | 242 | */ |
@@ -312,46 +293,10 @@ enum { | |||
312 | #endif /* ENABLE_FEATURE_GZIP_LEVELS */ | 293 | #endif /* ENABLE_FEATURE_GZIP_LEVELS */ |
313 | }; | 294 | }; |
314 | 295 | ||
315 | |||
316 | struct globals { | 296 | struct globals { |
297 | /* =========================================================================== */ | ||
298 | /* global buffers, allocated once */ | ||
317 | 299 | ||
318 | #if ENABLE_FEATURE_GZIP_LEVELS | ||
319 | unsigned max_chain_length; | ||
320 | unsigned max_lazy_match; | ||
321 | unsigned good_match; | ||
322 | unsigned nice_match; | ||
323 | #define max_chain_length (G1.max_chain_length) | ||
324 | #define max_lazy_match (G1.max_lazy_match) | ||
325 | #define good_match (G1.good_match) | ||
326 | #define nice_match (G1.nice_match) | ||
327 | #endif | ||
328 | |||
329 | lng block_start; | ||
330 | |||
331 | /* window position at the beginning of the current output block. Gets | ||
332 | * negative when the window is moved backwards. | ||
333 | */ | ||
334 | unsigned ins_h; /* hash index of string to be inserted */ | ||
335 | |||
336 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH) | ||
337 | /* Number of bits by which ins_h and del_h must be shifted at each | ||
338 | * input step. It must be such that after MIN_MATCH steps, the oldest | ||
339 | * byte no longer takes part in the hash key, that is: | ||
340 | * H_SHIFT * MIN_MATCH >= HASH_BITS | ||
341 | */ | ||
342 | |||
343 | unsigned prev_length; | ||
344 | |||
345 | /* Length of the best match at previous step. Matches not greater than this | ||
346 | * are discarded. This is used in the lazy match evaluation. | ||
347 | */ | ||
348 | |||
349 | unsigned strstart; /* start of string to insert */ | ||
350 | unsigned match_start; /* start of matching string */ | ||
351 | unsigned lookahead; /* number of valid bytes ahead in window */ | ||
352 | |||
353 | /* =========================================================================== | ||
354 | */ | ||
355 | #define DECLARE(type, array, size) \ | 300 | #define DECLARE(type, array, size) \ |
356 | type * array | 301 | type * array |
357 | #define ALLOC(type, array, size) \ | 302 | #define ALLOC(type, array, size) \ |
@@ -359,8 +304,6 @@ struct globals { | |||
359 | #define FREE(array) \ | 304 | #define FREE(array) \ |
360 | do { free(array); array = NULL; } while (0) | 305 | do { free(array); array = NULL; } while (0) |
361 | 306 | ||
362 | /* global buffers */ | ||
363 | |||
364 | /* buffer for literals or lengths */ | 307 | /* buffer for literals or lengths */ |
365 | /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ | 308 | /* DECLARE(uch, l_buf, LIT_BUFSIZE); */ |
366 | DECLARE(uch, l_buf, INBUFSIZ); | 309 | DECLARE(uch, l_buf, INBUFSIZ); |
@@ -390,6 +333,46 @@ struct globals { | |||
390 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ | 333 | /* DECLARE(Pos, head, 1<<HASH_BITS); */ |
391 | #define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ | 334 | #define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ |
392 | 335 | ||
336 | /* =========================================================================== */ | ||
337 | /* all members below are zeroed out in pack_gzip() for each next file */ | ||
338 | |||
339 | uint32_t crc; /* shift register contents */ | ||
340 | /*uint32_t *crc_32_tab;*/ | ||
341 | |||
342 | #if ENABLE_FEATURE_GZIP_LEVELS | ||
343 | unsigned max_chain_length; | ||
344 | unsigned max_lazy_match; | ||
345 | unsigned good_match; | ||
346 | unsigned nice_match; | ||
347 | #define max_chain_length (G1.max_chain_length) | ||
348 | #define max_lazy_match (G1.max_lazy_match) | ||
349 | #define good_match (G1.good_match) | ||
350 | #define nice_match (G1.nice_match) | ||
351 | #endif | ||
352 | |||
353 | /* window position at the beginning of the current output block. Gets | ||
354 | * negative when the window is moved backwards. | ||
355 | */ | ||
356 | lng block_start; | ||
357 | |||
358 | unsigned ins_h; /* hash index of string to be inserted */ | ||
359 | |||
360 | /* Number of bits by which ins_h and del_h must be shifted at each | ||
361 | * input step. It must be such that after MIN_MATCH steps, the oldest | ||
362 | * byte no longer takes part in the hash key, that is: | ||
363 | * H_SHIFT * MIN_MATCH >= HASH_BITS | ||
364 | */ | ||
365 | #define H_SHIFT ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH) | ||
366 | |||
367 | /* Length of the best match at previous step. Matches not greater than this | ||
368 | * are discarded. This is used in the lazy match evaluation. | ||
369 | */ | ||
370 | unsigned prev_length; | ||
371 | |||
372 | unsigned strstart; /* start of string to insert */ | ||
373 | unsigned match_start; /* start of matching string */ | ||
374 | unsigned lookahead; /* number of valid bytes ahead in window */ | ||
375 | |||
393 | /* number of input bytes */ | 376 | /* number of input bytes */ |
394 | ulg isize; /* only 32 bits stored in .gz file */ | 377 | ulg isize; /* only 32 bits stored in .gz file */ |
395 | 378 | ||
@@ -401,40 +384,35 @@ struct globals { | |||
401 | unsigned insize; /* valid bytes in l_buf */ | 384 | unsigned insize; /* valid bytes in l_buf */ |
402 | #endif | 385 | #endif |
403 | unsigned outcnt; /* bytes in output buffer */ | 386 | unsigned outcnt; /* bytes in output buffer */ |
404 | |||
405 | smallint eofile; /* flag set at end of input file */ | 387 | smallint eofile; /* flag set at end of input file */ |
406 | 388 | ||
407 | /* =========================================================================== | 389 | /* =========================================================================== |
408 | * Local data used by the "bit string" routines. | 390 | * Local data used by the "bit string" routines. |
409 | */ | 391 | */ |
410 | 392 | ||
411 | unsigned short bi_buf; | ||
412 | |||
413 | /* Output buffer. bits are inserted starting at the bottom (least significant | 393 | /* Output buffer. bits are inserted starting at the bottom (least significant |
414 | * bits). | 394 | * bits). |
415 | */ | 395 | */ |
396 | unsigned bi_buf; /* was unsigned short */ | ||
416 | 397 | ||
417 | #undef BUF_SIZE | 398 | #undef BUF_SIZE |
418 | #define BUF_SIZE (8 * sizeof(G1.bi_buf)) | 399 | #define BUF_SIZE (int)(8 * sizeof(G1.bi_buf)) |
400 | |||
419 | /* Number of bits used within bi_buf. (bi_buf might be implemented on | 401 | /* Number of bits used within bi_buf. (bi_buf might be implemented on |
420 | * more than 16 bits on some systems.) | 402 | * more than 16 bits on some systems.) |
421 | */ | 403 | */ |
422 | 404 | unsigned bi_valid; | |
423 | int bi_valid; | ||
424 | |||
425 | /* Current input function. Set to mem_read for in-memory compression */ | ||
426 | 405 | ||
427 | #ifdef DEBUG | 406 | #ifdef DEBUG |
428 | ulg bits_sent; /* bit length of the compressed data */ | 407 | ulg bits_sent; /* bit length of the compressed data */ |
408 | # define DEBUG_bits_sent(v) (void)(G1.bits_sent v) | ||
409 | #else | ||
410 | # define DEBUG_bits_sent(v) ((void)0) | ||
429 | #endif | 411 | #endif |
430 | |||
431 | /*uint32_t *crc_32_tab;*/ | ||
432 | uint32_t crc; /* shift register contents */ | ||
433 | }; | 412 | }; |
434 | 413 | ||
435 | #define G1 (*(ptr_to_globals - 1)) | 414 | #define G1 (*(ptr_to_globals - 1)) |
436 | 415 | ||
437 | |||
438 | /* =========================================================================== | 416 | /* =========================================================================== |
439 | * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. | 417 | * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. |
440 | * (used for the compressed data only) | 418 | * (used for the compressed data only) |
@@ -448,7 +426,6 @@ static void flush_outbuf(void) | |||
448 | G1.outcnt = 0; | 426 | G1.outcnt = 0; |
449 | } | 427 | } |
450 | 428 | ||
451 | |||
452 | /* =========================================================================== | 429 | /* =========================================================================== |
453 | */ | 430 | */ |
454 | /* put_8bit is used for the compressed output */ | 431 | /* put_8bit is used for the compressed output */ |
@@ -473,12 +450,13 @@ static void put_16bit(ush w) | |||
473 | if (outcnt < OUTBUFSIZ-2) { | 450 | if (outcnt < OUTBUFSIZ-2) { |
474 | /* Common case */ | 451 | /* Common case */ |
475 | ush *dst16 = (void*) dst; | 452 | ush *dst16 = (void*) dst; |
476 | *dst16 = w; /* unalinged LSB 16-bit store */ | 453 | *dst16 = w; /* unaligned LSB 16-bit store */ |
477 | G1.outcnt = outcnt + 2; | 454 | G1.outcnt = outcnt + 2; |
478 | return; | 455 | return; |
479 | } | 456 | } |
480 | *dst = (uch)w; | 457 | *dst = (uch)w; |
481 | w >>= 8; | 458 | w >>= 8; |
459 | G1.outcnt = ++outcnt; | ||
482 | #else | 460 | #else |
483 | *dst = (uch)w; | 461 | *dst = (uch)w; |
484 | w >>= 8; | 462 | w >>= 8; |
@@ -488,20 +466,38 @@ static void put_16bit(ush w) | |||
488 | G1.outcnt = outcnt + 2; | 466 | G1.outcnt = outcnt + 2; |
489 | return; | 467 | return; |
490 | } | 468 | } |
469 | G1.outcnt = ++outcnt; | ||
491 | #endif | 470 | #endif |
492 | 471 | ||
493 | /* Slowpath: we will need to do flush_outbuf() */ | 472 | /* Slowpath: we will need to do flush_outbuf() */ |
494 | G1.outcnt = ++outcnt; | ||
495 | if (outcnt == OUTBUFSIZ) | 473 | if (outcnt == OUTBUFSIZ) |
496 | flush_outbuf(); | 474 | flush_outbuf(); /* here */ |
497 | put_8bit(w); | 475 | put_8bit(w); /* or here */ |
498 | } | 476 | } |
499 | 477 | ||
478 | #define OPTIMIZED_PUT_32BIT (CONFIG_GZIP_FAST > 0 && BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN) | ||
500 | static void put_32bit(ulg n) | 479 | static void put_32bit(ulg n) |
501 | { | 480 | { |
481 | if (OPTIMIZED_PUT_32BIT) { | ||
482 | unsigned outcnt = G1.outcnt; | ||
483 | if (outcnt < OUTBUFSIZ-4) { | ||
484 | /* Common case */ | ||
485 | ulg *dst32 = (void*) &G1.outbuf[outcnt]; | ||
486 | *dst32 = n; /* unaligned LSB 32-bit store */ | ||
487 | //bb_error_msg("%p", dst32); // store alignment debugging | ||
488 | G1.outcnt = outcnt + 4; | ||
489 | return; | ||
490 | } | ||
491 | } | ||
502 | put_16bit(n); | 492 | put_16bit(n); |
503 | put_16bit(n >> 16); | 493 | put_16bit(n >> 16); |
504 | } | 494 | } |
495 | static ALWAYS_INLINE void flush_outbuf_if_32bit_optimized(void) | ||
496 | { | ||
497 | /* If put_32bit() performs 32bit stores && it is used in send_bits() */ | ||
498 | if (OPTIMIZED_PUT_32BIT && BUF_SIZE > 16) | ||
499 | flush_outbuf(); | ||
500 | } | ||
505 | 501 | ||
506 | /* =========================================================================== | 502 | /* =========================================================================== |
507 | * Run a set of bytes through the crc shift register. If s is a NULL | 503 | * Run a set of bytes through the crc shift register. If s is a NULL |
@@ -513,7 +509,6 @@ static void updcrc(uch * s, unsigned n) | |||
513 | G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table /*G1.crc_32_tab*/); | 509 | G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table /*G1.crc_32_tab*/); |
514 | } | 510 | } |
515 | 511 | ||
516 | |||
517 | /* =========================================================================== | 512 | /* =========================================================================== |
518 | * Read a new buffer from the current input file, perform end-of-line | 513 | * Read a new buffer from the current input file, perform end-of-line |
519 | * translation, and update the crc and input file size. | 514 | * translation, and update the crc and input file size. |
@@ -534,34 +529,45 @@ static unsigned file_read(void *buf, unsigned size) | |||
534 | return len; | 529 | return len; |
535 | } | 530 | } |
536 | 531 | ||
537 | |||
538 | /* =========================================================================== | 532 | /* =========================================================================== |
539 | * Send a value on a given number of bits. | 533 | * Send a value on a given number of bits. |
540 | * IN assertion: length <= 16 and value fits in length bits. | 534 | * IN assertion: length <= 16 and value fits in length bits. |
541 | */ | 535 | */ |
542 | static void send_bits(int value, int length) | 536 | static void send_bits(unsigned value, unsigned length) |
543 | { | 537 | { |
538 | unsigned new_buf; | ||
539 | |||
544 | #ifdef DEBUG | 540 | #ifdef DEBUG |
545 | Tracev((stderr, " l %2d v %4x ", length, value)); | 541 | Tracev((stderr, " l %2d v %4x ", length, value)); |
546 | Assert(length > 0 && length <= 15, "invalid length"); | 542 | Assert(length > 0 && length <= 15, "invalid length"); |
547 | G1.bits_sent += length; | 543 | DEBUG_bits_sent(+= length); |
548 | #endif | 544 | #endif |
549 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and | 545 | BUILD_BUG_ON(BUF_SIZE != 32 && BUF_SIZE != 16); |
550 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | 546 | |
551 | * unused bits in value. | 547 | new_buf = G1.bi_buf | (value << G1.bi_valid); |
552 | */ | 548 | /* NB: the above may sometimes do "<< 32" shift (undefined) |
553 | if (G1.bi_valid > (int) BUF_SIZE - length) { | 549 | * if check below is changed to "length > BUF_SIZE" instead of >= */ |
554 | G1.bi_buf |= (value << G1.bi_valid); | 550 | length += G1.bi_valid; |
555 | put_16bit(G1.bi_buf); | 551 | |
556 | G1.bi_buf = (ush) value >> (BUF_SIZE - G1.bi_valid); | 552 | /* If bi_buf is full */ |
557 | G1.bi_valid += length - BUF_SIZE; | 553 | if (length >= BUF_SIZE) { |
558 | } else { | 554 | /* ...use (valid) bits from bi_buf and |
559 | G1.bi_buf |= value << G1.bi_valid; | 555 | * (BUF_SIZE - bi_valid) bits from value, |
560 | G1.bi_valid += length; | 556 | * leaving (width - (BUF_SIZE-bi_valid)) unused bits in value. |
557 | */ | ||
558 | value >>= (BUF_SIZE - G1.bi_valid); | ||
559 | if (BUF_SIZE == 32) { | ||
560 | put_32bit(new_buf); | ||
561 | } else { /* 16 */ | ||
562 | put_16bit(new_buf); | ||
563 | } | ||
564 | new_buf = value; | ||
565 | length -= BUF_SIZE; | ||
561 | } | 566 | } |
567 | G1.bi_buf = new_buf; | ||
568 | G1.bi_valid = length; | ||
562 | } | 569 | } |
563 | 570 | ||
564 | |||
565 | /* =========================================================================== | 571 | /* =========================================================================== |
566 | * Reverse the first len bits of a code, using straightforward code (a faster | 572 | * Reverse the first len bits of a code, using straightforward code (a faster |
567 | * method would use a table) | 573 | * method would use a table) |
@@ -579,25 +585,24 @@ static unsigned bi_reverse(unsigned code, int len) | |||
579 | } | 585 | } |
580 | } | 586 | } |
581 | 587 | ||
582 | |||
583 | /* =========================================================================== | 588 | /* =========================================================================== |
584 | * Write out any remaining bits in an incomplete byte. | 589 | * Write out any remaining bits in an incomplete byte. |
585 | */ | 590 | */ |
586 | static void bi_windup(void) | 591 | static void bi_windup(void) |
587 | { | 592 | { |
588 | if (G1.bi_valid > 8) { | 593 | unsigned bits = G1.bi_buf; |
589 | put_16bit(G1.bi_buf); | 594 | int cnt = G1.bi_valid; |
590 | } else if (G1.bi_valid > 0) { | 595 | |
591 | put_8bit(G1.bi_buf); | 596 | while (cnt > 0) { |
597 | put_8bit(bits); | ||
598 | bits >>= 8; | ||
599 | cnt -= 8; | ||
592 | } | 600 | } |
593 | G1.bi_buf = 0; | 601 | G1.bi_buf = 0; |
594 | G1.bi_valid = 0; | 602 | G1.bi_valid = 0; |
595 | #ifdef DEBUG | 603 | DEBUG_bits_sent(= (G1.bits_sent + 7) & ~7); |
596 | G1.bits_sent = (G1.bits_sent + 7) & ~7; | ||
597 | #endif | ||
598 | } | 604 | } |
599 | 605 | ||
600 | |||
601 | /* =========================================================================== | 606 | /* =========================================================================== |
602 | * Copy a stored block to the zip file, storing first the length and its | 607 | * Copy a stored block to the zip file, storing first the length and its |
603 | * one's complement if requested. | 608 | * one's complement if requested. |
@@ -607,21 +612,19 @@ static void copy_block(char *buf, unsigned len, int header) | |||
607 | bi_windup(); /* align on byte boundary */ | 612 | bi_windup(); /* align on byte boundary */ |
608 | 613 | ||
609 | if (header) { | 614 | if (header) { |
610 | put_16bit(len); | 615 | unsigned v = ((uint16_t)len) | ((~len) << 16); |
611 | put_16bit(~len); | 616 | put_32bit(v); |
612 | #ifdef DEBUG | 617 | DEBUG_bits_sent(+= 2 * 16); |
613 | G1.bits_sent += 2 * 16; | ||
614 | #endif | ||
615 | } | 618 | } |
616 | #ifdef DEBUG | 619 | DEBUG_bits_sent(+= (ulg) len << 3); |
617 | G1.bits_sent += (ulg) len << 3; | ||
618 | #endif | ||
619 | while (len--) { | 620 | while (len--) { |
620 | put_8bit(*buf++); | 621 | put_8bit(*buf++); |
621 | } | 622 | } |
623 | /* The above can 32-bit misalign outbuf */ | ||
624 | if (G1.outcnt & 3) /* syscalls are expensive, is it really misaligned? */ | ||
625 | flush_outbuf_if_32bit_optimized(); | ||
622 | } | 626 | } |
623 | 627 | ||
624 | |||
625 | /* =========================================================================== | 628 | /* =========================================================================== |
626 | * Fill the window when the lookahead becomes insufficient. | 629 | * Fill the window when the lookahead becomes insufficient. |
627 | * Updates strstart and lookahead, and sets eofile if end of input file. | 630 | * Updates strstart and lookahead, and sets eofile if end of input file. |
@@ -679,7 +682,12 @@ static void fill_window(void) | |||
679 | } | 682 | } |
680 | } | 683 | } |
681 | } | 684 | } |
682 | 685 | /* Both users fill window with the same loop: */ | |
686 | static void fill_window_if_needed(void) | ||
687 | { | ||
688 | while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile) | ||
689 | fill_window(); | ||
690 | } | ||
683 | 691 | ||
684 | /* =========================================================================== | 692 | /* =========================================================================== |
685 | * Set match_start to the longest match starting at the given string and | 693 | * Set match_start to the longest match starting at the given string and |
@@ -770,7 +778,6 @@ static int longest_match(IPos cur_match) | |||
770 | return best_len; | 778 | return best_len; |
771 | } | 779 | } |
772 | 780 | ||
773 | |||
774 | #ifdef DEBUG | 781 | #ifdef DEBUG |
775 | /* =========================================================================== | 782 | /* =========================================================================== |
776 | * Check that the match at match_start is indeed a match. | 783 | * Check that the match at match_start is indeed a match. |
@@ -1049,24 +1056,14 @@ struct globals2 { | |||
1049 | ulg opt_len; /* bit length of current block with optimal trees */ | 1056 | ulg opt_len; /* bit length of current block with optimal trees */ |
1050 | ulg static_len; /* bit length of current block with static trees */ | 1057 | ulg static_len; /* bit length of current block with static trees */ |
1051 | 1058 | ||
1052 | ulg compressed_len; /* total bit length of compressed file */ | 1059 | // ulg compressed_len; /* total bit length of compressed file */ |
1053 | }; | 1060 | }; |
1054 | 1061 | ||
1055 | #define G2ptr ((struct globals2*)(ptr_to_globals)) | 1062 | #define G2ptr ((struct globals2*)(ptr_to_globals)) |
1056 | #define G2 (*G2ptr) | 1063 | #define G2 (*G2ptr) |
1057 | 1064 | ||
1058 | |||
1059 | /* =========================================================================== | 1065 | /* =========================================================================== |
1060 | */ | 1066 | */ |
1061 | static void gen_codes(ct_data * tree, int max_code); | ||
1062 | static void build_tree(tree_desc * desc); | ||
1063 | static void scan_tree(ct_data * tree, int max_code); | ||
1064 | static void send_tree(ct_data * tree, int max_code); | ||
1065 | static int build_bl_tree(void); | ||
1066 | static void send_all_trees(int lcodes, int dcodes, int blcodes); | ||
1067 | static void compress_block(ct_data * ltree, ct_data * dtree); | ||
1068 | |||
1069 | |||
1070 | #ifndef DEBUG | 1067 | #ifndef DEBUG |
1071 | /* Send a code of the given tree. c and tree must not have side effects */ | 1068 | /* Send a code of the given tree. c and tree must not have side effects */ |
1072 | # define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len) | 1069 | # define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len) |
@@ -1086,7 +1083,6 @@ static void compress_block(ct_data * ltree, ct_data * dtree); | |||
1086 | * The arguments must not have side effects. | 1083 | * The arguments must not have side effects. |
1087 | */ | 1084 | */ |
1088 | 1085 | ||
1089 | |||
1090 | /* =========================================================================== | 1086 | /* =========================================================================== |
1091 | * Initialize a new block. | 1087 | * Initialize a new block. |
1092 | */ | 1088 | */ |
@@ -1109,7 +1105,6 @@ static void init_block(void) | |||
1109 | G2.flag_bit = 1; | 1105 | G2.flag_bit = 1; |
1110 | } | 1106 | } |
1111 | 1107 | ||
1112 | |||
1113 | /* =========================================================================== | 1108 | /* =========================================================================== |
1114 | * Restore the heap property by moving down the tree starting at node k, | 1109 | * Restore the heap property by moving down the tree starting at node k, |
1115 | * exchanging a node with the smallest of its two sons if necessary, stopping | 1110 | * exchanging a node with the smallest of its two sons if necessary, stopping |
@@ -1147,7 +1142,6 @@ static void pqdownheap(ct_data * tree, int k) | |||
1147 | G2.heap[k] = v; | 1142 | G2.heap[k] = v; |
1148 | } | 1143 | } |
1149 | 1144 | ||
1150 | |||
1151 | /* =========================================================================== | 1145 | /* =========================================================================== |
1152 | * Compute the optimal bit lengths for a tree and update the total bit length | 1146 | * Compute the optimal bit lengths for a tree and update the total bit length |
1153 | * for the current block. | 1147 | * for the current block. |
@@ -1245,7 +1239,6 @@ static void gen_bitlen(tree_desc * desc) | |||
1245 | } | 1239 | } |
1246 | } | 1240 | } |
1247 | 1241 | ||
1248 | |||
1249 | /* =========================================================================== | 1242 | /* =========================================================================== |
1250 | * Generate the codes for a given tree and bit counts (which need not be | 1243 | * Generate the codes for a given tree and bit counts (which need not be |
1251 | * optimal). | 1244 | * optimal). |
@@ -1289,7 +1282,6 @@ static void gen_codes(ct_data * tree, int max_code) | |||
1289 | } | 1282 | } |
1290 | } | 1283 | } |
1291 | 1284 | ||
1292 | |||
1293 | /* =========================================================================== | 1285 | /* =========================================================================== |
1294 | * Construct one Huffman tree and assigns the code bit strings and lengths. | 1286 | * Construct one Huffman tree and assigns the code bit strings and lengths. |
1295 | * Update the total bit length for the current block. | 1287 | * Update the total bit length for the current block. |
@@ -1396,7 +1388,6 @@ static void build_tree(tree_desc * desc) | |||
1396 | gen_codes((ct_data *) tree, max_code); | 1388 | gen_codes((ct_data *) tree, max_code); |
1397 | } | 1389 | } |
1398 | 1390 | ||
1399 | |||
1400 | /* =========================================================================== | 1391 | /* =========================================================================== |
1401 | * Scan a literal or distance tree to determine the frequencies of the codes | 1392 | * Scan a literal or distance tree to determine the frequencies of the codes |
1402 | * in the bit length tree. Updates opt_len to take into account the repeat | 1393 | * in the bit length tree. Updates opt_len to take into account the repeat |
@@ -1451,7 +1442,6 @@ static void scan_tree(ct_data * tree, int max_code) | |||
1451 | } | 1442 | } |
1452 | } | 1443 | } |
1453 | 1444 | ||
1454 | |||
1455 | /* =========================================================================== | 1445 | /* =========================================================================== |
1456 | * Send a literal or distance tree in compressed form, using the codes in | 1446 | * Send a literal or distance tree in compressed form, using the codes in |
1457 | * bl_tree. | 1447 | * bl_tree. |
@@ -1509,7 +1499,6 @@ static void send_tree(ct_data * tree, int max_code) | |||
1509 | } | 1499 | } |
1510 | } | 1500 | } |
1511 | 1501 | ||
1512 | |||
1513 | /* =========================================================================== | 1502 | /* =========================================================================== |
1514 | * Construct the Huffman tree for the bit lengths and return the index in | 1503 | * Construct the Huffman tree for the bit lengths and return the index in |
1515 | * bl_order of the last bit length code to send. | 1504 | * bl_order of the last bit length code to send. |
@@ -1538,12 +1527,11 @@ static int build_bl_tree(void) | |||
1538 | } | 1527 | } |
1539 | /* Update opt_len to include the bit length tree and counts */ | 1528 | /* Update opt_len to include the bit length tree and counts */ |
1540 | G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; | 1529 | G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; |
1541 | Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); | 1530 | Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", (long)G2.opt_len, (long)G2.static_len)); |
1542 | 1531 | ||
1543 | return max_blindex; | 1532 | return max_blindex; |
1544 | } | 1533 | } |
1545 | 1534 | ||
1546 | |||
1547 | /* =========================================================================== | 1535 | /* =========================================================================== |
1548 | * Send the header for a block using dynamic Huffman trees: the counts, the | 1536 | * Send the header for a block using dynamic Huffman trees: the counts, the |
1549 | * lengths of the bit length codes, the literal tree and the distance tree. | 1537 | * lengths of the bit length codes, the literal tree and the distance tree. |
@@ -1564,16 +1552,15 @@ static void send_all_trees(int lcodes, int dcodes, int blcodes) | |||
1564 | Tracev((stderr, "\nbl code %2d ", bl_order[rank])); | 1552 | Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
1565 | send_bits(G2.bl_tree[bl_order[rank]].Len, 3); | 1553 | send_bits(G2.bl_tree[bl_order[rank]].Len, 3); |
1566 | } | 1554 | } |
1567 | Tracev((stderr, "\nbl tree: sent %ld", G1.bits_sent)); | 1555 | Tracev((stderr, "\nbl tree: sent %ld", (long)G1.bits_sent)); |
1568 | 1556 | ||
1569 | send_tree((ct_data *) G2.dyn_ltree, lcodes - 1); /* send the literal tree */ | 1557 | send_tree((ct_data *) G2.dyn_ltree, lcodes - 1); /* send the literal tree */ |
1570 | Tracev((stderr, "\nlit tree: sent %ld", G1.bits_sent)); | 1558 | Tracev((stderr, "\nlit tree: sent %ld", (long)G1.bits_sent)); |
1571 | 1559 | ||
1572 | send_tree((ct_data *) G2.dyn_dtree, dcodes - 1); /* send the distance tree */ | 1560 | send_tree((ct_data *) G2.dyn_dtree, dcodes - 1); /* send the distance tree */ |
1573 | Tracev((stderr, "\ndist tree: sent %ld", G1.bits_sent)); | 1561 | Tracev((stderr, "\ndist tree: sent %ld", (long)G1.bits_sent)); |
1574 | } | 1562 | } |
1575 | 1563 | ||
1576 | |||
1577 | /* =========================================================================== | 1564 | /* =========================================================================== |
1578 | * Save the match info and tally the frequency counts. Return true if | 1565 | * Save the match info and tally the frequency counts. Return true if |
1579 | * the current block must be flushed. | 1566 | * the current block must be flushed. |
@@ -1619,7 +1606,8 @@ static int ct_tally(int dist, int lc) | |||
1619 | out_length >>= 3; | 1606 | out_length >>= 3; |
1620 | Trace((stderr, | 1607 | Trace((stderr, |
1621 | "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", | 1608 | "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", |
1622 | G2.last_lit, G2.last_dist, in_length, out_length, | 1609 | G2.last_lit, G2.last_dist, |
1610 | (long)in_length, (long)out_length, | ||
1623 | 100L - out_length * 100L / in_length)); | 1611 | 100L - out_length * 100L / in_length)); |
1624 | if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2) | 1612 | if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2) |
1625 | return 1; | 1613 | return 1; |
@@ -1679,13 +1667,12 @@ static void compress_block(ct_data * ltree, ct_data * dtree) | |||
1679 | SEND_CODE(END_BLOCK, ltree); | 1667 | SEND_CODE(END_BLOCK, ltree); |
1680 | } | 1668 | } |
1681 | 1669 | ||
1682 | |||
1683 | /* =========================================================================== | 1670 | /* =========================================================================== |
1684 | * Determine the best encoding for the current block: dynamic trees, static | 1671 | * Determine the best encoding for the current block: dynamic trees, static |
1685 | * trees or store, and output the encoded block to the zip file. This function | 1672 | * trees or store, and output the encoded block to the zip file. This function |
1686 | * returns the total compressed length for the file so far. | 1673 | * returns the total compressed length for the file so far. |
1687 | */ | 1674 | */ |
1688 | static ulg flush_block(char *buf, ulg stored_len, int eof) | 1675 | static void flush_block(char *buf, ulg stored_len, int eof) |
1689 | { | 1676 | { |
1690 | ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ | 1677 | ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
1691 | int max_blindex; /* index of last bit length code of non zero freq */ | 1678 | int max_blindex; /* index of last bit length code of non zero freq */ |
@@ -1694,10 +1681,10 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) | |||
1694 | 1681 | ||
1695 | /* Construct the literal and distance trees */ | 1682 | /* Construct the literal and distance trees */ |
1696 | build_tree(&G2.l_desc); | 1683 | build_tree(&G2.l_desc); |
1697 | Tracev((stderr, "\nlit data: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); | 1684 | Tracev((stderr, "\nlit data: dyn %ld, stat %ld", (long)G2.opt_len, (long)G2.static_len)); |
1698 | 1685 | ||
1699 | build_tree(&G2.d_desc); | 1686 | build_tree(&G2.d_desc); |
1700 | Tracev((stderr, "\ndist data: dyn %ld, stat %ld", G2.opt_len, G2.static_len)); | 1687 | Tracev((stderr, "\ndist data: dyn %ld, stat %ld", (long)G2.opt_len, (long)G2.static_len)); |
1701 | /* At this point, opt_len and static_len are the total bit lengths of | 1688 | /* At this point, opt_len and static_len are the total bit lengths of |
1702 | * the compressed block data, excluding the tree representations. | 1689 | * the compressed block data, excluding the tree representations. |
1703 | */ | 1690 | */ |
@@ -1713,7 +1700,9 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) | |||
1713 | 1700 | ||
1714 | Trace((stderr, | 1701 | Trace((stderr, |
1715 | "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", | 1702 | "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", |
1716 | opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len, | 1703 | (unsigned long)opt_lenb, (unsigned long)G2.opt_len, |
1704 | (unsigned long)static_lenb, (unsigned long)G2.static_len, | ||
1705 | (unsigned long)stored_len, | ||
1717 | G2.last_lit, G2.last_dist)); | 1706 | G2.last_lit, G2.last_dist)); |
1718 | 1707 | ||
1719 | if (static_lenb <= opt_lenb) | 1708 | if (static_lenb <= opt_lenb) |
@@ -1723,14 +1712,17 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) | |||
1723 | * and if the zip file can be seeked (to rewrite the local header), | 1712 | * and if the zip file can be seeked (to rewrite the local header), |
1724 | * the whole file is transformed into a stored file: | 1713 | * the whole file is transformed into a stored file: |
1725 | */ | 1714 | */ |
1726 | if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) { | 1715 | // seekable() is constant FALSE in busybox, and G2.compressed_len is disabled |
1727 | /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ | 1716 | // (this was the only user) |
1728 | if (buf == NULL) | 1717 | // if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) { |
1729 | bb_error_msg("block vanished"); | 1718 | // /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ |
1730 | 1719 | // if (buf == NULL) | |
1731 | copy_block(buf, (unsigned) stored_len, 0); /* without header */ | 1720 | // bb_error_msg("block vanished"); |
1732 | G2.compressed_len = stored_len << 3; | 1721 | // |
1733 | } else if (stored_len + 4 <= opt_lenb && buf != NULL) { | 1722 | // G2.compressed_len = stored_len << 3; |
1723 | // copy_block(buf, (unsigned) stored_len, 0); /* without header */ | ||
1724 | // } else | ||
1725 | if (stored_len + 4 <= opt_lenb && buf != NULL) { | ||
1734 | /* 4: two words for the lengths */ | 1726 | /* 4: two words for the lengths */ |
1735 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. | 1727 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
1736 | * Otherwise we can't have processed more than WSIZE input bytes since | 1728 | * Otherwise we can't have processed more than WSIZE input bytes since |
@@ -1739,35 +1731,35 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) | |||
1739 | * transform a block into a stored block. | 1731 | * transform a block into a stored block. |
1740 | */ | 1732 | */ |
1741 | send_bits((STORED_BLOCK << 1) + eof, 3); /* send block type */ | 1733 | send_bits((STORED_BLOCK << 1) + eof, 3); /* send block type */ |
1742 | G2.compressed_len = (G2.compressed_len + 3 + 7) & ~7L; | 1734 | // G2.compressed_len = ((G2.compressed_len + 3 + 7) & ~7L) |
1743 | G2.compressed_len += (stored_len + 4) << 3; | 1735 | // + ((stored_len + 4) << 3); |
1744 | |||
1745 | copy_block(buf, (unsigned) stored_len, 1); /* with header */ | 1736 | copy_block(buf, (unsigned) stored_len, 1); /* with header */ |
1746 | } else if (static_lenb == opt_lenb) { | 1737 | } else |
1738 | if (static_lenb == opt_lenb) { | ||
1747 | send_bits((STATIC_TREES << 1) + eof, 3); | 1739 | send_bits((STATIC_TREES << 1) + eof, 3); |
1748 | compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree); | 1740 | compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree); |
1749 | G2.compressed_len += 3 + G2.static_len; | 1741 | // G2.compressed_len += 3 + G2.static_len; |
1750 | } else { | 1742 | } else { |
1751 | send_bits((DYN_TREES << 1) + eof, 3); | 1743 | send_bits((DYN_TREES << 1) + eof, 3); |
1752 | send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1, | 1744 | send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1, |
1753 | max_blindex + 1); | 1745 | max_blindex + 1); |
1754 | compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree); | 1746 | compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree); |
1755 | G2.compressed_len += 3 + G2.opt_len; | 1747 | // G2.compressed_len += 3 + G2.opt_len; |
1756 | } | 1748 | } |
1757 | Assert(G2.compressed_len == G1.bits_sent, "bad compressed size"); | 1749 | // Assert(G2.compressed_len == G1.bits_sent, "bad compressed size"); |
1758 | init_block(); | 1750 | init_block(); |
1759 | 1751 | ||
1760 | if (eof) { | 1752 | if (eof) { |
1761 | bi_windup(); | 1753 | bi_windup(); |
1762 | G2.compressed_len += 7; /* align on byte boundary */ | 1754 | // G2.compressed_len += 7; /* align on byte boundary */ |
1763 | } | 1755 | } |
1764 | Tracev((stderr, "\ncomprlen %lu(%lu) ", G2.compressed_len >> 3, | 1756 | // Tracev((stderr, "\ncomprlen %lu(%lu) ", |
1765 | G2.compressed_len - 7 * eof)); | 1757 | // (unsigned long)G2.compressed_len >> 3, |
1758 | // (unsigned long)G2.compressed_len - 7 * eof)); | ||
1766 | 1759 | ||
1767 | return G2.compressed_len >> 3; | 1760 | return; /* was "return G2.compressed_len >> 3;" */ |
1768 | } | 1761 | } |
1769 | 1762 | ||
1770 | |||
1771 | /* =========================================================================== | 1763 | /* =========================================================================== |
1772 | * Update a hash value with the given input byte | 1764 | * Update a hash value with the given input byte |
1773 | * IN assertion: all calls to UPDATE_HASH are made with consecutive | 1765 | * IN assertion: all calls to UPDATE_HASH are made with consecutive |
@@ -1776,7 +1768,6 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) | |||
1776 | */ | 1768 | */ |
1777 | #define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK) | 1769 | #define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK) |
1778 | 1770 | ||
1779 | |||
1780 | /* =========================================================================== | 1771 | /* =========================================================================== |
1781 | * Same as above, but achieves better compression. We use a lazy | 1772 | * Same as above, but achieves better compression. We use a lazy |
1782 | * evaluation for matches: a match is finally adopted only if there is | 1773 | * evaluation for matches: a match is finally adopted only if there is |
@@ -1811,7 +1802,7 @@ do { \ | |||
1811 | head[G1.ins_h] = (s); \ | 1802 | head[G1.ins_h] = (s); \ |
1812 | } while (0) | 1803 | } while (0) |
1813 | 1804 | ||
1814 | static ulg deflate(void) | 1805 | static NOINLINE void deflate(void) |
1815 | { | 1806 | { |
1816 | IPos hash_head; /* head of hash chain */ | 1807 | IPos hash_head; /* head of hash chain */ |
1817 | IPos prev_match; /* previous match */ | 1808 | IPos prev_match; /* previous match */ |
@@ -1900,40 +1891,35 @@ static ulg deflate(void) | |||
1900 | G1.strstart++; | 1891 | G1.strstart++; |
1901 | G1.lookahead--; | 1892 | G1.lookahead--; |
1902 | } | 1893 | } |
1903 | Assert(G1.strstart <= G1.isize && lookahead <= G1.isize, "a bit too far"); | 1894 | Assert(G1.strstart <= G1.isize && G1.lookahead <= G1.isize, "a bit too far"); |
1904 | 1895 | ||
1905 | /* Make sure that we always have enough lookahead, except | 1896 | /* Make sure that we always have enough lookahead, except |
1906 | * at the end of the input file. We need MAX_MATCH bytes | 1897 | * at the end of the input file. We need MAX_MATCH bytes |
1907 | * for the next match, plus MIN_MATCH bytes to insert the | 1898 | * for the next match, plus MIN_MATCH bytes to insert the |
1908 | * string following the next match. | 1899 | * string following the next match. |
1909 | */ | 1900 | */ |
1910 | while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile) | 1901 | fill_window_if_needed(); |
1911 | fill_window(); | ||
1912 | } | 1902 | } |
1913 | if (match_available) | 1903 | if (match_available) |
1914 | ct_tally(0, G1.window[G1.strstart - 1]); | 1904 | ct_tally(0, G1.window[G1.strstart - 1]); |
1915 | 1905 | ||
1916 | return FLUSH_BLOCK(1); /* eof */ | 1906 | FLUSH_BLOCK(1); /* eof */ |
1917 | } | 1907 | } |
1918 | 1908 | ||
1919 | |||
1920 | /* =========================================================================== | 1909 | /* =========================================================================== |
1921 | * Initialize the bit string routines. | 1910 | * Initialize the bit string routines. |
1922 | */ | 1911 | */ |
1923 | static void bi_init(void) | 1912 | static void bi_init(void) |
1924 | { | 1913 | { |
1925 | G1.bi_buf = 0; | 1914 | //G1.bi_buf = 0; // globals are zeroed in pack_gzip() |
1926 | G1.bi_valid = 0; | 1915 | //G1.bi_valid = 0; // globals are zeroed in pack_gzip() |
1927 | #ifdef DEBUG | 1916 | //DEBUG_bits_sent(= 0L); // globals are zeroed in pack_gzip() |
1928 | G1.bits_sent = 0L; | ||
1929 | #endif | ||
1930 | } | 1917 | } |
1931 | 1918 | ||
1932 | |||
1933 | /* =========================================================================== | 1919 | /* =========================================================================== |
1934 | * Initialize the "longest match" routines for a new file | 1920 | * Initialize the "longest match" routines for a new file |
1935 | */ | 1921 | */ |
1936 | static void lm_init(ush * flagsp) | 1922 | static void lm_init(unsigned *flags16p) |
1937 | { | 1923 | { |
1938 | unsigned j; | 1924 | unsigned j; |
1939 | 1925 | ||
@@ -1942,11 +1928,11 @@ static void lm_init(ush * flagsp) | |||
1942 | /* prev will be initialized on the fly */ | 1928 | /* prev will be initialized on the fly */ |
1943 | 1929 | ||
1944 | /* speed options for the general purpose bit flag */ | 1930 | /* speed options for the general purpose bit flag */ |
1945 | *flagsp |= 2; /* FAST 4, SLOW 2 */ | 1931 | *flags16p |= 2; /* FAST 4, SLOW 2 */ |
1946 | /* ??? reduce max_chain_length for binary files */ | 1932 | /* ??? reduce max_chain_length for binary files */ |
1947 | 1933 | ||
1948 | G1.strstart = 0; | 1934 | //G1.strstart = 0; // globals are zeroed in pack_gzip() |
1949 | G1.block_start = 0L; | 1935 | //G1.block_start = 0L; // globals are zeroed in pack_gzip() |
1950 | 1936 | ||
1951 | G1.lookahead = file_read(G1.window, | 1937 | G1.lookahead = file_read(G1.window, |
1952 | sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE); | 1938 | sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE); |
@@ -1956,14 +1942,14 @@ static void lm_init(ush * flagsp) | |||
1956 | G1.lookahead = 0; | 1942 | G1.lookahead = 0; |
1957 | return; | 1943 | return; |
1958 | } | 1944 | } |
1959 | G1.eofile = 0; | 1945 | //G1.eofile = 0; // globals are zeroed in pack_gzip() |
1946 | |||
1960 | /* Make sure that we always have enough lookahead. This is important | 1947 | /* Make sure that we always have enough lookahead. This is important |
1961 | * if input comes from a device such as a tty. | 1948 | * if input comes from a device such as a tty. |
1962 | */ | 1949 | */ |
1963 | while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile) | 1950 | fill_window_if_needed(); |
1964 | fill_window(); | ||
1965 | 1951 | ||
1966 | G1.ins_h = 0; | 1952 | //G1.ins_h = 0; // globals are zeroed in pack_gzip() |
1967 | for (j = 0; j < MIN_MATCH - 1; j++) | 1953 | for (j = 0; j < MIN_MATCH - 1; j++) |
1968 | UPDATE_HASH(G1.ins_h, G1.window[j]); | 1954 | UPDATE_HASH(G1.ins_h, G1.window[j]); |
1969 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is | 1955 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is |
@@ -1971,7 +1957,6 @@ static void lm_init(ush * flagsp) | |||
1971 | */ | 1957 | */ |
1972 | } | 1958 | } |
1973 | 1959 | ||
1974 | |||
1975 | /* =========================================================================== | 1960 | /* =========================================================================== |
1976 | * Allocate the match buffer, initialize the various tables and save the | 1961 | * Allocate the match buffer, initialize the various tables and save the |
1977 | * location of the internal file attribute (ascii/binary) and method | 1962 | * location of the internal file attribute (ascii/binary) and method |
@@ -1985,7 +1970,7 @@ static void ct_init(void) | |||
1985 | int code; /* code value */ | 1970 | int code; /* code value */ |
1986 | int dist; /* distance index */ | 1971 | int dist; /* distance index */ |
1987 | 1972 | ||
1988 | G2.compressed_len = 0L; | 1973 | // //G2.compressed_len = 0L; // globals are zeroed in pack_gzip() |
1989 | 1974 | ||
1990 | #ifdef NOT_NEEDED | 1975 | #ifdef NOT_NEEDED |
1991 | if (G2.static_dtree[0].Len != 0) | 1976 | if (G2.static_dtree[0].Len != 0) |
@@ -2026,27 +2011,33 @@ static void ct_init(void) | |||
2026 | Assert(dist == 256, "ct_init: 256+dist != 512"); | 2011 | Assert(dist == 256, "ct_init: 256+dist != 512"); |
2027 | 2012 | ||
2028 | /* Construct the codes of the static literal tree */ | 2013 | /* Construct the codes of the static literal tree */ |
2029 | /* already zeroed - it's in bss | 2014 | //for (n = 0; n <= MAX_BITS; n++) // globals are zeroed in pack_gzip() |
2030 | for (n = 0; n <= MAX_BITS; n++) | 2015 | // G2.bl_count[n] = 0; |
2031 | G2.bl_count[n] = 0; */ | ||
2032 | 2016 | ||
2033 | n = 0; | 2017 | n = 0; |
2034 | while (n <= 143) { | 2018 | while (n <= 143) { |
2035 | G2.static_ltree[n++].Len = 8; | 2019 | G2.static_ltree[n++].Len = 8; |
2036 | G2.bl_count[8]++; | 2020 | //G2.bl_count[8]++; |
2037 | } | 2021 | } |
2022 | //G2.bl_count[8] = 143 + 1; | ||
2038 | while (n <= 255) { | 2023 | while (n <= 255) { |
2039 | G2.static_ltree[n++].Len = 9; | 2024 | G2.static_ltree[n++].Len = 9; |
2040 | G2.bl_count[9]++; | 2025 | //G2.bl_count[9]++; |
2041 | } | 2026 | } |
2027 | //G2.bl_count[9] = 255 - 143; | ||
2042 | while (n <= 279) { | 2028 | while (n <= 279) { |
2043 | G2.static_ltree[n++].Len = 7; | 2029 | G2.static_ltree[n++].Len = 7; |
2044 | G2.bl_count[7]++; | 2030 | //G2.bl_count[7]++; |
2045 | } | 2031 | } |
2032 | //G2.bl_count[7] = 279 - 255; | ||
2046 | while (n <= 287) { | 2033 | while (n <= 287) { |
2047 | G2.static_ltree[n++].Len = 8; | 2034 | G2.static_ltree[n++].Len = 8; |
2048 | G2.bl_count[8]++; | 2035 | //G2.bl_count[8]++; |
2049 | } | 2036 | } |
2037 | //G2.bl_count[8] += 287 - 279; | ||
2038 | G2.bl_count[7] = 279 - 255; | ||
2039 | G2.bl_count[8] = (143 + 1) + (287 - 279); | ||
2040 | G2.bl_count[9] = 255 - 143; | ||
2050 | /* Codes 286 and 287 do not exist, but we must include them in the | 2041 | /* Codes 286 and 287 do not exist, but we must include them in the |
2051 | * tree construction to get a canonical Huffman tree (longest code | 2042 | * tree construction to get a canonical Huffman tree (longest code |
2052 | * all ones) | 2043 | * all ones) |
@@ -2063,17 +2054,15 @@ static void ct_init(void) | |||
2063 | init_block(); | 2054 | init_block(); |
2064 | } | 2055 | } |
2065 | 2056 | ||
2066 | |||
2067 | /* =========================================================================== | 2057 | /* =========================================================================== |
2068 | * Deflate in to out. | 2058 | * Deflate in to out. |
2069 | * IN assertions: the input and output buffers are cleared. | 2059 | * IN assertions: the input and output buffers are cleared. |
2070 | */ | 2060 | */ |
2071 | |||
2072 | static void zip(void) | 2061 | static void zip(void) |
2073 | { | 2062 | { |
2074 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ | 2063 | unsigned deflate_flags; |
2075 | 2064 | ||
2076 | G1.outcnt = 0; | 2065 | //G1.outcnt = 0; // globals are zeroed in pack_gzip() |
2077 | 2066 | ||
2078 | /* Write the header to the gzip file. See algorithm.doc for the format */ | 2067 | /* Write the header to the gzip file. See algorithm.doc for the format */ |
2079 | /* magic header for gzip files: 1F 8B */ | 2068 | /* magic header for gzip files: 1F 8B */ |
@@ -2087,10 +2076,13 @@ static void zip(void) | |||
2087 | 2076 | ||
2088 | bi_init(); | 2077 | bi_init(); |
2089 | ct_init(); | 2078 | ct_init(); |
2079 | deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ | ||
2090 | lm_init(&deflate_flags); | 2080 | lm_init(&deflate_flags); |
2091 | 2081 | ||
2092 | put_8bit(deflate_flags); /* extra flags */ | 2082 | put_16bit(deflate_flags | 0x300); /* extra flags. OS id = 3 (Unix) */ |
2093 | put_8bit(3); /* OS identifier = 3 (Unix) */ | 2083 | |
2084 | /* The above 32-bit misaligns outbuf (10 bytes are stored), flush it */ | ||
2085 | flush_outbuf_if_32bit_optimized(); | ||
2094 | 2086 | ||
2095 | deflate(); | 2087 | deflate(); |
2096 | 2088 | ||
@@ -2101,20 +2093,21 @@ static void zip(void) | |||
2101 | flush_outbuf(); | 2093 | flush_outbuf(); |
2102 | } | 2094 | } |
2103 | 2095 | ||
2104 | |||
2105 | /* ======================================================================== */ | 2096 | /* ======================================================================== */ |
2106 | static | 2097 | static |
2107 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) | 2098 | IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) |
2108 | { | 2099 | { |
2100 | /* Reinit G1.xxx except pointers to allocated buffers, and entire G2 */ | ||
2101 | memset(&G1.crc, 0, (sizeof(G1) - offsetof(struct globals, crc)) + sizeof(G2)); | ||
2102 | |||
2109 | /* Clear input and output buffers */ | 2103 | /* Clear input and output buffers */ |
2110 | G1.outcnt = 0; | 2104 | //G1.outcnt = 0; |
2111 | #ifdef DEBUG | 2105 | #ifdef DEBUG |
2112 | G1.insize = 0; | 2106 | //G1.insize = 0; |
2113 | #endif | 2107 | #endif |
2114 | G1.isize = 0; | 2108 | //G1.isize = 0; |
2115 | 2109 | ||
2116 | /* Reinit G2.xxx */ | 2110 | /* Reinit G2.xxx */ |
2117 | memset(&G2, 0, sizeof(G2)); | ||
2118 | G2.l_desc.dyn_tree = G2.dyn_ltree; | 2111 | G2.l_desc.dyn_tree = G2.dyn_ltree; |
2119 | G2.l_desc.static_tree = G2.static_ltree; | 2112 | G2.l_desc.static_tree = G2.static_ltree; |
2120 | G2.l_desc.extra_bits = extra_lbits; | 2113 | G2.l_desc.extra_bits = extra_lbits; |
@@ -2218,16 +2211,16 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) | |||
2218 | 2211 | ||
2219 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | 2212 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
2220 | #if ENABLE_FEATURE_GZIP_LONG_OPTIONS | 2213 | #if ENABLE_FEATURE_GZIP_LONG_OPTIONS |
2221 | opt = getopt32long(argv, "cfkv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789", gzip_longopts); | 2214 | opt = getopt32long(argv, BBUNPK_OPTSTR IF_FEATURE_GZIP_DECOMPRESS("dt") "n123456789", gzip_longopts); |
2222 | #else | 2215 | #else |
2223 | opt = getopt32(argv, "cfkv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789"); | 2216 | opt = getopt32(argv, BBUNPK_OPTSTR IF_FEATURE_GZIP_DECOMPRESS("dt") "n123456789"); |
2224 | #endif | 2217 | #endif |
2225 | #if ENABLE_FEATURE_GZIP_DECOMPRESS /* gunzip_main may not be visible... */ | 2218 | #if ENABLE_FEATURE_GZIP_DECOMPRESS /* gunzip_main may not be visible... */ |
2226 | if (opt & 0x30) // -d and/or -t | 2219 | if (opt & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST)) /* -d and/or -t */ |
2227 | return gunzip_main(argc, argv); | 2220 | return gunzip_main(argc, argv); |
2228 | #endif | 2221 | #endif |
2229 | #if ENABLE_FEATURE_GZIP_LEVELS | 2222 | #if ENABLE_FEATURE_GZIP_LEVELS |
2230 | opt >>= ENABLE_FEATURE_GZIP_DECOMPRESS ? 8 : 6; /* drop cfkv[dt]qn bits */ | 2223 | opt >>= (BBUNPK_OPTSTRLEN IF_FEATURE_GZIP_DECOMPRESS(+ 2) + 1); /* drop cfkvq[dt]n bits */ |
2231 | if (opt == 0) | 2224 | if (opt == 0) |
2232 | opt = 1 << 6; /* default: 6 */ | 2225 | opt = 1 << 6; /* default: 6 */ |
2233 | opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ | 2226 | opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ |
@@ -2236,7 +2229,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) | |||
2236 | max_lazy_match = gzip_level_config[opt].lazy2 * 2; | 2229 | max_lazy_match = gzip_level_config[opt].lazy2 * 2; |
2237 | nice_match = gzip_level_config[opt].nice2 * 2; | 2230 | nice_match = gzip_level_config[opt].nice2 * 2; |
2238 | #endif | 2231 | #endif |
2239 | option_mask32 &= 0xf; /* retain only -cfkv */ | 2232 | option_mask32 &= BBUNPK_OPTSTRMASK; /* retain only -cfkvq */ |
2240 | 2233 | ||
2241 | /* Allocate all global buffers (for DYN_ALLOC option) */ | 2234 | /* Allocate all global buffers (for DYN_ALLOC option) */ |
2242 | ALLOC(uch, G1.l_buf, INBUFSIZ); | 2235 | ALLOC(uch, G1.l_buf, INBUFSIZ); |
@@ -2246,7 +2239,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) | |||
2246 | ALLOC(ush, G1.prev, 1L << BITS); | 2239 | ALLOC(ush, G1.prev, 1L << BITS); |
2247 | 2240 | ||
2248 | /* Initialize the CRC32 table */ | 2241 | /* Initialize the CRC32 table */ |
2249 | global_crc32_table = crc32_filltable(NULL, 0); | 2242 | global_crc32_new_table_le(); |
2250 | 2243 | ||
2251 | argv += optind; | 2244 | argv += optind; |
2252 | return bbunpack(argv, pack_gzip, append_ext, "gz"); | 2245 | return bbunpack(argv, pack_gzip, append_ext, "gz"); |
diff --git a/archival/libarchive/bz/blocksort.c b/archival/libarchive/bz/blocksort.c index e600cb7a7..92d6d8251 100644 --- a/archival/libarchive/bz/blocksort.c +++ b/archival/libarchive/bz/blocksort.c | |||
@@ -113,9 +113,8 @@ void fallbackQSort3(uint32_t* fmap, | |||
113 | int32_t loSt, | 113 | int32_t loSt, |
114 | int32_t hiSt) | 114 | int32_t hiSt) |
115 | { | 115 | { |
116 | int32_t unLo, unHi, ltLo, gtHi, n, m; | 116 | int32_t sp; |
117 | int32_t sp, lo, hi; | 117 | uint32_t r; |
118 | uint32_t med, r, r3; | ||
119 | int32_t stackLo[FALLBACK_QSORT_STACK_SIZE]; | 118 | int32_t stackLo[FALLBACK_QSORT_STACK_SIZE]; |
120 | int32_t stackHi[FALLBACK_QSORT_STACK_SIZE]; | 119 | int32_t stackHi[FALLBACK_QSORT_STACK_SIZE]; |
121 | 120 | ||
@@ -125,6 +124,11 @@ void fallbackQSort3(uint32_t* fmap, | |||
125 | fpush(loSt, hiSt); | 124 | fpush(loSt, hiSt); |
126 | 125 | ||
127 | while (sp > 0) { | 126 | while (sp > 0) { |
127 | int32_t unLo, unHi, ltLo, gtHi, n, m; | ||
128 | int32_t lo, hi; | ||
129 | uint32_t med; | ||
130 | uint32_t r3; | ||
131 | |||
128 | AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004); | 132 | AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004); |
129 | 133 | ||
130 | fpop(lo, hi); | 134 | fpop(lo, hi); |
@@ -161,7 +165,7 @@ void fallbackQSort3(uint32_t* fmap, | |||
161 | ltLo++; | 165 | ltLo++; |
162 | unLo++; | 166 | unLo++; |
163 | continue; | 167 | continue; |
164 | }; | 168 | } |
165 | if (n > 0) break; | 169 | if (n > 0) break; |
166 | unLo++; | 170 | unLo++; |
167 | } | 171 | } |
@@ -172,7 +176,7 @@ void fallbackQSort3(uint32_t* fmap, | |||
172 | mswap(fmap[unHi], fmap[gtHi]); | 176 | mswap(fmap[unHi], fmap[gtHi]); |
173 | gtHi--; unHi--; | 177 | gtHi--; unHi--; |
174 | continue; | 178 | continue; |
175 | }; | 179 | } |
176 | if (n < 0) break; | 180 | if (n < 0) break; |
177 | unHi--; | 181 | unHi--; |
178 | } | 182 | } |
@@ -227,17 +231,19 @@ void fallbackQSort3(uint32_t* fmap, | |||
227 | #define UNALIGNED_BH(zz) ((zz) & 0x01f) | 231 | #define UNALIGNED_BH(zz) ((zz) & 0x01f) |
228 | 232 | ||
229 | static | 233 | static |
230 | void fallbackSort(uint32_t* fmap, | 234 | void fallbackSort(EState* state) |
231 | uint32_t* eclass, | ||
232 | uint32_t* bhtab, | ||
233 | int32_t nblock) | ||
234 | { | 235 | { |
235 | int32_t ftab[257]; | 236 | int32_t ftab[257]; |
236 | int32_t ftabCopy[256]; | 237 | int32_t ftabCopy[256]; |
237 | int32_t H, i, j, k, l, r, cc, cc1; | 238 | int32_t H, i, j, k, l, r, cc, cc1; |
238 | int32_t nNotDone; | 239 | int32_t nNotDone; |
239 | int32_t nBhtab; | 240 | int32_t nBhtab; |
240 | uint8_t* eclass8 = (uint8_t*)eclass; | 241 | /* params */ |
242 | uint32_t *const fmap = state->arr1; | ||
243 | uint32_t *const eclass = state->arr2; | ||
244 | #define eclass8 ((uint8_t*)eclass) | ||
245 | uint32_t *const bhtab = state->ftab; | ||
246 | const int32_t nblock = state->nblock; | ||
241 | 247 | ||
242 | /* | 248 | /* |
243 | * Initial 1-char radix sort to generate | 249 | * Initial 1-char radix sort to generate |
@@ -326,7 +332,7 @@ void fallbackSort(uint32_t* fmap, | |||
326 | if (cc != cc1) { | 332 | if (cc != cc1) { |
327 | SET_BH(i); | 333 | SET_BH(i); |
328 | cc = cc1; | 334 | cc = cc1; |
329 | }; | 335 | } |
330 | } | 336 | } |
331 | } | 337 | } |
332 | } | 338 | } |
@@ -349,6 +355,7 @@ void fallbackSort(uint32_t* fmap, | |||
349 | eclass8[fmap[i]] = (uint8_t)j; | 355 | eclass8[fmap[i]] = (uint8_t)j; |
350 | } | 356 | } |
351 | AssertH(j < 256, 1005); | 357 | AssertH(j < 256, 1005); |
358 | #undef eclass8 | ||
352 | } | 359 | } |
353 | 360 | ||
354 | #undef SET_BH | 361 | #undef SET_BH |
@@ -367,25 +374,25 @@ void fallbackSort(uint32_t* fmap, | |||
367 | /*---------------------------------------------*/ | 374 | /*---------------------------------------------*/ |
368 | static | 375 | static |
369 | NOINLINE | 376 | NOINLINE |
370 | int mainGtU( | 377 | int mainGtU(EState* state, |
371 | uint32_t i1, | 378 | uint32_t i1, |
372 | uint32_t i2, | 379 | uint32_t i2) |
373 | uint8_t* block, | ||
374 | uint16_t* quadrant, | ||
375 | uint32_t nblock, | ||
376 | int32_t* budget) | ||
377 | { | 380 | { |
378 | int32_t k; | 381 | int32_t k; |
379 | uint8_t c1, c2; | 382 | uint8_t c1, c2; |
380 | uint16_t s1, s2; | 383 | uint16_t s1, s2; |
381 | 384 | ||
385 | uint8_t *const block = state->block; | ||
386 | uint16_t *const quadrant = state->quadrant; | ||
387 | const int32_t nblock = state->nblock; | ||
388 | |||
382 | /* Loop unrolling here is actually very useful | 389 | /* Loop unrolling here is actually very useful |
383 | * (generated code is much simpler), | 390 | * (generated code is much simpler), |
384 | * code size increase is only 270 bytes (i386) | 391 | * code size increase is only 270 bytes (i386) |
385 | * but speeds up compression 10% overall | 392 | * but speeds up compression 10% overall |
386 | */ | 393 | */ |
387 | 394 | ||
388 | #if CONFIG_BZIP2_FAST >= 1 | 395 | #if BZIP2_SPEED >= 1 |
389 | 396 | ||
390 | #define TIMES_8(code) \ | 397 | #define TIMES_8(code) \ |
391 | code; code; code; code; \ | 398 | code; code; code; code; \ |
@@ -435,7 +442,7 @@ int mainGtU( | |||
435 | if (i1 >= nblock) i1 -= nblock; | 442 | if (i1 >= nblock) i1 -= nblock; |
436 | if (i2 >= nblock) i2 -= nblock; | 443 | if (i2 >= nblock) i2 -= nblock; |
437 | 444 | ||
438 | (*budget)--; | 445 | state->budget--; |
439 | k -= 8; | 446 | k -= 8; |
440 | } while (k >= 0); | 447 | } while (k >= 0); |
441 | 448 | ||
@@ -452,42 +459,45 @@ int mainGtU( | |||
452 | * usually small, typically <= 20. | 459 | * usually small, typically <= 20. |
453 | */ | 460 | */ |
454 | static | 461 | static |
455 | const int32_t incs[14] = { | 462 | const uint32_t incs[14] = { |
456 | 1, 4, 13, 40, 121, 364, 1093, 3280, | 463 | 1, 4, 13, 40, 121, 364, 1093, 3280, |
457 | 9841, 29524, 88573, 265720, | 464 | 9841, 29524, 88573, 265720, |
458 | 797161, 2391484 | 465 | 797161, 2391484 |
459 | }; | 466 | }; |
460 | 467 | ||
461 | static | 468 | static |
462 | void mainSimpleSort(uint32_t* ptr, | 469 | void mainSimpleSort(EState* state, |
463 | uint8_t* block, | ||
464 | uint16_t* quadrant, | ||
465 | int32_t nblock, | ||
466 | int32_t lo, | 470 | int32_t lo, |
467 | int32_t hi, | 471 | int32_t hi, |
468 | int32_t d, | 472 | int32_t d) |
469 | int32_t* budget) | ||
470 | { | 473 | { |
471 | int32_t i, j, h, bigN, hp; | 474 | uint32_t *const ptr = state->ptr; |
472 | uint32_t v; | ||
473 | |||
474 | bigN = hi - lo + 1; | ||
475 | if (bigN < 2) return; | ||
476 | 475 | ||
477 | hp = 0; | 476 | /* At which increment to start? */ |
478 | while (incs[hp] < bigN) hp++; | 477 | int hp = 0; |
479 | hp--; | 478 | { |
479 | int bigN = hi - lo; | ||
480 | if (bigN <= 0) | ||
481 | return; | ||
482 | while (incs[hp] <= bigN) | ||
483 | hp++; | ||
484 | hp--; | ||
485 | } | ||
480 | 486 | ||
481 | for (; hp >= 0; hp--) { | 487 | for (; hp >= 0; hp--) { |
482 | h = incs[hp]; | 488 | int32_t i; |
489 | unsigned h; | ||
483 | 490 | ||
491 | h = incs[hp]; | ||
484 | i = lo + h; | 492 | i = lo + h; |
485 | while (1) { | 493 | while (1) { |
486 | /*-- copy 1 --*/ | 494 | unsigned j; |
495 | unsigned v; | ||
496 | |||
487 | if (i > hi) break; | 497 | if (i > hi) break; |
488 | v = ptr[i]; | 498 | v = ptr[i]; |
489 | j = i; | 499 | j = i; |
490 | while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | 500 | while (mainGtU(state, ptr[j-h]+d, v+d)) { |
491 | ptr[j] = ptr[j-h]; | 501 | ptr[j] = ptr[j-h]; |
492 | j = j - h; | 502 | j = j - h; |
493 | if (j <= (lo + h - 1)) break; | 503 | if (j <= (lo + h - 1)) break; |
@@ -496,24 +506,23 @@ void mainSimpleSort(uint32_t* ptr, | |||
496 | i++; | 506 | i++; |
497 | 507 | ||
498 | /* 1.5% overall speedup, +290 bytes */ | 508 | /* 1.5% overall speedup, +290 bytes */ |
499 | #if CONFIG_BZIP2_FAST >= 3 | 509 | #if BZIP2_SPEED >= 3 |
500 | /*-- copy 2 --*/ | 510 | /*-- copy 2 --*/ |
501 | if (i > hi) break; | 511 | if (i > hi) break; |
502 | v = ptr[i]; | 512 | v = ptr[i]; |
503 | j = i; | 513 | j = i; |
504 | while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | 514 | while (mainGtU(state, ptr[j-h]+d, v+d)) { |
505 | ptr[j] = ptr[j-h]; | 515 | ptr[j] = ptr[j-h]; |
506 | j = j - h; | 516 | j = j - h; |
507 | if (j <= (lo + h - 1)) break; | 517 | if (j <= (lo + h - 1)) break; |
508 | } | 518 | } |
509 | ptr[j] = v; | 519 | ptr[j] = v; |
510 | i++; | 520 | i++; |
511 | |||
512 | /*-- copy 3 --*/ | 521 | /*-- copy 3 --*/ |
513 | if (i > hi) break; | 522 | if (i > hi) break; |
514 | v = ptr[i]; | 523 | v = ptr[i]; |
515 | j = i; | 524 | j = i; |
516 | while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | 525 | while (mainGtU(state, ptr[j-h]+d, v+d)) { |
517 | ptr[j] = ptr[j-h]; | 526 | ptr[j] = ptr[j-h]; |
518 | j = j - h; | 527 | j = j - h; |
519 | if (j <= (lo + h - 1)) break; | 528 | if (j <= (lo + h - 1)) break; |
@@ -521,7 +530,7 @@ void mainSimpleSort(uint32_t* ptr, | |||
521 | ptr[j] = v; | 530 | ptr[j] = v; |
522 | i++; | 531 | i++; |
523 | #endif | 532 | #endif |
524 | if (*budget < 0) return; | 533 | if (state->budget < 0) return; |
525 | } | 534 | } |
526 | } | 535 | } |
527 | } | 536 | } |
@@ -545,7 +554,7 @@ uint8_t mmed3(uint8_t a, uint8_t b, uint8_t c) | |||
545 | t = a; | 554 | t = a; |
546 | a = b; | 555 | a = b; |
547 | b = t; | 556 | b = t; |
548 | }; | 557 | } |
549 | /* here b >= a */ | 558 | /* here b >= a */ |
550 | if (b > c) { | 559 | if (b > c) { |
551 | b = c; | 560 | b = c; |
@@ -586,15 +595,12 @@ uint8_t mmed3(uint8_t a, uint8_t b, uint8_t c) | |||
586 | #define MAIN_QSORT_STACK_SIZE 100 | 595 | #define MAIN_QSORT_STACK_SIZE 100 |
587 | 596 | ||
588 | static NOINLINE | 597 | static NOINLINE |
589 | void mainQSort3(uint32_t* ptr, | 598 | void mainQSort3(EState* state, |
590 | uint8_t* block, | ||
591 | uint16_t* quadrant, | ||
592 | int32_t nblock, | ||
593 | int32_t loSt, | 599 | int32_t loSt, |
594 | int32_t hiSt, | 600 | int32_t hiSt |
595 | int32_t dSt, | 601 | /*int32_t dSt*/) |
596 | int32_t* budget) | ||
597 | { | 602 | { |
603 | enum { dSt = BZ_N_RADIX }; | ||
598 | int32_t unLo, unHi, ltLo, gtHi, n, m, med; | 604 | int32_t unLo, unHi, ltLo, gtHi, n, m, med; |
599 | int32_t sp, lo, hi, d; | 605 | int32_t sp, lo, hi, d; |
600 | 606 | ||
@@ -606,6 +612,9 @@ void mainQSort3(uint32_t* ptr, | |||
606 | int32_t nextHi[3]; | 612 | int32_t nextHi[3]; |
607 | int32_t nextD [3]; | 613 | int32_t nextD [3]; |
608 | 614 | ||
615 | uint32_t *const ptr = state->ptr; | ||
616 | uint8_t *const block = state->block; | ||
617 | |||
609 | sp = 0; | 618 | sp = 0; |
610 | mpush(loSt, hiSt, dSt); | 619 | mpush(loSt, hiSt, dSt); |
611 | 620 | ||
@@ -616,8 +625,8 @@ void mainQSort3(uint32_t* ptr, | |||
616 | if (hi - lo < MAIN_QSORT_SMALL_THRESH | 625 | if (hi - lo < MAIN_QSORT_SMALL_THRESH |
617 | || d > MAIN_QSORT_DEPTH_THRESH | 626 | || d > MAIN_QSORT_DEPTH_THRESH |
618 | ) { | 627 | ) { |
619 | mainSimpleSort(ptr, block, quadrant, nblock, lo, hi, d, budget); | 628 | mainSimpleSort(state, lo, hi, d); |
620 | if (*budget < 0) | 629 | if (state->budget < 0) |
621 | return; | 630 | return; |
622 | continue; | 631 | continue; |
623 | } | 632 | } |
@@ -638,8 +647,8 @@ void mainQSort3(uint32_t* ptr, | |||
638 | ltLo++; | 647 | ltLo++; |
639 | unLo++; | 648 | unLo++; |
640 | continue; | 649 | continue; |
641 | }; | 650 | } |
642 | if (n > 0) break; | 651 | if (n > 0) break; |
643 | unLo++; | 652 | unLo++; |
644 | } | 653 | } |
645 | while (1) { | 654 | while (1) { |
@@ -651,8 +660,8 @@ void mainQSort3(uint32_t* ptr, | |||
651 | gtHi--; | 660 | gtHi--; |
652 | unHi--; | 661 | unHi--; |
653 | continue; | 662 | continue; |
654 | }; | 663 | } |
655 | if (n < 0) break; | 664 | if (n < 0) break; |
656 | unHi--; | 665 | unHi--; |
657 | } | 666 | } |
658 | if (unLo > unHi) | 667 | if (unLo > unHi) |
@@ -721,28 +730,24 @@ void mainQSort3(uint32_t* ptr, | |||
721 | #define CLEARMASK (~(SETMASK)) | 730 | #define CLEARMASK (~(SETMASK)) |
722 | 731 | ||
723 | static NOINLINE | 732 | static NOINLINE |
724 | void mainSort(EState* state, | 733 | void mainSort(EState* state) |
725 | uint32_t* ptr, | ||
726 | uint8_t* block, | ||
727 | uint16_t* quadrant, | ||
728 | uint32_t* ftab, | ||
729 | int32_t nblock, | ||
730 | int32_t* budget) | ||
731 | { | 734 | { |
732 | int32_t i, j, k, ss, sb; | 735 | int32_t i, j; |
733 | uint8_t c1; | ||
734 | int32_t numQSorted; | ||
735 | uint16_t s; | ||
736 | Bool bigDone[256]; | 736 | Bool bigDone[256]; |
737 | uint8_t runningOrder[256]; | ||
737 | /* bbox: moved to EState to save stack | 738 | /* bbox: moved to EState to save stack |
738 | int32_t runningOrder[256]; | ||
739 | int32_t copyStart[256]; | 739 | int32_t copyStart[256]; |
740 | int32_t copyEnd [256]; | 740 | int32_t copyEnd [256]; |
741 | */ | 741 | */ |
742 | #define runningOrder (state->mainSort__runningOrder) | ||
743 | #define copyStart (state->mainSort__copyStart) | 742 | #define copyStart (state->mainSort__copyStart) |
744 | #define copyEnd (state->mainSort__copyEnd) | 743 | #define copyEnd (state->mainSort__copyEnd) |
745 | 744 | ||
745 | uint32_t *const ptr = state->ptr; | ||
746 | uint8_t *const block = state->block; | ||
747 | uint32_t *const ftab = state->ftab; | ||
748 | const int32_t nblock = state->nblock; | ||
749 | uint16_t *const quadrant = state->quadrant; | ||
750 | |||
746 | /*-- set up the 2-byte frequency table --*/ | 751 | /*-- set up the 2-byte frequency table --*/ |
747 | /* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */ | 752 | /* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */ |
748 | memset(ftab, 0, 65537 * sizeof(ftab[0])); | 753 | memset(ftab, 0, 65537 * sizeof(ftab[0])); |
@@ -750,25 +755,25 @@ void mainSort(EState* state, | |||
750 | j = block[0] << 8; | 755 | j = block[0] << 8; |
751 | i = nblock - 1; | 756 | i = nblock - 1; |
752 | /* 3%, +300 bytes */ | 757 | /* 3%, +300 bytes */ |
753 | #if CONFIG_BZIP2_FAST >= 2 | 758 | #if BZIP2_SPEED >= 2 |
754 | for (; i >= 3; i -= 4) { | 759 | for (; i >= 3; i -= 4) { |
755 | quadrant[i] = 0; | 760 | quadrant[i] = 0; |
756 | j = (j >> 8) | (((uint16_t)block[i]) << 8); | 761 | j = (j >> 8) | (((unsigned)block[i]) << 8); |
757 | ftab[j]++; | 762 | ftab[j]++; |
758 | quadrant[i-1] = 0; | 763 | quadrant[i-1] = 0; |
759 | j = (j >> 8) | (((uint16_t)block[i-1]) << 8); | 764 | j = (j >> 8) | (((unsigned)block[i-1]) << 8); |
760 | ftab[j]++; | 765 | ftab[j]++; |
761 | quadrant[i-2] = 0; | 766 | quadrant[i-2] = 0; |
762 | j = (j >> 8) | (((uint16_t)block[i-2]) << 8); | 767 | j = (j >> 8) | (((unsigned)block[i-2]) << 8); |
763 | ftab[j]++; | 768 | ftab[j]++; |
764 | quadrant[i-3] = 0; | 769 | quadrant[i-3] = 0; |
765 | j = (j >> 8) | (((uint16_t)block[i-3]) << 8); | 770 | j = (j >> 8) | (((unsigned)block[i-3]) << 8); |
766 | ftab[j]++; | 771 | ftab[j]++; |
767 | } | 772 | } |
768 | #endif | 773 | #endif |
769 | for (; i >= 0; i--) { | 774 | for (; i >= 0; i--) { |
770 | quadrant[i] = 0; | 775 | quadrant[i] = 0; |
771 | j = (j >> 8) | (((uint16_t)block[i]) << 8); | 776 | j = (j >> 8) | (((unsigned)block[i]) << 8); |
772 | ftab[j]++; | 777 | ftab[j]++; |
773 | } | 778 | } |
774 | 779 | ||
@@ -785,33 +790,36 @@ void mainSort(EState* state, | |||
785 | ftab[i] = j; | 790 | ftab[i] = j; |
786 | } | 791 | } |
787 | 792 | ||
788 | s = block[0] << 8; | 793 | { |
789 | i = nblock - 1; | 794 | unsigned s; |
790 | #if CONFIG_BZIP2_FAST >= 2 | 795 | s = block[0] << 8; |
791 | for (; i >= 3; i -= 4) { | 796 | i = nblock - 1; |
792 | s = (s >> 8) | (block[i] << 8); | 797 | #if BZIP2_SPEED >= 2 |
793 | j = ftab[s] - 1; | 798 | for (; i >= 3; i -= 4) { |
794 | ftab[s] = j; | 799 | s = (s >> 8) | (block[i] << 8); |
795 | ptr[j] = i; | 800 | j = ftab[s] - 1; |
796 | s = (s >> 8) | (block[i-1] << 8); | 801 | ftab[s] = j; |
797 | j = ftab[s] - 1; | 802 | ptr[j] = i; |
798 | ftab[s] = j; | 803 | s = (s >> 8) | (block[i-1] << 8); |
799 | ptr[j] = i-1; | 804 | j = ftab[s] - 1; |
800 | s = (s >> 8) | (block[i-2] << 8); | 805 | ftab[s] = j; |
801 | j = ftab[s] - 1; | 806 | ptr[j] = i-1; |
802 | ftab[s] = j; | 807 | s = (s >> 8) | (block[i-2] << 8); |
803 | ptr[j] = i-2; | 808 | j = ftab[s] - 1; |
804 | s = (s >> 8) | (block[i-3] << 8); | 809 | ftab[s] = j; |
805 | j = ftab[s] - 1; | 810 | ptr[j] = i-2; |
806 | ftab[s] = j; | 811 | s = (s >> 8) | (block[i-3] << 8); |
807 | ptr[j] = i-3; | 812 | j = ftab[s] - 1; |
808 | } | 813 | ftab[s] = j; |
814 | ptr[j] = i-3; | ||
815 | } | ||
809 | #endif | 816 | #endif |
810 | for (; i >= 0; i--) { | 817 | for (; i >= 0; i--) { |
811 | s = (s >> 8) | (block[i] << 8); | 818 | s = (s >> 8) | (block[i] << 8); |
812 | j = ftab[s] - 1; | 819 | j = ftab[s] - 1; |
813 | ftab[s] = j; | 820 | ftab[s] = j; |
814 | ptr[j] = i; | 821 | ptr[j] = i; |
822 | } | ||
815 | } | 823 | } |
816 | 824 | ||
817 | /* | 825 | /* |
@@ -825,24 +833,23 @@ void mainSort(EState* state, | |||
825 | } | 833 | } |
826 | 834 | ||
827 | { | 835 | { |
828 | int32_t vv; | ||
829 | /* bbox: was: int32_t h = 1; */ | 836 | /* bbox: was: int32_t h = 1; */ |
830 | /* do h = 3 * h + 1; while (h <= 256); */ | 837 | /* do h = 3 * h + 1; while (h <= 256); */ |
831 | uint32_t h = 364; | 838 | unsigned h = 364; |
832 | 839 | ||
833 | do { | 840 | do { |
834 | /*h = h / 3;*/ | 841 | /*h = h / 3;*/ |
835 | h = (h * 171) >> 9; /* bbox: fast h/3 */ | 842 | h = (h * 171) >> 9; /* bbox: fast h/3 */ |
836 | for (i = h; i <= 255; i++) { | 843 | for (i = h; i <= 255; i++) { |
837 | vv = runningOrder[i]; | 844 | unsigned vv, jh; |
845 | vv = runningOrder[i]; /* uint8[] */ | ||
838 | j = i; | 846 | j = i; |
839 | while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) { | 847 | while (jh = j - h, BIGFREQ(runningOrder[jh]) > BIGFREQ(vv)) { |
840 | runningOrder[j] = runningOrder[j-h]; | 848 | runningOrder[j] = runningOrder[jh]; |
841 | j = j - h; | 849 | j = jh; |
842 | if (j <= (h - 1)) | 850 | if (j < h) |
843 | goto zero; | 851 | break; |
844 | } | 852 | } |
845 | zero: | ||
846 | runningOrder[j] = vv; | 853 | runningOrder[j] = vv; |
847 | } | 854 | } |
848 | } while (h != 1); | 855 | } while (h != 1); |
@@ -852,9 +859,8 @@ void mainSort(EState* state, | |||
852 | * The main sorting loop. | 859 | * The main sorting loop. |
853 | */ | 860 | */ |
854 | 861 | ||
855 | numQSorted = 0; | 862 | for (i = 0; /*i <= 255*/; i++) { |
856 | 863 | unsigned ss; | |
857 | for (i = 0; i <= 255; i++) { | ||
858 | 864 | ||
859 | /* | 865 | /* |
860 | * Process big buckets, starting with the least full. | 866 | * Process big buckets, starting with the least full. |
@@ -874,17 +880,14 @@ void mainSort(EState* state, | |||
874 | */ | 880 | */ |
875 | for (j = 0; j <= 255; j++) { | 881 | for (j = 0; j <= 255; j++) { |
876 | if (j != ss) { | 882 | if (j != ss) { |
883 | unsigned sb; | ||
877 | sb = (ss << 8) + j; | 884 | sb = (ss << 8) + j; |
878 | if (!(ftab[sb] & SETMASK)) { | 885 | if (!(ftab[sb] & SETMASK)) { |
879 | int32_t lo = ftab[sb] & CLEARMASK; | 886 | int32_t lo = ftab[sb] /*& CLEARMASK (redundant)*/; |
880 | int32_t hi = (ftab[sb+1] & CLEARMASK) - 1; | 887 | int32_t hi = (ftab[sb+1] & CLEARMASK) - 1; |
881 | if (hi > lo) { | 888 | if (hi > lo) { |
882 | mainQSort3( | 889 | mainQSort3(state, lo, hi /*,BZ_N_RADIX*/); |
883 | ptr, block, quadrant, nblock, | 890 | if (state->budget < 0) return; |
884 | lo, hi, BZ_N_RADIX, budget | ||
885 | ); | ||
886 | if (*budget < 0) return; | ||
887 | numQSorted += (hi - lo + 1); | ||
888 | } | 891 | } |
889 | } | 892 | } |
890 | ftab[sb] |= SETMASK; | 893 | ftab[sb] |= SETMASK; |
@@ -906,6 +909,8 @@ void mainSort(EState* state, | |||
906 | copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; | 909 | copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; |
907 | } | 910 | } |
908 | for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { | 911 | for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { |
912 | unsigned c1; | ||
913 | int32_t k; | ||
909 | k = ptr[j] - 1; | 914 | k = ptr[j] - 1; |
910 | if (k < 0) | 915 | if (k < 0) |
911 | k += nblock; | 916 | k += nblock; |
@@ -914,6 +919,8 @@ void mainSort(EState* state, | |||
914 | ptr[copyStart[c1]++] = k; | 919 | ptr[copyStart[c1]++] = k; |
915 | } | 920 | } |
916 | for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { | 921 | for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { |
922 | unsigned c1; | ||
923 | int32_t k; | ||
917 | k = ptr[j]-1; | 924 | k = ptr[j]-1; |
918 | if (k < 0) | 925 | if (k < 0) |
919 | k += nblock; | 926 | k += nblock; |
@@ -933,6 +940,9 @@ void mainSort(EState* state, | |||
933 | for (j = 0; j <= 255; j++) | 940 | for (j = 0; j <= 255; j++) |
934 | ftab[(j << 8) + ss] |= SETMASK; | 941 | ftab[(j << 8) + ss] |= SETMASK; |
935 | 942 | ||
943 | if (i == 255) | ||
944 | break; | ||
945 | |||
936 | /* | 946 | /* |
937 | * Step 3: | 947 | * Step 3: |
938 | * The [ss] big bucket is now done. Record this fact, | 948 | * The [ss] big bucket is now done. Record this fact, |
@@ -974,15 +984,15 @@ void mainSort(EState* state, | |||
974 | */ | 984 | */ |
975 | bigDone[ss] = True; | 985 | bigDone[ss] = True; |
976 | 986 | ||
977 | if (i < 255) { | 987 | { |
978 | int32_t bbStart = ftab[ss << 8] & CLEARMASK; | 988 | unsigned bbStart = ftab[ss << 8] & CLEARMASK; |
979 | int32_t bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; | 989 | unsigned bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; |
980 | int32_t shifts = 0; | 990 | unsigned shifts = 0; |
981 | 991 | ||
982 | while ((bbSize >> shifts) > 65534) shifts++; | 992 | while ((bbSize >> shifts) > 65534) shifts++; |
983 | 993 | ||
984 | for (j = bbSize-1; j >= 0; j--) { | 994 | for (j = bbSize-1; j >= 0; j--) { |
985 | int32_t a2update = ptr[bbStart + j]; | 995 | unsigned a2update = ptr[bbStart + j]; /* uint32[] */ |
986 | uint16_t qVal = (uint16_t)(j >> shifts); | 996 | uint16_t qVal = (uint16_t)(j >> shifts); |
987 | quadrant[a2update] = qVal; | 997 | quadrant[a2update] = qVal; |
988 | if (a2update < BZ_N_OVERSHOOT) | 998 | if (a2update < BZ_N_OVERSHOOT) |
@@ -1015,31 +1025,24 @@ void mainSort(EState* state, | |||
1015 | * arr1[0 .. nblock-1] holds sorted order | 1025 | * arr1[0 .. nblock-1] holds sorted order |
1016 | */ | 1026 | */ |
1017 | static NOINLINE | 1027 | static NOINLINE |
1018 | void BZ2_blockSort(EState* s) | 1028 | int32_t BZ2_blockSort(EState* state) |
1019 | { | 1029 | { |
1020 | /* In original bzip2 1.0.4, it's a parameter, but 30 | 1030 | /* In original bzip2 1.0.4, it's a parameter, but 30 |
1021 | * (which was the default) should work ok. */ | 1031 | * (which was the default) should work ok. */ |
1022 | enum { wfact = 30 }; | 1032 | enum { wfact = 30 }; |
1033 | unsigned i; | ||
1034 | int32_t origPtr = origPtr; | ||
1023 | 1035 | ||
1024 | uint32_t* ptr = s->ptr; | 1036 | if (state->nblock >= 10000) { |
1025 | uint8_t* block = s->block; | ||
1026 | uint32_t* ftab = s->ftab; | ||
1027 | int32_t nblock = s->nblock; | ||
1028 | uint16_t* quadrant; | ||
1029 | int32_t budget; | ||
1030 | int32_t i; | ||
1031 | |||
1032 | if (nblock < 10000) { | ||
1033 | fallbackSort(s->arr1, s->arr2, ftab, nblock); | ||
1034 | } else { | ||
1035 | /* Calculate the location for quadrant, remembering to get | 1037 | /* Calculate the location for quadrant, remembering to get |
1036 | * the alignment right. Assumes that &(block[0]) is at least | 1038 | * the alignment right. Assumes that &(block[0]) is at least |
1037 | * 2-byte aligned -- this should be ok since block is really | 1039 | * 2-byte aligned -- this should be ok since block is really |
1038 | * the first section of arr2. | 1040 | * the first section of arr2. |
1039 | */ | 1041 | */ |
1040 | i = nblock + BZ_N_OVERSHOOT; | 1042 | i = state->nblock + BZ_N_OVERSHOOT; |
1041 | if (i & 1) i++; | 1043 | if (i & 1) |
1042 | quadrant = (uint16_t*)(&(block[i])); | 1044 | i++; |
1045 | state->quadrant = (uint16_t*) &(state->block[i]); | ||
1043 | 1046 | ||
1044 | /* (wfact-1) / 3 puts the default-factor-30 | 1047 | /* (wfact-1) / 3 puts the default-factor-30 |
1045 | * transition point at very roughly the same place as | 1048 | * transition point at very roughly the same place as |
@@ -1048,22 +1051,26 @@ void BZ2_blockSort(EState* s) | |||
1048 | * resulting compressed stream is now the same regardless | 1051 | * resulting compressed stream is now the same regardless |
1049 | * of whether or not we use the main sort or fallback sort. | 1052 | * of whether or not we use the main sort or fallback sort. |
1050 | */ | 1053 | */ |
1051 | budget = nblock * ((wfact-1) / 3); | 1054 | state->budget = state->nblock * ((wfact-1) / 3); |
1052 | 1055 | mainSort(state); | |
1053 | mainSort(s, ptr, block, quadrant, ftab, nblock, &budget); | 1056 | if (state->budget >= 0) |
1054 | if (budget < 0) { | 1057 | goto good; |
1055 | fallbackSort(s->arr1, s->arr2, ftab, nblock); | ||
1056 | } | ||
1057 | } | 1058 | } |
1059 | fallbackSort(state); | ||
1060 | good: | ||
1058 | 1061 | ||
1059 | s->origPtr = -1; | 1062 | #if BZ_LIGHT_DEBUG |
1060 | for (i = 0; i < s->nblock; i++) | 1063 | origPtr = -1; |
1061 | if (ptr[i] == 0) { | 1064 | #endif |
1062 | s->origPtr = i; | 1065 | for (i = 0; i < state->nblock; i++) { |
1066 | if (state->ptr[i] == 0) { | ||
1067 | origPtr = i; | ||
1063 | break; | 1068 | break; |
1064 | }; | 1069 | } |
1070 | } | ||
1065 | 1071 | ||
1066 | AssertH(s->origPtr != -1, 1003); | 1072 | AssertH(origPtr != -1, 1003); |
1073 | return origPtr; | ||
1067 | } | 1074 | } |
1068 | 1075 | ||
1069 | 1076 | ||
diff --git a/archival/libarchive/bz/bzlib.c b/archival/libarchive/bz/bzlib.c index 5f7db747a..9af2f026d 100644 --- a/archival/libarchive/bz/bzlib.c +++ b/archival/libarchive/bz/bzlib.c | |||
@@ -55,8 +55,9 @@ void prepare_new_block(EState* s) | |||
55 | { | 55 | { |
56 | int i; | 56 | int i; |
57 | s->nblock = 0; | 57 | s->nblock = 0; |
58 | s->numZ = 0; | 58 | //indexes into s->zbits[], initialzation moved to init of s->zbits |
59 | s->state_out_pos = 0; | 59 | //s->posZ = s->zbits; // was: s->numZ = 0; |
60 | //s->state_out_pos = s->zbits; | ||
60 | BZ_INITIALISE_CRC(s->blockCRC); | 61 | BZ_INITIALISE_CRC(s->blockCRC); |
61 | /* inlined memset would be nice to have here */ | 62 | /* inlined memset would be nice to have here */ |
62 | for (i = 0; i < 256; i++) | 63 | for (i = 0; i < 256; i++) |
@@ -86,7 +87,7 @@ int isempty_RL(EState* s) | |||
86 | static | 87 | static |
87 | void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k) | 88 | void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k) |
88 | { | 89 | { |
89 | int32_t n; | 90 | unsigned n; |
90 | EState* s; | 91 | EState* s; |
91 | 92 | ||
92 | s = xzalloc(sizeof(EState)); | 93 | s = xzalloc(sizeof(EState)); |
@@ -237,11 +238,10 @@ void /*Bool*/ copy_output_until_stop(EState* s) | |||
237 | if (s->strm->avail_out == 0) break; | 238 | if (s->strm->avail_out == 0) break; |
238 | 239 | ||
239 | /*-- block done? --*/ | 240 | /*-- block done? --*/ |
240 | if (s->state_out_pos >= s->numZ) break; | 241 | if (s->state_out_pos >= s->posZ) break; |
241 | 242 | ||
242 | /*progress_out = True;*/ | 243 | /*progress_out = True;*/ |
243 | *(s->strm->next_out) = s->zbits[s->state_out_pos]; | 244 | *(s->strm->next_out) = *s->state_out_pos++; |
244 | s->state_out_pos++; | ||
245 | s->strm->avail_out--; | 245 | s->strm->avail_out--; |
246 | s->strm->next_out++; | 246 | s->strm->next_out++; |
247 | s->strm->total_out++; | 247 | s->strm->total_out++; |
@@ -261,7 +261,7 @@ void /*Bool*/ handle_compress(bz_stream *strm) | |||
261 | while (1) { | 261 | while (1) { |
262 | if (s->state == BZ_S_OUTPUT) { | 262 | if (s->state == BZ_S_OUTPUT) { |
263 | /*progress_out |=*/ copy_output_until_stop(s); | 263 | /*progress_out |=*/ copy_output_until_stop(s); |
264 | if (s->state_out_pos < s->numZ) break; | 264 | if (s->state_out_pos < s->posZ) break; |
265 | if (s->mode == BZ_M_FINISHING | 265 | if (s->mode == BZ_M_FINISHING |
266 | //# && s->avail_in_expect == 0 | 266 | //# && s->avail_in_expect == 0 |
267 | && s->strm->avail_in == 0 | 267 | && s->strm->avail_in == 0 |
@@ -336,7 +336,7 @@ int BZ2_bzCompress(bz_stream *strm, int action) | |||
336 | /*if (s->avail_in_expect != s->strm->avail_in) | 336 | /*if (s->avail_in_expect != s->strm->avail_in) |
337 | return BZ_SEQUENCE_ERROR;*/ | 337 | return BZ_SEQUENCE_ERROR;*/ |
338 | /*progress =*/ handle_compress(strm); | 338 | /*progress =*/ handle_compress(strm); |
339 | if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) | 339 | if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->posZ) |
340 | return BZ_FLUSH_OK; | 340 | return BZ_FLUSH_OK; |
341 | s->mode = BZ_M_RUNNING; | 341 | s->mode = BZ_M_RUNNING; |
342 | return BZ_RUN_OK; | 342 | return BZ_RUN_OK; |
@@ -349,9 +349,9 @@ int BZ2_bzCompress(bz_stream *strm, int action) | |||
349 | return BZ_SEQUENCE_ERROR;*/ | 349 | return BZ_SEQUENCE_ERROR;*/ |
350 | /*progress =*/ handle_compress(strm); | 350 | /*progress =*/ handle_compress(strm); |
351 | /*if (!progress) return BZ_SEQUENCE_ERROR;*/ | 351 | /*if (!progress) return BZ_SEQUENCE_ERROR;*/ |
352 | //#if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) | 352 | //#if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->posZ) |
353 | //# return BZ_FINISH_OK; | 353 | //# return BZ_FINISH_OK; |
354 | if (s->strm->avail_in > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) | 354 | if (s->strm->avail_in > 0 || !isempty_RL(s) || s->state_out_pos < s->posZ) |
355 | return BZ_FINISH_OK; | 355 | return BZ_FINISH_OK; |
356 | /*s->mode = BZ_M_IDLE;*/ | 356 | /*s->mode = BZ_M_IDLE;*/ |
357 | return BZ_STREAM_END; | 357 | return BZ_STREAM_END; |
diff --git a/archival/libarchive/bz/bzlib_private.h b/archival/libarchive/bz/bzlib_private.h index 43e674bec..ea0f29b7c 100644 --- a/archival/libarchive/bz/bzlib_private.h +++ b/archival/libarchive/bz/bzlib_private.h | |||
@@ -120,8 +120,11 @@ typedef struct EState { | |||
120 | 120 | ||
121 | /* mode this stream is in, and whether inputting */ | 121 | /* mode this stream is in, and whether inputting */ |
122 | /* or outputting data */ | 122 | /* or outputting data */ |
123 | int32_t mode; | 123 | uint8_t mode; |
124 | int32_t state; | 124 | uint8_t state; |
125 | |||
126 | /* misc administratium */ | ||
127 | uint8_t blockSize100k; | ||
125 | 128 | ||
126 | /* remembers avail_in when flush/finish requested */ | 129 | /* remembers avail_in when flush/finish requested */ |
127 | /* bbox: not needed, strm->avail_in always has the same value */ | 130 | /* bbox: not needed, strm->avail_in always has the same value */ |
@@ -129,20 +132,19 @@ typedef struct EState { | |||
129 | /* uint32_t avail_in_expect; */ | 132 | /* uint32_t avail_in_expect; */ |
130 | 133 | ||
131 | /* for doing the block sorting */ | 134 | /* for doing the block sorting */ |
132 | int32_t origPtr; | ||
133 | uint32_t *arr1; | 135 | uint32_t *arr1; |
134 | uint32_t *arr2; | 136 | uint32_t *arr2; |
135 | uint32_t *ftab; | 137 | uint32_t *ftab; |
136 | 138 | ||
139 | uint16_t *quadrant; | ||
140 | int32_t budget; | ||
141 | |||
137 | /* aliases for arr1 and arr2 */ | 142 | /* aliases for arr1 and arr2 */ |
138 | uint32_t *ptr; | 143 | uint32_t *ptr; |
139 | uint8_t *block; | 144 | uint8_t *block; |
140 | uint16_t *mtfv; | 145 | uint16_t *mtfv; |
141 | uint8_t *zbits; | 146 | uint8_t *zbits; |
142 | 147 | ||
143 | /* guess what */ | ||
144 | uint32_t *crc32table; | ||
145 | |||
146 | /* run-length-encoding of the input */ | 148 | /* run-length-encoding of the input */ |
147 | uint32_t state_in_ch; | 149 | uint32_t state_in_ch; |
148 | int32_t state_in_len; | 150 | int32_t state_in_len; |
@@ -150,20 +152,23 @@ typedef struct EState { | |||
150 | /* input and output limits and current posns */ | 152 | /* input and output limits and current posns */ |
151 | int32_t nblock; | 153 | int32_t nblock; |
152 | int32_t nblockMAX; | 154 | int32_t nblockMAX; |
153 | int32_t numZ; | 155 | //int32_t numZ; // index into s->zbits[], replaced by pointer: |
154 | int32_t state_out_pos; | 156 | uint8_t *posZ; |
157 | uint8_t *state_out_pos; | ||
155 | 158 | ||
156 | /* the buffer for bit stream creation */ | 159 | /* the buffer for bit stream creation */ |
157 | uint32_t bsBuff; | 160 | uint32_t bsBuff; |
158 | int32_t bsLive; | 161 | int32_t bsLive; |
159 | 162 | ||
163 | /* guess what */ | ||
164 | uint32_t *crc32table; | ||
165 | |||
160 | /* block and combined CRCs */ | 166 | /* block and combined CRCs */ |
161 | uint32_t blockCRC; | 167 | uint32_t blockCRC; |
162 | uint32_t combinedCRC; | 168 | uint32_t combinedCRC; |
163 | 169 | ||
164 | /* misc administratium */ | 170 | /* misc administratium */ |
165 | int32_t blockNo; | 171 | int32_t blockNo; |
166 | int32_t blockSize100k; | ||
167 | 172 | ||
168 | /* stuff for coding the MTF values */ | 173 | /* stuff for coding the MTF values */ |
169 | int32_t nMTF; | 174 | int32_t nMTF; |
@@ -183,7 +188,7 @@ typedef struct EState { | |||
183 | /* stack-saving measures: these can be local, but they are too big */ | 188 | /* stack-saving measures: these can be local, but they are too big */ |
184 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 189 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
185 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 190 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
186 | #if CONFIG_BZIP2_FAST >= 5 | 191 | #if BZIP2_SPEED >= 5 |
187 | /* second dimension: only 3 needed; 4 makes index calculations faster */ | 192 | /* second dimension: only 3 needed; 4 makes index calculations faster */ |
188 | uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4]; | 193 | uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4]; |
189 | #endif | 194 | #endif |
@@ -191,7 +196,6 @@ typedef struct EState { | |||
191 | int32_t BZ2_hbMakeCodeLengths__weight[BZ_MAX_ALPHA_SIZE * 2]; | 196 | int32_t BZ2_hbMakeCodeLengths__weight[BZ_MAX_ALPHA_SIZE * 2]; |
192 | int32_t BZ2_hbMakeCodeLengths__parent[BZ_MAX_ALPHA_SIZE * 2]; | 197 | int32_t BZ2_hbMakeCodeLengths__parent[BZ_MAX_ALPHA_SIZE * 2]; |
193 | 198 | ||
194 | int32_t mainSort__runningOrder[256]; | ||
195 | int32_t mainSort__copyStart[256]; | 199 | int32_t mainSort__copyStart[256]; |
196 | int32_t mainSort__copyEnd[256]; | 200 | int32_t mainSort__copyEnd[256]; |
197 | } EState; | 201 | } EState; |
@@ -199,7 +203,7 @@ typedef struct EState { | |||
199 | 203 | ||
200 | /*-- compression. --*/ | 204 | /*-- compression. --*/ |
201 | 205 | ||
202 | static void | 206 | static int32_t |
203 | BZ2_blockSort(EState*); | 207 | BZ2_blockSort(EState*); |
204 | 208 | ||
205 | static void | 209 | static void |
diff --git a/archival/libarchive/bz/compress.c b/archival/libarchive/bz/compress.c index 2d994685c..539ab927e 100644 --- a/archival/libarchive/bz/compress.c +++ b/archival/libarchive/bz/compress.c | |||
@@ -32,6 +32,12 @@ in the file LICENSE. | |||
32 | 32 | ||
33 | /* #include "bzlib_private.h" */ | 33 | /* #include "bzlib_private.h" */ |
34 | 34 | ||
35 | #if BZIP2_SPEED >= 5 | ||
36 | # define ALWAYS_INLINE_5 ALWAYS_INLINE | ||
37 | #else | ||
38 | # define ALWAYS_INLINE_5 /*nothing*/ | ||
39 | #endif | ||
40 | |||
35 | /*---------------------------------------------------*/ | 41 | /*---------------------------------------------------*/ |
36 | /*--- Bit stream I/O ---*/ | 42 | /*--- Bit stream I/O ---*/ |
37 | /*---------------------------------------------------*/ | 43 | /*---------------------------------------------------*/ |
@@ -50,8 +56,7 @@ static NOINLINE | |||
50 | void bsFinishWrite(EState* s) | 56 | void bsFinishWrite(EState* s) |
51 | { | 57 | { |
52 | while (s->bsLive > 0) { | 58 | while (s->bsLive > 0) { |
53 | s->zbits[s->numZ] = (uint8_t)(s->bsBuff >> 24); | 59 | *s->posZ++ = (uint8_t)(s->bsBuff >> 24); |
54 | s->numZ++; | ||
55 | s->bsBuff <<= 8; | 60 | s->bsBuff <<= 8; |
56 | s->bsLive -= 8; | 61 | s->bsLive -= 8; |
57 | } | 62 | } |
@@ -61,39 +66,74 @@ void bsFinishWrite(EState* s) | |||
61 | /*---------------------------------------------------*/ | 66 | /*---------------------------------------------------*/ |
62 | static | 67 | static |
63 | /* Helps only on level 5, on other levels hurts. ? */ | 68 | /* Helps only on level 5, on other levels hurts. ? */ |
64 | #if CONFIG_BZIP2_FAST >= 5 | 69 | ALWAYS_INLINE_5 |
65 | ALWAYS_INLINE | ||
66 | #endif | ||
67 | void bsW(EState* s, int32_t n, uint32_t v) | 70 | void bsW(EState* s, int32_t n, uint32_t v) |
68 | { | 71 | { |
69 | while (s->bsLive >= 8) { | 72 | while (s->bsLive >= 8) { |
70 | s->zbits[s->numZ] = (uint8_t)(s->bsBuff >> 24); | 73 | *s->posZ++ = (uint8_t)(s->bsBuff >> 24); |
71 | s->numZ++; | ||
72 | s->bsBuff <<= 8; | 74 | s->bsBuff <<= 8; |
73 | s->bsLive -= 8; | 75 | s->bsLive -= 8; |
74 | } | 76 | } |
75 | s->bsBuff |= (v << (32 - s->bsLive - n)); | 77 | s->bsBuff |= (v << (32 - s->bsLive - n)); |
76 | s->bsLive += n; | 78 | s->bsLive += n; |
77 | } | 79 | } |
80 | /* Same with n == 16: */ | ||
81 | static | ||
82 | ALWAYS_INLINE_5 | ||
83 | void bsW16(EState* s, uint32_t v) | ||
84 | { | ||
85 | while (s->bsLive >= 8) { | ||
86 | *s->posZ++ = (uint8_t)(s->bsBuff >> 24); | ||
87 | s->bsBuff <<= 8; | ||
88 | s->bsLive -= 8; | ||
89 | } | ||
90 | s->bsBuff |= (v << (16 - s->bsLive)); | ||
91 | s->bsLive += 16; | ||
92 | } | ||
93 | /* Same with n == 1: */ | ||
94 | static | ||
95 | ALWAYS_INLINE /* one callsite */ | ||
96 | void bsW1_1(EState* s) | ||
97 | { | ||
98 | /* need space for only 1 bit, no need for loop freeing > 8 bits */ | ||
99 | if (s->bsLive >= 8) { | ||
100 | *s->posZ++ = (uint8_t)(s->bsBuff >> 24); | ||
101 | s->bsBuff <<= 8; | ||
102 | s->bsLive -= 8; | ||
103 | } | ||
104 | s->bsBuff |= (1 << (31 - s->bsLive)); | ||
105 | s->bsLive += 1; | ||
106 | } | ||
107 | static | ||
108 | ALWAYS_INLINE_5 | ||
109 | void bsW1_0(EState* s) | ||
110 | { | ||
111 | /* need space for only 1 bit, no need for loop freeing > 8 bits */ | ||
112 | if (s->bsLive >= 8) { | ||
113 | *s->posZ++ = (uint8_t)(s->bsBuff >> 24); | ||
114 | s->bsBuff <<= 8; | ||
115 | s->bsLive -= 8; | ||
116 | } | ||
117 | //s->bsBuff |= (0 << (31 - s->bsLive)); | ||
118 | s->bsLive += 1; | ||
119 | } | ||
78 | 120 | ||
79 | 121 | ||
80 | /*---------------------------------------------------*/ | 122 | /*---------------------------------------------------*/ |
81 | static | 123 | static ALWAYS_INLINE |
82 | void bsPutU32(EState* s, unsigned u) | 124 | void bsPutU16(EState* s, unsigned u) |
83 | { | 125 | { |
84 | bsW(s, 8, (u >> 24) & 0xff); | 126 | bsW16(s, u); |
85 | bsW(s, 8, (u >> 16) & 0xff); | ||
86 | bsW(s, 8, (u >> 8) & 0xff); | ||
87 | bsW(s, 8, u & 0xff); | ||
88 | } | 127 | } |
89 | 128 | ||
90 | 129 | ||
91 | /*---------------------------------------------------*/ | 130 | /*---------------------------------------------------*/ |
92 | static | 131 | static |
93 | void bsPutU16(EState* s, unsigned u) | 132 | void bsPutU32(EState* s, unsigned u) |
94 | { | 133 | { |
95 | bsW(s, 8, (u >> 8) & 0xff); | 134 | //bsW(s, 32, u); // can't use: may try "uint32 << -n" |
96 | bsW(s, 8, u & 0xff); | 135 | bsW16(s, (u >> 16) & 0xffff); |
136 | bsW16(s, u & 0xffff); | ||
97 | } | 137 | } |
98 | 138 | ||
99 | 139 | ||
@@ -106,25 +146,57 @@ static | |||
106 | void makeMaps_e(EState* s) | 146 | void makeMaps_e(EState* s) |
107 | { | 147 | { |
108 | int i; | 148 | int i; |
109 | s->nInUse = 0; | 149 | unsigned cnt = 0; |
110 | for (i = 0; i < 256; i++) { | 150 | for (i = 0; i < 256; i++) { |
111 | if (s->inUse[i]) { | 151 | if (s->inUse[i]) { |
112 | s->unseqToSeq[i] = s->nInUse; | 152 | s->unseqToSeq[i] = cnt; |
113 | s->nInUse++; | 153 | cnt++; |
114 | } | 154 | } |
115 | } | 155 | } |
156 | s->nInUse = cnt; | ||
116 | } | 157 | } |
117 | 158 | ||
118 | 159 | ||
119 | /*---------------------------------------------------*/ | 160 | /*---------------------------------------------------*/ |
161 | /* | ||
162 | * This bit of code is performance-critical. | ||
163 | * On 32bit x86, gcc-6.3.0 was observed to spill ryy_j to stack, | ||
164 | * resulting in abysmal performance (x3 slowdown). | ||
165 | * Forcing it into a separate function alleviates register pressure, | ||
166 | * and spillage no longer happens. | ||
167 | * Other versions of gcc do not exhibit this problem, but out-of-line code | ||
168 | * seems to be helping them too (code is both smaller and faster). | ||
169 | * Therefore NOINLINE is enabled for the entire 32bit x86 arch for now, | ||
170 | * without a check for gcc version. | ||
171 | */ | ||
172 | static | ||
173 | #if defined __i386__ | ||
174 | NOINLINE | ||
175 | #endif | ||
176 | int inner_loop(uint8_t *yy, uint8_t ll_i) | ||
177 | { | ||
178 | register uint8_t rtmp; | ||
179 | register uint8_t* ryy_j; | ||
180 | rtmp = yy[1]; | ||
181 | yy[1] = yy[0]; | ||
182 | ryy_j = &(yy[1]); | ||
183 | while (ll_i != rtmp) { | ||
184 | register uint8_t rtmp2; | ||
185 | ryy_j++; | ||
186 | rtmp2 = rtmp; | ||
187 | rtmp = *ryy_j; | ||
188 | *ryy_j = rtmp2; | ||
189 | } | ||
190 | yy[0] = rtmp; | ||
191 | return ryy_j - &(yy[0]); | ||
192 | } | ||
120 | static NOINLINE | 193 | static NOINLINE |
121 | void generateMTFValues(EState* s) | 194 | void generateMTFValues(EState* s) |
122 | { | 195 | { |
123 | uint8_t yy[256]; | 196 | uint8_t yy[256]; |
124 | int32_t i, j; | 197 | int i; |
125 | int32_t zPend; | 198 | int zPend; |
126 | int32_t wr; | 199 | int32_t wr; |
127 | int32_t EOB; | ||
128 | 200 | ||
129 | /* | 201 | /* |
130 | * After sorting (eg, here), | 202 | * After sorting (eg, here), |
@@ -148,95 +220,74 @@ void generateMTFValues(EState* s) | |||
148 | * compressBlock(). | 220 | * compressBlock(). |
149 | */ | 221 | */ |
150 | uint32_t* ptr = s->ptr; | 222 | uint32_t* ptr = s->ptr; |
151 | uint8_t* block = s->block; | ||
152 | uint16_t* mtfv = s->mtfv; | ||
153 | 223 | ||
154 | makeMaps_e(s); | 224 | makeMaps_e(s); |
155 | EOB = s->nInUse+1; | ||
156 | |||
157 | for (i = 0; i <= EOB; i++) | ||
158 | s->mtfFreq[i] = 0; | ||
159 | 225 | ||
160 | wr = 0; | 226 | wr = 0; |
161 | zPend = 0; | 227 | zPend = 0; |
228 | for (i = 0; i <= s->nInUse+1; i++) | ||
229 | s->mtfFreq[i] = 0; | ||
230 | |||
162 | for (i = 0; i < s->nInUse; i++) | 231 | for (i = 0; i < s->nInUse; i++) |
163 | yy[i] = (uint8_t) i; | 232 | yy[i] = (uint8_t) i; |
164 | 233 | ||
165 | for (i = 0; i < s->nblock; i++) { | 234 | for (i = 0; i < s->nblock; i++) { |
166 | uint8_t ll_i; | 235 | uint8_t ll_i = ll_i; /* gcc 4.3.1 thinks it may be used w/o init */ |
236 | int32_t j; | ||
237 | |||
167 | AssertD(wr <= i, "generateMTFValues(1)"); | 238 | AssertD(wr <= i, "generateMTFValues(1)"); |
168 | j = ptr[i] - 1; | 239 | j = ptr[i] - 1; |
169 | if (j < 0) | 240 | if (j < 0) |
170 | j += s->nblock; | 241 | j += s->nblock; |
171 | ll_i = s->unseqToSeq[block[j]]; | 242 | ll_i = s->unseqToSeq[s->block[j]]; |
172 | AssertD(ll_i < s->nInUse, "generateMTFValues(2a)"); | 243 | AssertD(ll_i < s->nInUse, "generateMTFValues(2a)"); |
173 | 244 | ||
174 | if (yy[0] == ll_i) { | 245 | if (yy[0] == ll_i) { |
175 | zPend++; | 246 | zPend++; |
176 | } else { | 247 | continue; |
177 | if (zPend > 0) { | ||
178 | zPend--; | ||
179 | while (1) { | ||
180 | if (zPend & 1) { | ||
181 | mtfv[wr] = BZ_RUNB; wr++; | ||
182 | s->mtfFreq[BZ_RUNB]++; | ||
183 | } else { | ||
184 | mtfv[wr] = BZ_RUNA; wr++; | ||
185 | s->mtfFreq[BZ_RUNA]++; | ||
186 | } | ||
187 | if (zPend < 2) break; | ||
188 | zPend = (uint32_t)(zPend - 2) / 2; | ||
189 | /* bbox: unsigned div is easier */ | ||
190 | }; | ||
191 | zPend = 0; | ||
192 | } | ||
193 | { | ||
194 | register uint8_t rtmp; | ||
195 | register uint8_t* ryy_j; | ||
196 | register uint8_t rll_i; | ||
197 | rtmp = yy[1]; | ||
198 | yy[1] = yy[0]; | ||
199 | ryy_j = &(yy[1]); | ||
200 | rll_i = ll_i; | ||
201 | while (rll_i != rtmp) { | ||
202 | register uint8_t rtmp2; | ||
203 | ryy_j++; | ||
204 | rtmp2 = rtmp; | ||
205 | rtmp = *ryy_j; | ||
206 | *ryy_j = rtmp2; | ||
207 | }; | ||
208 | yy[0] = rtmp; | ||
209 | j = ryy_j - &(yy[0]); | ||
210 | mtfv[wr] = j+1; | ||
211 | wr++; | ||
212 | s->mtfFreq[j+1]++; | ||
213 | } | ||
214 | } | 248 | } |
215 | } | ||
216 | 249 | ||
217 | if (zPend > 0) { | 250 | if (zPend > 0) { |
218 | zPend--; | 251 | process_zPend: |
219 | while (1) { | 252 | zPend--; |
220 | if (zPend & 1) { | 253 | while (1) { |
221 | mtfv[wr] = BZ_RUNB; | 254 | #if 0 |
222 | wr++; | 255 | if (zPend & 1) { |
223 | s->mtfFreq[BZ_RUNB]++; | 256 | s->mtfv[wr] = BZ_RUNB; wr++; |
224 | } else { | 257 | s->mtfFreq[BZ_RUNB]++; |
225 | mtfv[wr] = BZ_RUNA; | 258 | } else { |
259 | s->mtfv[wr] = BZ_RUNA; wr++; | ||
260 | s->mtfFreq[BZ_RUNA]++; | ||
261 | } | ||
262 | #else /* same as above, since BZ_RUNA is 0 and BZ_RUNB is 1 */ | ||
263 | unsigned run = zPend & 1; | ||
264 | s->mtfv[wr] = run; | ||
226 | wr++; | 265 | wr++; |
227 | s->mtfFreq[BZ_RUNA]++; | 266 | s->mtfFreq[run]++; |
267 | #endif | ||
268 | zPend -= 2; | ||
269 | if (zPend < 0) | ||
270 | break; | ||
271 | zPend = (unsigned)zPend / 2; | ||
272 | /* bbox: unsigned div is easier */ | ||
228 | } | 273 | } |
229 | if (zPend < 2) | 274 | if (i < 0) /* came via "goto process_zPend"? exit */ |
230 | break; | 275 | goto end; |
231 | zPend = (uint32_t)(zPend - 2) / 2; | 276 | zPend = 0; |
232 | /* bbox: unsigned div is easier */ | 277 | } |
233 | }; | 278 | j = inner_loop(yy, ll_i); |
234 | zPend = 0; | 279 | s->mtfv[wr] = j+1; |
280 | wr++; | ||
281 | s->mtfFreq[j+1]++; | ||
235 | } | 282 | } |
236 | 283 | ||
237 | mtfv[wr] = EOB; | 284 | i = -1; |
285 | if (zPend > 0) | ||
286 | goto process_zPend; /* "process it and come back here" */ | ||
287 | end: | ||
288 | s->mtfv[wr] = s->nInUse+1; | ||
238 | wr++; | 289 | wr++; |
239 | s->mtfFreq[EOB]++; | 290 | s->mtfFreq[s->nInUse+1]++; |
240 | 291 | ||
241 | s->nMTF = wr; | 292 | s->nMTF = wr; |
242 | } | 293 | } |
@@ -249,8 +300,11 @@ void generateMTFValues(EState* s) | |||
249 | static NOINLINE | 300 | static NOINLINE |
250 | void sendMTFValues(EState* s) | 301 | void sendMTFValues(EState* s) |
251 | { | 302 | { |
252 | int32_t v, t, i, j, gs, ge, bt, bc, iter; | 303 | int32_t t, i; |
253 | int32_t nSelectors, alphaSize, minLen, maxLen, selCtr; | 304 | unsigned iter; |
305 | unsigned gs; | ||
306 | int32_t alphaSize; | ||
307 | unsigned nSelectors, selCtr; | ||
254 | int32_t nGroups; | 308 | int32_t nGroups; |
255 | 309 | ||
256 | /* | 310 | /* |
@@ -266,39 +320,49 @@ void sendMTFValues(EState* s) | |||
266 | #define rfreq sendMTFValues__rfreq | 320 | #define rfreq sendMTFValues__rfreq |
267 | #define len_pack sendMTFValues__len_pack | 321 | #define len_pack sendMTFValues__len_pack |
268 | 322 | ||
269 | uint16_t cost[BZ_N_GROUPS]; | 323 | unsigned /*uint16_t*/ cost[BZ_N_GROUPS]; |
270 | int32_t fave[BZ_N_GROUPS]; | ||
271 | 324 | ||
272 | uint16_t* mtfv = s->mtfv; | 325 | uint16_t* mtfv = s->mtfv; |
273 | 326 | ||
274 | alphaSize = s->nInUse + 2; | 327 | alphaSize = s->nInUse + 2; |
275 | for (t = 0; t < BZ_N_GROUPS; t++) | 328 | for (t = 0; t < BZ_N_GROUPS; t++) { |
329 | unsigned v; | ||
276 | for (v = 0; v < alphaSize; v++) | 330 | for (v = 0; v < alphaSize; v++) |
277 | s->len[t][v] = BZ_GREATER_ICOST; | 331 | s->len[t][v] = BZ_GREATER_ICOST; |
332 | } | ||
278 | 333 | ||
279 | /*--- Decide how many coding tables to use ---*/ | 334 | /*--- Decide how many coding tables to use ---*/ |
280 | AssertH(s->nMTF > 0, 3001); | 335 | AssertH(s->nMTF > 0, 3001); |
281 | if (s->nMTF < 200) nGroups = 2; else | 336 | // 1..199 = 2 |
282 | if (s->nMTF < 600) nGroups = 3; else | 337 | // 200..599 = 3 |
283 | if (s->nMTF < 1200) nGroups = 4; else | 338 | // 600..1199 = 4 |
284 | if (s->nMTF < 2400) nGroups = 5; else | 339 | // 1200..2399 = 5 |
285 | nGroups = 6; | 340 | // 2400..99999 = 6 |
341 | nGroups = 2; | ||
342 | nGroups += (s->nMTF >= 200); | ||
343 | nGroups += (s->nMTF >= 600); | ||
344 | nGroups += (s->nMTF >= 1200); | ||
345 | nGroups += (s->nMTF >= 2400); | ||
286 | 346 | ||
287 | /*--- Generate an initial set of coding tables ---*/ | 347 | /*--- Generate an initial set of coding tables ---*/ |
288 | { | 348 | { |
289 | int32_t nPart, remF, tFreq, aFreq; | 349 | unsigned nPart, remF; |
290 | 350 | ||
291 | nPart = nGroups; | 351 | nPart = nGroups; |
292 | remF = s->nMTF; | 352 | remF = s->nMTF; |
293 | gs = 0; | 353 | gs = 0; |
294 | while (nPart > 0) { | 354 | while (nPart > 0) { |
355 | unsigned v; | ||
356 | unsigned ge; | ||
357 | unsigned tFreq, aFreq; | ||
358 | |||
295 | tFreq = remF / nPart; | 359 | tFreq = remF / nPart; |
296 | ge = gs - 1; | 360 | ge = gs; |
297 | aFreq = 0; | 361 | aFreq = 0; |
298 | while (aFreq < tFreq && ge < alphaSize-1) { | 362 | while (aFreq < tFreq && ge < alphaSize) { |
299 | ge++; | 363 | aFreq += s->mtfFreq[ge++]; |
300 | aFreq += s->mtfFreq[ge]; | ||
301 | } | 364 | } |
365 | ge--; | ||
302 | 366 | ||
303 | if (ge > gs | 367 | if (ge > gs |
304 | && nPart != nGroups && nPart != 1 | 368 | && nPart != nGroups && nPart != 1 |
@@ -324,19 +388,19 @@ void sendMTFValues(EState* s) | |||
324 | * Iterate up to BZ_N_ITERS times to improve the tables. | 388 | * Iterate up to BZ_N_ITERS times to improve the tables. |
325 | */ | 389 | */ |
326 | for (iter = 0; iter < BZ_N_ITERS; iter++) { | 390 | for (iter = 0; iter < BZ_N_ITERS; iter++) { |
327 | for (t = 0; t < nGroups; t++) | 391 | for (t = 0; t < nGroups; t++) { |
328 | fave[t] = 0; | 392 | unsigned v; |
329 | |||
330 | for (t = 0; t < nGroups; t++) | ||
331 | for (v = 0; v < alphaSize; v++) | 393 | for (v = 0; v < alphaSize; v++) |
332 | s->rfreq[t][v] = 0; | 394 | s->rfreq[t][v] = 0; |
395 | } | ||
333 | 396 | ||
334 | #if CONFIG_BZIP2_FAST >= 5 | 397 | #if BZIP2_SPEED >= 5 |
335 | /* | 398 | /* |
336 | * Set up an auxiliary length table which is used to fast-track | 399 | * Set up an auxiliary length table which is used to fast-track |
337 | * the common case (nGroups == 6). | 400 | * the common case (nGroups == 6). |
338 | */ | 401 | */ |
339 | if (nGroups == 6) { | 402 | if (nGroups == 6) { |
403 | unsigned v; | ||
340 | for (v = 0; v < alphaSize; v++) { | 404 | for (v = 0; v < alphaSize; v++) { |
341 | s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; | 405 | s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; |
342 | s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; | 406 | s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; |
@@ -347,6 +411,9 @@ void sendMTFValues(EState* s) | |||
347 | nSelectors = 0; | 411 | nSelectors = 0; |
348 | gs = 0; | 412 | gs = 0; |
349 | while (1) { | 413 | while (1) { |
414 | unsigned ge; | ||
415 | unsigned bt, bc; | ||
416 | |||
350 | /*--- Set group start & end marks. --*/ | 417 | /*--- Set group start & end marks. --*/ |
351 | if (gs >= s->nMTF) | 418 | if (gs >= s->nMTF) |
352 | break; | 419 | break; |
@@ -360,7 +427,7 @@ void sendMTFValues(EState* s) | |||
360 | */ | 427 | */ |
361 | for (t = 0; t < nGroups; t++) | 428 | for (t = 0; t < nGroups; t++) |
362 | cost[t] = 0; | 429 | cost[t] = 0; |
363 | #if CONFIG_BZIP2_FAST >= 5 | 430 | #if BZIP2_SPEED >= 5 |
364 | if (nGroups == 6 && 50 == ge-gs+1) { | 431 | if (nGroups == 6 && 50 == ge-gs+1) { |
365 | /*--- fast track the common case ---*/ | 432 | /*--- fast track the common case ---*/ |
366 | register uint32_t cost01, cost23, cost45; | 433 | register uint32_t cost01, cost23, cost45; |
@@ -390,7 +457,7 @@ void sendMTFValues(EState* s) | |||
390 | { | 457 | { |
391 | /*--- slow version which correctly handles all situations ---*/ | 458 | /*--- slow version which correctly handles all situations ---*/ |
392 | for (i = gs; i <= ge; i++) { | 459 | for (i = gs; i <= ge; i++) { |
393 | uint16_t icv = mtfv[i]; | 460 | unsigned /*uint16_t*/ icv = mtfv[i]; |
394 | for (t = 0; t < nGroups; t++) | 461 | for (t = 0; t < nGroups; t++) |
395 | cost[t] += s->len[t][icv]; | 462 | cost[t] += s->len[t][icv]; |
396 | } | 463 | } |
@@ -409,7 +476,6 @@ void sendMTFValues(EState* s) | |||
409 | bt = t; | 476 | bt = t; |
410 | } | 477 | } |
411 | } | 478 | } |
412 | fave[bt]++; | ||
413 | s->selector[nSelectors] = bt; | 479 | s->selector[nSelectors] = bt; |
414 | nSelectors++; | 480 | nSelectors++; |
415 | 481 | ||
@@ -417,7 +483,7 @@ void sendMTFValues(EState* s) | |||
417 | * Increment the symbol frequencies for the selected table. | 483 | * Increment the symbol frequencies for the selected table. |
418 | */ | 484 | */ |
419 | /* 1% faster compress. +800 bytes */ | 485 | /* 1% faster compress. +800 bytes */ |
420 | #if CONFIG_BZIP2_FAST >= 4 | 486 | #if BZIP2_SPEED >= 4 |
421 | if (nGroups == 6 && 50 == ge-gs+1) { | 487 | if (nGroups == 6 && 50 == ge-gs+1) { |
422 | /*--- fast track the common case ---*/ | 488 | /*--- fast track the common case ---*/ |
423 | #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ | 489 | #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ |
@@ -464,6 +530,7 @@ void sendMTFValues(EState* s) | |||
464 | for (i = 0; i < nGroups; i++) | 530 | for (i = 0; i < nGroups; i++) |
465 | pos[i] = i; | 531 | pos[i] = i; |
466 | for (i = 0; i < nSelectors; i++) { | 532 | for (i = 0; i < nSelectors; i++) { |
533 | unsigned j; | ||
467 | ll_i = s->selector[i]; | 534 | ll_i = s->selector[i]; |
468 | j = 0; | 535 | j = 0; |
469 | tmp = pos[j]; | 536 | tmp = pos[j]; |
@@ -472,16 +539,16 @@ void sendMTFValues(EState* s) | |||
472 | tmp2 = tmp; | 539 | tmp2 = tmp; |
473 | tmp = pos[j]; | 540 | tmp = pos[j]; |
474 | pos[j] = tmp2; | 541 | pos[j] = tmp2; |
475 | }; | 542 | } |
476 | pos[0] = tmp; | 543 | pos[0] = tmp; |
477 | s->selectorMtf[i] = j; | 544 | s->selectorMtf[i] = j; |
478 | } | 545 | } |
479 | }; | 546 | } |
480 | 547 | ||
481 | /*--- Assign actual codes for the tables. --*/ | 548 | /*--- Assign actual codes for the tables. --*/ |
482 | for (t = 0; t < nGroups; t++) { | 549 | for (t = 0; t < nGroups; t++) { |
483 | minLen = 32; | 550 | unsigned minLen = 32; //todo: s->len[t][0]; |
484 | maxLen = 0; | 551 | unsigned maxLen = 0; //todo: s->len[t][0]; |
485 | for (i = 0; i < alphaSize; i++) { | 552 | for (i = 0; i < alphaSize; i++) { |
486 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; | 553 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; |
487 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; | 554 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; |
@@ -509,15 +576,16 @@ void sendMTFValues(EState* s) | |||
509 | } | 576 | } |
510 | } | 577 | } |
511 | 578 | ||
512 | bsW(s, 16, inUse16); | 579 | bsW16(s, inUse16); |
513 | 580 | ||
514 | inUse16 <<= (sizeof(int)*8 - 16); /* move 15th bit into sign bit */ | 581 | inUse16 <<= (sizeof(int)*8 - 16); /* move 15th bit into sign bit */ |
515 | for (i = 0; i < 16; i++) { | 582 | for (i = 0; i < 16; i++) { |
516 | if (inUse16 < 0) { | 583 | if (inUse16 < 0) { |
517 | unsigned v16 = 0; | 584 | unsigned v16 = 0; |
585 | unsigned j; | ||
518 | for (j = 0; j < 16; j++) | 586 | for (j = 0; j < 16; j++) |
519 | v16 = v16*2 + s->inUse[i * 16 + j]; | 587 | v16 = v16*2 + s->inUse[i * 16 + j]; |
520 | bsW(s, 16, v16); | 588 | bsW16(s, v16); |
521 | } | 589 | } |
522 | inUse16 <<= 1; | 590 | inUse16 <<= 1; |
523 | } | 591 | } |
@@ -527,19 +595,20 @@ void sendMTFValues(EState* s) | |||
527 | bsW(s, 3, nGroups); | 595 | bsW(s, 3, nGroups); |
528 | bsW(s, 15, nSelectors); | 596 | bsW(s, 15, nSelectors); |
529 | for (i = 0; i < nSelectors; i++) { | 597 | for (i = 0; i < nSelectors; i++) { |
598 | unsigned j; | ||
530 | for (j = 0; j < s->selectorMtf[i]; j++) | 599 | for (j = 0; j < s->selectorMtf[i]; j++) |
531 | bsW(s, 1, 1); | 600 | bsW1_1(s); |
532 | bsW(s, 1, 0); | 601 | bsW1_0(s); |
533 | } | 602 | } |
534 | 603 | ||
535 | /*--- Now the coding tables. ---*/ | 604 | /*--- Now the coding tables. ---*/ |
536 | for (t = 0; t < nGroups; t++) { | 605 | for (t = 0; t < nGroups; t++) { |
537 | int32_t curr = s->len[t][0]; | 606 | unsigned curr = s->len[t][0]; |
538 | bsW(s, 5, curr); | 607 | bsW(s, 5, curr); |
539 | for (i = 0; i < alphaSize; i++) { | 608 | for (i = 0; i < alphaSize; i++) { |
540 | while (curr < s->len[t][i]) { bsW(s, 2, 2); curr++; /* 10 */ }; | 609 | while (curr < s->len[t][i]) { bsW(s, 2, 2); curr++; /* 10 */ } |
541 | while (curr > s->len[t][i]) { bsW(s, 2, 3); curr--; /* 11 */ }; | 610 | while (curr > s->len[t][i]) { bsW(s, 2, 3); curr--; /* 11 */ } |
542 | bsW(s, 1, 0); | 611 | bsW1_0(s); |
543 | } | 612 | } |
544 | } | 613 | } |
545 | 614 | ||
@@ -547,6 +616,8 @@ void sendMTFValues(EState* s) | |||
547 | selCtr = 0; | 616 | selCtr = 0; |
548 | gs = 0; | 617 | gs = 0; |
549 | while (1) { | 618 | while (1) { |
619 | unsigned ge; | ||
620 | |||
550 | if (gs >= s->nMTF) | 621 | if (gs >= s->nMTF) |
551 | break; | 622 | break; |
552 | ge = gs + BZ_G_SIZE - 1; | 623 | ge = gs + BZ_G_SIZE - 1; |
@@ -605,17 +676,21 @@ void sendMTFValues(EState* s) | |||
605 | static | 676 | static |
606 | void BZ2_compressBlock(EState* s, int is_last_block) | 677 | void BZ2_compressBlock(EState* s, int is_last_block) |
607 | { | 678 | { |
679 | int32_t origPtr = origPtr; | ||
680 | |||
608 | if (s->nblock > 0) { | 681 | if (s->nblock > 0) { |
609 | BZ_FINALISE_CRC(s->blockCRC); | 682 | BZ_FINALISE_CRC(s->blockCRC); |
610 | s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); | 683 | s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); |
611 | s->combinedCRC ^= s->blockCRC; | 684 | s->combinedCRC ^= s->blockCRC; |
612 | if (s->blockNo > 1) | 685 | if (s->blockNo > 1) |
613 | s->numZ = 0; | 686 | s->posZ = s->zbits; // was: s->numZ = 0; |
614 | 687 | ||
615 | BZ2_blockSort(s); | 688 | origPtr = BZ2_blockSort(s); |
616 | } | 689 | } |
617 | 690 | ||
618 | s->zbits = &((uint8_t*)s->arr2)[s->nblock]; | 691 | s->zbits = &((uint8_t*)s->arr2)[s->nblock]; |
692 | s->posZ = s->zbits; | ||
693 | s->state_out_pos = s->zbits; | ||
619 | 694 | ||
620 | /*-- If this is the first block, create the stream header. --*/ | 695 | /*-- If this is the first block, create the stream header. --*/ |
621 | if (s->blockNo == 1) { | 696 | if (s->blockNo == 1) { |
@@ -649,9 +724,9 @@ void BZ2_compressBlock(EState* s, int is_last_block) | |||
649 | * so as to maintain backwards compatibility with | 724 | * so as to maintain backwards compatibility with |
650 | * older versions of bzip2. | 725 | * older versions of bzip2. |
651 | */ | 726 | */ |
652 | bsW(s, 1, 0); | 727 | bsW1_0(s); |
653 | 728 | ||
654 | bsW(s, 24, s->origPtr); | 729 | bsW(s, 24, origPtr); |
655 | generateMTFValues(s); | 730 | generateMTFValues(s); |
656 | sendMTFValues(s); | 731 | sendMTFValues(s); |
657 | } | 732 | } |
diff --git a/archival/libarchive/bz/huffman.c b/archival/libarchive/bz/huffman.c index bbec11adb..dc851cd3f 100644 --- a/archival/libarchive/bz/huffman.c +++ b/archival/libarchive/bz/huffman.c | |||
@@ -48,7 +48,7 @@ in the file LICENSE. | |||
48 | 48 | ||
49 | 49 | ||
50 | /* 90 bytes, 0.3% of overall compress speed */ | 50 | /* 90 bytes, 0.3% of overall compress speed */ |
51 | #if CONFIG_BZIP2_FAST >= 1 | 51 | #if BZIP2_SPEED >= 1 |
52 | 52 | ||
53 | /* macro works better than inline (gcc 4.2.1) */ | 53 | /* macro works better than inline (gcc 4.2.1) */ |
54 | #define DOWNHEAP1(heap, weight, Heap) \ | 54 | #define DOWNHEAP1(heap, weight, Heap) \ |
@@ -217,7 +217,7 @@ void BZ2_hbAssignCodes(int32_t *code, | |||
217 | if (length[i] == n) { | 217 | if (length[i] == n) { |
218 | code[i] = vec; | 218 | code[i] = vec; |
219 | vec++; | 219 | vec++; |
220 | }; | 220 | } |
221 | } | 221 | } |
222 | vec <<= 1; | 222 | vec <<= 1; |
223 | } | 223 | } |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 14a901792..7483a2cea 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -280,8 +280,8 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current | |||
280 | /* Given a list of code lengths and a maximum table size, make a set of | 280 | /* Given a list of code lengths and a maximum table size, make a set of |
281 | * tables to decode that set of codes. Return zero on success, one if | 281 | * tables to decode that set of codes. Return zero on success, one if |
282 | * the given code set is incomplete (the tables are still built in this | 282 | * the given code set is incomplete (the tables are still built in this |
283 | * case), two if the input is invalid (all zero length codes or an | 283 | * case), two if the input is invalid (an oversubscribed set of lengths) |
284 | * oversubscribed set of lengths) - in this case stores NULL in *t. | 284 | * - in this case stores NULL in *t. |
285 | * | 285 | * |
286 | * b: code lengths in bits (all assumed <= BMAX) | 286 | * b: code lengths in bits (all assumed <= BMAX) |
287 | * n: number of codes (assumed <= N_MAX) | 287 | * n: number of codes (assumed <= N_MAX) |
@@ -330,8 +330,15 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
330 | p++; /* can't combine with above line (Solaris bug) */ | 330 | p++; /* can't combine with above line (Solaris bug) */ |
331 | } while (--i); | 331 | } while (--i); |
332 | if (c[0] == n) { /* null input - all zero length codes */ | 332 | if (c[0] == n) { /* null input - all zero length codes */ |
333 | *m = 0; | 333 | q = xzalloc(3 * sizeof(*q)); |
334 | return 2; | 334 | //q[0].v.t = NULL; |
335 | q[1].e = 99; /* invalid code marker */ | ||
336 | q[1].b = 1; | ||
337 | q[2].e = 99; /* invalid code marker */ | ||
338 | q[2].b = 1; | ||
339 | *t = q + 1; | ||
340 | *m = 1; | ||
341 | return 0; | ||
335 | } | 342 | } |
336 | 343 | ||
337 | /* Find minimum and maximum length, bound *m by those */ | 344 | /* Find minimum and maximum length, bound *m by those */ |
@@ -1000,7 +1007,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) | |||
1000 | gunzip_bb = 0; | 1007 | gunzip_bb = 0; |
1001 | 1008 | ||
1002 | /* Create the crc table */ | 1009 | /* Create the crc table */ |
1003 | gunzip_crc_table = crc32_filltable(NULL, 0); | 1010 | gunzip_crc_table = crc32_new_table_le(); |
1004 | gunzip_crc = ~0; | 1011 | gunzip_crc = ~0; |
1005 | 1012 | ||
1006 | error_msg = "corrupted data"; | 1013 | error_msg = "corrupted data"; |
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 0be85500c..8ae7a275b 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c | |||
@@ -52,7 +52,7 @@ unpack_xz_stream(transformer_state_t *xstate) | |||
52 | IF_DESKTOP(long long) int total = 0; | 52 | IF_DESKTOP(long long) int total = 0; |
53 | 53 | ||
54 | if (!global_crc32_table) | 54 | if (!global_crc32_table) |
55 | global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | 55 | global_crc32_new_table_le(); |
56 | 56 | ||
57 | memset(&iobuf, 0, sizeof(iobuf)); | 57 | memset(&iobuf, 0, sizeof(iobuf)); |
58 | membuf = xmalloc(2 * BUFSIZ); | 58 | membuf = xmalloc(2 * BUFSIZ); |
diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c index 1809ec396..93e071c9f 100644 --- a/archival/libarchive/get_header_ar.c +++ b/archival/libarchive/get_header_ar.c | |||
@@ -83,7 +83,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
83 | */ | 83 | */ |
84 | ar_long_name_size = size; | 84 | ar_long_name_size = size; |
85 | free(ar_long_names); | 85 | free(ar_long_names); |
86 | ar_long_names = xmalloc(size); | 86 | ar_long_names = xzalloc(size + 1); |
87 | xread(archive_handle->src_fd, ar_long_names, size); | 87 | xread(archive_handle->src_fd, ar_long_names, size); |
88 | archive_handle->offset += size; | 88 | archive_handle->offset += size; |
89 | /* Return next header */ | 89 | /* Return next header */ |
@@ -107,7 +107,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
107 | unsigned long_offset; | 107 | unsigned long_offset; |
108 | 108 | ||
109 | /* The number after the '/' indicates the offset in the ar data section | 109 | /* The number after the '/' indicates the offset in the ar data section |
110 | * (saved in ar_long_names) that conatains the real filename */ | 110 | * (saved in ar_long_names) that contains the real filename */ |
111 | long_offset = read_num(&ar.formatted.name[1], 10, | 111 | long_offset = read_num(&ar.formatted.name[1], 10, |
112 | sizeof(ar.formatted.name) - 1); | 112 | sizeof(ar.formatted.name) - 1); |
113 | if (long_offset >= ar_long_name_size) { | 113 | if (long_offset >= ar_long_name_size) { |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index aeb54190f..5c495e14e 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -152,6 +152,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
152 | file_header_t *file_header = archive_handle->file_header; | 152 | file_header_t *file_header = archive_handle->file_header; |
153 | struct tar_header_t tar; | 153 | struct tar_header_t tar; |
154 | char *cp; | 154 | char *cp; |
155 | int tar_typeflag; /* can be "char", "int" seems give smaller code */ | ||
155 | int i, sum_u, sum; | 156 | int i, sum_u, sum; |
156 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | 157 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY |
157 | int sum_s; | 158 | int sum_s; |
@@ -253,10 +254,10 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
253 | * POSIX says that checksum is done on unsigned bytes, but | 254 | * POSIX says that checksum is done on unsigned bytes, but |
254 | * Sun and HP-UX gets it wrong... more details in | 255 | * Sun and HP-UX gets it wrong... more details in |
255 | * GNU tar source. */ | 256 | * GNU tar source. */ |
257 | sum_u = ' ' * sizeof(tar.chksum); | ||
256 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | 258 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY |
257 | sum_s = ' ' * sizeof(tar.chksum); | 259 | sum_s = sum_u; |
258 | #endif | 260 | #endif |
259 | sum_u = ' ' * sizeof(tar.chksum); | ||
260 | for (i = 0; i < 148; i++) { | 261 | for (i = 0; i < 148; i++) { |
261 | sum_u += ((unsigned char*)&tar)[i]; | 262 | sum_u += ((unsigned char*)&tar)[i]; |
262 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | 263 | #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY |
@@ -269,27 +270,22 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
269 | sum_s += ((signed char*)&tar)[i]; | 270 | sum_s += ((signed char*)&tar)[i]; |
270 | #endif | 271 | #endif |
271 | } | 272 | } |
272 | /* This field does not need special treatment (getOctal) */ | 273 | /* Most tarfiles have tar.chksum NUL or space terminated, but |
273 | { | 274 | * github.com decided to be "special" and have unterminated field: |
274 | char *endp; /* gcc likes temp var for &endp */ | 275 | * 0090: 30343300 30303031 33323731 30000000 |043.000132710...| |
275 | sum = strtoul(tar.chksum, &endp, 8); | 276 | * ^^^^^^^^| |
276 | if ((*endp != '\0' && *endp != ' ') | 277 | * Need to use GET_OCTAL. This overwrites tar.typeflag ---+ |
277 | || (sum_u != sum IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) | 278 | * (the '0' char immediately after chksum in example above) with NUL. |
278 | ) { | 279 | */ |
279 | bb_error_msg_and_die("invalid tar header checksum"); | 280 | tar_typeflag = (uint8_t)tar.typeflag; /* save it */ |
280 | } | 281 | sum = GET_OCTAL(tar.chksum); |
281 | } | 282 | if (sum_u != sum |
282 | /* don't use xstrtoul, tar.chksum may have leading spaces */ | 283 | IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum) |
283 | sum = strtoul(tar.chksum, NULL, 8); | 284 | ) { |
284 | if (sum_u != sum IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) { | ||
285 | bb_error_msg_and_die("invalid tar header checksum"); | 285 | bb_error_msg_and_die("invalid tar header checksum"); |
286 | } | 286 | } |
287 | 287 | ||
288 | /* 0 is reserved for high perf file, treat as normal file */ | 288 | /* GET_OCTAL trashes subsequent field, therefore we call it |
289 | if (!tar.typeflag) tar.typeflag = '0'; | ||
290 | parse_names = (tar.typeflag >= '0' && tar.typeflag <= '7'); | ||
291 | |||
292 | /* getOctal trashes subsequent field, therefore we call it | ||
293 | * on fields in reverse order */ | 289 | * on fields in reverse order */ |
294 | if (tar.devmajor[0]) { | 290 | if (tar.devmajor[0]) { |
295 | char t = tar.prefix[0]; | 291 | char t = tar.prefix[0]; |
@@ -299,6 +295,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
299 | file_header->device = makedev(major, minor); | 295 | file_header->device = makedev(major, minor); |
300 | tar.prefix[0] = t; | 296 | tar.prefix[0] = t; |
301 | } | 297 | } |
298 | |||
299 | /* 0 is reserved for high perf file, treat as normal file */ | ||
300 | if (tar_typeflag == '\0') tar_typeflag = '0'; | ||
301 | parse_names = (tar_typeflag >= '0' && tar_typeflag <= '7'); | ||
302 | |||
302 | file_header->link_target = NULL; | 303 | file_header->link_target = NULL; |
303 | if (!p_linkname && parse_names && tar.linkname[0]) { | 304 | if (!p_linkname && parse_names && tar.linkname[0]) { |
304 | file_header->link_target = xstrndup(tar.linkname, sizeof(tar.linkname)); | 305 | file_header->link_target = xstrndup(tar.linkname, sizeof(tar.linkname)); |
@@ -332,7 +333,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
332 | 333 | ||
333 | /* Set bits 12-15 of the files mode */ | 334 | /* Set bits 12-15 of the files mode */ |
334 | /* (typeflag was not trashed because chksum does not use getOctal) */ | 335 | /* (typeflag was not trashed because chksum does not use getOctal) */ |
335 | switch (tar.typeflag) { | 336 | switch (tar_typeflag) { |
336 | case '1': /* hardlink */ | 337 | case '1': /* hardlink */ |
337 | /* we mark hardlinks as regular files with zero size and a link name */ | 338 | /* we mark hardlinks as regular files with zero size and a link name */ |
338 | file_header->mode |= S_IFREG; | 339 | file_header->mode |= S_IFREG; |
@@ -381,7 +382,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
381 | case 'x': { /* pax extended header */ | 382 | case 'x': { /* pax extended header */ |
382 | if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ | 383 | if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ |
383 | goto skip_ext_hdr; | 384 | goto skip_ext_hdr; |
384 | process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g')); | 385 | process_pax_hdr(archive_handle, file_header->size, (tar_typeflag == 'g')); |
385 | goto again_after_align; | 386 | goto again_after_align; |
386 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 387 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
387 | /* See http://www.gnu.org/software/tar/manual/html_node/Extensions.html */ | 388 | /* See http://www.gnu.org/software/tar/manual/html_node/Extensions.html */ |
@@ -419,7 +420,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
419 | skip_ext_hdr: | 420 | skip_ext_hdr: |
420 | { | 421 | { |
421 | off_t sz; | 422 | off_t sz; |
422 | bb_error_msg("warning: skipping header '%c'", tar.typeflag); | 423 | bb_error_msg("warning: skipping header '%c'", tar_typeflag); |
423 | sz = (file_header->size + 511) & ~(off_t)511; | 424 | sz = (file_header->size + 511) & ~(off_t)511; |
424 | archive_handle->offset += sz; | 425 | archive_handle->offset += sz; |
425 | sz >>= 9; /* sz /= 512 but w/o contortions for signed div */ | 426 | sz >>= 9; /* sz /= 512 but w/o contortions for signed div */ |
@@ -429,7 +430,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
429 | goto again_after_align; | 430 | goto again_after_align; |
430 | } | 431 | } |
431 | default: | 432 | default: |
432 | bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag); | 433 | bb_error_msg_and_die("unknown typeflag: 0x%x", tar_typeflag); |
433 | } | 434 | } |
434 | 435 | ||
435 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 436 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
diff --git a/archival/libarchive/lzo1x_d.c b/archival/libarchive/lzo1x_d.c index 40b167e68..43cf4a04e 100644 --- a/archival/libarchive/lzo1x_d.c +++ b/archival/libarchive/lzo1x_d.c | |||
@@ -31,8 +31,7 @@ | |||
31 | ************************************************************************/ | 31 | ************************************************************************/ |
32 | /* safe decompression with overrun testing */ | 32 | /* safe decompression with overrun testing */ |
33 | int lzo1x_decompress_safe(const uint8_t* in, unsigned in_len, | 33 | int lzo1x_decompress_safe(const uint8_t* in, unsigned in_len, |
34 | uint8_t* out, unsigned* out_len, | 34 | uint8_t* out, unsigned* out_len /*, void* wrkmem */) |
35 | void* wrkmem UNUSED_PARAM) | ||
36 | { | 35 | { |
37 | register uint8_t* op; | 36 | register uint8_t* op; |
38 | register const uint8_t* ip; | 37 | register const uint8_t* ip; |
diff --git a/archival/lzop.c b/archival/lzop.c index 92411c23f..fef8cdba3 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -80,7 +80,7 @@ | |||
80 | //usage: "\n -F Don't verify checksum" | 80 | //usage: "\n -F Don't verify checksum" |
81 | //usage: | 81 | //usage: |
82 | //usage:#define unlzop_trivial_usage | 82 | //usage:#define unlzop_trivial_usage |
83 | //usage: "[-cfkvF] [FILE]..." | 83 | //usage: "[-cfUvF] [FILE]..." |
84 | //usage:#define unlzop_full_usage "\n\n" | 84 | //usage:#define unlzop_full_usage "\n\n" |
85 | //usage: " -c Write to stdout" | 85 | //usage: " -c Write to stdout" |
86 | //usage: "\n -f Force" | 86 | //usage: "\n -f Force" |
@@ -141,8 +141,7 @@ static void copy3(uint8_t* ip, const uint8_t* m_pos, unsigned off) | |||
141 | #define TEST_OP (op <= op_end) | 141 | #define TEST_OP (op <= op_end) |
142 | 142 | ||
143 | static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | 143 | static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, |
144 | uint8_t *out, unsigned *out_len, | 144 | uint8_t *out, unsigned *out_len /*, void* wrkmem */) |
145 | void* wrkmem UNUSED_PARAM) | ||
146 | { | 145 | { |
147 | uint8_t* op; | 146 | uint8_t* op; |
148 | uint8_t* ip; | 147 | uint8_t* ip; |
@@ -724,7 +723,7 @@ static NOINLINE int lzo_compress(const header_t *h) | |||
724 | /* optimize */ | 723 | /* optimize */ |
725 | if (h->method == M_LZO1X_999) { | 724 | if (h->method == M_LZO1X_999) { |
726 | unsigned new_len = src_len; | 725 | unsigned new_len = src_len; |
727 | r = lzo1x_optimize(b2, dst_len, b1, &new_len, NULL); | 726 | r = lzo1x_optimize(b2, dst_len, b1, &new_len /*, NULL*/); |
728 | if (r != 0 /*LZO_E_OK*/ || new_len != src_len) | 727 | if (r != 0 /*LZO_E_OK*/ || new_len != src_len) |
729 | bb_error_msg_and_die("internal error - optimization failed"); | 728 | bb_error_msg_and_die("internal error - optimization failed"); |
730 | } | 729 | } |
@@ -859,9 +858,9 @@ static NOINLINE int lzo_decompress(const header_t *h) | |||
859 | 858 | ||
860 | /* decompress */ | 859 | /* decompress */ |
861 | // if (option_mask32 & OPT_F) | 860 | // if (option_mask32 & OPT_F) |
862 | // r = lzo1x_decompress(b1, src_len, b2, &d, NULL); | 861 | // r = lzo1x_decompress(b1, src_len, b2, &d /*, NULL*/); |
863 | // else | 862 | // else |
864 | r = lzo1x_decompress_safe(b1, src_len, b2, &d, NULL); | 863 | r = lzo1x_decompress_safe(b1, src_len, b2, &d /*, NULL*/); |
865 | 864 | ||
866 | if (r != 0 /*LZO_E_OK*/ || dst_len != d) { | 865 | if (r != 0 /*LZO_E_OK*/ || dst_len != d) { |
867 | bb_error_msg_and_die("corrupted data"); | 866 | bb_error_msg_and_die("corrupted data"); |
@@ -1149,6 +1148,6 @@ int lzop_main(int argc UNUSED_PARAM, char **argv) | |||
1149 | if (ENABLE_UNLZOP && applet_name[4] == 'o') | 1148 | if (ENABLE_UNLZOP && applet_name[4] == 'o') |
1150 | option_mask32 |= OPT_DECOMPRESS; | 1149 | option_mask32 |= OPT_DECOMPRESS; |
1151 | 1150 | ||
1152 | global_crc32_table = crc32_filltable(NULL, 0); | 1151 | global_crc32_new_table_le(); |
1153 | return bbunpack(argv, pack_lzop, make_new_name_lzop, /*unused:*/ NULL); | 1152 | return bbunpack(argv, pack_lzop, make_new_name_lzop, /*unused:*/ NULL); |
1154 | } | 1153 | } |
diff --git a/archival/unzip.c b/archival/unzip.c index c5fb6a3ed..fb58b62c0 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -339,7 +339,9 @@ static void unzip_create_leading_dirs(const char *fn) | |||
339 | { | 339 | { |
340 | /* Create all leading directories */ | 340 | /* Create all leading directories */ |
341 | char *name = xstrdup(fn); | 341 | char *name = xstrdup(fn); |
342 | if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { | 342 | |
343 | /* mode of -1: set mode according to umask */ | ||
344 | if (bb_make_directory(dirname(name), -1, FILEUTILS_RECUR)) { | ||
343 | xfunc_die(); /* bb_make_directory is noisy */ | 345 | xfunc_die(); /* bb_make_directory is noisy */ |
344 | } | 346 | } |
345 | free(name); | 347 | free(name); |