Closed nemequ closed 9 years ago
Thanks - investigating this now.
Ok, the problem is caused by some key decompression parameters not exactly matching the compression parameters. Apologies, this needs to be documented better. Like LZMA, I don't store the compression params in the stream itself to save a few bits. (Admittedly, the # of bits saved is tiny.)
Specifically, the m_table_max_update_interval and m_table_update_interval_slow_rate parameters in the comp/decomp parameters structure must exactly match during compression/decompression. In your example, the comp. struct uses 64,64, and the decomp struct uses 64,16. They must both match (64,64). Otherwise, the decompressor will eventually fall horribly out of sync with the compressor and it'll eventually run off the rails - that's why you get the bad code error.
For most uses, you should just set both values to 0,0 and instead set the m_table_update_rate param to a value between [LZHAM_SLOWEST_TABLE_UPDATE_RATE, LZHAM_FASTEST_TABLE_UPDATE_RATE]. This single value internally controls both m_table_max_update_interval/m_table_update_interval_slow_rate. These 2 parameters are there to allow the user to experiment to find the best settings for their specific data.
I changed your example so both are either 0,0 or 64,64 and decompression works OK (decomp_res is 3).
If I hadn't locked the bitstream for v1.0 I could have stored a small hash of the compression parameters, so the decompressor could immediately bail if it detected a mismatch. I was guessing most users wouldn't bother tweaking the defaults except for the dictionary size.
A bit more detail: if the codec sees that either m_table_max_update_interval or m_table_update_interval_slow_rate are non-zero, it uses the values you specify to control the Huffman table update rates. Otherwise, it uses the single m_table_update_rate value (which defaults to LZHAM_DEFAULT_TABLE_UPDATE_RATE).
Most users should set both m_table_max_update_interval/m_table_update_interval_slow_rate to 0 and not worry about them.
Okay, that makes sense. For what it's worth, the reason I chose those parameters is because the documentation mentioned them being the default values (see lines 158 and 278). Perhaps you could update them to both be the same? If I were choosing non-default values I would have been much more suspicious of that when things went wrong.
Got it, I'll fix that.
I've changed the comments in lzham.h to be more clear.
Maybe I'm doing something wrong, but I feel like this should get me LZHAM_DECOMP_STATUS_SUCCESS not LZHAM_DECOMP_STATUS_FAILED_BAD_CODE: