+ unsigned num_threads);
+
+/**
+ * @defgroup G_compression Compression and decompression functions
+ *
+ * @brief Functions for XPRESS, LZX, and LZMS compression and decompression.
+ *
+ * These functions are already used by wimlib internally when appropriate for
+ * reading and writing WIM archives. But they are exported and documented so
+ * that they can be used in other applications or libraries for general-purpose
+ * lossless data compression. They are implemented in highly optimized C code,
+ * using state-of-the-art compression techniques. The main limitation is the
+ * lack of sliding window support; this has, however, allowed the algorithms to
+ * be optimized for block-based compression.
+ *
+ * @{
+ */
+
+/** Opaque compressor handle. */
+struct wimlib_compressor;
+
+/** Opaque decompressor handle. */
+struct wimlib_decompressor;
+
+/**
+ * Set the default compression level for the specified compression type. This
+ * is the compression level that wimlib_create_compressor() assumes if it is
+ * called with @p compression_level specified as 0.
+ *
+ * wimlib's WIM writing code (e.g. wimlib_write()) will pass 0 to
+ * wimlib_create_compressor() internally. Therefore, calling this function will
+ * affect the compression level of any data later written to WIM files using the
+ * specified compression type.
+ *
+ * The initial state, before this function is called, is that all compression
+ * types have a default compression level of 50.
+ *
+ * @param ctype
+ * Compression type for which to set the default compression level, as one
+ * of the ::wimlib_compression_type constants. Or, if this is the special
+ * value -1, the default compression levels for all compression types will
+ * be set.
+ * @param compression_level
+ * The default compression level to set. If 0, the "default default" level
+ * of 50 is restored. Otherwise, a higher value indicates higher
+ * compression, whereas a lower value indicates lower compression. See
+ * wimlib_create_compressor() for more information.
+ *
+ * @return 0 on success; nonzero on error.
+ *
+ * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
+ * @p ctype was neither a supported compression type nor -1.
+ */
+extern int
+wimlib_set_default_compression_level(int ctype, unsigned int compression_level);
+
+/**
+ * Returns the approximate number of bytes needed to allocate a compressor with
+ * wimlib_create_compressor() for the specified compression type, maximum block
+ * size, and compression level. @p compression_level may be 0, in which case
+ * the current default compression level for @p ctype is used. Returns 0 if the
+ * compression type is invalid, or the @p max_block_size for that compression
+ * type is invalid.
+ */
+extern uint64_t
+wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype,
+ size_t max_block_size,
+ unsigned int compression_level);
+
+/**
+ * Allocate a compressor for the specified compression type using the specified
+ * parameters. This function is part of wimlib's compression API; it is not
+ * necessary to call this to process a WIM file.
+ *
+ * @param ctype
+ * Compression type for which to create the compressor, as one of the
+ * ::wimlib_compression_type constants.
+ * @param max_block_size
+ * The maximum compression block size to support. This specifies the
+ * maximum allowed value for the @p uncompressed_size parameter of
+ * wimlib_compress() when called using this compressor.
+ * <br/>
+ * Usually, the amount of memory used by the compressor will scale in
+ * proportion to the @p max_block_size parameter.
+ * wimlib_get_compressor_needed_memory() can be used to query the specific
+ * amount of memory that will be required.
+ * <br/>
+ * This parameter must be at least 1 and must be less than or equal to a
+ * compression-type-specific limit.
+ * <br/>
+ * In general, the same value of @p max_block_size must be passed to
+ * wimlib_create_decompressor() when the data is later decompressed.
+ * However, some compression types have looser requirements regarding this.
+ * @param compression_level
+ * The compression level to use. If 0, the default compression level (50,
+ * or another value as set through wimlib_set_default_compression_level())
+ * is used. Otherwise, a higher value indicates higher compression. The
+ * values are scaled so that 10 is low compression, 50 is medium
+ * compression, and 100 is high compression. This is not a percentage;
+ * values above 100 are also valid.
+ * <br/>
+ * Using a higher-than-default compression level can result in a better
+ * compression ratio, but can significantly reduce performance. Similarly,
+ * using a lower-than-default compression level can result in better
+ * performance, but can significantly worsen the compression ratio. The
+ * exact results will depend heavily on the compression type and what
+ * algorithms are implemented for it. If you are considering using a
+ * non-default compression level, you should run benchmarks to see if it is
+ * worthwhile for your application.
+ * <br/>
+ * The compression level does not affect the format of the compressed data.
+ * Therefore, it is a compressor-only parameter and does not need to be
+ * passed to the decompressor.
+ * @param compressor_ret
+ * A location into which to return the pointer to the allocated compressor.
+ * The allocated compressor 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
+ * @p max_block_size was invalid for the compression type, or @p
+ * compressor_ret was @c NULL.
+ * @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,
+ unsigned int compression_level,
+ struct wimlib_compressor **compressor_ret);
+
+/**
+ * Compress a buffer of data.
+ *
+ * @param uncompressed_data
+ * Buffer containing the data to compress.
+ * @param uncompressed_size
+ * Size, in bytes, of the data to compress. This cannot be greater than
+ * the @p max_block_size with which wimlib_create_compressor() was called.
+ * (If it is, the data will not be compressed and 0 will be returned.)
+ * @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 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. If @c NULL, no action is taken.
+ */
+extern void
+wimlib_free_compressor(struct wimlib_compressor *compressor);