+ unsigned num_threads);
+
+/**
+ * @defgroup G_compression Compression and decompression functions
+ *
+ * @brief Functions for LZX, XPRESS, and LZMS compression and decompression,
+ * exported for convenience only, as they are already used by wimlib internally
+ * when appropriate.
+ *
+ * These functions can be used for general-purpose lossless data compression,
+ * but some limitations apply; for example, none of the compressors or
+ * decompressors currently support sliding windows, and there also exist
+ * slightly different variants of these formats that are not supported
+ * unmodified.
+ *
+ * @{
+ */
+
+/** Header for compression parameters to pass to wimlib_create_compressor() or
+ * wimlib_set_default_compressor_params(). */
+struct wimlib_compressor_params_header {
+ /** Size of the parameters, in bytes. */
+ uint32_t size;
+};
+
+/** Header for decompression parameters to pass to wimlib_create_decompressor()
+ * or wimlib_set_default_decompressor_params() */
+struct wimlib_decompressor_params_header {
+ /** Size of the parameters, in bytes. */
+ uint32_t size;
+};
+
+/** LZX compression parameters that can optionally be passed to
+ * wimlib_create_compressor() with the compression type
+ * ::WIMLIB_COMPRESSION_TYPE_LZX. */
+struct wimlib_lzx_compressor_params {
+ /** hdr.size Must be set to the size of this structure, in bytes. */
+ struct wimlib_compressor_params_header hdr;
+
+ /** Relatively fast LZX compression algorithm with a decent compression
+ * ratio. */
+#define WIMLIB_LZX_ALGORITHM_FAST 0
+
+ /** Slower LZX compression algorithm that provides a better compression
+ * ratio. This is the default. */
+#define WIMLIB_LZX_ALGORITHM_SLOW 1
+
+ /** Algorithm to use to perform the compression: either
+ * ::WIMLIB_LZX_ALGORITHM_FAST or ::WIMLIB_LZX_ALGORITHM_SLOW. The
+ * format is still LZX; this refers to the method the code will use to
+ * perform LZX-compatible compression. */
+ uint32_t algorithm : 3;
+
+ /** If set to 1, the default parameters for the specified algorithm are
+ * used rather than the ones specified in the following union. */
+ uint32_t use_defaults : 1;
+
+ union {
+ /** Parameters for the fast algorithm. */
+ struct wimlib_lzx_fast_params {
+ uint32_t fast_reserved1[10];
+ } fast;
+
+ /** Parameters for the "slow" algorithm. */
+ struct wimlib_lzx_slow_params {
+ /** If set to 1, the compressor can output length 2
+ * matches. If set 0, the compressor can only output
+ * matches of length 3 or greater. Suggested value: 1
+ */
+ uint32_t use_len2_matches : 1;
+
+ uint32_t slow_reserved1 : 31;
+
+ /** Matches with length (in bytes) greater than or equal
+ * to this value are immediately taken without spending
+ * time on minimum-cost measurements. Suggested value:
+ * 32. */
+ uint32_t nice_match_length;
+
+ /** Number of passes to compute a match/literal sequence
+ * for each LZX block. This is for an iterative
+ * algorithm that attempts to minimize the cost of the
+ * match/literal sequence by using a cost model provided
+ * by the previous iteration. Must be at least 1.
+ * Suggested value: 2. */
+ uint32_t num_optim_passes;
+
+ /** Reserved; set to 0. */
+ uint32_t slow_reserved_blocksplit;
+
+ /** Maximum depth to search for matches at each
+ * position. Suggested value: 50. */
+ uint32_t max_search_depth;
+
+ /* Note: max_matches_per_pos has been removed and no
+ * longer has any effect. */
+
+ uint32_t slow_reserved2[3];
+
+ /** Assumed cost of a main symbol with zero frequency.
+ * Must be at least 1 and no more than 16. Suggested
+ * value: 15. */
+ uint8_t main_nostat_cost;
+
+ /** Assumed cost of a length symbol with zero frequency.
+ * Must be at least 1 and no more than 16. Suggested
+ * value: 15. */
+ uint8_t len_nostat_cost;
+
+ /** Assumed cost of an aligned symbol with zero
+ * frequency. Must be at least 1 and no more than 8.
+ * Suggested value: 7. */
+ uint8_t aligned_nostat_cost;
+
+ uint8_t slow_reserved3[5];
+ } slow;
+ } alg_params;
+};
+
+/** LZMS compression parameters that can optionally be passed to
+ * wimlib_create_compressor() with the compression type
+ * ::WIMLIB_COMPRESSION_TYPE_LZMS. */
+struct wimlib_lzms_compressor_params {
+ /** hdr.size Must be set to the size of this structure, in bytes. */
+ struct wimlib_compressor_params_header hdr;
+
+ /** Minimum match length to output. This must be at least 2. Suggested
+ * value: 2 */
+ uint32_t min_match_length;
+
+ /** Maximum match length to output. This must be at least @p
+ * min_match_length. Suggested value: @p UINT32_MAX. */
+ uint32_t max_match_length;
+
+ /** Matches with length (in bytes) greater than or equal to this value
+ * are immediately taken without spending time on minimum-cost
+ * measurements. The minimum of @p max_match_length and @p
+ * nice_match_length may not exceed 65536. Suggested value: 32. */
+ uint32_t nice_match_length;
+
+ /** Maximum depth to search for matches at each position. Suggested
+ * value: 50. */
+ uint32_t max_search_depth;
+
+ /* Note: max_matches_per_pos has been removed and no longer has any
+ * effect. */
+
+ uint32_t reserved1;
+
+ /** Length of the array for the near-optimal LZ parsing algorithm. This
+ * must be at least 1. Suggested value: 1024. */
+ uint32_t optim_array_length;
+
+ uint64_t reserved2[4];
+};
+
+/** Opaque compressor handle. */
+struct wimlib_compressor;
+
+/** Opaque decompressor handle. */
+struct wimlib_decompressor;
+
+/**
+ * Set the default compression parameters for the specified compression type.
+ * This will affect both explicit and wimlib-internal calls to
+ * wimlib_create_compressor().
+ *
+ * @param ctype
+ * Compression type for which to set the default compression parameters.
+ * @param params
+ * Compression-type specific parameters. This may be @c NULL, in which
+ * case the "default default" parameters are restored.
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
+ * @p ctype was not a supported compression type.
+ * @retval ::WIMLIB_ERR_INVALID_PARAM
+ * @p params were invalid.
+ * @retval ::WIMLIB_ERR_NOMEM
+ * Not enough memory to duplicate the parameters (perhaps @c params->size
+ * was invalid).
+ */
+extern int
+wimlib_set_default_compressor_params(enum wimlib_compression_type ctype,
+ const struct wimlib_compressor_params_header *params);
+
+/**
+ * Returns the approximate number of bytes needed to allocate a compressor with
+ * wimlib_create_compressor() for the specified compression type, block size,
+ * and parameters. @p params may be @c NULL, in which case the current default
+ * parameters for @p ctype are used. Returns 0 if the compression type or
+ * parameters are invalid.
+ */
+extern uint64_t
+wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype,
+ size_t max_block_size,
+ const struct wimlib_compressor_params_header *params);
+
+/**
+ * Allocate a compressor for the specified compression type using the specified
+ * parameters.
+ *
+ * @param ctype
+ * Compression type for which to create the compressor.
+ * @param max_block_size
+ * Maximum block size to support. The exact meaning and allowed values for
+ * this parameter depend on the compression type, but it at least specifies
+ * the maximum allowed value for @p uncompressed_size to wimlib_compress().
+ * @param extra_params
+ * An optional pointer to extra compressor parameters for the specified
+ * compression type. For LZX, a pointer to ::wimlib_lzx_compressor_params
+ * may be specified here. If left @c NULL, the default parameters are
+ * used.
+ * @param compressor_ret
+ * A location into which to return the pointer to the allocated compressor,
+ * which can be used for any number of calls to wimlib_compress() before
+ * being freed with wimlib_free_compressor().
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
+ * @p ctype was not a supported compression type.
+ * @retval ::WIMLIB_ERR_INVALID_PARAM
+ * The compression parameters were invalid.
+ * @retval ::WIMLIB_ERR_NOMEM
+ * Insufficient memory to allocate the compressor.
+ */
+extern int
+wimlib_create_compressor(enum wimlib_compression_type ctype,
+ size_t max_block_size,
+ const struct wimlib_compressor_params_header *extra_params,
+ struct wimlib_compressor **compressor_ret);
+
+/**
+ * Losslessly compress a block of data using a compressor previously created
+ * with wimlib_create_compressor().
+ *
+ * @param uncompressed_data
+ * Buffer containing the data to compress.
+ * @param uncompressed_size
+ * Size, in bytes, of the data to compress.
+ * @param compressed_data
+ * Buffer into which to write the compressed data.
+ * @param compressed_size_avail
+ * Number of bytes available in @p compressed_data.
+ * @param compressor
+ * A compressor previously allocated with wimlib_create_compressor().
+ *
+ * @return
+ * The size of the compressed data, in bytes, or 0 if the input data could
+ * not be compressed to @p compressed_size_avail or fewer bytes.
+ */
+extern size_t
+wimlib_compress(const void *uncompressed_data, size_t uncompressed_size,
+ void *compressed_data, size_t compressed_size_avail,
+ struct wimlib_compressor *compressor);
+
+/**
+ * Free a compressor previously allocated with wimlib_create_compressor().
+ *
+ * @param compressor
+ * The compressor to free.
+ */
+extern void
+wimlib_free_compressor(struct wimlib_compressor *compressor);
+
+/**
+ * Set the default decompression parameters for the specified compression type.
+ * This will affect both explicit and wimlib-internal calls to
+ * wimlib_create_decompressor().
+ *
+ * @param ctype
+ * Compression type for which to set the default decompression parameters.
+ * @param params
+ * Compression-type specific parameters. This may be @c NULL, in which
+ * case the "default default" parameters are restored.
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
+ * @p ctype was not a supported compression type.
+ * @retval ::WIMLIB_ERR_NOMEM
+ * Not enough memory to duplicate the parameters (perhaps @c params->size
+ * was invalid).
+ */
+extern int
+wimlib_set_default_decompressor_params(enum wimlib_compression_type ctype,
+ const struct wimlib_decompressor_params_header *params);