1 |
/* vi: set sw=4 ts=4: */ |
/* vi: set sw=4 ts=4: */ |
|
#include "libbb.h" |
|
|
|
|
2 |
/* uncompress for busybox -- (c) 2002 Robert Griebl |
/* uncompress for busybox -- (c) 2002 Robert Griebl |
3 |
* |
* |
4 |
* based on the original compress42.c source |
* based on the original compress42.c source |
5 |
* (see disclaimer below) |
* (see disclaimer below) |
6 |
*/ |
*/ |
7 |
|
|
|
|
|
8 |
/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992. |
/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992. |
9 |
* |
* |
10 |
* Authors: |
* Authors: |
23 |
* [... History snipped ...] |
* [... History snipped ...] |
24 |
* |
* |
25 |
*/ |
*/ |
26 |
#include <stdio.h> |
|
27 |
#include <string.h> |
#include "libbb.h" |
28 |
#include <unistd.h> |
#include "unarchive.h" |
29 |
|
|
30 |
|
|
31 |
/* Default input buffer size */ |
/* Default input buffer size */ |
32 |
#define IBUFSIZ 2048 |
#define IBUFSIZ 2048 |
35 |
#define OBUFSIZ 2048 |
#define OBUFSIZ 2048 |
36 |
|
|
37 |
/* Defines for third byte of header */ |
/* Defines for third byte of header */ |
38 |
#define MAGIC_1 (char_type)'\037' /* First byte of compressed file */ |
#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ |
39 |
#define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */ |
/* Masks 0x20 and 0x40 are free. */ |
40 |
#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ |
/* I think 0x20 should mean that there is */ |
41 |
/* Masks 0x20 and 0x40 are free. */ |
/* a fourth header byte (for expansion). */ |
42 |
/* I think 0x20 should mean that there is */ |
#define BLOCK_MODE 0x80 /* Block compression if table is full and */ |
43 |
/* a fourth header byte (for expansion). */ |
/* compression rate is dropping flush tables */ |
44 |
#define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ |
/* the next two codes should not be changed lightly, as they must not */ |
45 |
/* compression rate is dropping flush tables */ |
/* lie within the contiguous general code space. */ |
46 |
/* the next two codes should not be changed lightly, as they must not */ |
#define FIRST 257 /* first free entry */ |
47 |
/* lie within the contiguous general code space. */ |
#define CLEAR 256 /* table clear output code */ |
|
#define FIRST 257 /* first free entry */ |
|
|
#define CLEAR 256 /* table clear output code */ |
|
48 |
|
|
49 |
#define INIT_BITS 9 /* initial number of bits/code */ |
#define INIT_BITS 9 /* initial number of bits/code */ |
50 |
|
|
51 |
|
|
52 |
/* machine variants which require cc -Dmachine: pdp11, z8000, DOS */ |
/* machine variants which require cc -Dmachine: pdp11, z8000, DOS */ |
53 |
#define FAST |
#define HBITS 17 /* 50% occupancy */ |
54 |
|
#define HSIZE (1<<HBITS) |
55 |
#define HBITS 17 /* 50% occupancy */ |
#define HMASK (HSIZE-1) /* unused */ |
56 |
#define HSIZE (1<<HBITS) |
#define HPRIME 9941 /* unused */ |
57 |
#define HMASK (HSIZE-1) |
#define BITS 16 |
58 |
#define HPRIME 9941 |
#define BITS_STR "16" |
59 |
#define BITS 16 |
#undef MAXSEG_64K /* unused */ |
60 |
#undef MAXSEG_64K |
#define MAXCODE(n) (1L << (n)) |
61 |
#define MAXCODE(n) (1L << (n)) |
|
62 |
|
#define htabof(i) htab[i] |
63 |
#define htabof(i) htab[i] |
#define codetabof(i) codetab[i] |
64 |
#define codetabof(i) codetab[i] |
#define tab_prefixof(i) codetabof(i) |
65 |
#define tab_prefixof(i) codetabof(i) |
#define tab_suffixof(i) ((unsigned char *)(htab))[i] |
66 |
#define tab_suffixof(i) ((unsigned char *)(htab))[i] |
#define de_stack ((unsigned char *)&(htab[HSIZE-1])) |
67 |
#define de_stack ((unsigned char *)&(htab[HSIZE-1])) |
#define clear_tab_prefixof() memset(codetab, 0, 256) |
|
#define clear_htab() memset(htab, -1, HSIZE) |
|
|
#define clear_tab_prefixof() memset(codetab, 0, 256); |
|
|
|
|
68 |
|
|
69 |
/* |
/* |
70 |
* Decompress stdin to stdout. This routine adapts to the codes in the |
* Decompress stdin to stdout. This routine adapts to the codes in the |
71 |
* file building the "string" table on-the-fly; requiring no table to |
* file building the "string" table on-the-fly; requiring no table to |
72 |
* be stored in the compressed file. The tables used herein are shared |
* be stored in the compressed file. |
|
* with those of the compress() routine. See the definitions above. |
|
73 |
*/ |
*/ |
74 |
|
|
75 |
USE_DESKTOP(long long) int |
USE_DESKTOP(long long) int FAST_FUNC |
76 |
uncompress(int fd_in, int fd_out) |
unpack_Z_stream(int fd_in, int fd_out) |
77 |
{ |
{ |
78 |
USE_DESKTOP(long long total_written = 0;) |
USE_DESKTOP(long long total_written = 0;) |
79 |
|
USE_DESKTOP(long long) int retval = -1; |
80 |
unsigned char *stackp; |
unsigned char *stackp; |
81 |
long int code; |
long code; |
82 |
int finchar; |
int finchar; |
83 |
long int oldcode; |
long oldcode; |
84 |
long int incode; |
long incode; |
85 |
int inbits; |
int inbits; |
86 |
int posbits; |
int posbits; |
87 |
int outpos; |
int outpos; |
88 |
int insize; |
int insize; |
89 |
int bitmask; |
int bitmask; |
90 |
long int free_ent; |
long free_ent; |
91 |
long int maxcode; |
long maxcode; |
92 |
long int maxmaxcode; |
long maxmaxcode; |
93 |
int n_bits; |
int n_bits; |
94 |
int rsize = 0; |
int rsize = 0; |
95 |
RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64); |
unsigned char *inbuf; /* were eating insane amounts of stack - */ |
96 |
RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048); |
unsigned char *outbuf; /* bad for some embedded targets */ |
97 |
unsigned char htab[HSIZE]; |
unsigned char *htab; |
98 |
unsigned short codetab[HSIZE]; |
unsigned short *codetab; |
99 |
|
|
100 |
/* Hmm, these were statics - why?! */ |
/* Hmm, these were statics - why?! */ |
101 |
/* user settable max # bits/code */ |
/* user settable max # bits/code */ |
103 |
/* block compress mode -C compatible with 2.0 */ |
/* block compress mode -C compatible with 2.0 */ |
104 |
int block_mode; /* = BLOCK_MODE; */ |
int block_mode; /* = BLOCK_MODE; */ |
105 |
|
|
106 |
memset(inbuf, 0, IBUFSIZ + 64); |
inbuf = xzalloc(IBUFSIZ + 64); |
107 |
memset(outbuf, 0, OBUFSIZ + 2048); |
outbuf = xzalloc(OBUFSIZ + 2048); |
108 |
|
htab = xzalloc(HSIZE); /* wsn't zeroed out before, maybe can xmalloc? */ |
109 |
|
codetab = xzalloc(HSIZE * sizeof(codetab[0])); |
110 |
|
|
111 |
insize = 0; |
insize = 0; |
112 |
|
|
114 |
* to do some cleanup (e.g. delete incomplete unpacked file etc) */ |
* to do some cleanup (e.g. delete incomplete unpacked file etc) */ |
115 |
if (full_read(fd_in, inbuf, 1) != 1) { |
if (full_read(fd_in, inbuf, 1) != 1) { |
116 |
bb_error_msg("short read"); |
bb_error_msg("short read"); |
117 |
return -1; |
goto err; |
118 |
} |
} |
119 |
|
|
120 |
maxbits = inbuf[0] & BIT_MASK; |
maxbits = inbuf[0] & BIT_MASK; |
123 |
|
|
124 |
if (maxbits > BITS) { |
if (maxbits > BITS) { |
125 |
bb_error_msg("compressed with %d bits, can only handle " |
bb_error_msg("compressed with %d bits, can only handle " |
126 |
"%d bits", maxbits, BITS); |
BITS_STR" bits", maxbits); |
127 |
return -1; |
goto err; |
128 |
} |
} |
129 |
|
|
130 |
n_bits = INIT_BITS; |
n_bits = INIT_BITS; |
138 |
free_ent = ((block_mode) ? FIRST : 256); |
free_ent = ((block_mode) ? FIRST : 256); |
139 |
|
|
140 |
/* As above, initialize the first 256 entries in the table. */ |
/* As above, initialize the first 256 entries in the table. */ |
141 |
clear_tab_prefixof(); |
/*clear_tab_prefixof(); - done by xzalloc */ |
142 |
|
|
143 |
for (code = 255; code >= 0; --code) { |
for (code = 255; code >= 0; --code) { |
144 |
tab_suffixof(code) = (unsigned char) code; |
tab_suffixof(code) = (unsigned char) code; |
230 |
insize, posbits, p[-1], p[0], p[1], p[2], p[3], |
insize, posbits, p[-1], p[0], p[1], p[2], p[3], |
231 |
(posbits & 07)); |
(posbits & 07)); |
232 |
bb_error_msg("uncompress: corrupt input"); |
bb_error_msg("uncompress: corrupt input"); |
233 |
return -1; |
goto err; |
234 |
} |
} |
235 |
|
|
236 |
*--stackp = (unsigned char) finchar; |
*--stackp = (unsigned char) finchar; |
238 |
} |
} |
239 |
|
|
240 |
/* Generate output characters in reverse order */ |
/* Generate output characters in reverse order */ |
241 |
while ((long int) code >= (long int) 256) { |
while ((long) code >= (long) 256) { |
242 |
*--stackp = tab_suffixof(code); |
*--stackp = tab_suffixof(code); |
243 |
code = tab_prefixof(code); |
code = tab_prefixof(code); |
244 |
} |
} |
297 |
USE_DESKTOP(total_written += outpos;) |
USE_DESKTOP(total_written += outpos;) |
298 |
} |
} |
299 |
|
|
300 |
RELEASE_CONFIG_BUFFER(inbuf); |
retval = USE_DESKTOP(total_written) + 0; |
301 |
RELEASE_CONFIG_BUFFER(outbuf); |
err: |
302 |
return USE_DESKTOP(total_written) + 0; |
free(inbuf); |
303 |
|
free(outbuf); |
304 |
|
free(htab); |
305 |
|
free(codetab); |
306 |
|
return retval; |
307 |
} |
} |