diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-13 03:36:03 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-13 03:36:03 +0000 |
commit | 77f1ec1b9bf100e6c10aa0856c7156e321511785 (patch) | |
tree | f20e5a9062ecad82a43bde81e3041a19c4292733 | |
parent | 11c23d7b990eae27357e5a41a97d62b9a214f7db (diff) | |
download | busybox-w32-77f1ec1b9bf100e6c10aa0856c7156e321511785.tar.gz busybox-w32-77f1ec1b9bf100e6c10aa0856c7156e321511785.tar.bz2 busybox-w32-77f1ec1b9bf100e6c10aa0856c7156e321511785.zip |
bzip2: port bzip2 1.0.4 to busybox. note: bzip2 code resides
in separate directory (archival/bz/*)
and is covered by BSD-style license.
code size: 13k
-rw-r--r-- | archival/Config.in | 16 | ||||
-rw-r--r-- | archival/Kbuild | 1 | ||||
-rw-r--r-- | archival/bz/LICENSE | 44 | ||||
-rw-r--r-- | archival/bz/README | 90 | ||||
-rw-r--r-- | archival/bz/blocksort.c | 1128 | ||||
-rw-r--r-- | archival/bz/bzlib.c | 433 | ||||
-rw-r--r-- | archival/bz/bzlib.h | 63 | ||||
-rw-r--r-- | archival/bz/bzlib_private.h | 234 | ||||
-rw-r--r-- | archival/bz/compress.c | 671 | ||||
-rw-r--r-- | archival/bz/crctable.c | 105 | ||||
-rw-r--r-- | archival/bz/huffman.c | 188 | ||||
-rw-r--r-- | archival/bz/randtable.c | 85 | ||||
-rw-r--r-- | archival/bzip2.c | 166 | ||||
-rw-r--r-- | archival/gzip.c | 11 | ||||
-rw-r--r-- | archival/libunarchive/Kbuild | 14 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 2 | ||||
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | include/platform.h | 6 | ||||
-rw-r--r-- | include/usage.h | 14 |
20 files changed, 3253 insertions, 22 deletions
diff --git a/archival/Config.in b/archival/Config.in index 49070da06..8d31ec771 100644 --- a/archival/Config.in +++ b/archival/Config.in | |||
@@ -48,12 +48,22 @@ config BUNZIP2 | |||
48 | conventional LZ77/LZ78-based compressors, and approaches the | 48 | conventional LZ77/LZ78-based compressors, and approaches the |
49 | performance of the PPM family of statistical compressors. | 49 | performance of the PPM family of statistical compressors. |
50 | 50 | ||
51 | The BusyBox bunzip2 applet is limited to de-compression only. | ||
52 | On an x86 system, this applet adds about 11K. | ||
53 | |||
54 | Unless you have a specific application which requires bunzip2, you | 51 | Unless you have a specific application which requires bunzip2, you |
55 | should probably say N here. | 52 | should probably say N here. |
56 | 53 | ||
54 | config BZIP2 | ||
55 | bool "bzip2" | ||
56 | default n | ||
57 | help | ||
58 | bzip2 is a compression utility using the Burrows-Wheeler block | ||
59 | sorting text compression algorithm, and Huffman coding. Compression | ||
60 | is generally considerably better than that achieved by more | ||
61 | conventional LZ77/LZ78-based compressors, and approaches the | ||
62 | performance of the PPM family of statistical compressors. | ||
63 | |||
64 | Unless you have a specific application which requires bzip2, you | ||
65 | should probably say N here. | ||
66 | |||
57 | config CPIO | 67 | config CPIO |
58 | bool "cpio" | 68 | bool "cpio" |
59 | default n | 69 | default n |
diff --git a/archival/Kbuild b/archival/Kbuild index 07b442f15..72dbdda0e 100644 --- a/archival/Kbuild +++ b/archival/Kbuild | |||
@@ -9,6 +9,7 @@ libs-y += libunarchive/ | |||
9 | lib-y:= | 9 | lib-y:= |
10 | lib-$(CONFIG_AR) += ar.o | 10 | lib-$(CONFIG_AR) += ar.o |
11 | lib-$(CONFIG_BUNZIP2) += bbunzip.o | 11 | lib-$(CONFIG_BUNZIP2) += bbunzip.o |
12 | lib-$(CONFIG_BZIP2) += bzip2.o bbunzip.o | ||
12 | lib-$(CONFIG_UNLZMA) += bbunzip.o | 13 | lib-$(CONFIG_UNLZMA) += bbunzip.o |
13 | lib-$(CONFIG_CPIO) += cpio.o | 14 | lib-$(CONFIG_CPIO) += cpio.o |
14 | lib-$(CONFIG_DPKG) += dpkg.o | 15 | lib-$(CONFIG_DPKG) += dpkg.o |
diff --git a/archival/bz/LICENSE b/archival/bz/LICENSE new file mode 100644 index 000000000..f01f08022 --- /dev/null +++ b/archival/bz/LICENSE | |||
@@ -0,0 +1,44 @@ | |||
1 | bzip2 applet in busybox is based on lightly-modified source | ||
2 | of bzip2 version 1.0.4. bzip2 source is distributed | ||
3 | under the following conditions (copied verbatim from LICENSE file) | ||
4 | =========================================================== | ||
5 | |||
6 | |||
7 | This program, "bzip2", the associated library "libbzip2", and all | ||
8 | documentation, are copyright (C) 1996-2006 Julian R Seward. All | ||
9 | rights reserved. | ||
10 | |||
11 | Redistribution and use in source and binary forms, with or without | ||
12 | modification, are permitted provided that the following conditions | ||
13 | are met: | ||
14 | |||
15 | 1. Redistributions of source code must retain the above copyright | ||
16 | notice, this list of conditions and the following disclaimer. | ||
17 | |||
18 | 2. The origin of this software must not be misrepresented; you must | ||
19 | not claim that you wrote the original software. If you use this | ||
20 | software in a product, an acknowledgment in the product | ||
21 | documentation would be appreciated but is not required. | ||
22 | |||
23 | 3. Altered source versions must be plainly marked as such, and must | ||
24 | not be misrepresented as being the original software. | ||
25 | |||
26 | 4. The name of the author may not be used to endorse or promote | ||
27 | products derived from this software without specific prior written | ||
28 | permission. | ||
29 | |||
30 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | ||
31 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
32 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
33 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
34 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
35 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | ||
36 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
37 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
38 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
39 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
40 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
41 | |||
42 | Julian Seward, Cambridge, UK. | ||
43 | jseward@bzip.org | ||
44 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
diff --git a/archival/bz/README b/archival/bz/README new file mode 100644 index 000000000..ef06d67da --- /dev/null +++ b/archival/bz/README | |||
@@ -0,0 +1,90 @@ | |||
1 | This file is an abridged version of README from bizp2 1.0.4 | ||
2 | Build instructions (which are not relevant to busyboxed bzip2) | ||
3 | are removed. | ||
4 | =========================================================== | ||
5 | |||
6 | |||
7 | This is the README for bzip2/libzip2. | ||
8 | This version is fully compatible with the previous public releases. | ||
9 | |||
10 | ------------------------------------------------------------------ | ||
11 | This file is part of bzip2/libbzip2, a program and library for | ||
12 | lossless, block-sorting data compression. | ||
13 | |||
14 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
15 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
16 | |||
17 | Please read the WARNING, DISCLAIMER and PATENTS sections in this file. | ||
18 | |||
19 | This program is released under the terms of the license contained | ||
20 | in the file LICENSE. | ||
21 | ------------------------------------------------------------------ | ||
22 | |||
23 | Please read and be aware of the following: | ||
24 | |||
25 | |||
26 | WARNING: | ||
27 | |||
28 | This program and library (attempts to) compress data by | ||
29 | performing several non-trivial transformations on it. | ||
30 | Unless you are 100% familiar with *all* the algorithms | ||
31 | contained herein, and with the consequences of modifying them, | ||
32 | you should NOT meddle with the compression or decompression | ||
33 | machinery. Incorrect changes can and very likely *will* | ||
34 | lead to disastrous loss of data. | ||
35 | |||
36 | |||
37 | DISCLAIMER: | ||
38 | |||
39 | I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE | ||
40 | USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED. | ||
41 | |||
42 | Every compression of a file implies an assumption that the | ||
43 | compressed file can be decompressed to reproduce the original. | ||
44 | Great efforts in design, coding and testing have been made to | ||
45 | ensure that this program works correctly. However, the complexity | ||
46 | of the algorithms, and, in particular, the presence of various | ||
47 | special cases in the code which occur with very low but non-zero | ||
48 | probability make it impossible to rule out the possibility of bugs | ||
49 | remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS | ||
50 | PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER | ||
51 | SMALL, THAT THE DATA WILL NOT BE RECOVERABLE. | ||
52 | |||
53 | That is not to say this program is inherently unreliable. | ||
54 | Indeed, I very much hope the opposite is true. bzip2/libbzip2 | ||
55 | has been carefully constructed and extensively tested. | ||
56 | |||
57 | |||
58 | PATENTS: | ||
59 | |||
60 | To the best of my knowledge, bzip2/libbzip2 does not use any | ||
61 | patented algorithms. However, I do not have the resources | ||
62 | to carry out a patent search. Therefore I cannot give any | ||
63 | guarantee of the above statement. | ||
64 | |||
65 | |||
66 | I hope you find bzip2 useful. Feel free to contact me at | ||
67 | jseward@bzip.org | ||
68 | if you have any suggestions or queries. Many people mailed me with | ||
69 | comments, suggestions and patches after the releases of bzip-0.15, | ||
70 | bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, | ||
71 | 1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this | ||
72 | feedback. I thank you for your comments. | ||
73 | |||
74 | bzip2's "home" is http://www.bzip.org/ | ||
75 | |||
76 | Julian Seward | ||
77 | jseward@bzip.org | ||
78 | Cambridge, UK. | ||
79 | |||
80 | 18 July 1996 (version 0.15) | ||
81 | 25 August 1996 (version 0.21) | ||
82 | 7 August 1997 (bzip2, version 0.1) | ||
83 | 29 August 1997 (bzip2, version 0.1pl2) | ||
84 | 23 August 1998 (bzip2, version 0.9.0) | ||
85 | 8 June 1999 (bzip2, version 0.9.5) | ||
86 | 4 Sept 1999 (bzip2, version 0.9.5d) | ||
87 | 5 May 2000 (bzip2, version 1.0pre8) | ||
88 | 30 December 2001 (bzip2, version 1.0.2pre1) | ||
89 | 15 February 2005 (bzip2, version 1.0.3) | ||
90 | 20 December 2006 (bzip2, version 1.0.4) | ||
diff --git a/archival/bz/blocksort.c b/archival/bz/blocksort.c new file mode 100644 index 000000000..7d2856ba7 --- /dev/null +++ b/archival/bz/blocksort.c | |||
@@ -0,0 +1,1128 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Block sorting machinery ---*/ | ||
9 | /*--- blocksort.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* #include "bzlib_private.h" */ | ||
27 | |||
28 | /*---------------------------------------------*/ | ||
29 | /*--- Fallback O(N log(N)^2) sorting ---*/ | ||
30 | /*--- algorithm, for repetitive blocks ---*/ | ||
31 | /*---------------------------------------------*/ | ||
32 | |||
33 | /*---------------------------------------------*/ | ||
34 | static | ||
35 | inline | ||
36 | void fallbackSimpleSort(uint32_t* fmap, | ||
37 | uint32_t* eclass, | ||
38 | int32_t lo, | ||
39 | int32_t hi) | ||
40 | { | ||
41 | int32_t i, j, tmp; | ||
42 | uint32_t ec_tmp; | ||
43 | |||
44 | if (lo == hi) return; | ||
45 | |||
46 | if (hi - lo > 3) { | ||
47 | for (i = hi-4; i >= lo; i--) { | ||
48 | tmp = fmap[i]; | ||
49 | ec_tmp = eclass[tmp]; | ||
50 | for (j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4) | ||
51 | fmap[j-4] = fmap[j]; | ||
52 | fmap[j-4] = tmp; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | for (i = hi-1; i >= lo; i--) { | ||
57 | tmp = fmap[i]; | ||
58 | ec_tmp = eclass[tmp]; | ||
59 | for (j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++) | ||
60 | fmap[j-1] = fmap[j]; | ||
61 | fmap[j-1] = tmp; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | |||
66 | /*---------------------------------------------*/ | ||
67 | #define fswap(zz1, zz2) \ | ||
68 | { \ | ||
69 | int32_t zztmp = zz1; \ | ||
70 | zz1 = zz2; \ | ||
71 | zz2 = zztmp; \ | ||
72 | } | ||
73 | |||
74 | #define fvswap(zzp1, zzp2, zzn) \ | ||
75 | { \ | ||
76 | int32_t yyp1 = (zzp1); \ | ||
77 | int32_t yyp2 = (zzp2); \ | ||
78 | int32_t yyn = (zzn); \ | ||
79 | while (yyn > 0) { \ | ||
80 | fswap(fmap[yyp1], fmap[yyp2]); \ | ||
81 | yyp1++; \ | ||
82 | yyp2++; \ | ||
83 | yyn--; \ | ||
84 | } \ | ||
85 | } | ||
86 | |||
87 | |||
88 | #define fmin(a,b) ((a) < (b)) ? (a) : (b) | ||
89 | |||
90 | #define fpush(lz,hz) { \ | ||
91 | stackLo[sp] = lz; \ | ||
92 | stackHi[sp] = hz; \ | ||
93 | sp++; \ | ||
94 | } | ||
95 | |||
96 | #define fpop(lz,hz) { \ | ||
97 | sp--; \ | ||
98 | lz = stackLo[sp]; \ | ||
99 | hz = stackHi[sp]; \ | ||
100 | } | ||
101 | |||
102 | #define FALLBACK_QSORT_SMALL_THRESH 10 | ||
103 | #define FALLBACK_QSORT_STACK_SIZE 100 | ||
104 | |||
105 | |||
106 | static | ||
107 | void fallbackQSort3(uint32_t* fmap, | ||
108 | uint32_t* eclass, | ||
109 | int32_t loSt, | ||
110 | int32_t hiSt) | ||
111 | { | ||
112 | int32_t unLo, unHi, ltLo, gtHi, n, m; | ||
113 | int32_t sp, lo, hi; | ||
114 | uint32_t med, r, r3; | ||
115 | int32_t stackLo[FALLBACK_QSORT_STACK_SIZE]; | ||
116 | int32_t stackHi[FALLBACK_QSORT_STACK_SIZE]; | ||
117 | |||
118 | r = 0; | ||
119 | |||
120 | sp = 0; | ||
121 | fpush(loSt, hiSt); | ||
122 | |||
123 | while (sp > 0) { | ||
124 | AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004); | ||
125 | |||
126 | fpop(lo, hi); | ||
127 | if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { | ||
128 | fallbackSimpleSort(fmap, eclass, lo, hi); | ||
129 | continue; | ||
130 | } | ||
131 | |||
132 | /* Random partitioning. Median of 3 sometimes fails to | ||
133 | * avoid bad cases. Median of 9 seems to help but | ||
134 | * looks rather expensive. This too seems to work but | ||
135 | * is cheaper. Guidance for the magic constants | ||
136 | * 7621 and 32768 is taken from Sedgewick's algorithms | ||
137 | * book, chapter 35. | ||
138 | */ | ||
139 | r = ((r * 7621) + 1) % 32768; | ||
140 | r3 = r % 3; | ||
141 | if (r3 == 0) | ||
142 | med = eclass[fmap[lo]]; | ||
143 | else if (r3 == 1) | ||
144 | med = eclass[fmap[(lo+hi)>>1]]; | ||
145 | else | ||
146 | med = eclass[fmap[hi]]; | ||
147 | |||
148 | unLo = ltLo = lo; | ||
149 | unHi = gtHi = hi; | ||
150 | |||
151 | while (1) { | ||
152 | while (1) { | ||
153 | if (unLo > unHi) break; | ||
154 | n = (int32_t)eclass[fmap[unLo]] - (int32_t)med; | ||
155 | if (n == 0) { | ||
156 | fswap(fmap[unLo], fmap[ltLo]); | ||
157 | ltLo++; | ||
158 | unLo++; | ||
159 | continue; | ||
160 | }; | ||
161 | if (n > 0) break; | ||
162 | unLo++; | ||
163 | } | ||
164 | while (1) { | ||
165 | if (unLo > unHi) break; | ||
166 | n = (int32_t)eclass[fmap[unHi]] - (int32_t)med; | ||
167 | if (n == 0) { | ||
168 | fswap(fmap[unHi], fmap[gtHi]); | ||
169 | gtHi--; unHi--; | ||
170 | continue; | ||
171 | }; | ||
172 | if (n < 0) break; | ||
173 | unHi--; | ||
174 | } | ||
175 | if (unLo > unHi) break; | ||
176 | fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; | ||
177 | } | ||
178 | |||
179 | AssertD(unHi == unLo-1, "fallbackQSort3(2)"); | ||
180 | |||
181 | if (gtHi < ltLo) continue; | ||
182 | |||
183 | n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); | ||
184 | m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); | ||
185 | |||
186 | n = lo + unLo - ltLo - 1; | ||
187 | m = hi - (gtHi - unHi) + 1; | ||
188 | |||
189 | if (n - lo > hi - m) { | ||
190 | fpush(lo, n); | ||
191 | fpush(m, hi); | ||
192 | } else { | ||
193 | fpush(m, hi); | ||
194 | fpush(lo, n); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | #undef fmin | ||
200 | #undef fpush | ||
201 | #undef fpop | ||
202 | #undef fswap | ||
203 | #undef fvswap | ||
204 | #undef FALLBACK_QSORT_SMALL_THRESH | ||
205 | #undef FALLBACK_QSORT_STACK_SIZE | ||
206 | |||
207 | |||
208 | /*---------------------------------------------*/ | ||
209 | /* Pre: | ||
210 | * nblock > 0 | ||
211 | * eclass exists for [0 .. nblock-1] | ||
212 | * ((UChar*)eclass) [0 .. nblock-1] holds block | ||
213 | * ptr exists for [0 .. nblock-1] | ||
214 | * | ||
215 | * Post: | ||
216 | * ((UChar*)eclass) [0 .. nblock-1] holds block | ||
217 | * All other areas of eclass destroyed | ||
218 | * fmap [0 .. nblock-1] holds sorted order | ||
219 | * bhtab[0 .. 2+(nblock/32)] destroyed | ||
220 | */ | ||
221 | |||
222 | #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) | ||
223 | #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) | ||
224 | #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) | ||
225 | #define WORD_BH(zz) bhtab[(zz) >> 5] | ||
226 | #define UNALIGNED_BH(zz) ((zz) & 0x01f) | ||
227 | |||
228 | static | ||
229 | void fallbackSort(uint32_t* fmap, | ||
230 | uint32_t* eclass, | ||
231 | uint32_t* bhtab, | ||
232 | int32_t nblock) | ||
233 | { | ||
234 | int32_t ftab[257]; | ||
235 | int32_t ftabCopy[256]; | ||
236 | int32_t H, i, j, k, l, r, cc, cc1; | ||
237 | int32_t nNotDone; | ||
238 | int32_t nBhtab; | ||
239 | UChar* eclass8 = (UChar*)eclass; | ||
240 | |||
241 | /* | ||
242 | * Initial 1-char radix sort to generate | ||
243 | * initial fmap and initial BH bits. | ||
244 | */ | ||
245 | for (i = 0; i < 257; i++) ftab[i] = 0; | ||
246 | for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; | ||
247 | for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; | ||
248 | for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; | ||
249 | |||
250 | for (i = 0; i < nblock; i++) { | ||
251 | j = eclass8[i]; | ||
252 | k = ftab[j] - 1; | ||
253 | ftab[j] = k; | ||
254 | fmap[k] = i; | ||
255 | } | ||
256 | |||
257 | nBhtab = 2 + (nblock / 32); | ||
258 | for (i = 0; i < nBhtab; i++) bhtab[i] = 0; | ||
259 | for (i = 0; i < 256; i++) SET_BH(ftab[i]); | ||
260 | |||
261 | /* | ||
262 | * Inductively refine the buckets. Kind-of an | ||
263 | * "exponential radix sort" (!), inspired by the | ||
264 | * Manber-Myers suffix array construction algorithm. | ||
265 | */ | ||
266 | |||
267 | /*-- set sentinel bits for block-end detection --*/ | ||
268 | for (i = 0; i < 32; i++) { | ||
269 | SET_BH(nblock + 2*i); | ||
270 | CLEAR_BH(nblock + 2*i + 1); | ||
271 | } | ||
272 | |||
273 | /*-- the log(N) loop --*/ | ||
274 | H = 1; | ||
275 | while (1) { | ||
276 | j = 0; | ||
277 | for (i = 0; i < nblock; i++) { | ||
278 | if (ISSET_BH(i)) | ||
279 | j = i; | ||
280 | k = fmap[i] - H; | ||
281 | if (k < 0) | ||
282 | k += nblock; | ||
283 | eclass[k] = j; | ||
284 | } | ||
285 | |||
286 | nNotDone = 0; | ||
287 | r = -1; | ||
288 | while (1) { | ||
289 | |||
290 | /*-- find the next non-singleton bucket --*/ | ||
291 | k = r + 1; | ||
292 | while (ISSET_BH(k) && UNALIGNED_BH(k)) | ||
293 | k++; | ||
294 | if (ISSET_BH(k)) { | ||
295 | while (WORD_BH(k) == 0xffffffff) k += 32; | ||
296 | while (ISSET_BH(k)) k++; | ||
297 | } | ||
298 | l = k - 1; | ||
299 | if (l >= nblock) | ||
300 | break; | ||
301 | while (!ISSET_BH(k) && UNALIGNED_BH(k)) | ||
302 | k++; | ||
303 | if (!ISSET_BH(k)) { | ||
304 | while (WORD_BH(k) == 0x00000000) k += 32; | ||
305 | while (!ISSET_BH(k)) k++; | ||
306 | } | ||
307 | r = k - 1; | ||
308 | if (r >= nblock) | ||
309 | break; | ||
310 | |||
311 | /*-- now [l, r] bracket current bucket --*/ | ||
312 | if (r > l) { | ||
313 | nNotDone += (r - l + 1); | ||
314 | fallbackQSort3(fmap, eclass, l, r); | ||
315 | |||
316 | /*-- scan bucket and generate header bits-- */ | ||
317 | cc = -1; | ||
318 | for (i = l; i <= r; i++) { | ||
319 | cc1 = eclass[fmap[i]]; | ||
320 | if (cc != cc1) { | ||
321 | SET_BH(i); | ||
322 | cc = cc1; | ||
323 | }; | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | |||
328 | H *= 2; | ||
329 | if (H > nblock || nNotDone == 0) | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Reconstruct the original block in | ||
335 | * eclass8 [0 .. nblock-1], since the | ||
336 | * previous phase destroyed it. | ||
337 | */ | ||
338 | j = 0; | ||
339 | for (i = 0; i < nblock; i++) { | ||
340 | while (ftabCopy[j] == 0) | ||
341 | j++; | ||
342 | ftabCopy[j]--; | ||
343 | eclass8[fmap[i]] = (UChar)j; | ||
344 | } | ||
345 | AssertH(j < 256, 1005); | ||
346 | } | ||
347 | |||
348 | #undef SET_BH | ||
349 | #undef CLEAR_BH | ||
350 | #undef ISSET_BH | ||
351 | #undef WORD_BH | ||
352 | #undef UNALIGNED_BH | ||
353 | |||
354 | |||
355 | /*---------------------------------------------*/ | ||
356 | /*--- The main, O(N^2 log(N)) sorting ---*/ | ||
357 | /*--- algorithm. Faster for "normal" ---*/ | ||
358 | /*--- non-repetitive blocks. ---*/ | ||
359 | /*---------------------------------------------*/ | ||
360 | |||
361 | /*---------------------------------------------*/ | ||
362 | static | ||
363 | inline | ||
364 | Bool mainGtU( | ||
365 | uint32_t i1, | ||
366 | uint32_t i2, | ||
367 | UChar* block, | ||
368 | uint16_t* quadrant, | ||
369 | uint32_t nblock, | ||
370 | int32_t* budget) | ||
371 | { | ||
372 | int32_t k; | ||
373 | UChar c1, c2; | ||
374 | uint16_t s1, s2; | ||
375 | |||
376 | ///unrolling | ||
377 | AssertD(i1 != i2, "mainGtU"); | ||
378 | /* 1 */ | ||
379 | c1 = block[i1]; c2 = block[i2]; | ||
380 | if (c1 != c2) return (c1 > c2); | ||
381 | i1++; i2++; | ||
382 | /* 2 */ | ||
383 | c1 = block[i1]; c2 = block[i2]; | ||
384 | if (c1 != c2) return (c1 > c2); | ||
385 | i1++; i2++; | ||
386 | /* 3 */ | ||
387 | c1 = block[i1]; c2 = block[i2]; | ||
388 | if (c1 != c2) return (c1 > c2); | ||
389 | i1++; i2++; | ||
390 | /* 4 */ | ||
391 | c1 = block[i1]; c2 = block[i2]; | ||
392 | if (c1 != c2) return (c1 > c2); | ||
393 | i1++; i2++; | ||
394 | /* 5 */ | ||
395 | c1 = block[i1]; c2 = block[i2]; | ||
396 | if (c1 != c2) return (c1 > c2); | ||
397 | i1++; i2++; | ||
398 | /* 6 */ | ||
399 | c1 = block[i1]; c2 = block[i2]; | ||
400 | if (c1 != c2) return (c1 > c2); | ||
401 | i1++; i2++; | ||
402 | /* 7 */ | ||
403 | c1 = block[i1]; c2 = block[i2]; | ||
404 | if (c1 != c2) return (c1 > c2); | ||
405 | i1++; i2++; | ||
406 | /* 8 */ | ||
407 | c1 = block[i1]; c2 = block[i2]; | ||
408 | if (c1 != c2) return (c1 > c2); | ||
409 | i1++; i2++; | ||
410 | /* 9 */ | ||
411 | c1 = block[i1]; c2 = block[i2]; | ||
412 | if (c1 != c2) return (c1 > c2); | ||
413 | i1++; i2++; | ||
414 | /* 10 */ | ||
415 | c1 = block[i1]; c2 = block[i2]; | ||
416 | if (c1 != c2) return (c1 > c2); | ||
417 | i1++; i2++; | ||
418 | /* 11 */ | ||
419 | c1 = block[i1]; c2 = block[i2]; | ||
420 | if (c1 != c2) return (c1 > c2); | ||
421 | i1++; i2++; | ||
422 | /* 12 */ | ||
423 | c1 = block[i1]; c2 = block[i2]; | ||
424 | if (c1 != c2) return (c1 > c2); | ||
425 | i1++; i2++; | ||
426 | |||
427 | k = nblock + 8; | ||
428 | |||
429 | ///unrolling | ||
430 | do { | ||
431 | /* 1 */ | ||
432 | c1 = block[i1]; c2 = block[i2]; | ||
433 | if (c1 != c2) return (c1 > c2); | ||
434 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
435 | if (s1 != s2) return (s1 > s2); | ||
436 | i1++; i2++; | ||
437 | /* 2 */ | ||
438 | c1 = block[i1]; c2 = block[i2]; | ||
439 | if (c1 != c2) return (c1 > c2); | ||
440 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
441 | if (s1 != s2) return (s1 > s2); | ||
442 | i1++; i2++; | ||
443 | /* 3 */ | ||
444 | c1 = block[i1]; c2 = block[i2]; | ||
445 | if (c1 != c2) return (c1 > c2); | ||
446 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
447 | if (s1 != s2) return (s1 > s2); | ||
448 | i1++; i2++; | ||
449 | /* 4 */ | ||
450 | c1 = block[i1]; c2 = block[i2]; | ||
451 | if (c1 != c2) return (c1 > c2); | ||
452 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
453 | if (s1 != s2) return (s1 > s2); | ||
454 | i1++; i2++; | ||
455 | /* 5 */ | ||
456 | c1 = block[i1]; c2 = block[i2]; | ||
457 | if (c1 != c2) return (c1 > c2); | ||
458 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
459 | if (s1 != s2) return (s1 > s2); | ||
460 | i1++; i2++; | ||
461 | /* 6 */ | ||
462 | c1 = block[i1]; c2 = block[i2]; | ||
463 | if (c1 != c2) return (c1 > c2); | ||
464 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
465 | if (s1 != s2) return (s1 > s2); | ||
466 | i1++; i2++; | ||
467 | /* 7 */ | ||
468 | c1 = block[i1]; c2 = block[i2]; | ||
469 | if (c1 != c2) return (c1 > c2); | ||
470 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
471 | if (s1 != s2) return (s1 > s2); | ||
472 | i1++; i2++; | ||
473 | /* 8 */ | ||
474 | c1 = block[i1]; c2 = block[i2]; | ||
475 | if (c1 != c2) return (c1 > c2); | ||
476 | s1 = quadrant[i1]; s2 = quadrant[i2]; | ||
477 | if (s1 != s2) return (s1 > s2); | ||
478 | i1++; i2++; | ||
479 | |||
480 | if (i1 >= nblock) i1 -= nblock; | ||
481 | if (i2 >= nblock) i2 -= nblock; | ||
482 | |||
483 | k -= 8; | ||
484 | (*budget)--; | ||
485 | } while (k >= 0); | ||
486 | |||
487 | return False; | ||
488 | } | ||
489 | |||
490 | |||
491 | /*---------------------------------------------*/ | ||
492 | /* | ||
493 | * Knuth's increments seem to work better | ||
494 | * than Incerpi-Sedgewick here. Possibly | ||
495 | * because the number of elems to sort is | ||
496 | * usually small, typically <= 20. | ||
497 | */ | ||
498 | static | ||
499 | const int32_t incs[14] = { | ||
500 | 1, 4, 13, 40, 121, 364, 1093, 3280, | ||
501 | 9841, 29524, 88573, 265720, | ||
502 | 797161, 2391484 | ||
503 | }; | ||
504 | |||
505 | static | ||
506 | void mainSimpleSort(uint32_t* ptr, | ||
507 | UChar* block, | ||
508 | uint16_t* quadrant, | ||
509 | int32_t nblock, | ||
510 | int32_t lo, | ||
511 | int32_t hi, | ||
512 | int32_t d, | ||
513 | int32_t* budget) | ||
514 | { | ||
515 | int32_t i, j, h, bigN, hp; | ||
516 | uint32_t v; | ||
517 | |||
518 | bigN = hi - lo + 1; | ||
519 | if (bigN < 2) return; | ||
520 | |||
521 | hp = 0; | ||
522 | while (incs[hp] < bigN) hp++; | ||
523 | hp--; | ||
524 | |||
525 | for (; hp >= 0; hp--) { | ||
526 | h = incs[hp]; | ||
527 | |||
528 | i = lo + h; | ||
529 | while (1) { | ||
530 | |||
531 | ///unrolling | ||
532 | /*-- copy 1 --*/ | ||
533 | if (i > hi) break; | ||
534 | v = ptr[i]; | ||
535 | j = i; | ||
536 | while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | ||
537 | ptr[j] = ptr[j-h]; | ||
538 | j = j - h; | ||
539 | if (j <= (lo + h - 1)) break; | ||
540 | } | ||
541 | ptr[j] = v; | ||
542 | i++; | ||
543 | |||
544 | /*-- copy 2 --*/ | ||
545 | if (i > hi) break; | ||
546 | v = ptr[i]; | ||
547 | j = i; | ||
548 | while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | ||
549 | ptr[j] = ptr[j-h]; | ||
550 | j = j - h; | ||
551 | if (j <= (lo + h - 1)) break; | ||
552 | } | ||
553 | ptr[j] = v; | ||
554 | i++; | ||
555 | |||
556 | /*-- copy 3 --*/ | ||
557 | if (i > hi) break; | ||
558 | v = ptr[i]; | ||
559 | j = i; | ||
560 | while (mainGtU (ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) { | ||
561 | ptr[j] = ptr[j-h]; | ||
562 | j = j - h; | ||
563 | if (j <= (lo + h - 1)) break; | ||
564 | } | ||
565 | ptr[j] = v; | ||
566 | i++; | ||
567 | |||
568 | if (*budget < 0) return; | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | |||
573 | |||
574 | /*---------------------------------------------*/ | ||
575 | /* | ||
576 | * The following is an implementation of | ||
577 | * an elegant 3-way quicksort for strings, | ||
578 | * described in a paper "Fast Algorithms for | ||
579 | * Sorting and Searching Strings", by Robert | ||
580 | * Sedgewick and Jon L. Bentley. | ||
581 | */ | ||
582 | |||
583 | #define mswap(zz1, zz2) \ | ||
584 | { \ | ||
585 | int32_t zztmp = zz1; \ | ||
586 | zz1 = zz2; \ | ||
587 | zz2 = zztmp; \ | ||
588 | } | ||
589 | |||
590 | #define mvswap(zzp1, zzp2, zzn) \ | ||
591 | { \ | ||
592 | int32_t yyp1 = (zzp1); \ | ||
593 | int32_t yyp2 = (zzp2); \ | ||
594 | int32_t yyn = (zzn); \ | ||
595 | while (yyn > 0) { \ | ||
596 | mswap(ptr[yyp1], ptr[yyp2]); \ | ||
597 | yyp1++; \ | ||
598 | yyp2++; \ | ||
599 | yyn--; \ | ||
600 | } \ | ||
601 | } | ||
602 | |||
603 | static | ||
604 | inline | ||
605 | UChar mmed3(UChar a, UChar b, UChar c) | ||
606 | { | ||
607 | UChar t; | ||
608 | if (a > b) { | ||
609 | t = a; | ||
610 | a = b; | ||
611 | b = t; | ||
612 | }; | ||
613 | if (b > c) { | ||
614 | b = c; | ||
615 | if (a > b) | ||
616 | b = a; | ||
617 | } | ||
618 | return b; | ||
619 | } | ||
620 | |||
621 | #define mmin(a,b) ((a) < (b)) ? (a) : (b) | ||
622 | |||
623 | #define mpush(lz,hz,dz) \ | ||
624 | { \ | ||
625 | stackLo[sp] = lz; \ | ||
626 | stackHi[sp] = hz; \ | ||
627 | stackD [sp] = dz; \ | ||
628 | sp++; \ | ||
629 | } | ||
630 | |||
631 | #define mpop(lz,hz,dz) \ | ||
632 | { \ | ||
633 | sp--; \ | ||
634 | lz = stackLo[sp]; \ | ||
635 | hz = stackHi[sp]; \ | ||
636 | dz = stackD [sp]; \ | ||
637 | } | ||
638 | |||
639 | |||
640 | #define mnextsize(az) (nextHi[az]-nextLo[az]) | ||
641 | |||
642 | #define mnextswap(az,bz) \ | ||
643 | { \ | ||
644 | int32_t tz; \ | ||
645 | tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ | ||
646 | tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ | ||
647 | tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; \ | ||
648 | } | ||
649 | |||
650 | #define MAIN_QSORT_SMALL_THRESH 20 | ||
651 | #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) | ||
652 | #define MAIN_QSORT_STACK_SIZE 100 | ||
653 | |||
654 | static | ||
655 | void mainQSort3(uint32_t* ptr, | ||
656 | UChar* block, | ||
657 | uint16_t* quadrant, | ||
658 | int32_t nblock, | ||
659 | int32_t loSt, | ||
660 | int32_t hiSt, | ||
661 | int32_t dSt, | ||
662 | int32_t* budget) | ||
663 | { | ||
664 | int32_t unLo, unHi, ltLo, gtHi, n, m, med; | ||
665 | int32_t sp, lo, hi, d; | ||
666 | |||
667 | int32_t stackLo[MAIN_QSORT_STACK_SIZE]; | ||
668 | int32_t stackHi[MAIN_QSORT_STACK_SIZE]; | ||
669 | int32_t stackD [MAIN_QSORT_STACK_SIZE]; | ||
670 | |||
671 | int32_t nextLo[3]; | ||
672 | int32_t nextHi[3]; | ||
673 | int32_t nextD [3]; | ||
674 | |||
675 | sp = 0; | ||
676 | mpush(loSt, hiSt, dSt); | ||
677 | |||
678 | while (sp > 0) { | ||
679 | AssertH(sp < MAIN_QSORT_STACK_SIZE - 2, 1001); | ||
680 | |||
681 | mpop(lo, hi, d); | ||
682 | if (hi - lo < MAIN_QSORT_SMALL_THRESH | ||
683 | || d > MAIN_QSORT_DEPTH_THRESH | ||
684 | ) { | ||
685 | mainSimpleSort(ptr, block, quadrant, nblock, lo, hi, d, budget); | ||
686 | if (*budget < 0) | ||
687 | return; | ||
688 | continue; | ||
689 | } | ||
690 | |||
691 | med = (int32_t) mmed3(block[ptr[lo ] + d], | ||
692 | block[ptr[hi ] + d], | ||
693 | block[ptr[(lo+hi) >> 1] + d]); | ||
694 | |||
695 | unLo = ltLo = lo; | ||
696 | unHi = gtHi = hi; | ||
697 | |||
698 | while (1) { | ||
699 | while (1) { | ||
700 | if (unLo > unHi) | ||
701 | break; | ||
702 | n = ((int32_t)block[ptr[unLo]+d]) - med; | ||
703 | if (n == 0) { | ||
704 | mswap(ptr[unLo], ptr[ltLo]); | ||
705 | ltLo++; | ||
706 | unLo++; | ||
707 | continue; | ||
708 | }; | ||
709 | if (n > 0) break; | ||
710 | unLo++; | ||
711 | } | ||
712 | while (1) { | ||
713 | if (unLo > unHi) | ||
714 | break; | ||
715 | n = ((int32_t)block[ptr[unHi]+d]) - med; | ||
716 | if (n == 0) { | ||
717 | mswap(ptr[unHi], ptr[gtHi]); | ||
718 | gtHi--; | ||
719 | unHi--; | ||
720 | continue; | ||
721 | }; | ||
722 | if (n < 0) break; | ||
723 | unHi--; | ||
724 | } | ||
725 | if (unLo > unHi) | ||
726 | break; | ||
727 | mswap(ptr[unLo], ptr[unHi]); | ||
728 | unLo++; | ||
729 | unHi--; | ||
730 | } | ||
731 | |||
732 | AssertD(unHi == unLo-1, "mainQSort3(2)"); | ||
733 | |||
734 | if (gtHi < ltLo) { | ||
735 | mpush(lo, hi, d + 1); | ||
736 | continue; | ||
737 | } | ||
738 | |||
739 | n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); | ||
740 | m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); | ||
741 | |||
742 | n = lo + unLo - ltLo - 1; | ||
743 | m = hi - (gtHi - unHi) + 1; | ||
744 | |||
745 | nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; | ||
746 | nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; | ||
747 | nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; | ||
748 | |||
749 | if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); | ||
750 | if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); | ||
751 | if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); | ||
752 | |||
753 | AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)"); | ||
754 | AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)"); | ||
755 | |||
756 | mpush (nextLo[0], nextHi[0], nextD[0]); | ||
757 | mpush (nextLo[1], nextHi[1], nextD[1]); | ||
758 | mpush (nextLo[2], nextHi[2], nextD[2]); | ||
759 | } | ||
760 | } | ||
761 | |||
762 | #undef mswap | ||
763 | #undef mvswap | ||
764 | #undef mpush | ||
765 | #undef mpop | ||
766 | #undef mmin | ||
767 | #undef mnextsize | ||
768 | #undef mnextswap | ||
769 | #undef MAIN_QSORT_SMALL_THRESH | ||
770 | #undef MAIN_QSORT_DEPTH_THRESH | ||
771 | #undef MAIN_QSORT_STACK_SIZE | ||
772 | |||
773 | |||
774 | /*---------------------------------------------*/ | ||
775 | /* Pre: | ||
776 | * nblock > N_OVERSHOOT | ||
777 | * block32 exists for [0 .. nblock-1 +N_OVERSHOOT] | ||
778 | * ((UChar*)block32) [0 .. nblock-1] holds block | ||
779 | * ptr exists for [0 .. nblock-1] | ||
780 | * | ||
781 | * Post: | ||
782 | * ((UChar*)block32) [0 .. nblock-1] holds block | ||
783 | * All other areas of block32 destroyed | ||
784 | * ftab[0 .. 65536] destroyed | ||
785 | * ptr [0 .. nblock-1] holds sorted order | ||
786 | * if (*budget < 0), sorting was abandoned | ||
787 | */ | ||
788 | |||
789 | #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) | ||
790 | #define SETMASK (1 << 21) | ||
791 | #define CLEARMASK (~(SETMASK)) | ||
792 | |||
793 | static NOINLINE | ||
794 | void mainSort(uint32_t* ptr, | ||
795 | UChar* block, | ||
796 | uint16_t* quadrant, | ||
797 | uint32_t* ftab, | ||
798 | int32_t nblock, | ||
799 | int32_t* budget) | ||
800 | { | ||
801 | int32_t i, j, k, ss, sb; | ||
802 | int32_t runningOrder[256]; | ||
803 | Bool bigDone[256]; | ||
804 | int32_t copyStart[256]; | ||
805 | int32_t copyEnd [256]; | ||
806 | UChar c1; | ||
807 | int32_t numQSorted; | ||
808 | uint16_t s; | ||
809 | |||
810 | /*-- set up the 2-byte frequency table --*/ | ||
811 | /* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */ | ||
812 | memset(ftab, 0, 65537 * sizeof(ftab[0])); | ||
813 | |||
814 | j = block[0] << 8; | ||
815 | i = nblock-1; | ||
816 | #if 0 | ||
817 | for (; i >= 3; i -= 4) { | ||
818 | quadrant[i] = 0; | ||
819 | j = (j >> 8) |(((uint16_t)block[i]) << 8); | ||
820 | ftab[j]++; | ||
821 | quadrant[i-1] = 0; | ||
822 | j = (j >> 8) |(((uint16_t)block[i-1]) << 8); | ||
823 | ftab[j]++; | ||
824 | quadrant[i-2] = 0; | ||
825 | j = (j >> 8) |(((uint16_t)block[i-2]) << 8); | ||
826 | ftab[j]++; | ||
827 | quadrant[i-3] = 0; | ||
828 | j = (j >> 8) |(((uint16_t)block[i-3]) << 8); | ||
829 | ftab[j]++; | ||
830 | } | ||
831 | #endif | ||
832 | for (; i >= 0; i--) { | ||
833 | quadrant[i] = 0; | ||
834 | j = (j >> 8) |(((uint16_t)block[i]) << 8); | ||
835 | ftab[j]++; | ||
836 | } | ||
837 | |||
838 | /*-- (emphasises close relationship of block & quadrant) --*/ | ||
839 | for (i = 0; i < BZ_N_OVERSHOOT; i++) { | ||
840 | block [nblock+i] = block[i]; | ||
841 | quadrant[nblock+i] = 0; | ||
842 | } | ||
843 | |||
844 | /*-- Complete the initial radix sort --*/ | ||
845 | for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; | ||
846 | |||
847 | s = block[0] << 8; | ||
848 | i = nblock-1; | ||
849 | #if 0 | ||
850 | for (; i >= 3; i -= 4) { | ||
851 | s = (s >> 8) | (block[i] << 8); | ||
852 | j = ftab[s] -1; | ||
853 | ftab[s] = j; | ||
854 | ptr[j] = i; | ||
855 | s = (s >> 8) | (block[i-1] << 8); | ||
856 | j = ftab[s] -1; | ||
857 | ftab[s] = j; | ||
858 | ptr[j] = i-1; | ||
859 | s = (s >> 8) | (block[i-2] << 8); | ||
860 | j = ftab[s] -1; | ||
861 | ftab[s] = j; | ||
862 | ptr[j] = i-2; | ||
863 | s = (s >> 8) | (block[i-3] << 8); | ||
864 | j = ftab[s] -1; | ||
865 | ftab[s] = j; | ||
866 | ptr[j] = i-3; | ||
867 | } | ||
868 | #endif | ||
869 | for (; i >= 0; i--) { | ||
870 | s = (s >> 8) | (block[i] << 8); | ||
871 | j = ftab[s] -1; | ||
872 | ftab[s] = j; | ||
873 | ptr[j] = i; | ||
874 | } | ||
875 | |||
876 | /* | ||
877 | * Now ftab contains the first loc of every small bucket. | ||
878 | * Calculate the running order, from smallest to largest | ||
879 | * big bucket. | ||
880 | */ | ||
881 | for (i = 0; i <= 255; i++) { | ||
882 | bigDone [i] = False; | ||
883 | runningOrder[i] = i; | ||
884 | } | ||
885 | |||
886 | { | ||
887 | int32_t vv; | ||
888 | /* was: int32_t h = 1; */ | ||
889 | /* do h = 3 * h + 1; while (h <= 256); */ | ||
890 | int32_t h = 364; | ||
891 | |||
892 | do { | ||
893 | h = h / 3; | ||
894 | for (i = h; i <= 255; i++) { | ||
895 | vv = runningOrder[i]; | ||
896 | j = i; | ||
897 | while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) { | ||
898 | runningOrder[j] = runningOrder[j-h]; | ||
899 | j = j - h; | ||
900 | if (j <= (h - 1)) goto zero; | ||
901 | } | ||
902 | zero: | ||
903 | runningOrder[j] = vv; | ||
904 | } | ||
905 | } while (h != 1); | ||
906 | } | ||
907 | |||
908 | /* | ||
909 | * The main sorting loop. | ||
910 | */ | ||
911 | |||
912 | numQSorted = 0; | ||
913 | |||
914 | for (i = 0; i <= 255; i++) { | ||
915 | |||
916 | /* | ||
917 | * Process big buckets, starting with the least full. | ||
918 | * Basically this is a 3-step process in which we call | ||
919 | * mainQSort3 to sort the small buckets [ss, j], but | ||
920 | * also make a big effort to avoid the calls if we can. | ||
921 | */ | ||
922 | ss = runningOrder[i]; | ||
923 | |||
924 | /* | ||
925 | * Step 1: | ||
926 | * Complete the big bucket [ss] by quicksorting | ||
927 | * any unsorted small buckets [ss, j], for j != ss. | ||
928 | * Hopefully previous pointer-scanning phases have already | ||
929 | * completed many of the small buckets [ss, j], so | ||
930 | * we don't have to sort them at all. | ||
931 | */ | ||
932 | for (j = 0; j <= 255; j++) { | ||
933 | if (j != ss) { | ||
934 | sb = (ss << 8) + j; | ||
935 | if (!(ftab[sb] & SETMASK)) { | ||
936 | int32_t lo = ftab[sb] & CLEARMASK; | ||
937 | int32_t hi = (ftab[sb+1] & CLEARMASK) - 1; | ||
938 | if (hi > lo) { | ||
939 | mainQSort3 ( | ||
940 | ptr, block, quadrant, nblock, | ||
941 | lo, hi, BZ_N_RADIX, budget | ||
942 | ); | ||
943 | numQSorted += (hi - lo + 1); | ||
944 | if (*budget < 0) return; | ||
945 | } | ||
946 | } | ||
947 | ftab[sb] |= SETMASK; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | AssertH(!bigDone[ss], 1006); | ||
952 | |||
953 | /* | ||
954 | * Step 2: | ||
955 | * Now scan this big bucket [ss] so as to synthesise the | ||
956 | * sorted order for small buckets [t, ss] for all t, | ||
957 | * including, magically, the bucket [ss,ss] too. | ||
958 | * This will avoid doing Real Work in subsequent Step 1's. | ||
959 | */ | ||
960 | { | ||
961 | for (j = 0; j <= 255; j++) { | ||
962 | copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; | ||
963 | copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; | ||
964 | } | ||
965 | for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { | ||
966 | k = ptr[j] - 1; | ||
967 | if (k < 0) | ||
968 | k += nblock; | ||
969 | c1 = block[k]; | ||
970 | if (!bigDone[c1]) | ||
971 | ptr[copyStart[c1]++] = k; | ||
972 | } | ||
973 | for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { | ||
974 | k = ptr[j]-1; | ||
975 | if (k < 0) | ||
976 | k += nblock; | ||
977 | c1 = block[k]; | ||
978 | if (!bigDone[c1]) | ||
979 | ptr[copyEnd[c1]--] = k; | ||
980 | } | ||
981 | } | ||
982 | |||
983 | AssertH((copyStart[ss]-1 == copyEnd[ss]) | ||
984 | || | ||
985 | /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. | ||
986 | * Necessity for this case is demonstrated by compressing | ||
987 | * a sequence of approximately 48.5 million of character | ||
988 | * 251; 1.0.0/1.0.1 will then die here. */ | ||
989 | (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), | ||
990 | 1007) | ||
991 | |||
992 | for (j = 0; j <= 255; j++) | ||
993 | ftab[(j << 8) + ss] |= SETMASK; | ||
994 | |||
995 | /* | ||
996 | * Step 3: | ||
997 | * The [ss] big bucket is now done. Record this fact, | ||
998 | * and update the quadrant descriptors. Remember to | ||
999 | * update quadrants in the overshoot area too, if | ||
1000 | * necessary. The "if (i < 255)" test merely skips | ||
1001 | * this updating for the last bucket processed, since | ||
1002 | * updating for the last bucket is pointless. | ||
1003 | * | ||
1004 | * The quadrant array provides a way to incrementally | ||
1005 | * cache sort orderings, as they appear, so as to | ||
1006 | * make subsequent comparisons in fullGtU() complete | ||
1007 | * faster. For repetitive blocks this makes a big | ||
1008 | * difference (but not big enough to be able to avoid | ||
1009 | * the fallback sorting mechanism, exponential radix sort). | ||
1010 | * | ||
1011 | * The precise meaning is: at all times: | ||
1012 | * | ||
1013 | * for 0 <= i < nblock and 0 <= j <= nblock | ||
1014 | * | ||
1015 | * if block[i] != block[j], | ||
1016 | * | ||
1017 | * then the relative values of quadrant[i] and | ||
1018 | * quadrant[j] are meaningless. | ||
1019 | * | ||
1020 | * else { | ||
1021 | * if quadrant[i] < quadrant[j] | ||
1022 | * then the string starting at i lexicographically | ||
1023 | * precedes the string starting at j | ||
1024 | * | ||
1025 | * else if quadrant[i] > quadrant[j] | ||
1026 | * then the string starting at j lexicographically | ||
1027 | * precedes the string starting at i | ||
1028 | * | ||
1029 | * else | ||
1030 | * the relative ordering of the strings starting | ||
1031 | * at i and j has not yet been determined. | ||
1032 | * } | ||
1033 | */ | ||
1034 | bigDone[ss] = True; | ||
1035 | |||
1036 | if (i < 255) { | ||
1037 | int32_t bbStart = ftab[ss << 8] & CLEARMASK; | ||
1038 | int32_t bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; | ||
1039 | int32_t shifts = 0; | ||
1040 | |||
1041 | while ((bbSize >> shifts) > 65534) shifts++; | ||
1042 | |||
1043 | for (j = bbSize-1; j >= 0; j--) { | ||
1044 | int32_t a2update = ptr[bbStart + j]; | ||
1045 | uint16_t qVal = (uint16_t)(j >> shifts); | ||
1046 | quadrant[a2update] = qVal; | ||
1047 | if (a2update < BZ_N_OVERSHOOT) | ||
1048 | quadrant[a2update + nblock] = qVal; | ||
1049 | } | ||
1050 | AssertH(((bbSize-1) >> shifts) <= 65535, 1002); | ||
1051 | } | ||
1052 | |||
1053 | } | ||
1054 | } | ||
1055 | |||
1056 | #undef BIGFREQ | ||
1057 | #undef SETMASK | ||
1058 | #undef CLEARMASK | ||
1059 | |||
1060 | |||
1061 | /*---------------------------------------------*/ | ||
1062 | /* Pre: | ||
1063 | * nblock > 0 | ||
1064 | * arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] | ||
1065 | * ((UChar*)arr2)[0 .. nblock-1] holds block | ||
1066 | * arr1 exists for [0 .. nblock-1] | ||
1067 | * | ||
1068 | * Post: | ||
1069 | * ((UChar*)arr2) [0 .. nblock-1] holds block | ||
1070 | * All other areas of block destroyed | ||
1071 | * ftab[0 .. 65536] destroyed | ||
1072 | * arr1[0 .. nblock-1] holds sorted order | ||
1073 | */ | ||
1074 | static NOINLINE | ||
1075 | void BZ2_blockSort(EState* s) | ||
1076 | { | ||
1077 | /* In original bzip2 1.0.4, it's a parameter, but 30 | ||
1078 | * should work ok. */ | ||
1079 | enum { wfact = 30 }; | ||
1080 | |||
1081 | uint32_t* ptr = s->ptr; | ||
1082 | UChar* block = s->block; | ||
1083 | uint32_t* ftab = s->ftab; | ||
1084 | int32_t nblock = s->nblock; | ||
1085 | uint16_t* quadrant; | ||
1086 | int32_t budget; | ||
1087 | int32_t i; | ||
1088 | |||
1089 | if (nblock < 10000) { | ||
1090 | fallbackSort(s->arr1, s->arr2, ftab, nblock); | ||
1091 | } else { | ||
1092 | /* Calculate the location for quadrant, remembering to get | ||
1093 | * the alignment right. Assumes that &(block[0]) is at least | ||
1094 | * 2-byte aligned -- this should be ok since block is really | ||
1095 | * the first section of arr2. | ||
1096 | */ | ||
1097 | i = nblock + BZ_N_OVERSHOOT; | ||
1098 | if (i & 1) i++; | ||
1099 | quadrant = (uint16_t*)(&(block[i])); | ||
1100 | |||
1101 | /* (wfact-1) / 3 puts the default-factor-30 | ||
1102 | * transition point at very roughly the same place as | ||
1103 | * with v0.1 and v0.9.0. | ||
1104 | * Not that it particularly matters any more, since the | ||
1105 | * resulting compressed stream is now the same regardless | ||
1106 | * of whether or not we use the main sort or fallback sort. | ||
1107 | */ | ||
1108 | budget = nblock * ((wfact-1) / 3); | ||
1109 | |||
1110 | mainSort(ptr, block, quadrant, ftab, nblock, &budget); | ||
1111 | if (budget < 0) { | ||
1112 | fallbackSort(s->arr1, s->arr2, ftab, nblock); | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1116 | s->origPtr = -1; | ||
1117 | for (i = 0; i < s->nblock; i++) | ||
1118 | if (ptr[i] == 0) { | ||
1119 | s->origPtr = i; break; | ||
1120 | }; | ||
1121 | |||
1122 | AssertH(s->origPtr != -1, 1003); | ||
1123 | } | ||
1124 | |||
1125 | |||
1126 | /*-------------------------------------------------------------*/ | ||
1127 | /*--- end blocksort.c ---*/ | ||
1128 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/bzlib.c b/archival/bz/bzlib.c new file mode 100644 index 000000000..3125bb0bf --- /dev/null +++ b/archival/bz/bzlib.c | |||
@@ -0,0 +1,433 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Library top-level functions. ---*/ | ||
9 | /*--- bzlib.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* CHANGES | ||
27 | * 0.9.0 -- original version. | ||
28 | * 0.9.0a/b -- no changes in this file. | ||
29 | * 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). | ||
30 | * fixed bzWrite/bzRead to ignore zero-length requests. | ||
31 | * fixed bzread to correctly handle read requests after EOF. | ||
32 | * wrong parameter order in call to bzDecompressInit in | ||
33 | * bzBuffToBuffDecompress. Fixed. | ||
34 | */ | ||
35 | |||
36 | /* #include "bzlib_private.h" */ | ||
37 | |||
38 | /*---------------------------------------------------*/ | ||
39 | /*--- Compression stuff ---*/ | ||
40 | /*---------------------------------------------------*/ | ||
41 | |||
42 | /*---------------------------------------------------*/ | ||
43 | #ifndef BZ_NO_STDIO | ||
44 | static void bz_assert_fail(int errcode) | ||
45 | { | ||
46 | /* if (errcode == 1007) bb_error_msg_and_die("probably bad RAM"); */ | ||
47 | bb_error_msg_and_die("bzip2 internal error %d", errcode); | ||
48 | } | ||
49 | #endif | ||
50 | |||
51 | |||
52 | /*---------------------------------------------------*/ | ||
53 | static | ||
54 | void prepare_new_block(EState* s) | ||
55 | { | ||
56 | int32_t i; | ||
57 | s->nblock = 0; | ||
58 | s->numZ = 0; | ||
59 | s->state_out_pos = 0; | ||
60 | BZ_INITIALISE_CRC(s->blockCRC); | ||
61 | for (i = 0; i < 256; i++) s->inUse[i] = False; | ||
62 | s->blockNo++; | ||
63 | } | ||
64 | |||
65 | |||
66 | /*---------------------------------------------------*/ | ||
67 | static | ||
68 | ALWAYS_INLINE | ||
69 | void init_RL(EState* s) | ||
70 | { | ||
71 | s->state_in_ch = 256; | ||
72 | s->state_in_len = 0; | ||
73 | } | ||
74 | |||
75 | |||
76 | static | ||
77 | Bool isempty_RL(EState* s) | ||
78 | { | ||
79 | if (s->state_in_ch < 256 && s->state_in_len > 0) | ||
80 | return False; | ||
81 | return True; | ||
82 | } | ||
83 | |||
84 | |||
85 | /*---------------------------------------------------*/ | ||
86 | static | ||
87 | void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k) | ||
88 | { | ||
89 | int32_t n; | ||
90 | EState* s; | ||
91 | |||
92 | s = xzalloc(sizeof(EState)); | ||
93 | s->strm = strm; | ||
94 | |||
95 | n = 100000 * blockSize100k; | ||
96 | s->arr1 = xmalloc(n * sizeof(uint32_t)); | ||
97 | s->mtfv = (uint16_t*)s->arr1; | ||
98 | s->ptr = (uint32_t*)s->arr1; | ||
99 | s->arr2 = xmalloc((n + BZ_N_OVERSHOOT) * sizeof(uint32_t)); | ||
100 | s->block = (UChar*)s->arr2; | ||
101 | s->ftab = xmalloc(65537 * sizeof(uint32_t)); | ||
102 | |||
103 | s->state = BZ_S_INPUT; | ||
104 | s->mode = BZ_M_RUNNING; | ||
105 | s->blockSize100k = blockSize100k; | ||
106 | s->nblockMAX = n - 19; | ||
107 | |||
108 | strm->state = s; | ||
109 | /*strm->total_in = 0;*/ | ||
110 | strm->total_out = 0; | ||
111 | init_RL(s); | ||
112 | prepare_new_block(s); | ||
113 | } | ||
114 | |||
115 | |||
116 | /*---------------------------------------------------*/ | ||
117 | static | ||
118 | void add_pair_to_block(EState* s) | ||
119 | { | ||
120 | int32_t i; | ||
121 | UChar ch = (UChar)(s->state_in_ch); | ||
122 | for (i = 0; i < s->state_in_len; i++) { | ||
123 | BZ_UPDATE_CRC(s->blockCRC, ch); | ||
124 | } | ||
125 | s->inUse[s->state_in_ch] = True; | ||
126 | switch (s->state_in_len) { | ||
127 | case 1: | ||
128 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
129 | break; | ||
130 | case 2: | ||
131 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
132 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
133 | break; | ||
134 | case 3: | ||
135 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
136 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
137 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
138 | break; | ||
139 | default: | ||
140 | s->inUse[s->state_in_len-4] = True; | ||
141 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
142 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
143 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
144 | s->block[s->nblock] = (UChar)ch; s->nblock++; | ||
145 | s->block[s->nblock] = ((UChar)(s->state_in_len-4)); | ||
146 | s->nblock++; | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | |||
152 | /*---------------------------------------------------*/ | ||
153 | static | ||
154 | void flush_RL(EState* s) | ||
155 | { | ||
156 | if (s->state_in_ch < 256) add_pair_to_block(s); | ||
157 | init_RL(s); | ||
158 | } | ||
159 | |||
160 | |||
161 | /*---------------------------------------------------*/ | ||
162 | #define ADD_CHAR_TO_BLOCK(zs, zchh0) \ | ||
163 | { \ | ||
164 | uint32_t zchh = (uint32_t)(zchh0); \ | ||
165 | /*-- fast track the common case --*/ \ | ||
166 | if (zchh != zs->state_in_ch && zs->state_in_len == 1) { \ | ||
167 | UChar ch = (UChar)(zs->state_in_ch); \ | ||
168 | BZ_UPDATE_CRC(zs->blockCRC, ch); \ | ||
169 | zs->inUse[zs->state_in_ch] = True; \ | ||
170 | zs->block[zs->nblock] = (UChar)ch; \ | ||
171 | zs->nblock++; \ | ||
172 | zs->state_in_ch = zchh; \ | ||
173 | } \ | ||
174 | else \ | ||
175 | /*-- general, uncommon cases --*/ \ | ||
176 | if (zchh != zs->state_in_ch || \ | ||
177 | zs->state_in_len == 255) { \ | ||
178 | if (zs->state_in_ch < 256) \ | ||
179 | add_pair_to_block(zs); \ | ||
180 | zs->state_in_ch = zchh; \ | ||
181 | zs->state_in_len = 1; \ | ||
182 | } else { \ | ||
183 | zs->state_in_len++; \ | ||
184 | } \ | ||
185 | } | ||
186 | |||
187 | |||
188 | /*---------------------------------------------------*/ | ||
189 | static | ||
190 | Bool copy_input_until_stop(EState* s) | ||
191 | { | ||
192 | Bool progress_in = False; | ||
193 | |||
194 | //vda: cannot simplify this until avail_in_expect is removed | ||
195 | if (s->mode == BZ_M_RUNNING) { | ||
196 | /*-- fast track the common case --*/ | ||
197 | while (1) { | ||
198 | /*-- block full? --*/ | ||
199 | if (s->nblock >= s->nblockMAX) break; | ||
200 | /*-- no input? --*/ | ||
201 | if (s->strm->avail_in == 0) break; | ||
202 | progress_in = True; | ||
203 | ADD_CHAR_TO_BLOCK(s, (uint32_t)(*((UChar*)(s->strm->next_in)))); | ||
204 | s->strm->next_in++; | ||
205 | s->strm->avail_in--; | ||
206 | /*s->strm->total_in++;*/ | ||
207 | } | ||
208 | } else { | ||
209 | /*-- general, uncommon case --*/ | ||
210 | while (1) { | ||
211 | /*-- block full? --*/ | ||
212 | if (s->nblock >= s->nblockMAX) break; | ||
213 | /*-- no input? --*/ | ||
214 | if (s->strm->avail_in == 0) break; | ||
215 | /*-- flush/finish end? --*/ | ||
216 | if (s->avail_in_expect == 0) break; | ||
217 | progress_in = True; | ||
218 | ADD_CHAR_TO_BLOCK(s, (uint32_t)(*((UChar*)(s->strm->next_in)))); | ||
219 | s->strm->next_in++; | ||
220 | s->strm->avail_in--; | ||
221 | /*s->strm->total_in++;*/ | ||
222 | s->avail_in_expect--; | ||
223 | } | ||
224 | } | ||
225 | return progress_in; | ||
226 | } | ||
227 | |||
228 | |||
229 | /*---------------------------------------------------*/ | ||
230 | static | ||
231 | Bool copy_output_until_stop(EState* s) | ||
232 | { | ||
233 | Bool progress_out = False; | ||
234 | |||
235 | while (1) { | ||
236 | |||
237 | /*-- no output space? --*/ | ||
238 | if (s->strm->avail_out == 0) break; | ||
239 | |||
240 | /*-- block done? --*/ | ||
241 | if (s->state_out_pos >= s->numZ) break; | ||
242 | |||
243 | progress_out = True; | ||
244 | *(s->strm->next_out) = s->zbits[s->state_out_pos]; | ||
245 | s->state_out_pos++; | ||
246 | s->strm->avail_out--; | ||
247 | s->strm->next_out++; | ||
248 | s->strm->total_out++; | ||
249 | } | ||
250 | |||
251 | return progress_out; | ||
252 | } | ||
253 | |||
254 | |||
255 | /*---------------------------------------------------*/ | ||
256 | static | ||
257 | Bool handle_compress(bz_stream *strm) | ||
258 | { | ||
259 | Bool progress_in = False; | ||
260 | Bool progress_out = False; | ||
261 | EState* s = strm->state; | ||
262 | |||
263 | while (1) { | ||
264 | if (s->state == BZ_S_OUTPUT) { | ||
265 | progress_out |= copy_output_until_stop(s); | ||
266 | if (s->state_out_pos < s->numZ) break; | ||
267 | if (s->mode == BZ_M_FINISHING | ||
268 | && s->avail_in_expect == 0 | ||
269 | && isempty_RL(s)) | ||
270 | break; | ||
271 | prepare_new_block(s); | ||
272 | s->state = BZ_S_INPUT; | ||
273 | if (s->mode == BZ_M_FLUSHING | ||
274 | && s->avail_in_expect == 0 | ||
275 | && isempty_RL(s)) | ||
276 | break; | ||
277 | } | ||
278 | |||
279 | if (s->state == BZ_S_INPUT) { | ||
280 | progress_in |= copy_input_until_stop(s); | ||
281 | if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { | ||
282 | flush_RL(s); | ||
283 | BZ2_compressBlock(s, (Bool)(s->mode == BZ_M_FINISHING)); | ||
284 | s->state = BZ_S_OUTPUT; | ||
285 | } else | ||
286 | if (s->nblock >= s->nblockMAX) { | ||
287 | BZ2_compressBlock(s, False); | ||
288 | s->state = BZ_S_OUTPUT; | ||
289 | } else | ||
290 | if (s->strm->avail_in == 0) { | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | } | ||
296 | |||
297 | return progress_in || progress_out; | ||
298 | } | ||
299 | |||
300 | |||
301 | /*---------------------------------------------------*/ | ||
302 | static | ||
303 | int BZ2_bzCompress(bz_stream *strm, int action) | ||
304 | { | ||
305 | Bool progress; | ||
306 | EState* s; | ||
307 | if (strm == NULL) return BZ_PARAM_ERROR; | ||
308 | s = strm->state; | ||
309 | if (s == NULL) return BZ_PARAM_ERROR; | ||
310 | if (s->strm != strm) return BZ_PARAM_ERROR; | ||
311 | |||
312 | preswitch: | ||
313 | switch (s->mode) { | ||
314 | |||
315 | case BZ_M_IDLE: | ||
316 | return BZ_SEQUENCE_ERROR; | ||
317 | |||
318 | case BZ_M_RUNNING: | ||
319 | if (action == BZ_RUN) { | ||
320 | progress = handle_compress(strm); | ||
321 | return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; | ||
322 | } | ||
323 | else | ||
324 | if (action == BZ_FLUSH) { | ||
325 | s->avail_in_expect = strm->avail_in; | ||
326 | s->mode = BZ_M_FLUSHING; | ||
327 | goto preswitch; | ||
328 | } | ||
329 | else | ||
330 | if (action == BZ_FINISH) { | ||
331 | s->avail_in_expect = strm->avail_in; | ||
332 | s->mode = BZ_M_FINISHING; | ||
333 | goto preswitch; | ||
334 | } | ||
335 | else | ||
336 | return BZ_PARAM_ERROR; | ||
337 | |||
338 | case BZ_M_FLUSHING: | ||
339 | if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; | ||
340 | if (s->avail_in_expect != s->strm->avail_in) | ||
341 | return BZ_SEQUENCE_ERROR; | ||
342 | progress = handle_compress(strm); | ||
343 | if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) | ||
344 | return BZ_FLUSH_OK; | ||
345 | s->mode = BZ_M_RUNNING; | ||
346 | return BZ_RUN_OK; | ||
347 | |||
348 | case BZ_M_FINISHING: | ||
349 | if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; | ||
350 | if (s->avail_in_expect != s->strm->avail_in) | ||
351 | return BZ_SEQUENCE_ERROR; | ||
352 | progress = handle_compress(strm); | ||
353 | if (!progress) return BZ_SEQUENCE_ERROR; | ||
354 | if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) | ||
355 | return BZ_FINISH_OK; | ||
356 | s->mode = BZ_M_IDLE; | ||
357 | return BZ_STREAM_END; | ||
358 | } | ||
359 | return BZ_OK; /*--not reached--*/ | ||
360 | } | ||
361 | |||
362 | |||
363 | /*---------------------------------------------------*/ | ||
364 | static | ||
365 | int BZ2_bzCompressEnd(bz_stream *strm) | ||
366 | { | ||
367 | EState* s; | ||
368 | if (strm == NULL) return BZ_PARAM_ERROR; | ||
369 | s = strm->state; | ||
370 | if (s == NULL) return BZ_PARAM_ERROR; | ||
371 | if (s->strm != strm) return BZ_PARAM_ERROR; | ||
372 | |||
373 | if (s->arr1 != NULL) free(s->arr1); | ||
374 | if (s->arr2 != NULL) free(s->arr2); | ||
375 | if (s->ftab != NULL) free(s->ftab); | ||
376 | free(strm->state); | ||
377 | |||
378 | strm->state = NULL; | ||
379 | |||
380 | return BZ_OK; | ||
381 | } | ||
382 | |||
383 | |||
384 | /*---------------------------------------------------*/ | ||
385 | /*--- Misc convenience stuff ---*/ | ||
386 | /*---------------------------------------------------*/ | ||
387 | |||
388 | /*---------------------------------------------------*/ | ||
389 | #ifdef EXAMPLE_CODE_FOR_MEM_TO_MEM_COMPRESSION | ||
390 | static | ||
391 | int BZ2_bzBuffToBuffCompress(char* dest, | ||
392 | unsigned int* destLen, | ||
393 | char* source, | ||
394 | unsigned int sourceLen, | ||
395 | int blockSize100k) | ||
396 | { | ||
397 | bz_stream strm; | ||
398 | int ret; | ||
399 | |||
400 | if (dest == NULL || destLen == NULL || | ||
401 | source == NULL || | ||
402 | blockSize100k < 1 || blockSize100k > 9) | ||
403 | return BZ_PARAM_ERROR; | ||
404 | |||
405 | BZ2_bzCompressInit(&strm, blockSize100k); | ||
406 | |||
407 | strm.next_in = source; | ||
408 | strm.next_out = dest; | ||
409 | strm.avail_in = sourceLen; | ||
410 | strm.avail_out = *destLen; | ||
411 | |||
412 | ret = BZ2_bzCompress(&strm, BZ_FINISH); | ||
413 | if (ret == BZ_FINISH_OK) goto output_overflow; | ||
414 | if (ret != BZ_STREAM_END) goto errhandler; | ||
415 | |||
416 | /* normal termination */ | ||
417 | *destLen -= strm.avail_out; | ||
418 | BZ2_bzCompressEnd(&strm); | ||
419 | return BZ_OK; | ||
420 | |||
421 | output_overflow: | ||
422 | BZ2_bzCompressEnd(&strm); | ||
423 | return BZ_OUTBUFF_FULL; | ||
424 | |||
425 | errhandler: | ||
426 | BZ2_bzCompressEnd(&strm); | ||
427 | return ret; | ||
428 | } | ||
429 | #endif | ||
430 | |||
431 | /*-------------------------------------------------------------*/ | ||
432 | /*--- end bzlib.c ---*/ | ||
433 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/bzlib.h b/archival/bz/bzlib.h new file mode 100644 index 000000000..805e9b328 --- /dev/null +++ b/archival/bz/bzlib.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Public header file for the library. ---*/ | ||
9 | /*--- bzlib.h ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | #define BZ_RUN 0 | ||
27 | #define BZ_FLUSH 1 | ||
28 | #define BZ_FINISH 2 | ||
29 | |||
30 | #define BZ_OK 0 | ||
31 | #define BZ_RUN_OK 1 | ||
32 | #define BZ_FLUSH_OK 2 | ||
33 | #define BZ_FINISH_OK 3 | ||
34 | #define BZ_STREAM_END 4 | ||
35 | #define BZ_SEQUENCE_ERROR (-1) | ||
36 | #define BZ_PARAM_ERROR (-2) | ||
37 | #define BZ_MEM_ERROR (-3) | ||
38 | #define BZ_DATA_ERROR (-4) | ||
39 | #define BZ_DATA_ERROR_MAGIC (-5) | ||
40 | #define BZ_IO_ERROR (-6) | ||
41 | #define BZ_UNEXPECTED_EOF (-7) | ||
42 | #define BZ_OUTBUFF_FULL (-8) | ||
43 | #define BZ_CONFIG_ERROR (-9) | ||
44 | |||
45 | typedef struct bz_stream { | ||
46 | char *next_in; | ||
47 | char *next_out; | ||
48 | unsigned avail_in; | ||
49 | unsigned avail_out; | ||
50 | /*unsigned long long total_in;*/ | ||
51 | unsigned long long total_out; | ||
52 | void *state; | ||
53 | } bz_stream; | ||
54 | |||
55 | /*-- Core (low-level) library functions --*/ | ||
56 | |||
57 | static void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k); | ||
58 | static int BZ2_bzCompress(bz_stream *strm, int action); | ||
59 | static int BZ2_bzCompressEnd(bz_stream *strm); | ||
60 | |||
61 | /*-------------------------------------------------------------*/ | ||
62 | /*--- end bzlib.h ---*/ | ||
63 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/bzlib_private.h b/archival/bz/bzlib_private.h new file mode 100644 index 000000000..24ffbee9c --- /dev/null +++ b/archival/bz/bzlib_private.h | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Private header file for the library. ---*/ | ||
9 | /*--- bzlib_private.h ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* #include "bzlib.h" */ | ||
27 | |||
28 | #define BZ_DEBUG 0 | ||
29 | //#define BZ_NO_STDIO 1 - does not work | ||
30 | |||
31 | |||
32 | /*-- General stuff. --*/ | ||
33 | |||
34 | typedef unsigned char Bool; | ||
35 | typedef unsigned char UChar; | ||
36 | |||
37 | #define True ((Bool)1) | ||
38 | #define False ((Bool)0) | ||
39 | |||
40 | static void bz_assert_fail(int errcode) ATTRIBUTE_NORETURN; | ||
41 | #define AssertH(cond, errcode) \ | ||
42 | { \ | ||
43 | if (!(cond)) \ | ||
44 | bz_assert_fail(errcode); \ | ||
45 | } | ||
46 | |||
47 | #if BZ_DEBUG | ||
48 | #define AssertD(cond, msg) \ | ||
49 | { \ | ||
50 | if (!(cond)) \ | ||
51 | bb_error_msg_and_die("(debug build): internal error %s", msg); \ | ||
52 | } | ||
53 | #else | ||
54 | #define AssertD(cond, msg) do { } while (0) | ||
55 | #endif | ||
56 | |||
57 | |||
58 | /*-- Header bytes. --*/ | ||
59 | |||
60 | #define BZ_HDR_B 0x42 /* 'B' */ | ||
61 | #define BZ_HDR_Z 0x5a /* 'Z' */ | ||
62 | #define BZ_HDR_h 0x68 /* 'h' */ | ||
63 | #define BZ_HDR_0 0x30 /* '0' */ | ||
64 | |||
65 | #define BZ_HDR_BZh0 0x425a6830 | ||
66 | |||
67 | /*-- Constants for the back end. --*/ | ||
68 | |||
69 | #define BZ_MAX_ALPHA_SIZE 258 | ||
70 | #define BZ_MAX_CODE_LEN 23 | ||
71 | |||
72 | #define BZ_RUNA 0 | ||
73 | #define BZ_RUNB 1 | ||
74 | |||
75 | #define BZ_N_GROUPS 6 | ||
76 | #define BZ_G_SIZE 50 | ||
77 | #define BZ_N_ITERS 4 | ||
78 | |||
79 | #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) | ||
80 | |||
81 | |||
82 | /*-- Stuff for randomising repetitive blocks. --*/ | ||
83 | |||
84 | static const int32_t BZ2_rNums[512]; | ||
85 | |||
86 | #define BZ_RAND_DECLS \ | ||
87 | int32_t rNToGo; \ | ||
88 | int32_t rTPos \ | ||
89 | |||
90 | #define BZ_RAND_INIT_MASK \ | ||
91 | s->rNToGo = 0; \ | ||
92 | s->rTPos = 0 \ | ||
93 | |||
94 | #define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) | ||
95 | |||
96 | #define BZ_RAND_UPD_MASK \ | ||
97 | { \ | ||
98 | if (s->rNToGo == 0) { \ | ||
99 | s->rNToGo = BZ2_rNums[s->rTPos]; \ | ||
100 | s->rTPos++; \ | ||
101 | if (s->rTPos == 512) s->rTPos = 0; \ | ||
102 | } \ | ||
103 | s->rNToGo--; \ | ||
104 | } | ||
105 | |||
106 | |||
107 | /*-- Stuff for doing CRCs. --*/ | ||
108 | |||
109 | static const uint32_t BZ2_crc32Table[256]; | ||
110 | |||
111 | #define BZ_INITIALISE_CRC(crcVar) \ | ||
112 | { \ | ||
113 | crcVar = 0xffffffffL; \ | ||
114 | } | ||
115 | |||
116 | #define BZ_FINALISE_CRC(crcVar) \ | ||
117 | { \ | ||
118 | crcVar = ~(crcVar); \ | ||
119 | } | ||
120 | |||
121 | #define BZ_UPDATE_CRC(crcVar,cha) \ | ||
122 | { \ | ||
123 | crcVar = (crcVar << 8) ^ BZ2_crc32Table[(crcVar >> 24) ^ ((UChar)cha)]; \ | ||
124 | } | ||
125 | |||
126 | |||
127 | /*-- States and modes for compression. --*/ | ||
128 | |||
129 | #define BZ_M_IDLE 1 | ||
130 | #define BZ_M_RUNNING 2 | ||
131 | #define BZ_M_FLUSHING 3 | ||
132 | #define BZ_M_FINISHING 4 | ||
133 | |||
134 | #define BZ_S_OUTPUT 1 | ||
135 | #define BZ_S_INPUT 2 | ||
136 | |||
137 | #define BZ_N_RADIX 2 | ||
138 | #define BZ_N_QSORT 12 | ||
139 | #define BZ_N_SHELL 18 | ||
140 | #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) | ||
141 | |||
142 | |||
143 | /*-- Structure holding all the compression-side stuff. --*/ | ||
144 | |||
145 | typedef struct EState { | ||
146 | /* pointer back to the struct bz_stream */ | ||
147 | bz_stream *strm; | ||
148 | |||
149 | /* mode this stream is in, and whether inputting */ | ||
150 | /* or outputting data */ | ||
151 | int32_t mode; | ||
152 | int32_t state; | ||
153 | |||
154 | /* remembers avail_in when flush/finish requested */ | ||
155 | uint32_t avail_in_expect; //vda: do we need this? | ||
156 | |||
157 | /* for doing the block sorting */ | ||
158 | uint32_t *arr1; | ||
159 | uint32_t *arr2; | ||
160 | uint32_t *ftab; | ||
161 | int32_t origPtr; | ||
162 | |||
163 | /* aliases for arr1 and arr2 */ | ||
164 | uint32_t *ptr; | ||
165 | UChar *block; | ||
166 | uint16_t *mtfv; | ||
167 | UChar *zbits; | ||
168 | |||
169 | /* run-length-encoding of the input */ | ||
170 | uint32_t state_in_ch; | ||
171 | int32_t state_in_len; | ||
172 | BZ_RAND_DECLS; | ||
173 | |||
174 | /* input and output limits and current posns */ | ||
175 | int32_t nblock; | ||
176 | int32_t nblockMAX; | ||
177 | int32_t numZ; | ||
178 | int32_t state_out_pos; | ||
179 | |||
180 | /* the buffer for bit stream creation */ | ||
181 | uint32_t bsBuff; | ||
182 | int32_t bsLive; | ||
183 | |||
184 | /* block and combined CRCs */ | ||
185 | uint32_t blockCRC; | ||
186 | uint32_t combinedCRC; | ||
187 | |||
188 | /* misc administratium */ | ||
189 | int32_t blockNo; | ||
190 | int32_t blockSize100k; | ||
191 | |||
192 | /* stuff for coding the MTF values */ | ||
193 | int32_t nMTF; | ||
194 | |||
195 | /* map of bytes used in block */ | ||
196 | int32_t nInUse; | ||
197 | Bool inUse[256]; | ||
198 | UChar unseqToSeq[256]; | ||
199 | |||
200 | /* stuff for coding the MTF values */ | ||
201 | int32_t mtfFreq [BZ_MAX_ALPHA_SIZE]; | ||
202 | UChar selector [BZ_MAX_SELECTORS]; | ||
203 | UChar selectorMtf[BZ_MAX_SELECTORS]; | ||
204 | |||
205 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
206 | int32_t code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
207 | int32_t rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
208 | #ifdef FAST_GROUP6 | ||
209 | /* second dimension: only 3 needed; 4 makes index calculations faster */ | ||
210 | uint32_t len_pack[BZ_MAX_ALPHA_SIZE][4]; | ||
211 | #endif | ||
212 | } EState; | ||
213 | |||
214 | |||
215 | /*-- compression. --*/ | ||
216 | |||
217 | static void | ||
218 | BZ2_blockSort(EState*); | ||
219 | |||
220 | static void | ||
221 | BZ2_compressBlock(EState*, Bool); | ||
222 | |||
223 | static void | ||
224 | BZ2_bsInitWrite(EState*); | ||
225 | |||
226 | static void | ||
227 | BZ2_hbAssignCodes(int32_t*, UChar*, int32_t, int32_t, int32_t); | ||
228 | |||
229 | static void | ||
230 | BZ2_hbMakeCodeLengths(UChar*, int32_t*, int32_t, int32_t); | ||
231 | |||
232 | /*-------------------------------------------------------------*/ | ||
233 | /*--- end bzlib_private.h ---*/ | ||
234 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/compress.c b/archival/bz/compress.c new file mode 100644 index 000000000..54426dcc7 --- /dev/null +++ b/archival/bz/compress.c | |||
@@ -0,0 +1,671 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Compression machinery (not incl block sorting) ---*/ | ||
9 | /*--- compress.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* CHANGES | ||
27 | * 0.9.0 -- original version. | ||
28 | * 0.9.0a/b -- no changes in this file. | ||
29 | * 0.9.0c -- changed setting of nGroups in sendMTFValues() | ||
30 | * so as to do a bit better on small files | ||
31 | */ | ||
32 | |||
33 | /* #include "bzlib_private.h" */ | ||
34 | |||
35 | /*---------------------------------------------------*/ | ||
36 | /*--- Bit stream I/O ---*/ | ||
37 | /*---------------------------------------------------*/ | ||
38 | |||
39 | /*---------------------------------------------------*/ | ||
40 | static | ||
41 | void BZ2_bsInitWrite(EState* s) | ||
42 | { | ||
43 | s->bsLive = 0; | ||
44 | s->bsBuff = 0; | ||
45 | } | ||
46 | |||
47 | |||
48 | /*---------------------------------------------------*/ | ||
49 | static NOINLINE | ||
50 | void bsFinishWrite(EState* s) | ||
51 | { | ||
52 | while (s->bsLive > 0) { | ||
53 | s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); | ||
54 | s->numZ++; | ||
55 | s->bsBuff <<= 8; | ||
56 | s->bsLive -= 8; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | |||
61 | /*---------------------------------------------------*/ | ||
62 | static | ||
63 | /* Forced inlining results in +600 bytes code, | ||
64 | * 2% faster compression. Not worth it. */ | ||
65 | /*ALWAYS_INLINE*/ | ||
66 | void bsW(EState* s, int32_t n, uint32_t v) | ||
67 | { | ||
68 | while (s->bsLive >= 8) { | ||
69 | s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); | ||
70 | s->numZ++; | ||
71 | s->bsBuff <<= 8; | ||
72 | s->bsLive -= 8; | ||
73 | } | ||
74 | s->bsBuff |= (v << (32 - s->bsLive - n)); | ||
75 | s->bsLive += n; | ||
76 | } | ||
77 | |||
78 | |||
79 | /*---------------------------------------------------*/ | ||
80 | static | ||
81 | void bsPutU32(EState* s, uint32_t u) | ||
82 | { | ||
83 | bsW(s, 8, (u >> 24) & 0xff); | ||
84 | bsW(s, 8, (u >> 16) & 0xff); | ||
85 | bsW(s, 8, (u >> 8) & 0xff); | ||
86 | bsW(s, 8, u & 0xff); | ||
87 | } | ||
88 | |||
89 | |||
90 | /*---------------------------------------------------*/ | ||
91 | static | ||
92 | void bsPutUChar(EState* s, UChar c) | ||
93 | { | ||
94 | bsW(s, 8, (uint32_t)c); | ||
95 | } | ||
96 | |||
97 | |||
98 | /*---------------------------------------------------*/ | ||
99 | /*--- The back end proper ---*/ | ||
100 | /*---------------------------------------------------*/ | ||
101 | |||
102 | /*---------------------------------------------------*/ | ||
103 | static | ||
104 | void makeMaps_e(EState* s) | ||
105 | { | ||
106 | int32_t i; | ||
107 | s->nInUse = 0; | ||
108 | for (i = 0; i < 256; i++) { | ||
109 | if (s->inUse[i]) { | ||
110 | s->unseqToSeq[i] = s->nInUse; | ||
111 | s->nInUse++; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | |||
117 | /*---------------------------------------------------*/ | ||
118 | static NOINLINE | ||
119 | void generateMTFValues(EState* s) | ||
120 | { | ||
121 | UChar yy[256]; | ||
122 | int32_t i, j; | ||
123 | int32_t zPend; | ||
124 | int32_t wr; | ||
125 | int32_t EOB; | ||
126 | |||
127 | /* | ||
128 | * After sorting (eg, here), | ||
129 | * s->arr1[0 .. s->nblock-1] holds sorted order, | ||
130 | * and | ||
131 | * ((UChar*)s->arr2)[0 .. s->nblock-1] | ||
132 | * holds the original block data. | ||
133 | * | ||
134 | * The first thing to do is generate the MTF values, | ||
135 | * and put them in | ||
136 | * ((uint16_t*)s->arr1)[0 .. s->nblock-1]. | ||
137 | * Because there are strictly fewer or equal MTF values | ||
138 | * than block values, ptr values in this area are overwritten | ||
139 | * with MTF values only when they are no longer needed. | ||
140 | * | ||
141 | * The final compressed bitstream is generated into the | ||
142 | * area starting at | ||
143 | * (UChar*) (&((UChar*)s->arr2)[s->nblock]) | ||
144 | * | ||
145 | * These storage aliases are set up in bzCompressInit(), | ||
146 | * except for the last one, which is arranged in | ||
147 | * compressBlock(). | ||
148 | */ | ||
149 | uint32_t* ptr = s->ptr; | ||
150 | UChar* block = s->block; | ||
151 | uint16_t* mtfv = s->mtfv; | ||
152 | |||
153 | makeMaps_e(s); | ||
154 | EOB = s->nInUse+1; | ||
155 | |||
156 | for (i = 0; i <= EOB; i++) | ||
157 | s->mtfFreq[i] = 0; | ||
158 | |||
159 | wr = 0; | ||
160 | zPend = 0; | ||
161 | for (i = 0; i < s->nInUse; i++) | ||
162 | yy[i] = (UChar) i; | ||
163 | |||
164 | for (i = 0; i < s->nblock; i++) { | ||
165 | UChar ll_i; | ||
166 | AssertD(wr <= i, "generateMTFValues(1)"); | ||
167 | j = ptr[i]-1; | ||
168 | if (j < 0) | ||
169 | j += s->nblock; | ||
170 | ll_i = s->unseqToSeq[block[j]]; | ||
171 | AssertD(ll_i < s->nInUse, "generateMTFValues(2a)"); | ||
172 | |||
173 | if (yy[0] == ll_i) { | ||
174 | zPend++; | ||
175 | } else { | ||
176 | if (zPend > 0) { | ||
177 | zPend--; | ||
178 | while (1) { | ||
179 | if (zPend & 1) { | ||
180 | mtfv[wr] = BZ_RUNB; wr++; | ||
181 | s->mtfFreq[BZ_RUNB]++; | ||
182 | } else { | ||
183 | mtfv[wr] = BZ_RUNA; wr++; | ||
184 | s->mtfFreq[BZ_RUNA]++; | ||
185 | } | ||
186 | if (zPend < 2) break; | ||
187 | zPend = (zPend - 2) / 2; | ||
188 | }; | ||
189 | zPend = 0; | ||
190 | } | ||
191 | { | ||
192 | register UChar rtmp; | ||
193 | register UChar* ryy_j; | ||
194 | register UChar rll_i; | ||
195 | rtmp = yy[1]; | ||
196 | yy[1] = yy[0]; | ||
197 | ryy_j = &(yy[1]); | ||
198 | rll_i = ll_i; | ||
199 | while (rll_i != rtmp) { | ||
200 | register UChar rtmp2; | ||
201 | ryy_j++; | ||
202 | rtmp2 = rtmp; | ||
203 | rtmp = *ryy_j; | ||
204 | *ryy_j = rtmp2; | ||
205 | }; | ||
206 | yy[0] = rtmp; | ||
207 | j = ryy_j - &(yy[0]); | ||
208 | mtfv[wr] = j+1; | ||
209 | wr++; | ||
210 | s->mtfFreq[j+1]++; | ||
211 | } | ||
212 | |||
213 | } | ||
214 | } | ||
215 | |||
216 | if (zPend > 0) { | ||
217 | zPend--; | ||
218 | while (1) { | ||
219 | if (zPend & 1) { | ||
220 | mtfv[wr] = BZ_RUNB; wr++; | ||
221 | s->mtfFreq[BZ_RUNB]++; | ||
222 | } else { | ||
223 | mtfv[wr] = BZ_RUNA; wr++; | ||
224 | s->mtfFreq[BZ_RUNA]++; | ||
225 | } | ||
226 | if (zPend < 2) | ||
227 | break; | ||
228 | zPend = (zPend - 2) / 2; | ||
229 | }; | ||
230 | zPend = 0; | ||
231 | } | ||
232 | |||
233 | mtfv[wr] = EOB; | ||
234 | wr++; | ||
235 | s->mtfFreq[EOB]++; | ||
236 | |||
237 | s->nMTF = wr; | ||
238 | } | ||
239 | |||
240 | |||
241 | /*---------------------------------------------------*/ | ||
242 | #define BZ_LESSER_ICOST 0 | ||
243 | #define BZ_GREATER_ICOST 15 | ||
244 | |||
245 | static NOINLINE | ||
246 | void sendMTFValues(EState* s) | ||
247 | { | ||
248 | int32_t v, t, i, j, gs, ge, totc, bt, bc, iter; | ||
249 | int32_t nSelectors, alphaSize, minLen, maxLen, selCtr; | ||
250 | int32_t nGroups, nBytes; | ||
251 | |||
252 | /* | ||
253 | * UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
254 | * is a global since the decoder also needs it. | ||
255 | * | ||
256 | * int32_t code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
257 | * int32_t rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | ||
258 | * are also globals only used in this proc. | ||
259 | * Made global to keep stack frame size small. | ||
260 | */ | ||
261 | |||
262 | uint16_t cost[BZ_N_GROUPS]; | ||
263 | int32_t fave[BZ_N_GROUPS]; | ||
264 | |||
265 | uint16_t* mtfv = s->mtfv; | ||
266 | |||
267 | alphaSize = s->nInUse+2; | ||
268 | for (t = 0; t < BZ_N_GROUPS; t++) | ||
269 | for (v = 0; v < alphaSize; v++) | ||
270 | s->len[t][v] = BZ_GREATER_ICOST; | ||
271 | |||
272 | /*--- Decide how many coding tables to use ---*/ | ||
273 | AssertH(s->nMTF > 0, 3001); | ||
274 | if (s->nMTF < 200) nGroups = 2; else | ||
275 | if (s->nMTF < 600) nGroups = 3; else | ||
276 | if (s->nMTF < 1200) nGroups = 4; else | ||
277 | if (s->nMTF < 2400) nGroups = 5; else | ||
278 | nGroups = 6; | ||
279 | |||
280 | /*--- Generate an initial set of coding tables ---*/ | ||
281 | { | ||
282 | int32_t nPart, remF, tFreq, aFreq; | ||
283 | |||
284 | nPart = nGroups; | ||
285 | remF = s->nMTF; | ||
286 | gs = 0; | ||
287 | while (nPart > 0) { | ||
288 | tFreq = remF / nPart; | ||
289 | ge = gs-1; | ||
290 | aFreq = 0; | ||
291 | while (aFreq < tFreq && ge < alphaSize-1) { | ||
292 | ge++; | ||
293 | aFreq += s->mtfFreq[ge]; | ||
294 | } | ||
295 | |||
296 | if (ge > gs | ||
297 | && nPart != nGroups && nPart != 1 | ||
298 | && ((nGroups-nPart) % 2 == 1) | ||
299 | ) { | ||
300 | aFreq -= s->mtfFreq[ge]; | ||
301 | ge--; | ||
302 | } | ||
303 | |||
304 | for (v = 0; v < alphaSize; v++) | ||
305 | if (v >= gs && v <= ge) | ||
306 | s->len[nPart-1][v] = BZ_LESSER_ICOST; | ||
307 | else | ||
308 | s->len[nPart-1][v] = BZ_GREATER_ICOST; | ||
309 | |||
310 | nPart--; | ||
311 | gs = ge+1; | ||
312 | remF -= aFreq; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * Iterate up to BZ_N_ITERS times to improve the tables. | ||
318 | */ | ||
319 | for (iter = 0; iter < BZ_N_ITERS; iter++) { | ||
320 | for (t = 0; t < nGroups; t++) | ||
321 | fave[t] = 0; | ||
322 | |||
323 | for (t = 0; t < nGroups; t++) | ||
324 | for (v = 0; v < alphaSize; v++) | ||
325 | s->rfreq[t][v] = 0; | ||
326 | |||
327 | #ifdef FAST_GROUP6 | ||
328 | /* | ||
329 | * Set up an auxiliary length table which is used to fast-track | ||
330 | * the common case (nGroups == 6). | ||
331 | */ | ||
332 | if (nGroups == 6) { | ||
333 | for (v = 0; v < alphaSize; v++) { | ||
334 | s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; | ||
335 | s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; | ||
336 | s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; | ||
337 | } | ||
338 | } | ||
339 | #endif | ||
340 | |||
341 | nSelectors = 0; | ||
342 | totc = 0; | ||
343 | gs = 0; | ||
344 | while (1) { | ||
345 | /*--- Set group start & end marks. --*/ | ||
346 | if (gs >= s->nMTF) | ||
347 | break; | ||
348 | ge = gs + BZ_G_SIZE - 1; | ||
349 | if (ge >= s->nMTF) | ||
350 | ge = s->nMTF-1; | ||
351 | |||
352 | /* | ||
353 | * Calculate the cost of this group as coded | ||
354 | * by each of the coding tables. | ||
355 | */ | ||
356 | for (t = 0; t < nGroups; t++) | ||
357 | cost[t] = 0; | ||
358 | #ifdef FAST_GROUP6 | ||
359 | if (nGroups == 6 && 50 == ge-gs+1) { | ||
360 | /*--- fast track the common case ---*/ | ||
361 | register uint32_t cost01, cost23, cost45; | ||
362 | register uint16_t icv; | ||
363 | cost01 = cost23 = cost45 = 0; | ||
364 | #define BZ_ITER(nn) \ | ||
365 | icv = mtfv[gs+(nn)]; \ | ||
366 | cost01 += s->len_pack[icv][0]; \ | ||
367 | cost23 += s->len_pack[icv][1]; \ | ||
368 | cost45 += s->len_pack[icv][2]; | ||
369 | BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); | ||
370 | BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); | ||
371 | BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); | ||
372 | BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); | ||
373 | BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); | ||
374 | BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); | ||
375 | BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); | ||
376 | BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); | ||
377 | BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); | ||
378 | BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); | ||
379 | #undef BZ_ITER | ||
380 | cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; | ||
381 | cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; | ||
382 | cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; | ||
383 | |||
384 | } else | ||
385 | #endif | ||
386 | { | ||
387 | /*--- slow version which correctly handles all situations ---*/ | ||
388 | for (i = gs; i <= ge; i++) { | ||
389 | uint16_t icv = mtfv[i]; | ||
390 | for (t = 0; t < nGroups; t++) | ||
391 | cost[t] += s->len[t][icv]; | ||
392 | } | ||
393 | } | ||
394 | /* | ||
395 | * Find the coding table which is best for this group, | ||
396 | * and record its identity in the selector table. | ||
397 | */ | ||
398 | bc = 999999999; | ||
399 | bt = -1; | ||
400 | //bc = cost[0]; | ||
401 | //bt = 0; | ||
402 | for (t = 0; t < nGroups; t++) { | ||
403 | if (cost[t] < bc) { | ||
404 | bc = cost[t]; | ||
405 | bt = t; | ||
406 | } | ||
407 | } | ||
408 | totc += bc; | ||
409 | fave[bt]++; | ||
410 | s->selector[nSelectors] = bt; | ||
411 | nSelectors++; | ||
412 | |||
413 | /* | ||
414 | * Increment the symbol frequencies for the selected table. | ||
415 | */ | ||
416 | /* ~0.5% faster compress. +800 bytes */ | ||
417 | #if 0 | ||
418 | if (nGroups == 6 && 50 == ge-gs+1) { | ||
419 | /*--- fast track the common case ---*/ | ||
420 | #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ | ||
421 | BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); | ||
422 | BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); | ||
423 | BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); | ||
424 | BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); | ||
425 | BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); | ||
426 | BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); | ||
427 | BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); | ||
428 | BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); | ||
429 | BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); | ||
430 | BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); | ||
431 | #undef BZ_ITUR | ||
432 | gs = ge+1; | ||
433 | } else | ||
434 | #endif | ||
435 | { | ||
436 | /*--- slow version which correctly handles all situations ---*/ | ||
437 | while (gs <= ge) { | ||
438 | s->rfreq[bt][mtfv[gs]]++; | ||
439 | gs++; | ||
440 | } | ||
441 | /* already is: gs = ge+1; */ | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Recompute the tables based on the accumulated frequencies. | ||
447 | */ | ||
448 | /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See | ||
449 | * comment in huffman.c for details. */ | ||
450 | for (t = 0; t < nGroups; t++) | ||
451 | BZ2_hbMakeCodeLengths(&(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/); | ||
452 | } | ||
453 | |||
454 | AssertH(nGroups < 8, 3002); | ||
455 | AssertH(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003); | ||
456 | |||
457 | /*--- Compute MTF values for the selectors. ---*/ | ||
458 | { | ||
459 | UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; | ||
460 | |||
461 | for (i = 0; i < nGroups; i++) | ||
462 | pos[i] = i; | ||
463 | for (i = 0; i < nSelectors; i++) { | ||
464 | ll_i = s->selector[i]; | ||
465 | j = 0; | ||
466 | tmp = pos[j]; | ||
467 | while (ll_i != tmp) { | ||
468 | j++; | ||
469 | tmp2 = tmp; | ||
470 | tmp = pos[j]; | ||
471 | pos[j] = tmp2; | ||
472 | }; | ||
473 | pos[0] = tmp; | ||
474 | s->selectorMtf[i] = j; | ||
475 | } | ||
476 | }; | ||
477 | |||
478 | /*--- Assign actual codes for the tables. --*/ | ||
479 | for (t = 0; t < nGroups; t++) { | ||
480 | minLen = 32; | ||
481 | maxLen = 0; | ||
482 | for (i = 0; i < alphaSize; i++) { | ||
483 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; | ||
484 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; | ||
485 | } | ||
486 | AssertH(!(maxLen > 17 /*20*/), 3004); | ||
487 | AssertH(!(minLen < 1), 3005); | ||
488 | BZ2_hbAssignCodes(&(s->code[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize); | ||
489 | } | ||
490 | |||
491 | /*--- Transmit the mapping table. ---*/ | ||
492 | { | ||
493 | Bool inUse16[16]; | ||
494 | for (i = 0; i < 16; i++) { | ||
495 | inUse16[i] = False; | ||
496 | for (j = 0; j < 16; j++) | ||
497 | if (s->inUse[i * 16 + j]) | ||
498 | inUse16[i] = True; | ||
499 | } | ||
500 | |||
501 | nBytes = s->numZ; | ||
502 | for (i = 0; i < 16; i++) { | ||
503 | if (inUse16[i]) | ||
504 | bsW(s, 1, 1); | ||
505 | else | ||
506 | bsW(s, 1, 0); | ||
507 | } | ||
508 | |||
509 | for (i = 0; i < 16; i++) { | ||
510 | if (inUse16[i]) { | ||
511 | for (j = 0; j < 16; j++) { | ||
512 | if (s->inUse[i * 16 + j]) | ||
513 | bsW(s, 1, 1); | ||
514 | else | ||
515 | bsW(s, 1, 0); | ||
516 | } | ||
517 | } | ||
518 | } | ||
519 | } | ||
520 | |||
521 | /*--- Now the selectors. ---*/ | ||
522 | nBytes = s->numZ; | ||
523 | bsW(s, 3, nGroups); | ||
524 | bsW(s, 15, nSelectors); | ||
525 | for (i = 0; i < nSelectors; i++) { | ||
526 | for (j = 0; j < s->selectorMtf[i]; j++) | ||
527 | bsW(s, 1, 1); | ||
528 | bsW(s, 1, 0); | ||
529 | } | ||
530 | |||
531 | /*--- Now the coding tables. ---*/ | ||
532 | nBytes = s->numZ; | ||
533 | |||
534 | for (t = 0; t < nGroups; t++) { | ||
535 | int32_t curr = s->len[t][0]; | ||
536 | bsW(s, 5, curr); | ||
537 | for (i = 0; i < alphaSize; i++) { | ||
538 | while (curr < s->len[t][i]) { bsW(s, 2, 2); curr++; /* 10 */ }; | ||
539 | while (curr > s->len[t][i]) { bsW(s, 2, 3); curr--; /* 11 */ }; | ||
540 | bsW(s, 1, 0); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | /*--- And finally, the block data proper ---*/ | ||
545 | nBytes = s->numZ; | ||
546 | selCtr = 0; | ||
547 | gs = 0; | ||
548 | while (1) { | ||
549 | if (gs >= s->nMTF) | ||
550 | break; | ||
551 | ge = gs + BZ_G_SIZE - 1; | ||
552 | if (ge >= s->nMTF) | ||
553 | ge = s->nMTF-1; | ||
554 | AssertH(s->selector[selCtr] < nGroups, 3006); | ||
555 | |||
556 | /* Costs 1300 bytes and is _slower_ (on Intel Core 2) */ | ||
557 | #if 0 | ||
558 | if (nGroups == 6 && 50 == ge-gs+1) { | ||
559 | /*--- fast track the common case ---*/ | ||
560 | uint16_t mtfv_i; | ||
561 | UChar* s_len_sel_selCtr = &(s->len[s->selector[selCtr]][0]); | ||
562 | int32_t* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]); | ||
563 | #define BZ_ITAH(nn) \ | ||
564 | mtfv_i = mtfv[gs+(nn)]; \ | ||
565 | bsW(s, s_len_sel_selCtr[mtfv_i], s_code_sel_selCtr[mtfv_i]) | ||
566 | BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); | ||
567 | BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); | ||
568 | BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); | ||
569 | BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); | ||
570 | BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); | ||
571 | BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); | ||
572 | BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); | ||
573 | BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); | ||
574 | BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); | ||
575 | BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); | ||
576 | #undef BZ_ITAH | ||
577 | gs = ge+1; | ||
578 | } else | ||
579 | #endif | ||
580 | { | ||
581 | /*--- slow version which correctly handles all situations ---*/ | ||
582 | /* code is bit bigger, but moves multiply out of the loop */ | ||
583 | UChar* s_len_sel_selCtr = &(s->len [s->selector[selCtr]][0]); | ||
584 | int32_t* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]); | ||
585 | while (gs <= ge) { | ||
586 | bsW(s, | ||
587 | s_len_sel_selCtr[mtfv[gs]], | ||
588 | s_code_sel_selCtr[mtfv[gs]] | ||
589 | ); | ||
590 | gs++; | ||
591 | } | ||
592 | /* already is: gs = ge+1; */ | ||
593 | } | ||
594 | selCtr++; | ||
595 | } | ||
596 | AssertH(selCtr == nSelectors, 3007); | ||
597 | } | ||
598 | |||
599 | |||
600 | /*---------------------------------------------------*/ | ||
601 | static | ||
602 | void BZ2_compressBlock(EState* s, Bool is_last_block) | ||
603 | { | ||
604 | if (s->nblock > 0) { | ||
605 | BZ_FINALISE_CRC(s->blockCRC); | ||
606 | s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); | ||
607 | s->combinedCRC ^= s->blockCRC; | ||
608 | if (s->blockNo > 1) | ||
609 | s->numZ = 0; | ||
610 | |||
611 | BZ2_blockSort(s); | ||
612 | } | ||
613 | |||
614 | s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); | ||
615 | |||
616 | /*-- If this is the first block, create the stream header. --*/ | ||
617 | if (s->blockNo == 1) { | ||
618 | BZ2_bsInitWrite(s); | ||
619 | /*bsPutUChar(s, BZ_HDR_B);*/ | ||
620 | /*bsPutUChar(s, BZ_HDR_Z);*/ | ||
621 | /*bsPutUChar(s, BZ_HDR_h);*/ | ||
622 | /*bsPutUChar(s, (UChar)(BZ_HDR_0 + s->blockSize100k));*/ | ||
623 | bsPutU32(s, BZ_HDR_BZh0 + s->blockSize100k); | ||
624 | } | ||
625 | |||
626 | if (s->nblock > 0) { | ||
627 | /*bsPutUChar(s, 0x31);*/ | ||
628 | /*bsPutUChar(s, 0x41);*/ | ||
629 | /*bsPutUChar(s, 0x59);*/ | ||
630 | /*bsPutUChar(s, 0x26);*/ | ||
631 | bsPutU32(s, 0x31415926); | ||
632 | bsPutUChar(s, 0x53); | ||
633 | bsPutUChar(s, 0x59); | ||
634 | |||
635 | /*-- Now the block's CRC, so it is in a known place. --*/ | ||
636 | bsPutU32(s, s->blockCRC); | ||
637 | |||
638 | /* | ||
639 | * Now a single bit indicating (non-)randomisation. | ||
640 | * As of version 0.9.5, we use a better sorting algorithm | ||
641 | * which makes randomisation unnecessary. So always set | ||
642 | * the randomised bit to 'no'. Of course, the decoder | ||
643 | * still needs to be able to handle randomised blocks | ||
644 | * so as to maintain backwards compatibility with | ||
645 | * older versions of bzip2. | ||
646 | */ | ||
647 | bsW(s, 1, 0); | ||
648 | |||
649 | bsW(s, 24, s->origPtr); | ||
650 | generateMTFValues(s); | ||
651 | sendMTFValues(s); | ||
652 | } | ||
653 | |||
654 | /*-- If this is the last block, add the stream trailer. --*/ | ||
655 | if (is_last_block) { | ||
656 | /*bsPutUChar(s, 0x17);*/ | ||
657 | /*bsPutUChar(s, 0x72);*/ | ||
658 | /*bsPutUChar(s, 0x45);*/ | ||
659 | /*bsPutUChar(s, 0x38);*/ | ||
660 | bsPutU32(s, 0x17724538); | ||
661 | bsPutUChar(s, 0x50); | ||
662 | bsPutUChar(s, 0x90); | ||
663 | bsPutU32(s, s->combinedCRC); | ||
664 | bsFinishWrite(s); | ||
665 | } | ||
666 | } | ||
667 | |||
668 | |||
669 | /*-------------------------------------------------------------*/ | ||
670 | /*--- end compress.c ---*/ | ||
671 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/crctable.c b/archival/bz/crctable.c new file mode 100644 index 000000000..dadd372d3 --- /dev/null +++ b/archival/bz/crctable.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Table for doing CRCs ---*/ | ||
9 | /*--- crctable.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* #include "bzlib_private.h" */ | ||
27 | |||
28 | /* | ||
29 | * I think this is an implementation of the AUTODIN-II, | ||
30 | * Ethernet & FDDI 32-bit CRC standard. Vaguely derived | ||
31 | * from code by Rob Warnock, in Section 51 of the | ||
32 | * comp.compression FAQ. | ||
33 | */ | ||
34 | |||
35 | static const uint32_t BZ2_crc32Table[256] = { | ||
36 | 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, | ||
37 | 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, | ||
38 | 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, | ||
39 | 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, | ||
40 | 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, | ||
41 | 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, | ||
42 | 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, | ||
43 | 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, | ||
44 | 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, | ||
45 | 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, | ||
46 | 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, | ||
47 | 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, | ||
48 | 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, | ||
49 | 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, | ||
50 | 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, | ||
51 | 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, | ||
52 | 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, | ||
53 | 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, | ||
54 | 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, | ||
55 | 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, | ||
56 | 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, | ||
57 | 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, | ||
58 | 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, | ||
59 | 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, | ||
60 | 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, | ||
61 | 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, | ||
62 | 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, | ||
63 | 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, | ||
64 | 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, | ||
65 | 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, | ||
66 | 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, | ||
67 | 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, | ||
68 | 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, | ||
69 | 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, | ||
70 | 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, | ||
71 | 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, | ||
72 | 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, | ||
73 | 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, | ||
74 | 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, | ||
75 | 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, | ||
76 | 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, | ||
77 | 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, | ||
78 | 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, | ||
79 | 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, | ||
80 | 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, | ||
81 | 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, | ||
82 | 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, | ||
83 | 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, | ||
84 | 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, | ||
85 | 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, | ||
86 | 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, | ||
87 | 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, | ||
88 | 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, | ||
89 | 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, | ||
90 | 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, | ||
91 | 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, | ||
92 | 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, | ||
93 | 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, | ||
94 | 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, | ||
95 | 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, | ||
96 | 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, | ||
97 | 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, | ||
98 | 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, | ||
99 | 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L | ||
100 | }; | ||
101 | |||
102 | |||
103 | /*-------------------------------------------------------------*/ | ||
104 | /*--- end crctable.c ---*/ | ||
105 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/huffman.c b/archival/bz/huffman.c new file mode 100644 index 000000000..d01af11c2 --- /dev/null +++ b/archival/bz/huffman.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Huffman coding low-level stuff ---*/ | ||
9 | /*--- huffman.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* #include "bzlib_private.h" */ | ||
27 | |||
28 | /*---------------------------------------------------*/ | ||
29 | #define WEIGHTOF(zz0) ((zz0) & 0xffffff00) | ||
30 | #define DEPTHOF(zz1) ((zz1) & 0x000000ff) | ||
31 | #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) | ||
32 | |||
33 | #define ADDWEIGHTS(zw1,zw2) \ | ||
34 | (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ | ||
35 | (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) | ||
36 | |||
37 | #define UPHEAP(z) \ | ||
38 | { \ | ||
39 | int32_t zz, tmp; \ | ||
40 | zz = z; \ | ||
41 | tmp = heap[zz]; \ | ||
42 | while (weight[tmp] < weight[heap[zz >> 1]]) { \ | ||
43 | heap[zz] = heap[zz >> 1]; \ | ||
44 | zz >>= 1; \ | ||
45 | } \ | ||
46 | heap[zz] = tmp; \ | ||
47 | } | ||
48 | |||
49 | #define DOWNHEAP(z) \ | ||
50 | { \ | ||
51 | int32_t zz, yy, tmp; \ | ||
52 | zz = z; tmp = heap[zz]; \ | ||
53 | while (1) { \ | ||
54 | yy = zz << 1; \ | ||
55 | if (yy > nHeap) \ | ||
56 | break; \ | ||
57 | if (yy < nHeap \ | ||
58 | && weight[heap[yy+1]] < weight[heap[yy]]) \ | ||
59 | yy++; \ | ||
60 | if (weight[tmp] < weight[heap[yy]]) \ | ||
61 | break; \ | ||
62 | heap[zz] = heap[yy]; \ | ||
63 | zz = yy; \ | ||
64 | } \ | ||
65 | heap[zz] = tmp; \ | ||
66 | } | ||
67 | |||
68 | |||
69 | /*---------------------------------------------------*/ | ||
70 | static | ||
71 | void BZ2_hbMakeCodeLengths(UChar *len, | ||
72 | int32_t *freq, | ||
73 | int32_t alphaSize, | ||
74 | int32_t maxLen) | ||
75 | { | ||
76 | /* | ||
77 | * Nodes and heap entries run from 1. Entry 0 | ||
78 | * for both the heap and nodes is a sentinel. | ||
79 | */ | ||
80 | int32_t nNodes, nHeap, n1, n2, i, j, k; | ||
81 | Bool tooLong; | ||
82 | |||
83 | int32_t heap [BZ_MAX_ALPHA_SIZE + 2]; | ||
84 | int32_t weight[BZ_MAX_ALPHA_SIZE * 2]; | ||
85 | int32_t parent[BZ_MAX_ALPHA_SIZE * 2]; | ||
86 | |||
87 | for (i = 0; i < alphaSize; i++) | ||
88 | weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; | ||
89 | |||
90 | while (1) { | ||
91 | nNodes = alphaSize; | ||
92 | nHeap = 0; | ||
93 | |||
94 | heap[0] = 0; | ||
95 | weight[0] = 0; | ||
96 | parent[0] = -2; | ||
97 | |||
98 | for (i = 1; i <= alphaSize; i++) { | ||
99 | parent[i] = -1; | ||
100 | nHeap++; | ||
101 | heap[nHeap] = i; | ||
102 | UPHEAP(nHeap); | ||
103 | } | ||
104 | |||
105 | AssertH(nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001); | ||
106 | |||
107 | while (nHeap > 1) { | ||
108 | n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); | ||
109 | n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); | ||
110 | nNodes++; | ||
111 | parent[n1] = parent[n2] = nNodes; | ||
112 | weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); | ||
113 | parent[nNodes] = -1; | ||
114 | nHeap++; | ||
115 | heap[nHeap] = nNodes; | ||
116 | UPHEAP(nHeap); | ||
117 | } | ||
118 | |||
119 | AssertH(nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002); | ||
120 | |||
121 | tooLong = False; | ||
122 | for (i = 1; i <= alphaSize; i++) { | ||
123 | j = 0; | ||
124 | k = i; | ||
125 | while (parent[k] >= 0) { | ||
126 | k = parent[k]; | ||
127 | j++; | ||
128 | } | ||
129 | len[i-1] = j; | ||
130 | if (j > maxLen) | ||
131 | tooLong = True; | ||
132 | } | ||
133 | |||
134 | if (!tooLong) | ||
135 | break; | ||
136 | |||
137 | /* 17 Oct 04: keep-going condition for the following loop used | ||
138 | to be 'i < alphaSize', which missed the last element, | ||
139 | theoretically leading to the possibility of the compressor | ||
140 | looping. However, this count-scaling step is only needed if | ||
141 | one of the generated Huffman code words is longer than | ||
142 | maxLen, which up to and including version 1.0.2 was 20 bits, | ||
143 | which is extremely unlikely. In version 1.0.3 maxLen was | ||
144 | changed to 17 bits, which has minimal effect on compression | ||
145 | ratio, but does mean this scaling step is used from time to | ||
146 | time, enough to verify that it works. | ||
147 | |||
148 | This means that bzip2-1.0.3 and later will only produce | ||
149 | Huffman codes with a maximum length of 17 bits. However, in | ||
150 | order to preserve backwards compatibility with bitstreams | ||
151 | produced by versions pre-1.0.3, the decompressor must still | ||
152 | handle lengths of up to 20. */ | ||
153 | |||
154 | for (i = 1; i <= alphaSize; i++) { | ||
155 | j = weight[i] >> 8; | ||
156 | j = 1 + (j / 2); | ||
157 | weight[i] = j << 8; | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | |||
162 | |||
163 | /*---------------------------------------------------*/ | ||
164 | static | ||
165 | void BZ2_hbAssignCodes(int32_t *code, | ||
166 | UChar *length, | ||
167 | int32_t minLen, | ||
168 | int32_t maxLen, | ||
169 | int32_t alphaSize) | ||
170 | { | ||
171 | int32_t n, vec, i; | ||
172 | |||
173 | vec = 0; | ||
174 | for (n = minLen; n <= maxLen; n++) { | ||
175 | for (i = 0; i < alphaSize; i++) { | ||
176 | if (length[i] == n) { | ||
177 | code[i] = vec; | ||
178 | vec++; | ||
179 | }; | ||
180 | } | ||
181 | vec <<= 1; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | |||
186 | /*-------------------------------------------------------------*/ | ||
187 | /*--- end huffman.c ---*/ | ||
188 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bz/randtable.c b/archival/bz/randtable.c new file mode 100644 index 000000000..8a3c562da --- /dev/null +++ b/archival/bz/randtable.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * bzip2 is written by Julian Seward <jseward@bzip.org>. | ||
3 | * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>. | ||
4 | * See README and LICENSE files in this directory for more information. | ||
5 | */ | ||
6 | |||
7 | /*-------------------------------------------------------------*/ | ||
8 | /*--- Table for randomising repetitive blocks ---*/ | ||
9 | /*--- randtable.c ---*/ | ||
10 | /*-------------------------------------------------------------*/ | ||
11 | |||
12 | /* ------------------------------------------------------------------ | ||
13 | This file is part of bzip2/libbzip2, a program and library for | ||
14 | lossless, block-sorting data compression. | ||
15 | |||
16 | bzip2/libbzip2 version 1.0.4 of 20 December 2006 | ||
17 | Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org> | ||
18 | |||
19 | Please read the WARNING, DISCLAIMER and PATENTS sections in the | ||
20 | README file. | ||
21 | |||
22 | This program is released under the terms of the license contained | ||
23 | in the file LICENSE. | ||
24 | ------------------------------------------------------------------ */ | ||
25 | |||
26 | /* #include "bzlib_private.h" */ | ||
27 | |||
28 | static const int32_t BZ2_rNums[512] = { | ||
29 | 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, | ||
30 | 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, | ||
31 | 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, | ||
32 | 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, | ||
33 | 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, | ||
34 | 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, | ||
35 | 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, | ||
36 | 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, | ||
37 | 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, | ||
38 | 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, | ||
39 | 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, | ||
40 | 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, | ||
41 | 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, | ||
42 | 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, | ||
43 | 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, | ||
44 | 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, | ||
45 | 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, | ||
46 | 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, | ||
47 | 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, | ||
48 | 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, | ||
49 | 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, | ||
50 | 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, | ||
51 | 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, | ||
52 | 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, | ||
53 | 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, | ||
54 | 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, | ||
55 | 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, | ||
56 | 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, | ||
57 | 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, | ||
58 | 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, | ||
59 | 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, | ||
60 | 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, | ||
61 | 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, | ||
62 | 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, | ||
63 | 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, | ||
64 | 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, | ||
65 | 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, | ||
66 | 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, | ||
67 | 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, | ||
68 | 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, | ||
69 | 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, | ||
70 | 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, | ||
71 | 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, | ||
72 | 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, | ||
73 | 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, | ||
74 | 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, | ||
75 | 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, | ||
76 | 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, | ||
77 | 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, | ||
78 | 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, | ||
79 | 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, | ||
80 | 936, 638 | ||
81 | }; | ||
82 | |||
83 | /*-------------------------------------------------------------*/ | ||
84 | /*--- end randtable.c ---*/ | ||
85 | /*-------------------------------------------------------------*/ | ||
diff --git a/archival/bzip2.c b/archival/bzip2.c new file mode 100644 index 000000000..04478eecc --- /dev/null +++ b/archival/bzip2.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
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 | |||
12 | /* This buys 6% speed for nearly 4k code */ | ||
13 | /*#define FAST_GROUP6 1*/ | ||
14 | |||
15 | #include "bz/bzlib.h" | ||
16 | |||
17 | #include "bz/bzlib_private.h" | ||
18 | |||
19 | #include "bz/blocksort.c" | ||
20 | #include "bz/bzlib.c" | ||
21 | #include "bz/compress.c" | ||
22 | #include "bz/crctable.c" | ||
23 | #include "bz/huffman.c" | ||
24 | #include "bz/randtable.c" | ||
25 | |||
26 | /* No point in being shy and having very small buffer here. | ||
27 | * bzip2 internal buffers are much bigger anyway, hundreds of kbytes. | ||
28 | * If iobuf is several pages long, malloc() may use mmap, | ||
29 | * making iobuf is page aligned and thus (maybe) have one memcpy less | ||
30 | * if kernel is clever enough. | ||
31 | */ | ||
32 | enum { | ||
33 | IOBUF_SIZE = 8 * 1024 | ||
34 | }; | ||
35 | |||
36 | /* Returns: | ||
37 | * <0 on write errors (examine errno), | ||
38 | * >0 on short writes (errno == 0) | ||
39 | * 0 no error (entire input consume, gimme more) | ||
40 | * on "impossible" errors (internal bzip2 compressor bug) dies | ||
41 | */ | ||
42 | static | ||
43 | ssize_t bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, void *wbuf) | ||
44 | { | ||
45 | int n, n2, ret; | ||
46 | |||
47 | /* if (len == 0) return 0; */ | ||
48 | |||
49 | strm->avail_in = rlen; | ||
50 | strm->next_in = rbuf; | ||
51 | while (1) { | ||
52 | strm->avail_out = IOBUF_SIZE; | ||
53 | strm->next_out = wbuf; | ||
54 | |||
55 | ret = BZ2_bzCompress(strm, BZ_RUN); | ||
56 | if (ret != BZ_RUN_OK) | ||
57 | bb_error_msg_and_die("internal error %d", ret); | ||
58 | |||
59 | n = IOBUF_SIZE - strm->avail_out; | ||
60 | if (n) { | ||
61 | /* short reads must have errno == 0 */ | ||
62 | errno = 0; | ||
63 | n2 = full_write(STDOUT_FILENO, wbuf, n); | ||
64 | if (n2 != n) | ||
65 | return n2 ? n2 : 1; | ||
66 | } | ||
67 | |||
68 | if (strm->avail_in == 0) | ||
69 | return 0; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | |||
74 | /*---------------------------------------------------*/ | ||
75 | static | ||
76 | USE_DESKTOP(long long) int bz_write_tail(bz_stream *strm, void *wbuf) | ||
77 | { | ||
78 | int n, n2, ret; | ||
79 | USE_DESKTOP(long long) int total; | ||
80 | |||
81 | total = -1; | ||
82 | while (1) { | ||
83 | strm->avail_out = IOBUF_SIZE; | ||
84 | strm->next_out = wbuf; | ||
85 | |||
86 | ret = BZ2_bzCompress(strm, BZ_FINISH); | ||
87 | if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) | ||
88 | bb_error_msg_and_die("internal error %d", ret); | ||
89 | |||
90 | n = IOBUF_SIZE - strm->avail_out; | ||
91 | if (n) { | ||
92 | n2 = full_write(STDOUT_FILENO, wbuf, n); | ||
93 | if (n2 != n) | ||
94 | goto err; | ||
95 | } | ||
96 | |||
97 | if (ret == BZ_STREAM_END) | ||
98 | break; | ||
99 | } | ||
100 | |||
101 | total = 0 USE_DESKTOP( + strm->total_out ); | ||
102 | err: | ||
103 | BZ2_bzCompressEnd(strm); | ||
104 | return total; | ||
105 | } | ||
106 | |||
107 | |||
108 | static | ||
109 | USE_DESKTOP(long long) int compressStream(void) | ||
110 | { | ||
111 | USE_DESKTOP(long long) int total; | ||
112 | ssize_t count; | ||
113 | bz_stream bzs; /* it's small */ | ||
114 | #define strm (&bzs) | ||
115 | char *iobuf; | ||
116 | #define rbuf iobuf | ||
117 | #define wbuf (iobuf + IOBUF_SIZE) | ||
118 | |||
119 | iobuf = xmalloc(2 * IOBUF_SIZE); | ||
120 | |||
121 | BZ2_bzCompressInit(strm, 9 /*blockSize100k*/); | ||
122 | |||
123 | while (1) { | ||
124 | count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE); | ||
125 | if (count < 0) | ||
126 | bb_perror_msg("read error"); | ||
127 | if (count <= 0) | ||
128 | break; | ||
129 | count = bz_write(strm, rbuf, count, wbuf); | ||
130 | if (count) { | ||
131 | bb_perror_msg(count < 0 ? "write error" : "short write"); | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | total = bz_write_tail(strm, wbuf); | ||
137 | free(iobuf); | ||
138 | /* we had no error _only_ if count == 0 */ | ||
139 | return count == 0 ? total : -1; | ||
140 | } | ||
141 | |||
142 | static | ||
143 | char* make_new_name_bzip2(char *filename) | ||
144 | { | ||
145 | return xasprintf("%s.bz2", filename); | ||
146 | } | ||
147 | |||
148 | int bzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
149 | int bzip2_main(int argc, char **argv) | ||
150 | { | ||
151 | unsigned opt; | ||
152 | |||
153 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | ||
154 | opt = getopt32(argv, "cfv" USE_BUNZIP2("d") "q123456789" ); | ||
155 | #if ENABLE_BUNZIP2 /* bunzip2_main may not be visible... */ | ||
156 | if (opt & 0x8) // -d | ||
157 | return bunzip2_main(argc, argv); | ||
158 | #endif | ||
159 | option_mask32 &= 0x7; /* ignore -q, -0..9 */ | ||
160 | //if (opt & 0x1) // -c | ||
161 | //if (opt & 0x2) // -f | ||
162 | //if (opt & 0x4) // -v | ||
163 | argv += optind; | ||
164 | |||
165 | return bbunpack(argv, make_new_name_bzip2, compressStream); | ||
166 | } | ||
diff --git a/archival/gzip.c b/archival/gzip.c index bc7502e70..00299b17c 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -2032,15 +2032,14 @@ int gzip_main(int argc, char **argv) | |||
2032 | 2032 | ||
2033 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | 2033 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
2034 | opt = getopt32(argv, "cfv" USE_GUNZIP("d") "q123456789" ); | 2034 | opt = getopt32(argv, "cfv" USE_GUNZIP("d") "q123456789" ); |
2035 | option_mask32 &= 0x7; /* Clear -d, ignore -q, -0..9 */ | ||
2036 | //if (opt & 0x1) // -c | ||
2037 | //if (opt & 0x2) // -f | ||
2038 | //if (opt & 0x4) // -v | ||
2039 | #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ | 2035 | #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ |
2040 | if (opt & 0x8) { // -d | 2036 | if (opt & 0x8) // -d |
2041 | return gunzip_main(argc, argv); | 2037 | return gunzip_main(argc, argv); |
2042 | } | ||
2043 | #endif | 2038 | #endif |
2039 | option_mask32 &= 0x7; /* ignore -q, -0..9 */ | ||
2040 | //if (opt & 0x1) // -c | ||
2041 | //if (opt & 0x2) // -f | ||
2042 | //if (opt & 0x4) // -v | ||
2044 | argv += optind; | 2043 | argv += optind; |
2045 | 2044 | ||
2046 | PTR_TO_GLOBALS = xzalloc(sizeof(struct globals) + sizeof(struct globals2)) | 2045 | PTR_TO_GLOBALS = xzalloc(sizeof(struct globals) + sizeof(struct globals2)) |
diff --git a/archival/libunarchive/Kbuild b/archival/libunarchive/Kbuild index a58a84f4b..1bc054a96 100644 --- a/archival/libunarchive/Kbuild +++ b/archival/libunarchive/Kbuild | |||
@@ -28,8 +28,6 @@ lib-y:= \ | |||
28 | find_list_entry.o \ | 28 | find_list_entry.o \ |
29 | init_handle.o | 29 | init_handle.o |
30 | 30 | ||
31 | GUNZIP_FILES:= decompress_unzip.o | ||
32 | |||
33 | DPKG_FILES:= \ | 31 | DPKG_FILES:= \ |
34 | get_header_ar.o \ | 32 | get_header_ar.o \ |
35 | unpack_ar_archive.o \ | 33 | unpack_ar_archive.o \ |
@@ -51,19 +49,19 @@ lib-$(CONFIG_UNLZMA) += decompress_unlzma.o | |||
51 | lib-$(CONFIG_CPIO) += get_header_cpio.o | 49 | lib-$(CONFIG_CPIO) += get_header_cpio.o |
52 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) | 50 | lib-$(CONFIG_DPKG) += $(DPKG_FILES) |
53 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) | 51 | lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) |
54 | lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += $(GUNZIP_FILES) get_header_tar_gz.o | 52 | lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += decompress_unzip.o get_header_tar_gz.o |
55 | lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o | 53 | lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o |
56 | lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o | 54 | lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o |
57 | lib-$(CONFIG_GUNZIP) += $(GUNZIP_FILES) | 55 | lib-$(CONFIG_GUNZIP) += decompress_unzip.o |
58 | lib-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o | 56 | lib-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o |
59 | lib-$(CONFIG_RPM2CPIO) += $(GUNZIP_FILES) get_header_cpio.o | 57 | lib-$(CONFIG_RPM2CPIO) += decompress_unzip.o get_header_cpio.o |
60 | lib-$(CONFIG_RPM) += $(GUNZIP_FILES) get_header_cpio.o | 58 | lib-$(CONFIG_RPM) += decompress_unzip.o get_header_cpio.o |
61 | lib-$(CONFIG_FEATURE_RPM_BZ2) += decompress_bunzip2.o | 59 | lib-$(CONFIG_FEATURE_RPM_BZ2) += decompress_bunzip2.o |
62 | lib-$(CONFIG_TAR) += get_header_tar.o | 60 | lib-$(CONFIG_TAR) += get_header_tar.o |
63 | lib-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o | 61 | lib-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o |
64 | lib-$(CONFIG_FEATURE_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o | 62 | lib-$(CONFIG_FEATURE_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o |
65 | lib-$(CONFIG_FEATURE_TAR_GZIP) += $(GUNZIP_FILES) get_header_tar_gz.o | 63 | lib-$(CONFIG_FEATURE_TAR_GZIP) += decompress_unzip.o get_header_tar_gz.o |
66 | lib-$(CONFIG_FEATURE_TAR_COMPRESS) += decompress_uncompress.o | 64 | lib-$(CONFIG_FEATURE_TAR_COMPRESS) += decompress_uncompress.o |
67 | lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o | 65 | lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o |
68 | lib-$(CONFIG_UNZIP) += $(GUNZIP_FILES) | 66 | lib-$(CONFIG_UNZIP) += decompress_unzip.o |
69 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o | 67 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o |
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 52be6b25d..0572bee68 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c | |||
@@ -323,7 +323,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
323 | } while (--i); | 323 | } while (--i); |
324 | if (c[0] == n) { /* null input - all zero length codes */ | 324 | if (c[0] == n) { /* null input - all zero length codes */ |
325 | *m = 0; | 325 | *m = 0; |
326 | return 2; | 326 | return 2; |
327 | } | 327 | } |
328 | 328 | ||
329 | /* Find minimum and maximum length, bound *m by those */ | 329 | /* Find minimum and maximum length, bound *m by those */ |
diff --git a/include/applets.h b/include/applets.h index ceab00334..29a5d09e3 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -88,6 +88,7 @@ USE_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER)) | |||
88 | //USE_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER)) | 88 | //USE_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER)) |
89 | USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 89 | USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
90 | USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat)) | 90 | USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat)) |
91 | USE_BZIP2(APPLET(bzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | ||
91 | USE_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 92 | USE_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
92 | USE_CAT(APPLET_NOFORK(cat, cat, _BB_DIR_BIN, _BB_SUID_NEVER, cat)) | 93 | USE_CAT(APPLET_NOFORK(cat, cat, _BB_DIR_BIN, _BB_SUID_NEVER, cat)) |
93 | USE_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER)) | 94 | USE_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER)) |
diff --git a/include/libbb.h b/include/libbb.h index be548a306..af385e232 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -709,6 +709,9 @@ int chown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
709 | #if ENABLE_GUNZIP | 709 | #if ENABLE_GUNZIP |
710 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 710 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
711 | #endif | 711 | #endif |
712 | #if ENABLE_BUNZIP2 | ||
713 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
714 | #endif | ||
712 | int bbunpack(char **argv, | 715 | int bbunpack(char **argv, |
713 | char* (*make_new_name)(char *filename), | 716 | char* (*make_new_name)(char *filename), |
714 | USE_DESKTOP(long long) int (*unpacker)(void) | 717 | USE_DESKTOP(long long) int (*unpacker)(void) |
diff --git a/include/platform.h b/include/platform.h index 53d72829f..edb0f8ab0 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -54,7 +54,8 @@ | |||
54 | # define ATTRIBUTE_ALIGNED(m) __attribute__ ((__aligned__(m))) | 54 | # define ATTRIBUTE_ALIGNED(m) __attribute__ ((__aligned__(m))) |
55 | # if __GNUC_PREREQ (3,0) | 55 | # if __GNUC_PREREQ (3,0) |
56 | # define ALWAYS_INLINE __attribute__ ((always_inline)) inline | 56 | # define ALWAYS_INLINE __attribute__ ((always_inline)) inline |
57 | # define NOINLINE __attribute__((noinline)) | 57 | /* I've seen a toolchain where I needed __noinline__ instead of noinline */ |
58 | # define NOINLINE __attribute__((__noinline__)) | ||
58 | # if !ENABLE_WERROR | 59 | # if !ENABLE_WERROR |
59 | # define ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) | 60 | # define ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) |
60 | # define ATTRIBUTE_UNUSED_RESULT __attribute__ ((warn_unused_result)) | 61 | # define ATTRIBUTE_UNUSED_RESULT __attribute__ ((warn_unused_result)) |
@@ -63,7 +64,8 @@ | |||
63 | # define ATTRIBUTE_UNUSED_RESULT /* n/a */ | 64 | # define ATTRIBUTE_UNUSED_RESULT /* n/a */ |
64 | # endif | 65 | # endif |
65 | # else | 66 | # else |
66 | # define ALWAYS_INLINE inline | 67 | # define ALWAYS_INLINE inline /* n/a */ |
68 | # define NOINLINE /* n/a */ | ||
67 | # define ATTRIBUTE_DEPRECATED /* n/a */ | 69 | # define ATTRIBUTE_DEPRECATED /* n/a */ |
68 | # define ATTRIBUTE_UNUSED_RESULT /* n/a */ | 70 | # define ATTRIBUTE_UNUSED_RESULT /* n/a */ |
69 | # endif | 71 | # endif |
diff --git a/include/usage.h b/include/usage.h index b53820d7b..4c697d380 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -127,6 +127,16 @@ | |||
127 | " -c Write output to standard output\n" \ | 127 | " -c Write output to standard output\n" \ |
128 | " -f Force" | 128 | " -f Force" |
129 | 129 | ||
130 | #define bzip2_trivial_usage \ | ||
131 | "[OPTION]... [FILE]..." | ||
132 | #define bzip2_full_usage \ | ||
133 | "Compress FILE(s) with bzip2 algorithm.\n" \ | ||
134 | "When FILE is '-' or unspecified, reads standard input. Implies -c." \ | ||
135 | "\n\nOptions:\n" \ | ||
136 | " -c Write output to standard output instead of FILE.bz\n" \ | ||
137 | " -d Decompress\n" \ | ||
138 | " -f Force" | ||
139 | |||
130 | #define busybox_notes_usage \ | 140 | #define busybox_notes_usage \ |
131 | "Hello world!\n" | 141 | "Hello world!\n" |
132 | 142 | ||
@@ -1201,7 +1211,7 @@ | |||
1201 | "Uncompress FILE (or standard input if FILE is '-')" \ | 1211 | "Uncompress FILE (or standard input if FILE is '-')" \ |
1202 | "\n\nOptions:\n" \ | 1212 | "\n\nOptions:\n" \ |
1203 | " -c Write output to standard output\n" \ | 1213 | " -c Write output to standard output\n" \ |
1204 | " -f Force read when source is a terminal\n" \ | 1214 | " -f Force\n" \ |
1205 | " -t Test compressed file integrity" | 1215 | " -t Test compressed file integrity" |
1206 | #define gunzip_example_usage \ | 1216 | #define gunzip_example_usage \ |
1207 | "$ ls -la /tmp/BusyBox*\n" \ | 1217 | "$ ls -la /tmp/BusyBox*\n" \ |
@@ -1218,7 +1228,7 @@ | |||
1218 | "\n\nOptions:\n" \ | 1228 | "\n\nOptions:\n" \ |
1219 | " -c Write output to standard output instead of FILE.gz\n" \ | 1229 | " -c Write output to standard output instead of FILE.gz\n" \ |
1220 | " -d Decompress\n" \ | 1230 | " -d Decompress\n" \ |
1221 | " -f Force write when destination is a terminal" | 1231 | " -f Force" |
1222 | #define gzip_example_usage \ | 1232 | #define gzip_example_usage \ |
1223 | "$ ls -la /tmp/busybox*\n" \ | 1233 | "$ ls -la /tmp/busybox*\n" \ |
1224 | "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/busybox.tar\n" \ | 1234 | "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/busybox.tar\n" \ |