Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/archival/libunarchive/decompress_uncompress.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/archival/libunarchive/decompress_uncompress.c
r902 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #include "libbb.h" 2 3 … … 6 7 * (see disclaimer below) 7 8 */ 8 9 9 10 10 /* (N)compress42.c - File compression ala IEEE Computer, Mar 1992. … … 26 26 * 27 27 */ 28 #include <stdio.h>29 #include <string.h>30 #include <unistd.h>31 28 32 29 /* Default input buffer size */ … … 37 34 38 35 /* Defines for third byte of header */ 39 #define MAGIC_1 (char_type)'\037' /* First byte of compressed file */ 40 #define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */ 41 #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ 42 /* Masks 0x20 and 0x40 are free. */ 43 /* I think 0x20 should mean that there is */ 44 /* a fourth header byte (for expansion). */ 45 #define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ 46 /* compression rate is dropping flush tables */ 47 /* the next two codes should not be changed lightly, as they must not */ 48 /* lie within the contiguous general code space. */ 49 #define FIRST 257 /* first free entry */ 50 #define CLEAR 256 /* table clear output code */ 51 52 #define INIT_BITS 9 /* initial number of bits/code */ 36 #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ 37 /* Masks 0x20 and 0x40 are free. */ 38 /* I think 0x20 should mean that there is */ 39 /* a fourth header byte (for expansion). */ 40 #define BLOCK_MODE 0x80 /* Block compression if table is full and */ 41 /* compression rate is dropping flush tables */ 42 /* the next two codes should not be changed lightly, as they must not */ 43 /* lie within the contiguous general code space. */ 44 #define FIRST 257 /* first free entry */ 45 #define CLEAR 256 /* table clear output code */ 46 47 #define INIT_BITS 9 /* initial number of bits/code */ 53 48 54 49 55 50 /* machine variants which require cc -Dmachine: pdp11, z8000, DOS */ 56 #define FAST 57 58 #define HBITS 17 /* 50% occupancy */ 59 #define HSIZE (1<<HBITS) 60 #define HMASK (HSIZE-1) 61 #define HPRIME 9941 62 #define BITS 16 63 #undef MAXSEG_64K 64 #define MAXCODE(n) (1L << (n)) 65 66 /* Block compress mode -C compatible with 2.0 */ 67 static int block_mode = BLOCK_MODE; 68 69 /* user settable max # bits/code */ 70 static int maxbits = BITS; 71 72 #define htabof(i) htab[i] 73 #define codetabof(i) codetab[i] 74 #define tab_prefixof(i) codetabof(i) 75 #define tab_suffixof(i) ((unsigned char *)(htab))[i] 76 #define de_stack ((unsigned char *)&(htab[HSIZE-1])) 77 #define clear_htab() memset(htab, -1, HSIZE) 78 #define clear_tab_prefixof() memset(codetab, 0, 256); 79 51 #define HBITS 17 /* 50% occupancy */ 52 #define HSIZE (1<<HBITS) 53 #define HMASK (HSIZE-1) /* unused */ 54 #define HPRIME 9941 /* unused */ 55 #define BITS 16 56 #define BITS_STR "16" 57 #undef MAXSEG_64K /* unused */ 58 #define MAXCODE(n) (1L << (n)) 59 60 #define htabof(i) htab[i] 61 #define codetabof(i) codetab[i] 62 #define tab_prefixof(i) codetabof(i) 63 #define tab_suffixof(i) ((unsigned char *)(htab))[i] 64 #define de_stack ((unsigned char *)&(htab[HSIZE-1])) 65 #define clear_tab_prefixof() memset(codetab, 0, 256) 80 66 81 67 /* 82 68 * Decompress stdin to stdout. This routine adapts to the codes in the 83 69 * file building the "string" table on-the-fly; requiring no table to 84 * be stored in the compressed file. The tables used herein are shared 85 * with those of the compress() routine. See the definitions above. 70 * be stored in the compressed file. 86 71 */ 87 72 88 int uncompress(int fd_in, int fd_out) 73 USE_DESKTOP(long long) int 74 uncompress(int fd_in, int fd_out) 89 75 { 76 USE_DESKTOP(long long total_written = 0;) 77 USE_DESKTOP(long long) int retval = -1; 90 78 unsigned char *stackp; 91 long intcode;79 long code; 92 80 int finchar; 93 long intoldcode;94 long in t incode;81 long oldcode; 82 long incode; 95 83 int inbits; 96 84 int posbits; … … 98 86 int insize; 99 87 int bitmask; 100 long intfree_ent;101 long intmaxcode;102 long intmaxmaxcode;88 long free_ent; 89 long maxcode; 90 long maxmaxcode; 103 91 int n_bits; 104 92 int rsize = 0; 105 RESERVE_CONFIG_UBUFFER(inbuf, IBUFSIZ + 64); 106 RESERVE_CONFIG_UBUFFER(outbuf, OBUFSIZ + 2048); 107 unsigned char htab[HSIZE]; 108 unsigned short codetab[HSIZE]; 109 memset(inbuf, 0, IBUFSIZ + 64); 110 memset(outbuf, 0, OBUFSIZ + 2048); 93 unsigned char *inbuf; /* were eating insane amounts of stack - */ 94 unsigned char *outbuf; /* bad for some embedded targets */ 95 unsigned char *htab; 96 unsigned short *codetab; 97 98 /* Hmm, these were statics - why?! */ 99 /* user settable max # bits/code */ 100 int maxbits; /* = BITS; */ 101 /* block compress mode -C compatible with 2.0 */ 102 int block_mode; /* = BLOCK_MODE; */ 103 104 inbuf = xzalloc(IBUFSIZ + 64); 105 outbuf = xzalloc(OBUFSIZ + 2048); 106 htab = xzalloc(HSIZE); /* wsn't zeroed out before, maybe can xmalloc? */ 107 codetab = xzalloc(HSIZE * sizeof(codetab[0])); 111 108 112 109 insize = 0; 113 110 114 inbuf[0] = bb_xread_char(fd_in); 111 /* xread isn't good here, we have to return - caller may want 112 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ 113 if (full_read(fd_in, inbuf, 1) != 1) { 114 bb_error_msg("short read"); 115 goto err; 116 } 115 117 116 118 maxbits = inbuf[0] & BIT_MASK; … … 119 121 120 122 if (maxbits > BITS) { 121 bb_error_msg("compressed with %d bits, can only handle %d bits", maxbits,122 BITS);123 return -1;123 bb_error_msg("compressed with %d bits, can only handle " 124 BITS_STR" bits", maxbits); 125 goto err; 124 126 } 125 127 126 maxcode = MAXCODE(n_bits = INIT_BITS) - 1; 127 bitmask = (1 << n_bits) - 1; 128 n_bits = INIT_BITS; 129 maxcode = MAXCODE(INIT_BITS) - 1; 130 bitmask = (1 << INIT_BITS) - 1; 128 131 oldcode = -1; 129 132 finchar = 0; … … 134 137 135 138 /* As above, initialize the first 256 entries in the table. */ 136 clear_tab_prefixof();139 /*clear_tab_prefixof(); - done by xzalloc */ 137 140 138 141 for (code = 255; code >= 0; --code) { … … 141 144 142 145 do { 143 resetbuf:; 146 resetbuf: 144 147 { 145 148 int i; … … 147 150 int o; 148 151 149 e = insize - (o = (posbits >> 3)); 152 o = posbits >> 3; 153 e = insize - o; 150 154 151 155 for (i = 0; i < e; ++i) … … 158 162 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { 159 163 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); 164 //error check?? 160 165 insize += rsize; 161 166 } … … 182 187 unsigned char *p = &inbuf[posbits >> 3]; 183 188 184 code = 185 ((((long) (p[0])) | ((long) (p[1]) << 8) | 186 ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; 189 code = ((((long) (p[0])) | ((long) (p[1]) << 8) | 190 ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; 187 191 } 188 192 posbits += n_bits; … … 190 194 191 195 if (oldcode == -1) { 192 outbuf[outpos++] = (unsigned char) (finchar = 193 (int) (oldcode = code)); 196 oldcode = code; 197 finchar = (int) oldcode; 198 outbuf[outpos++] = (unsigned char) finchar; 194 199 continue; 195 200 } … … 202 207 ((n_bits << 3) - 203 208 (posbits - 1 + (n_bits << 3)) % (n_bits << 3))); 204 maxcode = MAXCODE(n_bits = INIT_BITS) - 1; 205 bitmask = (1 << n_bits) - 1; 209 n_bits = INIT_BITS; 210 maxcode = MAXCODE(INIT_BITS) - 1; 211 bitmask = (1 << INIT_BITS) - 1; 206 212 goto resetbuf; 207 213 } … … 223 229 (posbits & 07)); 224 230 bb_error_msg("uncompress: corrupt input"); 225 return -1;231 goto err; 226 232 } 227 233 … … 231 237 232 238 /* Generate output characters in reverse order */ 233 while ((long int) code >= (long int) 256) {239 while ((long) code >= (long) 256) { 234 240 *--stackp = tab_suffixof(code); 235 241 code = tab_prefixof(code); 236 242 } 237 243 238 *--stackp = (unsigned char) (finchar = tab_suffixof(code)); 244 finchar = tab_suffixof(code); 245 *--stackp = (unsigned char) finchar; 239 246 240 247 /* And put them out in forward order */ … … 242 249 int i; 243 250 244 if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) { 251 i = de_stack - stackp; 252 if (outpos + i >= OBUFSIZ) { 245 253 do { 246 254 if (i > OBUFSIZ - outpos) { … … 254 262 255 263 if (outpos >= OBUFSIZ) { 256 write(fd_out, outbuf, outpos); 264 full_write(fd_out, outbuf, outpos); 265 //error check?? 266 USE_DESKTOP(total_written += outpos;) 257 267 outpos = 0; 258 268 } 259 269 stackp += i; 260 } while ((i = (de_stack - stackp)) > 0); 270 i = de_stack - stackp; 271 } while (i > 0); 261 272 } else { 262 273 memcpy(outbuf + outpos, stackp, i); … … 266 277 267 278 /* Generate the new entry. */ 268 if ((code = free_ent) < maxmaxcode) { 279 code = free_ent; 280 if (code < maxmaxcode) { 269 281 tab_prefixof(code) = (unsigned short) oldcode; 270 282 tab_suffixof(code) = (unsigned char) finchar; … … 279 291 280 292 if (outpos > 0) { 281 write(fd_out, outbuf, outpos); 293 full_write(fd_out, outbuf, outpos); 294 //error check?? 295 USE_DESKTOP(total_written += outpos;) 282 296 } 283 297 284 RELEASE_CONFIG_BUFFER(inbuf); 285 RELEASE_CONFIG_BUFFER(outbuf); 286 return 0; 298 retval = USE_DESKTOP(total_written) + 0; 299 err: 300 free(inbuf); 301 free(outbuf); 302 free(htab); 303 free(codetab); 304 return retval; 287 305 }
Note:
See TracChangeset
for help on using the changeset viewer.