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).
Now calling tinf_uncompress_dyn() will produce d.destSize uncompressed bytes
in d->dest (autoincremented). Before using tinf_uncompress_dyn(),
tinf_uncompress_dyn_init() should be called, with a buffer for sliding
dictionary.
destRemaining was set instead of destSize, this caused the destRemaining
to be re-initialized in follow-up call to tinf_uncompress_dyn() function
with destSize which was uninitialized.
Without destSize being explicitly set, you get random failures
with TINF_DEST_OVERFLOW being returned (since destSize winds up
being initialized with a random value from the stack).
The new API takes a pointer to TINF_DATA (which thus can be allocated by
caller the way it sees fit) and provides callback to incrementally increase
size of decompression buffer.
Build them dynamically as needed, just for blocks needing them, using the
same objects as dymanic trees. Given how most deflated files structured,
this won't need to be done too often.
Codelengths are used to decode length, based on which length tree is built.
That means that codelength and length trees' lifetimes are serialized,
advantage of which we take to save bunch of runtime memory.