read_gz patch 3 from Laurence Anderson
This commit is contained in:
parent
efe7889086
commit
0126fda5bb
@ -155,12 +155,6 @@ static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current
|
||||
return(bitbuffer);
|
||||
}
|
||||
|
||||
static void abort_gzip(void)
|
||||
{
|
||||
error_msg("gzip aborted\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static void make_gunzip_crc_table(void)
|
||||
{
|
||||
const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */
|
||||
@ -438,24 +432,37 @@ static void flush_gunzip_window(void)
|
||||
* tl, td: literal/length and distance decoder tables
|
||||
* bl, bd: number of bits decoded by tl[] and td[]
|
||||
*/
|
||||
static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const unsigned int bd)
|
||||
static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
|
||||
{
|
||||
unsigned int e; /* table entry flag/number of extra bits */
|
||||
unsigned int n, d; /* length and index for copy */
|
||||
unsigned int w; /* current gunzip_window position */
|
||||
huft_t *t; /* pointer to table entry */
|
||||
unsigned int ml, md; /* masks for bl and bd bits */
|
||||
unsigned int b; /* bit buffer */
|
||||
unsigned int k; /* number of bits in bit buffer */
|
||||
static unsigned int e; /* table entry flag/number of extra bits */
|
||||
static unsigned int n, d; /* length and index for copy */
|
||||
static unsigned int w; /* current gunzip_window position */
|
||||
static huft_t *t; /* pointer to table entry */
|
||||
static unsigned int ml, md; /* masks for bl and bd bits */
|
||||
static unsigned int b; /* bit buffer */
|
||||
static unsigned int k; /* number of bits in bit buffer */
|
||||
static huft_t *tl, *td;
|
||||
static unsigned int bl, bd;
|
||||
static int resumeCopy = 0;
|
||||
|
||||
/* make local copies of globals */
|
||||
b = gunzip_bb; /* initialize bit buffer */
|
||||
k = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
if (setup) { // 1st time we are called, copy in variables
|
||||
tl = my_tl;
|
||||
td = my_td;
|
||||
bl = my_bl;
|
||||
bd = my_bd;
|
||||
/* make local copies of globals */
|
||||
b = gunzip_bb; /* initialize bit buffer */
|
||||
k = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
return 0; // Don't actually do anything the first time
|
||||
}
|
||||
|
||||
if (resumeCopy) goto do_copy;
|
||||
|
||||
while (1) { /* do until end of block */
|
||||
b = fill_bitbuffer(b, &k, bl);
|
||||
if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
|
||||
@ -475,8 +482,9 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
gunzip_window[w++] = (unsigned char) t->v.n;
|
||||
if (w == gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
return -1;
|
||||
}
|
||||
} else { /* it's an EOB or a length */
|
||||
|
||||
@ -512,7 +520,7 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
k -= e;
|
||||
|
||||
/* do the copy */
|
||||
do {
|
||||
do_copy: do {
|
||||
n -= (e =
|
||||
(e =
|
||||
gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
|
||||
@ -530,11 +538,14 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
}
|
||||
if (w == gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
if (n) resumeCopy = 1;
|
||||
else resumeCopy = 0;
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while (n);
|
||||
resumeCopy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,16 +554,56 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
gunzip_bb = b; /* restore global bit buffer */
|
||||
gunzip_bk = k;
|
||||
|
||||
/* normally just after call to inflate_codes, but save code by putting it here */
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
|
||||
{
|
||||
static int n, b_stored, k_stored, w;
|
||||
if (setup) {
|
||||
n = my_n;
|
||||
b_stored = my_b_stored;
|
||||
k_stored = my_k_stored;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
return 0; // Don't do anything first time
|
||||
}
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--) {
|
||||
b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
|
||||
gunzip_window[w++] = (unsigned char) b_stored;
|
||||
if (w == (unsigned int) gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
return -1; // Means more stuff 2do
|
||||
}
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
}
|
||||
|
||||
/* restore the globals from the locals */
|
||||
gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
|
||||
gunzip_bb = b_stored; /* restore global bit buffer */
|
||||
gunzip_bk = k_stored;
|
||||
return 0; // Finished
|
||||
}
|
||||
|
||||
/*
|
||||
* decompress an inflated block
|
||||
* e: last block flag
|
||||
*
|
||||
* GLOBAL VARIABLES: bb, kk,
|
||||
*/
|
||||
// Return values: -1 = inflate_stored, -2 = inflate_codes
|
||||
static int inflate_block(int *e)
|
||||
{
|
||||
unsigned t; /* block type */
|
||||
@ -585,14 +636,12 @@ static int inflate_block(int *e)
|
||||
case 0: /* Inflate stored */
|
||||
{
|
||||
unsigned int n; /* number of bytes in block */
|
||||
unsigned int w; /* current gunzip_window position */
|
||||
unsigned int b_stored; /* bit buffer */
|
||||
unsigned int k_stored; /* number of bits in bit buffer */
|
||||
|
||||
/* make local copies of globals */
|
||||
b_stored = gunzip_bb; /* initialize bit buffer */
|
||||
k_stored = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
|
||||
/* go to byte boundary */
|
||||
n = k_stored & 7;
|
||||
@ -612,24 +661,8 @@ static int inflate_block(int *e)
|
||||
b_stored >>= 16;
|
||||
k_stored -= 16;
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--) {
|
||||
b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
|
||||
gunzip_window[w++] = (unsigned char) b_stored;
|
||||
if (w == (unsigned int) gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
w = 0;
|
||||
}
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
}
|
||||
|
||||
/* restore the globals from the locals */
|
||||
gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
|
||||
gunzip_bb = b_stored; /* restore global bit buffer */
|
||||
gunzip_bk = k_stored;
|
||||
return 0;
|
||||
inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
|
||||
return -1;
|
||||
}
|
||||
case 1: /* Inflate fixed
|
||||
* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
@ -673,14 +706,11 @@ static int inflate_block(int *e)
|
||||
}
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
|
||||
|
||||
/* huft_free code moved into inflate_codes */
|
||||
|
||||
return -2;
|
||||
}
|
||||
case 2: /* Inflate dynamic */
|
||||
{
|
||||
@ -828,14 +858,11 @@ static int inflate_block(int *e)
|
||||
}
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd)) {
|
||||
return 1;
|
||||
}
|
||||
inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
/* huft_free code moved into inflate_codes */
|
||||
|
||||
return -2;
|
||||
}
|
||||
default:
|
||||
/* bad block type */
|
||||
@ -862,7 +889,11 @@ extern ssize_t read_gz(int fd, void *buf, size_t count)
|
||||
if (e) return 0; // No more data here!
|
||||
gunzip_hufts = 0;
|
||||
r = inflate_block(&e);
|
||||
if (r != 0) {
|
||||
if (r == -1) { // Call inflate_stored while returning -1
|
||||
while(inflate_stored(0,0,0,0) == -1) flush_gunzip_window();
|
||||
} else if (r == -2) { // Call inflate_codes while returning -1
|
||||
while(inflate_codes(0,0,0,0,0) == -1) flush_gunzip_window();
|
||||
} else {
|
||||
error_msg_and_die("inflate error %d", r);
|
||||
return -1;
|
||||
}
|
||||
@ -895,15 +926,6 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
|
||||
|
||||
gunzip_in_buffer = malloc(8);
|
||||
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGINT, (sig_type) abort_gzip);
|
||||
}
|
||||
#ifdef SIGHUP
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGHUP, (sig_type) abort_gzip);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initialize gunzip_window, bit buffer */
|
||||
gunzip_bk = 0;
|
||||
gunzip_bb = 0;
|
||||
|
@ -155,12 +155,6 @@ static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current
|
||||
return(bitbuffer);
|
||||
}
|
||||
|
||||
static void abort_gzip(void)
|
||||
{
|
||||
error_msg("gzip aborted\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static void make_gunzip_crc_table(void)
|
||||
{
|
||||
const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */
|
||||
@ -438,24 +432,37 @@ static void flush_gunzip_window(void)
|
||||
* tl, td: literal/length and distance decoder tables
|
||||
* bl, bd: number of bits decoded by tl[] and td[]
|
||||
*/
|
||||
static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const unsigned int bd)
|
||||
static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
|
||||
{
|
||||
unsigned int e; /* table entry flag/number of extra bits */
|
||||
unsigned int n, d; /* length and index for copy */
|
||||
unsigned int w; /* current gunzip_window position */
|
||||
huft_t *t; /* pointer to table entry */
|
||||
unsigned int ml, md; /* masks for bl and bd bits */
|
||||
unsigned int b; /* bit buffer */
|
||||
unsigned int k; /* number of bits in bit buffer */
|
||||
static unsigned int e; /* table entry flag/number of extra bits */
|
||||
static unsigned int n, d; /* length and index for copy */
|
||||
static unsigned int w; /* current gunzip_window position */
|
||||
static huft_t *t; /* pointer to table entry */
|
||||
static unsigned int ml, md; /* masks for bl and bd bits */
|
||||
static unsigned int b; /* bit buffer */
|
||||
static unsigned int k; /* number of bits in bit buffer */
|
||||
static huft_t *tl, *td;
|
||||
static unsigned int bl, bd;
|
||||
static int resumeCopy = 0;
|
||||
|
||||
/* make local copies of globals */
|
||||
b = gunzip_bb; /* initialize bit buffer */
|
||||
k = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
if (setup) { // 1st time we are called, copy in variables
|
||||
tl = my_tl;
|
||||
td = my_td;
|
||||
bl = my_bl;
|
||||
bd = my_bd;
|
||||
/* make local copies of globals */
|
||||
b = gunzip_bb; /* initialize bit buffer */
|
||||
k = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
/* inflate the coded data */
|
||||
ml = mask_bits[bl]; /* precompute masks for speed */
|
||||
md = mask_bits[bd];
|
||||
return 0; // Don't actually do anything the first time
|
||||
}
|
||||
|
||||
if (resumeCopy) goto do_copy;
|
||||
|
||||
while (1) { /* do until end of block */
|
||||
b = fill_bitbuffer(b, &k, bl);
|
||||
if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
|
||||
@ -475,8 +482,9 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
gunzip_window[w++] = (unsigned char) t->v.n;
|
||||
if (w == gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
return -1;
|
||||
}
|
||||
} else { /* it's an EOB or a length */
|
||||
|
||||
@ -512,7 +520,7 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
k -= e;
|
||||
|
||||
/* do the copy */
|
||||
do {
|
||||
do_copy: do {
|
||||
n -= (e =
|
||||
(e =
|
||||
gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
|
||||
@ -530,11 +538,14 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
}
|
||||
if (w == gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
if (n) resumeCopy = 1;
|
||||
else resumeCopy = 0;
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while (n);
|
||||
resumeCopy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,16 +554,56 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
|
||||
gunzip_bb = b; /* restore global bit buffer */
|
||||
gunzip_bk = k;
|
||||
|
||||
/* normally just after call to inflate_codes, but save code by putting it here */
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
|
||||
{
|
||||
static int n, b_stored, k_stored, w;
|
||||
if (setup) {
|
||||
n = my_n;
|
||||
b_stored = my_b_stored;
|
||||
k_stored = my_k_stored;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
return 0; // Don't do anything first time
|
||||
}
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--) {
|
||||
b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
|
||||
gunzip_window[w++] = (unsigned char) b_stored;
|
||||
if (w == (unsigned int) gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
//flush_gunzip_window();
|
||||
w = 0;
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
return -1; // Means more stuff 2do
|
||||
}
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
}
|
||||
|
||||
/* restore the globals from the locals */
|
||||
gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
|
||||
gunzip_bb = b_stored; /* restore global bit buffer */
|
||||
gunzip_bk = k_stored;
|
||||
return 0; // Finished
|
||||
}
|
||||
|
||||
/*
|
||||
* decompress an inflated block
|
||||
* e: last block flag
|
||||
*
|
||||
* GLOBAL VARIABLES: bb, kk,
|
||||
*/
|
||||
// Return values: -1 = inflate_stored, -2 = inflate_codes
|
||||
static int inflate_block(int *e)
|
||||
{
|
||||
unsigned t; /* block type */
|
||||
@ -585,14 +636,12 @@ static int inflate_block(int *e)
|
||||
case 0: /* Inflate stored */
|
||||
{
|
||||
unsigned int n; /* number of bytes in block */
|
||||
unsigned int w; /* current gunzip_window position */
|
||||
unsigned int b_stored; /* bit buffer */
|
||||
unsigned int k_stored; /* number of bits in bit buffer */
|
||||
|
||||
/* make local copies of globals */
|
||||
b_stored = gunzip_bb; /* initialize bit buffer */
|
||||
k_stored = gunzip_bk;
|
||||
w = gunzip_outbuf_count; /* initialize gunzip_window position */
|
||||
|
||||
/* go to byte boundary */
|
||||
n = k_stored & 7;
|
||||
@ -612,24 +661,8 @@ static int inflate_block(int *e)
|
||||
b_stored >>= 16;
|
||||
k_stored -= 16;
|
||||
|
||||
/* read and output the compressed data */
|
||||
while (n--) {
|
||||
b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
|
||||
gunzip_window[w++] = (unsigned char) b_stored;
|
||||
if (w == (unsigned int) gunzip_wsize) {
|
||||
gunzip_outbuf_count = (w);
|
||||
flush_gunzip_window();
|
||||
w = 0;
|
||||
}
|
||||
b_stored >>= 8;
|
||||
k_stored -= 8;
|
||||
}
|
||||
|
||||
/* restore the globals from the locals */
|
||||
gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
|
||||
gunzip_bb = b_stored; /* restore global bit buffer */
|
||||
gunzip_bk = k_stored;
|
||||
return 0;
|
||||
inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
|
||||
return -1;
|
||||
}
|
||||
case 1: /* Inflate fixed
|
||||
* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
@ -673,14 +706,11 @@ static int inflate_block(int *e)
|
||||
}
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
|
||||
|
||||
/* huft_free code moved into inflate_codes */
|
||||
|
||||
return -2;
|
||||
}
|
||||
case 2: /* Inflate dynamic */
|
||||
{
|
||||
@ -828,14 +858,11 @@ static int inflate_block(int *e)
|
||||
}
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
if (inflate_codes(tl, td, bl, bd)) {
|
||||
return 1;
|
||||
}
|
||||
inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
huft_free(td);
|
||||
return 0;
|
||||
/* huft_free code moved into inflate_codes */
|
||||
|
||||
return -2;
|
||||
}
|
||||
default:
|
||||
/* bad block type */
|
||||
@ -862,7 +889,11 @@ extern ssize_t read_gz(int fd, void *buf, size_t count)
|
||||
if (e) return 0; // No more data here!
|
||||
gunzip_hufts = 0;
|
||||
r = inflate_block(&e);
|
||||
if (r != 0) {
|
||||
if (r == -1) { // Call inflate_stored while returning -1
|
||||
while(inflate_stored(0,0,0,0) == -1) flush_gunzip_window();
|
||||
} else if (r == -2) { // Call inflate_codes while returning -1
|
||||
while(inflate_codes(0,0,0,0,0) == -1) flush_gunzip_window();
|
||||
} else {
|
||||
error_msg_and_die("inflate error %d", r);
|
||||
return -1;
|
||||
}
|
||||
@ -895,15 +926,6 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
|
||||
|
||||
gunzip_in_buffer = malloc(8);
|
||||
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGINT, (sig_type) abort_gzip);
|
||||
}
|
||||
#ifdef SIGHUP
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
(void) signal(SIGHUP, (sig_type) abort_gzip);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initialize gunzip_window, bit buffer */
|
||||
gunzip_bk = 0;
|
||||
gunzip_bb = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user