// File: lzham.h - Copyright (c) 2009-2012 Richard Geldreich, Jr. <richgel99@gmail.com>
// LZHAM uses the MIT License. See Copyright Notice and license at the end of this file.
//
// This is the main header file, includable from C or C++ files, which defines all the publically available API's, structs, and types used by the LZHAM codec.
//
// Notes:
//
// As of LZHAM alpha8, there are now two sets of API's:
// - The first (oldest) API directly exposes all of the codec's functionality. See lzham_compress_init(), lzham_decompress_init(), etc. This API has the lowest overhead
// and is the most tested.
// - The new API implements the most useful/popular subset of the zlib API, but doesn't expose all of the codec's functionality yet. See the lzham_z* functions.
// This functionality is provided because most users of compression libraries are already very familiar with the nuts and bolts of the zlib API.
// For the most common zlib usage cases LZHAM is an almost drop-in replacement for zlib. To make switching from zlib even easier, you can define the LZHAM_DEFINE_ZLIB_API macro,
// which causes this header to #define most zlib symbols to their LZHAM equivalents.
// Note that LZHAM does not actually implement the deflate/inflate algorithm, so it cannot decompress streams created by standard zlib yet (and of course, zlib cannot decompress
// streams created by LZHAM). Internally, this API is mostly implemented via the older low-level LZHAM API.
LZHAM_COMP_FLAG_FORCE_POLAR_CODING=1,// Forces Polar codes vs. Huffman, for a slight increase in decompression speed.
LZHAM_COMP_FLAG_EXTREME_PARSING=2,// Improves ratio by allowing the compressor's parse graph to grow "higher" (up to 4 parent nodes per output node), but is much slower.
LZHAM_COMP_FLAG_DETERMINISTIC_PARSING=4,// Guarantees that the compressed output will always be the same given the same input and parameters (no variation between runs due to kernel threading scheduling).
// If enabled, the compressor is free to use any optimizations which could lower the decompression rate (such
// as adaptively resetting the Huffman table update rate to maximum frequency, which is costly for the decompressor).
lzham_uint32m_struct_size;// set to sizeof(lzham_compress_params)
lzham_uint32m_dict_size_log2;// set to the log2(dictionary_size), must range between [LZHAM_MIN_DICT_SIZE_LOG2, LZHAM_MAX_DICT_SIZE_LOG2_X86] for x86 LZHAM_MAX_DICT_SIZE_LOG2_X64 for x64
lzham_compress_levelm_level;// set to LZHAM_COMP_LEVEL_FASTEST, etc.
lzham_int32m_max_helper_threads;// max # of additional "helper" threads to create, must range between [-1,LZHAM_MAX_HELPER_THREADS], where -1=max practical
lzham_uint32m_cpucache_total_lines;// set to 0 (optimize compressed stream to avoid L1/L2 cache misses - not currently supported)
lzham_uint32m_cpucache_line_size;// set to 0
lzham_uint32m_compress_flags;// optional compression flags (see lzham_compress_flags enum)
lzham_uint32m_num_seed_bytes;// for delta compression (optional) - number of seed bytes pointed to by m_pSeed_bytes
constvoid*m_pSeed_bytes;// for delta compression (optional) - pointer to seed bytes buffer, must be at least m_num_seed_bytes long
}lzham_compress_params;
typedefstruct
{
lzham_uint32adler32;
lzham_uint32crc32;
}lzham_compress_checksums;
// Initializes a compressor. Returns a pointer to the compressor's internal state, or NULL on failure.
// pParams cannot be NULL. Be sure to initialize the pParams->m_struct_size member to sizeof(lzham_compress_params) (along with the other members to reasonable values) before calling this function.
// TODO: With large dictionaries this function could take a while (due to memory allocation). I need to add a reinit() API for compression (decompression already has one).
// Compresses an arbitrarily sized block of data, writing as much available compressed data as possible to the output buffer.
// This method may be called as many times as needed, but for best perf. try not to call it with tiny buffers.
// pState - Pointer to internal compression state, created by lzham_compress_init.
// pIn_buf, pIn_buf_size - Pointer to input data buffer, and pointer to a size_t containing the number of bytes available in this buffer.
// On return, *pIn_buf_size will be set to the number of bytes read from the buffer.
// pOut_buf, pOut_buf_size - Pointer to the output data buffer, and a pointer to a size_t containing the max number of bytes that can be written to this buffer.
// On return, *pOut_buf_size will be set to the number of bytes written to this buffer.
// no_more_input_bytes_flag - Set to true to indicate that no more input bytes are available to compress (EOF). Once you call this function with this param set to true, it must stay set to true in all future calls.
//
// Normal return status codes:
// LZHAM_COMP_STATUS_NOT_FINISHED - Compression can continue, but the compressor needs more input, or it needs more room in the output buffer.
// LZHAM_COMP_STATUS_NEEDS_MORE_INPUT - Compression can contintue, but the compressor has no more output, and has no input but we're not at EOF. Supply more input to continue.
// Success/failure return status codes:
// LZHAM_COMP_STATUS_SUCCESS - Compression has completed successfully.
// LZHAM_COMP_STATUS_FAILED, LZHAM_COMP_STATUS_FAILED_INITIALIZING, LZHAM_COMP_STATUS_INVALID_PARAMETER - Something went wrong.
// LZHAM_DECOMP_STATUS_NOT_FINISHED indicates that the decompressor is flushing its internal buffer to the caller's output buffer.
// There may be more bytes available to decompress on the next call, but there is no guarantee.
LZHAM_DECOMP_STATUS_NOT_FINISHED=0,
// LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT indicates that the decompressor is trying to flush its internal buffer to the caller's output buffer,
// but the caller hasn't provided any space to copy this data to the caller's output buffer. Call the lzham_decompress() again with a non-empty sized output buffer.
LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT,
// LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT indicates that the decompressor has consumed all input bytes, has not encountered an "end of stream" code,
// and the caller hasn't set no_more_input_bytes_flag to true, so it's expecting more input to proceed.
LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT,
// All the following enums always (and MUST) indicate failure/success.
// m_dict_size_log2 MUST match the value used during compression!
// If m_num_seed_bytes != 0, LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED must not be set (i.e. static "seed" dictionaries are not compatible with unbuffered decompression).
// The seed buffer's contents and size must match the seed buffer used during compression.
typedefstruct
{
lzham_uint32m_struct_size;// set to sizeof(lzham_decompress_params)
lzham_uint32m_dict_size_log2;// set to the log2(dictionary_size), must range between [LZHAM_MIN_DICT_SIZE_LOG2, LZHAM_MAX_DICT_SIZE_LOG2_X86] for x86 LZHAM_MAX_DICT_SIZE_LOG2_X64 for x64
lzham_uint32m_decompress_flags;// optional decompression flags (see lzham_decompress_flags enum)
lzham_uint32m_num_seed_bytes;// for delta compression (optional) - number of seed bytes pointed to by m_pSeed_bytes
constvoid*m_pSeed_bytes;// for delta compression (optional) - pointer to seed bytes buffer, must be at least m_num_seed_bytes long
}lzham_decompress_params;
typedefstruct
{
lzham_uint32adler32;
lzham_uint32crc32;
}lzham_decompress_checksums;
// Initializes a decompressor.
// pParams cannot be NULL. Be sure to initialize the pParams->m_struct_size member to sizeof(lzham_decompress_params) (along with the other members to reasonable values) before calling this function.
// Note: With large dictionaries this function could take a while (due to memory allocation). To serially decompress multiple streams, it's faster to init a compressor once and
// reuse it using by calling lzham_decompress_reinit().
// Quickly re-initializes the decompressor to its initial state given an already allocated/initialized state (doesn't do any memory alloc unless necessary).
// Decompresses an arbitrarily sized block of compressed data, writing as much available decompressed data as possible to the output buffer.
// This method is implemented as a coroutine so it may be called as many times as needed. However, for best perf. try not to call it with tiny buffers.
// pState - Pointer to internal decompression state, originally created by lzham_decompress_init.
// pIn_buf, pIn_buf_size - Pointer to input data buffer, and pointer to a size_t containing the number of bytes available in this buffer.
// On return, *pIn_buf_size will be set to the number of bytes read from the buffer.
// pOut_buf, pOut_buf_size - Pointer to the output data buffer, and a pointer to a size_t containing the max number of bytes that can be written to this buffer.
// On return, *pOut_buf_size will be set to the number of bytes written to this buffer.
// no_more_input_bytes_flag - Set to true to indicate that no more input bytes are available to compress (EOF). Once you call this function with this param set to true, it must stay set to true in all future calls.
// Notes:
// In unbuffered mode, the output buffer MUST be large enough to hold the entire decompressed stream. Otherwise, you'll receive the
// LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL error (which is currently unrecoverable during unbuffered decompression).
// In buffered mode, if the output buffer's size is 0 bytes, the caller is indicating that no more output bytes are expected from the
// decompressor. In this case, if the decompressor actually has more bytes you'll receive the LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT
// error (which is recoverable in the buffered case - just call lzham_decompress() again with a non-zero size output buffer).
// ------------------- zlib-style API Definitions.
// Important note: LZHAM doesn't internally support the Deflate algorithm, but for API compatibility the "Deflate" and "Inflate" names are retained here.
typedefunsignedlonglzham_z_ulong;
// Heap allocation callbacks.
// Note that lzham_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long.
// For compression, you typically only need to use LZHAM_NO_FLUSH and LZHAM_FINISH.
// LZHAM_Z_SYNC_FLUSH and LZHAM_Z_FULL_FLUSH during compression forces compression of all buffered input.
//
// For decompression, you typically only need to use LZHAM_Z_SYNC_FLUSH or LZHAM_Z_FINISH.
// LZHAM_Z_FINISH during decompression guarantees that the output buffer is large enough to hold all remaining data to decompress.
// See http://www.bolet.org/~pornin/deflate-flush.html
// Must directly map to lzham_flush_t
enum
{
LZHAM_Z_NO_FLUSH=0,// compression/decompression
LZHAM_Z_PARTIAL_FLUSH=1,// compression/decompression, same as LZHAM_Z_SYNC_FLUSH
LZHAM_Z_SYNC_FLUSH=2,// compression/decompression, when compressing: flush current block (if any), always outputs sync block (aligns output to byte boundary, a 0xFFFF0000 marker will appear in the output stream)
LZHAM_Z_FULL_FLUSH=3,// compression/decompression, when compressing: same as LZHAM_Z_SYNC_FLUSH but also forces a full state flush (LZ dictionary, all symbol statistics)
LZHAM_Z_FINISH=4,// compression/decompression
LZHAM_Z_BLOCK=5,// not supported
LZHAM_Z_TABLE_FLUSH=10// compression only, resets all symbol table update rates to maximum frequency (LZHAM extension)
};
// Return status codes. LZHAM_Z_PARAM_ERROR is non-standard.
enum
{
LZHAM_Z_OK=0,
LZHAM_Z_STREAM_END=1,
LZHAM_Z_NEED_DICT=2,
LZHAM_Z_ERRNO=-1,
LZHAM_Z_STREAM_ERROR=-2,
LZHAM_Z_DATA_ERROR=-3,
LZHAM_Z_MEM_ERROR=-4,
LZHAM_Z_BUF_ERROR=-5,
LZHAM_Z_VERSION_ERROR=-6,
LZHAM_Z_PARAM_ERROR=-10000
};
// Compression levels.
enum
{
LZHAM_Z_NO_COMPRESSION=0,
LZHAM_Z_BEST_SPEED=1,
LZHAM_Z_BEST_COMPRESSION=9,
LZHAM_Z_UBER_COMPRESSION=10,// uber = best with extreme parsing (can be very slow)
LZHAM_Z_DEFAULT_COMPRESSION=-1
};
// Window bits
// Important note: The zlib-style API's default to 32KB dictionary for API compatibility. For improved compression, be sure to call deflateInit2/inflateInit2 and specify larger custom window_bits values!
// If changing the calling code isn't practical, unremark LZHAM_Z_API_FORCE_WINDOW_BITS.
#define LZHAM_Z_DEFAULT_WINDOW_BITS 15
// Define LZHAM_Z_API_FORCE_WINDOW_BITS to force the entire library to use a constant value for window_bits (helps with porting) in all zlib API's.
// TODO: Might be useful to provide an API to control this at runtime.
//#define LZHAM_Z_API_FORCE_WINDOW_BITS 23
// Data types
#define LZHAM_Z_BINARY 0
#define LZHAM_Z_TEXT 1
#define LZHAM_Z_ASCII 1
#define LZHAM_Z_UNKNOWN 2
structlzham_z_internal_state;
// Compression/decompression stream struct.
typedefstruct
{
constunsignedchar*next_in;// pointer to next byte to read
unsignedintavail_in;// number of bytes available at next_in
lzham_z_ulongtotal_in;// total number of bytes consumed so far
unsignedchar*next_out;// pointer to next byte to write
unsignedintavail_out;// number of bytes that can be written to next_out
lzham_z_ulongtotal_out;// total number of bytes produced so far
char*msg;// error msg (unused)
structlzham_z_internal_state*state;// internal state, allocated by zalloc/zfree
// LZHAM does not support per-stream heap callbacks. Use lzham_set_memory_callbacks() instead.
// These members are ignored - they are here for backwards compatibility with zlib.
lzham_z_alloc_funczalloc;// optional heap allocation function (defaults to malloc)
lzham_z_free_funczfree;// optional heap free function (defaults to free)
void*opaque;// heap alloc function user pointer
intdata_type;// data_type (unused)
lzham_z_ulongadler32;// adler32 of the source or uncompressed data
lzham_z_ulongcrc32;// crc32 of the source or uncompressed data
lzham_z_ulongreserved;// not used
}lzham_z_stream;
typedeflzham_z_stream*lzham_z_streamp;
LZHAM_DLL_EXPORTconstchar*lzham_z_version(void);
// lzham_deflateInit() initializes a compressor with default options:
// Parameters:
// pStream must point to an initialized lzham_stream struct.
// level must be between [LZHAM_NO_COMPRESSION, LZHAM_BEST_COMPRESSION].
// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
// Return values:
// LZHAM_OK on success.
// LZHAM_STREAM_ERROR if the stream is bogus.
// LZHAM_PARAM_ERROR if the input parameters are bogus.
// lzham_deflateInit2() is like lzham_deflate(), except with more control:
// Additional parameters:
// method must be LZHAM_Z_DEFLATED or LZHAM_Z_LZHAM (LZHAM_Z_DEFLATED will be internally converted to LZHAM_Z_LZHAM with a windowsize of LZHAM_Z_DEFAULT_WINDOW_BITS)
// window_bits must be LZHAM_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -LZHAM_Z_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
// mem_level must be between [1, 9] (it's checked but ignored by lzham)
// Quickly resets a compressor without having to reallocate anything. Same as calling lzham_z_deflateEnd() followed by lzham_z_deflateInit()/lzham_z_deflateInit2().
// lzham_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
// Parameters:
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
// flush may be LZHAM_Z_NO_FLUSH, LZHAM_Z_PARTIAL_FLUSH/LZHAM_Z_SYNC_FLUSH, LZHAM_Z_FULL_FLUSH, or LZHAM_Z_FINISH.
// Return values:
// LZHAM_Z_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
// LZHAM_Z_STREAM_END if all input has been consumed and all output bytes have been written. Don't call lzham_z_deflate() on the stream anymore.
// LZHAM_Z_STREAM_ERROR if the stream is bogus.
// LZHAM_Z_PARAM_ERROR if one of the parameters is invalid.
// LZHAM_Z_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
// lzham_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by lzham_z_deflate(), assuming flush is set to only LZHAM_Z_NO_FLUSH or LZHAM_Z_FINISH.
// lzham_z_inflateInit2() is like lzham_z_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
// window_bits must be LZHAM_Z_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -LZHAM_Z_DEFAULT_WINDOW_BITS (raw stream with no zlib header/footer).
// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
// Parameters:
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
// flush may be LZHAM_Z_NO_FLUSH, LZHAM_Z_SYNC_FLUSH, or LZHAM_Z_FINISH.
// On the first call, if flush is LZHAM_Z_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
// LZHAM_Z_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
// Return values:
// LZHAM_Z_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
// LZHAM_Z_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
// LZHAM_Z_STREAM_ERROR if the stream is bogus.
// LZHAM_Z_DATA_ERROR if the deflate stream is invalid.
// LZHAM_Z_PARAM_ERROR if one of the parameters is invalid.
// LZHAM_Z_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call lzham_inflate() again
// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
// Returns a string description of the specified error code, or NULL if the error code is invalid.
LZHAM_DLL_EXPORTconstchar*lzham_z_error(interr);
// Redefine zlib-compatible names to lzham equivalents, so lzham can be used as a more or less drop-in replacement for the subset of zlib that lzham supports.
// Define LZHAM_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.