Annotation of /tags/mkinitrd-6_3_1/busybox/archival/bzip2.c
Parent Directory | Revision Log
Revision 1123 -
(hide annotations)
(download)
Wed Aug 18 21:56:57 2010 UTC (14 years, 1 month ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/archival/bzip2.c
File MIME type: text/plain
File size: 4686 byte(s)
Wed Aug 18 21:56:57 2010 UTC (14 years, 1 month ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/archival/bzip2.c
File MIME type: text/plain
File size: 4686 byte(s)
-updated to busybox-1.17.1
1 | niro | 816 | /* |
2 | * Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * This file uses bzip2 library code which is written | ||
5 | * by Julian Seward <jseward@bzip.org>. | ||
6 | * See README and LICENSE files in bz/ directory for more information | ||
7 | * about bzip2 library code. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | #include "unarchive.h" | ||
12 | |||
13 | #define CONFIG_BZIP2_FEATURE_SPEED 1 | ||
14 | |||
15 | /* Speed test: | ||
16 | * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). | ||
17 | * Stock bzip2 is 26.4% slower than bbox bzip2 at SPEED 1 | ||
18 | * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). | ||
19 | * At SPEED 5 difference is 32.7%. | ||
20 | * | ||
21 | * Test run of all CONFIG_BZIP2_FEATURE_SPEED values on a 11Mb text file: | ||
22 | * Size Time (3 runs) | ||
23 | * 0: 10828 4.145 4.146 4.148 | ||
24 | * 1: 11097 3.845 3.860 3.861 | ||
25 | * 2: 11392 3.763 3.767 3.768 | ||
26 | * 3: 11892 3.722 3.724 3.727 | ||
27 | * 4: 12740 3.637 3.640 3.644 | ||
28 | * 5: 17273 3.497 3.509 3.509 | ||
29 | */ | ||
30 | |||
31 | |||
32 | #define BZ_DEBUG 0 | ||
33 | /* Takes ~300 bytes, detects corruption caused by bad RAM etc */ | ||
34 | #define BZ_LIGHT_DEBUG 0 | ||
35 | |||
36 | #include "bz/bzlib.h" | ||
37 | |||
38 | #include "bz/bzlib_private.h" | ||
39 | |||
40 | #include "bz/blocksort.c" | ||
41 | #include "bz/bzlib.c" | ||
42 | #include "bz/compress.c" | ||
43 | #include "bz/huffman.c" | ||
44 | |||
45 | /* No point in being shy and having very small buffer here. | ||
46 | * bzip2 internal buffers are much bigger anyway, hundreds of kbytes. | ||
47 | * If iobuf is several pages long, malloc() may use mmap, | ||
48 | * making iobuf is page aligned and thus (maybe) have one memcpy less | ||
49 | * if kernel is clever enough. | ||
50 | */ | ||
51 | enum { | ||
52 | IOBUF_SIZE = 8 * 1024 | ||
53 | }; | ||
54 | |||
55 | static uint8_t level; | ||
56 | |||
57 | /* NB: compressStream() has to return -1 on errors, not die. | ||
58 | * bbunpack() will correctly clean up in this case | ||
59 | * (delete incomplete .bz2 file) | ||
60 | */ | ||
61 | |||
62 | /* Returns: | ||
63 | * -1 on errors | ||
64 | * total written bytes so far otherwise | ||
65 | */ | ||
66 | static | ||
67 | niro | 984 | IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, void *wbuf) |
68 | niro | 816 | { |
69 | int n, n2, ret; | ||
70 | |||
71 | strm->avail_in = rlen; | ||
72 | strm->next_in = rbuf; | ||
73 | while (1) { | ||
74 | strm->avail_out = IOBUF_SIZE; | ||
75 | strm->next_out = wbuf; | ||
76 | |||
77 | ret = BZ2_bzCompress(strm, rlen ? BZ_RUN : BZ_FINISH); | ||
78 | if (ret != BZ_RUN_OK /* BZ_RUNning */ | ||
79 | && ret != BZ_FINISH_OK /* BZ_FINISHing, but not done yet */ | ||
80 | && ret != BZ_STREAM_END /* BZ_FINISHed */ | ||
81 | ) { | ||
82 | bb_error_msg_and_die("internal error %d", ret); | ||
83 | } | ||
84 | |||
85 | n = IOBUF_SIZE - strm->avail_out; | ||
86 | if (n) { | ||
87 | n2 = full_write(STDOUT_FILENO, wbuf, n); | ||
88 | if (n2 != n) { | ||
89 | if (n2 >= 0) | ||
90 | errno = 0; /* prevent bogus error message */ | ||
91 | niro | 1123 | bb_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error); |
92 | niro | 816 | return -1; |
93 | } | ||
94 | } | ||
95 | |||
96 | if (ret == BZ_STREAM_END) | ||
97 | break; | ||
98 | if (rlen && strm->avail_in == 0) | ||
99 | break; | ||
100 | } | ||
101 | niro | 984 | return 0 IF_DESKTOP( + strm->total_out ); |
102 | niro | 816 | } |
103 | |||
104 | static | ||
105 | niro | 1123 | IF_DESKTOP(long long) int FAST_FUNC compressStream(unpack_info_t *info UNUSED_PARAM) |
106 | niro | 816 | { |
107 | niro | 984 | IF_DESKTOP(long long) int total; |
108 | niro | 816 | ssize_t count; |
109 | bz_stream bzs; /* it's small */ | ||
110 | #define strm (&bzs) | ||
111 | char *iobuf; | ||
112 | #define rbuf iobuf | ||
113 | #define wbuf (iobuf + IOBUF_SIZE) | ||
114 | |||
115 | iobuf = xmalloc(2 * IOBUF_SIZE); | ||
116 | BZ2_bzCompressInit(strm, level); | ||
117 | |||
118 | while (1) { | ||
119 | count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE); | ||
120 | if (count < 0) { | ||
121 | niro | 1123 | bb_perror_msg(bb_msg_read_error); |
122 | niro | 816 | total = -1; |
123 | break; | ||
124 | } | ||
125 | /* if count == 0, bz_write finalizes compression */ | ||
126 | total = bz_write(strm, rbuf, count, wbuf); | ||
127 | if (count == 0 || total < 0) | ||
128 | break; | ||
129 | } | ||
130 | |||
131 | #if ENABLE_FEATURE_CLEAN_UP | ||
132 | BZ2_bzCompressEnd(strm); | ||
133 | free(iobuf); | ||
134 | #endif | ||
135 | return total; | ||
136 | } | ||
137 | |||
138 | int bzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
139 | int bzip2_main(int argc UNUSED_PARAM, char **argv) | ||
140 | { | ||
141 | unsigned opt; | ||
142 | |||
143 | /* standard bzip2 flags | ||
144 | * -d --decompress force decompression | ||
145 | * -z --compress force compression | ||
146 | * -k --keep keep (don't delete) input files | ||
147 | * -f --force overwrite existing output files | ||
148 | * -t --test test compressed file integrity | ||
149 | * -c --stdout output to standard out | ||
150 | * -q --quiet suppress noncritical error messages | ||
151 | * -v --verbose be verbose (a 2nd -v gives more) | ||
152 | * -s --small use less memory (at most 2500k) | ||
153 | * -1 .. -9 set block size to 100k .. 900k | ||
154 | * --fast alias for -1 | ||
155 | * --best alias for -9 | ||
156 | */ | ||
157 | |||
158 | opt_complementary = "s2"; /* -s means -2 (compatibility) */ | ||
159 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | ||
160 | niro | 984 | opt = getopt32(argv, "cfv" IF_BUNZIP2("dt") "123456789qzs"); |
161 | niro | 816 | #if ENABLE_BUNZIP2 /* bunzip2_main may not be visible... */ |
162 | if (opt & 0x18) // -d and/or -t | ||
163 | return bunzip2_main(argc, argv); | ||
164 | opt >>= 5; | ||
165 | #else | ||
166 | opt >>= 3; | ||
167 | #endif | ||
168 | opt = (uint8_t)opt; /* isolate bits for -1..-8 */ | ||
169 | opt |= 0x100; /* if nothing else, assume -9 */ | ||
170 | level = 1; | ||
171 | while (!(opt & 1)) { | ||
172 | level++; | ||
173 | opt >>= 1; | ||
174 | } | ||
175 | |||
176 | argv += optind; | ||
177 | option_mask32 &= 0x7; /* ignore all except -cfv */ | ||
178 | niro | 1123 | return bbunpack(argv, compressStream, append_ext, "bz2"); |
179 | niro | 816 | } |