tinflate: Support either stream or inplace uncompress mode.
If tinf_uncompress_dyn_init() called with NULL dictionary, inplace mode will be active. Output will still be produced in chunks of .destSize, but any data written to .dest pointer should remain there (and the pointer itself should not be touched after initialization).
This commit is contained in:
parent
9daa35b843
commit
dd802431ad
2 changed files with 19 additions and 7 deletions
|
|
@ -73,7 +73,10 @@ typedef struct TINF_DATA {
|
|||
} TINF_DATA;
|
||||
|
||||
#define TINF_PUT(d, c) \
|
||||
{ *d->dest++ = c; d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; }
|
||||
{ \
|
||||
*d->dest++ = c; \
|
||||
if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \
|
||||
}
|
||||
|
||||
|
||||
/* low-level API */
|
||||
|
|
|
|||
|
|
@ -349,16 +349,25 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
|
|||
dist = tinf_decode_symbol(d, dt);
|
||||
/* possibly get more bits from distance code */
|
||||
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
|
||||
d->lzOff = d->dict_idx - offs;
|
||||
if (d->lzOff < 0) {
|
||||
d->lzOff += d->dict_size;
|
||||
if (d->dict_ring) {
|
||||
d->lzOff = d->dict_idx - offs;
|
||||
if (d->lzOff < 0) {
|
||||
d->lzOff += d->dict_size;
|
||||
}
|
||||
} else {
|
||||
d->lzOff = -offs;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy next byte from dict substring */
|
||||
TINF_PUT(d, d->dict_ring[d->lzOff]);
|
||||
if (++d->lzOff == d->dict_size) {
|
||||
d->lzOff = 0;
|
||||
if (d->dict_ring) {
|
||||
TINF_PUT(d, d->dict_ring[d->lzOff]);
|
||||
if (++d->lzOff == d->dict_size) {
|
||||
d->lzOff = 0;
|
||||
}
|
||||
} else {
|
||||
d->dest[0] = d->dest[d->lzOff];
|
||||
d->dest++;
|
||||
}
|
||||
d->curlen--;
|
||||
return TINF_OK;
|
||||
|
|
|
|||
Loading…
Reference in a new issue