*
* @section sec_intro Introduction
*
- * This is the documentation for the library interface of wimlib 1.5.1, a C
+ * This is the documentation for the library interface of wimlib 1.5.3, a C
* library for creating, modifying, extracting, and mounting files in the
* Windows Imaging Format. This documentation is intended for developers only.
* If you have installed wimlib and want to know how to use the @b wimlib-imagex
* documented in the man page for @b wimlib-imagex.
*
* - The old WIM format from Vista pre-releases is not supported.
- * - Compressed resource chunk sizes other than 32768 are not supported. This
- * doesn't seem to be a real problem because the chunk size always seems to be
- * this value.
* - wimlib does not provide a clone of the @b PEImg tool, or the @b Dism
* functionality other than that already present in @b ImageX, that allows you
* to make certain Windows-specific modifications to a Windows PE image, such
* specialized function (wimlib_split()) is needed to create a split WIM.
*/
-/** @defgroup G_compression Compression and decompression functions
- *
- * @brief Functions for LZX and XPRESS compression and decompression, exported
- * for convenience only. These functions normally do not need to be used.
- */
-
#ifndef _WIMLIB_H
#define _WIMLIB_H
#define WIMLIB_MINOR_VERSION 5
/** Patch version of the library (for example, the 5 in 1.2.5). */
-#define WIMLIB_PATCH_VERSION 1
+#define WIMLIB_PATCH_VERSION 3
#ifdef __cplusplus
extern "C" {
/** Compressed resources in the WIM use XPRESS compression. */
WIMLIB_COMPRESSION_TYPE_XPRESS = 2,
+
+ /** Compressed resources in the WIM use LZMS compression. Currently,
+ * wimlib has a decompressor for this format but not a compressor. LZMS
+ * compression is only compatible with wimlib v1.6.0 and later and with
+ * WIMGAPI Windows 8 and later (and some restrictions apply on the
+ * latter). */
+ WIMLIB_COMPRESSION_TYPE_LZMS = 3,
};
/** @} */
WIMLIB_SCAN_DENTRY_OK = 0,
/** File or directory is being excluded from capture due
- * to the capture configuration file. */
+ * to the capture configuration file, or being an
+ * absolute symbolic link that points outside of the
+ * capture directory without ::WIMLIB_ADD_FLAG_NORPFIX.
+ */
WIMLIB_SCAN_DENTRY_EXCLUDED,
/** File or directory is being excluded from capture due
* ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and
* ::WIMLIB_PROGRESS_MSG_SCAN_END. */
const wimlib_tchar *wim_target_path;
+
+ /** Number of directories scanned so far, including the root
+ * directory but excluding any unsupported/excluded directories.
+ * */
+ uint64_t num_dirs_scanned;
+
+ /** Number of non-directories scanned so far, excluding any
+ * unsupported/excluded files. */
+ uint64_t num_nondirs_scanned;
+
+ /** Number of bytes of file data that have been detected so far.
+ * This data may not actually have been read yet, and it will
+ * not actually be written to the WIM file until wimlib_write()
+ * or wimlib_overwrite() has been called. */
+ uint64_t num_bytes_scanned;
} scan;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN,
uint32_t reserved[9];
};
-/** Information about a unique resource in the WIM file.
- */
+/** Information about a unique stream in the WIM file. (A stream is the same
+ * thing as a "resource", except in the case of packed resources.) */
struct wimlib_resource_entry {
- /** Uncompressed size of the resource in bytes. */
+ /** Uncompressed size of the stream in bytes. */
uint64_t uncompressed_size;
- /** Compressed size of the resource in bytes. This will be the same as
- * @p uncompressed_size if the resource is uncompressed. */
+ /** Compressed size of the stream in bytes. This will be the same as @p
+ * uncompressed_size if the stream is uncompressed. Or, if @p
+ * is_packed_streams is 1, this will be 0. */
uint64_t compressed_size;
- /** Offset, in bytes, of this resource from the start of the WIM file.
+ /** Offset, in bytes, of this stream from the start of the WIM file. Or
+ * if @p packed is 1, then this is actually the offset at which this
+ * stream begins in the uncompressed contents of the packed resource.
*/
uint64_t offset;
- /** SHA1 message digest of the resource's uncompressed contents. */
+ /** SHA1 message digest of the stream's uncompressed contents. */
uint8_t sha1_hash[20];
- /** Which part number of the split WIM this resource is in. This should
+ /** Which part number of the split WIM this stream is in. This should
* be the same as the part number provided by wimlib_get_wim_info(). */
uint32_t part_number;
- /** Number of times this resource is referenced over all WIM images. */
+ /** Number of times this stream is referenced over all WIM images. */
uint32_t reference_count;
- /** 1 if this resource is compressed. */
+ /** 1 if this stream is compressed. */
uint32_t is_compressed : 1;
- /** 1 if this resource is a metadata resource rather than a file
- * resource. */
+ /** 1 if this stream is a metadata resource rather than a file resource.
+ * */
uint32_t is_metadata : 1;
uint32_t is_free : 1;
uint32_t is_spanned : 1;
- /** 1 if this resource was not found in the lookup table of the
+ /** 1 if this stream was not found in the lookup table of the
* ::WIMStruct. This normally implies a missing call to
* wimlib_reference_resource_files() or wimlib_reference_resources().
- */
+ * */
uint32_t is_missing : 1;
- uint32_t reserved_flags : 27;
- uint64_t reserved[4];
+ /** 1 if this stream is located in a packed resource which may contain
+ * other streams (all compressed together) as well. */
+ uint32_t packed : 1;
+
+ uint32_t reserved_flags : 26;
+
+ /** If @p packed is 1, then this will specify the offset of the packed
+ * resource in the WIM. */
+ uint64_t raw_resource_offset_in_wim;
+
+ /** If @p is_packed_streams is 1, then this will specify the compressed
+ * size of the packed resource in the WIM. */
+ uint64_t raw_resource_compressed_size;
+
+ uint64_t reserved[2];
};
/** A stream of a file in the WIM. */
/** This flag no longer does anything but is reserved for future use. */
#define WIMLIB_EXTRACT_FLAG_VERBOSE 0x00000008
-/** Read the WIM file sequentially while extracting the image. */
+/** Read the WIM file sequentially while extracting the image. As of wimlib
+ * v1.6.0 this is the default behavior, and this flag no longer does anything.
+ */
#define WIMLIB_EXTRACT_FLAG_SEQUENTIAL 0x00000010
/** Extract special UNIX data captured with ::WIMLIB_ADD_FLAG_UNIX_DATA. Only
* behavior is currently less than satisfactory. Do not use (yet). */
#define WIMLIB_EXTRACT_FLAG_RESUME 0x00010000
+/** Perform the extraction ordered by the tree of files to extract rather than
+ * how the underlying streams are arranged in the WIM file. For regular WIM
+ * files this may decrease or increase performance, depending on various
+ * factors. For WIM files containing packed streams this will decrease
+ * performance. */
+#define WIMLIB_EXTRACT_FLAG_FILE_ORDER 0x00020000
+
/** @} */
/** @ingroup G_mounting_wim_images
* @{ */
* already implied for wimlib_overwrite(). */
#define WIMLIB_WRITE_FLAG_STREAMS_OK 0x00000400
-/** Use the slow LZX compression algorithm (rather than the default fast LZX
- * compression algorithm) to try to achieve a higher compression ratio. Only
- * has an effect if the WIM uses LZX compression; not to be confused with "fast"
- * (XPRESS) compression. This can be combined with
- * ::WIMLIB_WRITE_FLAG_RECOMPRESS. */
-#define WIMLIB_WRITE_FLAG_COMPRESS_SLOW 0x00000800
+#define WIMLIB_WRITE_FLAG_RESERVED 0x00000800
+
+/** When writing streams in the resulting WIM file, pack multiple streams into a
+ * single WIM resource instead of compressing them independently. This tends to
+ * produce a better compression ratio at the cost of less random access.
+ * Furthermore, WIMs created with this flag are only compatible with wimlib
+ * v1.6.0 or later and WIMGAPI Windows 8 or later, seemingly for Windows Setup
+ * only and <b>not including ImageX and Dism</b>. WIMs created with this flag
+ * use version number 3584 in their header instead of 68864. If this flag is
+ * passed to wimlib_overwrite() and the WIM did not previously contain packed
+ * streams, the WIM's version number will be changed to 3584 and the new streams
+ * will be written packed. */
+#define WIMLIB_WRITE_FLAG_PACK_STREAMS 0x00001000
+
+/** Compress all streams independently. This produces a WIM optimized for
+ * random access and compatibility, as noted in the documentation for
+ * ::WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS. For wimlib_write(), this is the
+ * default behavior. For wimlib_overwrite(), this is the default if the WIM file
+ * did not already contain packed streams. Also, for wimlib_overwrite(), if the
+ * WIM already contained packed streams, specifying this flag but not
+ * ::WIMLIB_WRITE_FLAG_REBUILD will cause new streams to be written unpacked,
+ * but the WIM itself will not be rebuilt and may still contain packed streams.
+ */
+#define WIMLIB_WRITE_FLAG_NO_PACK_STREAMS 0x00002000
/** @} */
/** @ingroup G_general
int extract_flags;
};
-/** @} */
-/** @ingroup G_compression
- * @{ */
-
-/** LZX compression parameters to pass to wimlib_lzx_alloc_context(). */
-struct wimlib_lzx_params {
- /** Must be set to the size of this structure, in bytes. */
- uint32_t size_of_this;
-
- /** Relatively fast LZX compression algorithm with a decent compression
- * ratio; the suggested default. */
-#define WIMLIB_LZX_ALGORITHM_FAST 0
-
- /** Slower LZX compression algorithm that provides a better compression
- * ratio. */
-#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 only outputs
- * matches of length 3 or greater. Suggested value: 1
- */
- uint32_t use_len2_matches : 1;
-
- uint32_t slow_reserved1 : 31;
-
- /** This is the maximum match length to return from the
- * binary tree match-finder. Any match reaching this
- * limit is still extended as far as possible. Must be
- * at least 3 and no more than 257. Suggested value:
- * 32. */
- uint32_t num_fast_bytes;
-
- /** 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: 3. */
- uint32_t num_optim_passes;
-
- /** The number of times to attempt to recursively split
- * each LZX block. Up to (2**(num_split_passes)
- * sub-blocks can be created for a given input. This
- * parameter can be 0, in which case the full input is
- * always output as one block. Suggested value: 3.
- */
- uint32_t num_split_passes;
-
- uint32_t slow_reserved2[4];
-
- /** 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;
- };
-};
-
-/** Opaque LZX compression context. */
-struct wimlib_lzx_context;
/** @} */
/** @ingroup G_general
* Extracts the XML data of a WIM file to a file stream. Every WIM file
* includes a string of XML that describes the images contained in the WIM.
*
+ * See wimlib_get_xml_data() to read the XML data into memory instead.
+ *
* @param wim
* Pointer to the ::WIMStruct for a WIM file, which does not necessarily
* have to be standalone (e.g. it could be part of a split WIM).
extern int
wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);
+/**
+ * @ingroup G_wim_information
+ *
+ * Read the XML data of a WIM file into an in-memory buffer. Every WIM file
+ * includes a string of XML that describes the images contained in the WIM.
+ *
+ * See wimlib_extract_xml_data() to extract the XML data to a file stream
+ * instead.
+ *
+ * @param wim
+ * Pointer to the ::WIMStruct for a WIM file, which does not necessarily
+ * have to be standalone (e.g. it could be part of a split WIM).
+ * @param buf_ret
+ * On success, a pointer to an allocated buffer containing the raw UTF16-LE
+ * XML data is written to this location.
+ * @param bufsize_ret
+ * The size of the XML data in bytes is written to this location.
+ *
+ * @return 0 on success; nonzero on error.
+ * @retval ::WIMLIB_ERR_INVALID_PARAM
+ * @p wim is not a ::WIMStruct that was created by wimlib_open_wim(), or
+ * @p buf_ret or @p bufsize_ret was @c NULL.
+ * @retval ::WIMLIB_ERR_NOMEM
+ * @retval ::WIMLIB_ERR_READ
+ * @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE
+ * Failed to read the XML data from the WIM.
+ */
+extern int
+wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret);
+
/**
* @ingroup G_general
*
int wim_write_flags,
wimlib_progress_func_t progress_func);
-/**
- * @ingroup G_compression
- *
- * Compress a chunk of a WIM resource using LZX compression.
- *
- * This function is exported for convenience only and should only be used by
- * library clients looking to make use of wimlib's compression code for another
- * purpose.
- *
- * @param chunk
- * Uncompressed data of the chunk.
- * @param chunk_size
- * Size of the uncompressed chunk, in bytes.
- * @param out
- * Pointer to output buffer of size at least (@p chunk_size - 1) bytes.
- *
- * @return
- * The size of the compressed data written to @p out in bytes, or 0 if the
- * data could not be compressed to (@p chunk_size - 1) bytes or fewer.
- *
- * As a special requirement, the compression code is optimized for the WIM
- * format and therefore requires (@p chunk_size <= 32768).
- */
-extern unsigned
-wimlib_lzx_compress(const void *chunk, unsigned chunk_size, void *out);
-
-/**
- * @ingroup G_compression
- *
- * Equivalent to wimlib_lzx_compress(), but uses the specified compression
- * context, allocated by wimlib_lzx_alloc_context().
- */
-extern unsigned
-wimlib_lzx_compress2(const void *chunk, unsigned chunk_size, void *out,
- struct wimlib_lzx_context *ctx);
-
-/**
- * @ingroup G_compression
- *
- * Allocate a LZX compression context using the specified parameters.
- *
- * This function is exported for convenience only and should only be used by
- * library clients looking to make use of wimlib's compression code for another
- * purpose.
- *
- * @param params
- * Compression parameters to use, or @c NULL to use the default algorithm
- * and parameters.
- *
- * @param ctx_ret
- * A pointer to either @c NULL or an existing ::wimlib_lzx_context. If
- * <code>*ctx_ret == NULL</code>, the new context is allocated. If
- * <code>*ctx_ret != NULL</code>, the existing context is re-used if
- * possible. Alternatively, this argument can itself be @c NULL to
- * indicate that only parameter validation is to be performed.
- *
- * @return 0 on success; nonzero on error.
- *
- * @retval ::WIMLIB_ERR_INVALID_PARAM
- * The compression parameters were invalid.
- * @retval ::WIMLIB_ERR_NOMEM
- * Not enough memory to allocate the compression context.
- */
-extern int
-wimlib_lzx_alloc_context(const struct wimlib_lzx_params *params,
- struct wimlib_lzx_context **ctx_pp);
-
-/**
- * @ingroup G_compression
- *
- * Free the specified LZX compression context, allocated with
- * wimlib_lzx_alloc_context().
- */
-extern void
-wimlib_lzx_free_context(struct wimlib_lzx_context *ctx);
-
-/**
- * @ingroup G_compression
- *
- * Decompresses a block of LZX-compressed data as used in the WIM file format.
- *
- * Note that this will NOT work unmodified for LZX as used in the cabinet
- * format, which is not the same as in the WIM format!
- *
- * This function is exported for convenience only and should only be used by
- * library clients looking to make use of wimlib's compression code for another
- * purpose.
- *
- * @param compressed_data
- * Pointer to the compressed data.
- *
- * @param compressed_len
- * Length of the compressed data, in bytes.
- *
- * @param uncompressed_data
- * Pointer to the buffer into which to write the uncompressed data.
- *
- * @param uncompressed_len
- * Length of the uncompressed data. It must be 32768 bytes or less.
- *
- * @return
- * 0 on success; non-zero on failure.
- */
-extern int
-wimlib_lzx_decompress(const void *compressed_data, unsigned compressed_len,
- void *uncompressed_data, unsigned uncompressed_len);
-
/**
* @ingroup G_mounting_wim_images
* chunk of the WIM does not match the corresponding message digest given
* in the integrity table.
* @retval ::WIMLIB_ERR_INVALID_CHUNK_SIZE
- * Resources in @p wim_file are compressed, but the chunk size is not 32768.
+ * Resources in @p wim_file are compressed, but the chunk size was invalid
+ * for the WIM's compression format.
* @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
* The header of @p wim_file says that resources in the WIM are compressed,
* but the header flag indicating LZX or XPRESS compression is not set.
wimlib_set_image_descripton(WIMStruct *wim, int image,
const wimlib_tchar *description);
+/**
+ * @ingroup G_writing_and_overwriting_wims
+ *
+ * Set the compression chunk size of a WIM to use in subsequent calls to
+ * wimlib_write() or wimlib_overwrite().
+ *
+ * A compression chunk size will result in a greater compression ratio, but the
+ * speed of random access to the WIM will be reduced, and the effect of an
+ * increased compression chunk size is limited by the size of each file being
+ * compressed.
+ *
+ * <b>WARNING: Microsoft's software is seemingly incompatible with LZX chunk
+ * sizes other than 32768. Chunk sizes other than 32768 (for any format) are
+ * also incompatible with wimlib v1.5.3 and earlier.</b>
+ *
+ * @param wim
+ * ::WIMStruct for a WIM.
+ * @param out_chunk_size
+ * The chunk size (in bytes) to set. The valid chunk sizes are dependent
+ * on the compression format. The XPRESS compression format supports chunk
+ * sizes that are powers of 2 with exponents between 15 and 26 inclusively,
+ * whereas the LZX compression format supports chunk sizes that are powers
+ * of 2 with exponents between 15 and 21 inclusively.
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_CHUNK_SIZE
+ * @p ctype is not a supported chunk size.
+ */
+extern int
+wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size);
+
+/**
+ * @ingroup G_writing_and_overwriting_wims
+ *
+ * Set the compression type of a WIM to use in subsequent calls to
+ * wimlib_write() or wimlib_overwrite().
+ *
+ * @param wim
+ * ::WIMStruct for a WIM.
+ * @param ctype
+ * The compression type to set (one of ::wimlib_compression_type). If this
+ * compression type is incompatible with the current output chunk size
+ * (either the default or as set with wimlib_set_output_chunk_size()), the
+ * output chunk size is reset to the default for that compression type.
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_PARAM
+ * @p ctype did not specify a valid compression type.
+ */
+extern int
+wimlib_set_output_compression_type(WIMStruct *wim, int ctype);
+
/**
* @ingroup G_modifying_wims
*
* A function equivalent to @c realloc() that wimlib will use to reallocate
* memory. If @c NULL, the free function is set back to the default @c
* realloc() from the C library.
- * @return 0 on success; nonzero on error.
- * @retval ::WIMLIB_ERR_UNSUPPORTED
- * wimlib was compiled with the @c --without-custom-memory-allocator flag,
- * so custom memory allocators are unsupported.
+ * @return 0
*/
extern int
wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
unsigned num_threads,
wimlib_progress_func_t progress_func);
+/**
+ * @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.
+ */
+
+/**
+ * @ingroup G_compression
+ * @{
+ */
+
+/** 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;
+
+ uint32_t reserved;
+};
+
+/** 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;
+
+ uint32_t reserved;
+};
+
+/** 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; the suggested default. */
+#define WIMLIB_LZX_ALGORITHM_FAST 0
+
+ /** Slower LZX compression algorithm that provides a better compression
+ * ratio. */
+#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 only outputs
+ * 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) longer than this
+ * value are immediately taken without spending time on
+ * minimum-cost measurements. Suggested value: 32. */
+ uint32_t num_fast_bytes;
+
+ /** 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;
+
+ /** Maximum number of potentially good matches to
+ * consider for each position. Suggested value: 3. */
+ uint32_t max_matches_per_pos;
+
+ uint32_t slow_reserved2[2];
+
+ /** 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;
+};
+
+/** Opaque compressor handle. */
+struct wimlib_compressor;
+
+/** Opaque decompressor handle. */
+struct wimlib_decompressor;
+
+/** @} */
+
+/**
+ * @ingroup G_compression
+ *
+ * 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_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);
+
+/**
+ * @ingroup G_compression
+ *
+ * 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);
+
+/**
+ * @ingroup G_compression
+ *
+ * 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);
+
/**
* @ingroup G_compression
*
- * This function is equivalent to wimlib_lzx_compress(), but instead compresses
- * the data using "XPRESS" compression.
+ * Free a compressor previously allocated with wimlib_create_compressor().
+ *
+ * @param compressor
+ * The compressor to free.
*/
-extern unsigned
-wimlib_xpress_compress(const void *chunk, unsigned chunk_size, void *out);
+extern void
+wimlib_free_compressor(struct wimlib_compressor *compressor);
/**
* @ingroup G_compression
*
- * This function is equivalent to wimlib_lzx_decompress(), but instead assumes
- * the data is compressed using "XPRESS" compression.
+ * 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_xpress_decompress(const void *compressed_data, unsigned compressed_len,
- void *uncompressed_data, unsigned uncompressed_len);
+wimlib_set_default_decompressor_params(enum wimlib_compression_type ctype,
+ const struct wimlib_decompressor_params_header *params);
+
+/**
+ * @ingroup G_compression
+ *
+ * Allocate a decompressor for the specified compression type using the
+ * specified parameters.
+ *
+ * @param ctype
+ * Compression type for which to create the decompressor.
+ * @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_decompress().
+ * @param extra_params
+ * An optional pointer to extra decompressor parameters for the specified
+ * compression type. If @c NULL, the default parameters are used.
+ * @param decompressor_ret
+ * A location into which to return the pointer to the allocated
+ * decompressor, which can be used for any number of calls to
+ * wimlib_decompress() before being freed with wimlib_free_decompressor().
+ *
+ * @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 decompression parameters were invalid.
+ * @retval ::WIMLIB_ERR_NOMEM
+ * Insufficient memory to allocate the decompressor.
+ */
+extern int
+wimlib_create_decompressor(enum wimlib_compression_type ctype,
+ size_t max_block_size,
+ const struct wimlib_decompressor_params_header *extra_params,
+ struct wimlib_decompressor **decompressor_ret);
+
+/**
+ * @ingroup G_compression
+ *
+ * Decompress a block of data using a decompressor previously created with
+ * wimlib_create_decompressor().
+ *
+ * @param compressed_data
+ * Buffer containing the data to decompress.
+ * @param compressed_size
+ * Size, in bytes, of the data to decompress.
+ * @param uncompressed_data
+ * Buffer into which to write the uncompressed data.
+ * @param uncompressed_size
+ * Size, in bytes, of the data when uncompressed.
+ * @param decompressor
+ * A decompressor previously allocated with wimlib_create_decompressor().
+ *
+ * @return 0 on success; nonzero on error.
+ */
+extern int
+wimlib_decompress(const void *compressed_data, size_t compressed_size,
+ void *uncompressed_data, size_t uncompressed_size,
+ struct wimlib_decompressor *decompressor);
+
+/**
+ * @ingroup G_compression
+ *
+ * Free a decompressor previously allocated with wimlib_create_decompressor().
+ *
+ * @param decompressor
+ * The decompressor to free.
+ */
+extern void
+wimlib_free_decompressor(struct wimlib_decompressor *decompressor);
+
#ifdef __cplusplus
}