]> wimlib.net Git - wimlib/blobdiff - include/wimlib.h
Comment fixes
[wimlib] / include / wimlib.h
index 00e8e5e7c582c2f237238064d4e8d48b10b7402b..4a47ebacbbdb70e7921b2e35d74c0b9c43cf9672 100644 (file)
  * 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
 
@@ -426,7 +417,11 @@ enum wimlib_compression_type {
        /** Compressed resources in the WIM use XPRESS compression. */
        WIMLIB_COMPRESSION_TYPE_XPRESS = 2,
 
-       /** TODO  */
+       /** 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,
 };
 
@@ -620,7 +615,10 @@ union wimlib_progress_info {
                        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
@@ -633,6 +631,21 @@ union wimlib_progress_info {
                 * ::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,
@@ -947,55 +960,64 @@ struct wimlib_wim_info {
        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 is_partial : 1;
+       /** 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;
-       uint64_t raw_resource_uncompressed_size;
+
+       /** 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[1];
+       uint64_t reserved[2];
 };
 
 /** A stream of a file in the WIM.  */
@@ -1289,7 +1311,9 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
 /** 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
@@ -1352,6 +1376,13 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
  * 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
  * @{ */
@@ -1513,6 +1544,29 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
 
 #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
  * @{ */
@@ -1654,97 +1708,6 @@ struct wimlib_extract_command {
        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;
-
-                       /** 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 LZX compression context.  */
-struct wimlib_lzx_context;
 
 /** @} */
 /** @ingroup G_general
@@ -2724,159 +2687,6 @@ wimlib_join(const wimlib_tchar * const *swms,
            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)
-                       _wimlib_deprecated;
-
-/**
- * @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 window_size
- *     Size of the LZX window.  Must be a power of 2 between 2^15 and 2^21,
- *     inclusively.
- *
- * @param params
- *     Compression parameters to use, or @c NULL to use the default 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 window size or compression parameters were invalid.
- * @retval ::WIMLIB_ERR_NOMEM
- *     Not enough memory to allocate the compression context.
- */
-extern int
-wimlib_lzx_alloc_context(uint32_t window_size,
-                        const struct wimlib_lzx_params *params,
-                        struct wimlib_lzx_context **ctx_pp);
-
-/**
- * @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_compression
- *
- * Equivalent to wimlib_lzx_decompress(), except the window size is specified in
- * @p max_window_size as any power of 2 between 2^15 and 2^21, inclusively, and
- * @p uncompressed_len may be any size less than or equal to @p max_window_size.
- */
-extern int
-wimlib_lzx_decompress2(const void *compressed_data, unsigned compressed_len,
-                      void *uncompressed_data, unsigned uncompressed_len,
-                      uint32_t max_window_size);
-
-/**
- * @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
- *
- * Set the global default LZX compression parameters.
- *
- * @param params
- *     The LZX compression parameters to set.  These default parameters will be
- *     used by any calls to wimlib_lzx_alloc_context() with @c NULL LZX
- *     parameters specified, as well as by any future compression performed by
- *     the library itself.  Passing @p NULL here resets the default LZX
- *     parameters to their original value.
- *
- * @return 0 on success; nonzero on error.
- *
- * @retval ::WIMLIB_ERR_INVALID_PARAM
- *     The compression parameters were invalid.
- */
-extern int
-wimlib_lzx_set_default_params(const struct wimlib_lzx_params *params);
-
-/**
- * @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_mounting_wim_images
@@ -3000,7 +2810,8 @@ wimlib_mount_image(WIMStruct *wim,
  *     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.
@@ -3394,9 +3205,9 @@ wimlib_set_image_descripton(WIMStruct *wim, int image,
  * increased compression chunk size is limited by the size of each file being
  * compressed.
  *
- * <b>WARNING: Changing the compression chunk size to any value other than the
- * default of 32768 bytes eliminates compatibility with Microsoft's software,
- * except when increasing the XPRESS chunk size before Windows 8.</b>
+ * <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.
@@ -3928,62 +3739,333 @@ wimlib_write_to_fd(WIMStruct *wim,
                   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
  *
- * Compress a chunk of data using XPRESS compression.
+ * Allocate a compressor for the specified compression type 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 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
  *
- * As of wimlib v1.5.4, this function can be used with @p chunk_size greater
- * than 32768 bytes and is only limited by available memory.  However, the
- * XPRESS format itself still caps match offsets to 65535, so if a larger chunk
- * size is chosen, then the matching will effectively occur in a sliding window
- * over it.
+ * Losslessly compress a block of data using a compressor previously created
+ * with wimlib_create_compressor().
  *
- * @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.
+ * @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 written to @p out in bytes, or 0 if the
- *     data could not be compressed to (@p chunk_size - 1) bytes or fewer.
+ *     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
+ *
+ * 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
  *
- * Decompresses a chunk of XPRESS-compressed data.
+ * Set the default decompression parameters for the specified compression type.
+ * This will affect both explicit and wimlib-internal calls to
+ * wimlib_create_decompressor().
  *
- * 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 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.
  *
- * @param compressed_data
- *     Pointer to the compressed data.
+ * @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);
+
+/**
+ * @ingroup G_compression
  *
- * @param compressed_len
- *     Length of the compressed data, in bytes.
+ * Allocate a decompressor for the specified compression type using the
+ * specified parameters.
  *
- * @param uncompressed_data
- *     Pointer to the buffer into which to write the uncompressed data.
+ * @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().
  *
- * @param uncompressed_len
- *     Length of the uncompressed data.
+ * @return 0 on success; nonzero on error.
  *
- * @return
- *     0 on success; non-zero on failure.
+ * @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_xpress_decompress(const void *compressed_data, unsigned compressed_len,
-                        void *uncompressed_data, unsigned uncompressed_len);
+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
 }