Manuel
*/
-#include <setjmp.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-
#include "libbb.h"
-
#include "unarchive.h"
/* Constants for Huffman coding */
-#define MAX_GROUPS 6
-#define GROUP_SIZE 50 /* 64 would have been more efficient */
-#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */
-#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
-#define SYMBOL_RUNA 0
-#define SYMBOL_RUNB 1
+#define MAX_GROUPS 6
+#define GROUP_SIZE 50 /* 64 would have been more efficient */
+#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */
+#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
+#define SYMBOL_RUNA 0
+#define SYMBOL_RUNB 1
/* Status return values */
-#define RETVAL_OK 0
-#define RETVAL_LAST_BLOCK (-1)
-#define RETVAL_NOT_BZIP_DATA (-2)
-#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
-#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
-#define RETVAL_DATA_ERROR (-5)
-#define RETVAL_OUT_OF_MEMORY (-6)
-#define RETVAL_OBSOLETE_INPUT (-7)
+#define RETVAL_OK 0
+#define RETVAL_LAST_BLOCK (-1)
+#define RETVAL_NOT_BZIP_DATA (-2)
+#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
+#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
+#define RETVAL_DATA_ERROR (-5)
+#define RETVAL_OUT_OF_MEMORY (-6)
+#define RETVAL_OBSOLETE_INPUT (-7)
/* Other housekeeping constants */
-#define IOBUF_SIZE 4096
+#define IOBUF_SIZE 4096
/* This is what we know about each Huffman coding group */
struct group_data {
/* Reset longjmp I/O error handling */
i=setjmp(bd->jmpbuf);
- if(i) return i;
+ if (i) return i;
/* Read in header signature and CRC, then validate signature.
(last block signature means CRC is for whole file, return now) */
some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
it didn't actually work. */
- if(get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
- if((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
+ if (get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
+ if ((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
/* mapping table: if some byte values are never used (encoding things
like ascii text), the compression code removes the gaps to have fewer
for (i=0;i<16;i++) {
if(t&(1<<(15-i))) {
k=get_bits(bd,16);
- for(j=0;j<16;j++)
+ for (j=0;j<16;j++)
if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j;
}
}
start of the list.) */
if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR;
- for(i=0; i<groupCount; i++) mtfSymbol[i] = i;
- for(i=0; i<nSelectors; i++) {
+ for (i=0; i<groupCount; i++) mtfSymbol[i] = i;
+ for (i=0; i<nSelectors; i++) {
/* Get next value */
- for(j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
+ for (j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR;
/* Decode MTF to get the next selector */
uc = mtfSymbol[j];
- for(;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
+ for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1];
mtfSymbol[0]=selectors[i]=uc;
}
t=get_bits(bd, 5)-1;
for (i = 0; i < symCount; i++) {
- for(;;) {
+ for (;;) {
if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
return RETVAL_DATA_ERROR;
/* Find largest and smallest lengths in this group */
minLen=maxLen=length[0];
- for(i = 1; i < symCount; i++) {
+ for (i = 1; i < symCount; i++) {
if(length[i] > maxLen) maxLen = length[i];
else if(length[i] < minLen) minLen = length[i];
}
/* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
pp=0;
- for(i=minLen;i<=maxLen;i++) {
+ for (i=minLen;i<=maxLen;i++) {
temp[i]=limit[i]=0;
- for(t=0;t<symCount;t++)
+ for (t=0;t<symCount;t++)
if(length[t]==i) hufGroup->permute[pp++] = t;
}
/* Initialize symbol occurrence counters and symbol Move To Front table */
- for(i=0;i<256;i++) {
+ for (i=0;i<256;i++) {
byteCount[i] = 0;
mtfSymbol[i]=(unsigned char)i;
}
/* Loop through compressed symbols. */
runPos=dbufCount=selector=0;
- for(;;) {
+ for (;;) {
/* fetch next Huffman coding group from list. */
/* Figure how how many bits are in next symbol and unget extras */
i=hufGroup->minLen;
- while(j>limit[i]) ++i;
+ while (j>limit[i]) ++i;
bd->inbufBitCount += (hufGroup->maxLen - i);
/* Huffman decode value to get nextSym (with bounds checking) */
uc = symToByte[mtfSymbol[0]];
byteCount[uc] += t;
- while(t--) dbuf[dbufCount++]=uc;
+ while (t--) dbuf[dbufCount++]=uc;
}
/* Is this the terminating symbol? */
/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
j=0;
- for(i=0;i<256;i++) {
+ for (i=0;i<256;i++) {
k=j+byteCount[i];
byteCount[i] = j;
j=k;
/* Loop outputting bytes */
- for(;;) {
+ for (;;) {
/* If the output buffer is full, snapshot state and return */
/* Init the CRC32 table (big endian) */
- bd->crc32Table = bb_crc32_filltable(1);
+ bd->crc32Table = crc32_filltable(1);
/* Setup for I/O error handling via longjmp */
/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
not end of file.) */
-int uncompressStream(int src_fd, int dst_fd)
+USE_DESKTOP(long long) int
+uncompressStream(int src_fd, int dst_fd)
{
+ USE_DESKTOP(long long total_written = 0;)
char *outbuf;
bunzip_data *bd;
int i;
outbuf=xmalloc(IOBUF_SIZE);
- if(!(i=start_bunzip(&bd,src_fd,0,0))) {
- for(;;) {
+ i=start_bunzip(&bd,src_fd,0,0);
+ if(!i) {
+ for (;;) {
if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break;
if(i!=write(dst_fd,outbuf,i)) {
i=RETVAL_UNEXPECTED_OUTPUT_EOF;
break;
}
+ USE_DESKTOP(total_written += i;)
}
}
if(i==RETVAL_LAST_BLOCK) {
if (bd->headerCRC!=bd->totalCRC) {
- bb_error_msg("Data integrity error when decompressing.");
+ bb_error_msg("data integrity error when decompressing");
} else {
i=RETVAL_OK;
}
} else if (i==RETVAL_UNEXPECTED_OUTPUT_EOF) {
- bb_error_msg("Compressed file ends unexpectedly");
+ bb_error_msg("compressed file ends unexpectedly");
} else {
- bb_error_msg("Decompression failed");
+ bb_error_msg("decompression failed");
}
free(bd->dbuf);
free(bd);
free(outbuf);
- return i;
+ return i ? i : USE_DESKTOP(total_written) + 0;
}
#ifdef TESTING
static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data",
"Unexpected input EOF","Unexpected output EOF","Data error",
- "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
+ "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."};
/* Dumb little test thing, decompress stdin to stdout */
int main(int argc, char *argv[])
int i=uncompressStream(0,1);
char c;
- if(i) fprintf(stderr,"%s\n", bunzip_errors[-i]);
- else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
+ if(i<0) fprintf(stderr,"%s\n", bunzip_errors[-i]);
+ else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n");
return -i;
}
#endif