]> wimlib.net Git - wimlib/blobdiff - include/wimlib.h
Scan progress: Add # of files, directories, and bytes scanned
[wimlib] / include / wimlib.h
index 7bab4a34170e1a36ce2505cb29e82dabadc78147..71ef0a8e160d0270bf3497b3621f663bc2cfbe2e 100644 (file)
@@ -33,7 +33,7 @@
  *
  * @section sec_intro Introduction
  *
- * This is the documentation for the library interface of wimlib 1.5.2, 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
 #define WIMLIB_MINOR_VERSION 5
 
 /** Patch version of the library (for example, the 5 in 1.2.5). */
-#define WIMLIB_PATCH_VERSION 2
+#define WIMLIB_PATCH_VERSION 3
 
 #ifdef __cplusplus
 extern "C" {
@@ -425,6 +425,13 @@ enum wimlib_compression_type {
 
        /** 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,
 };
 
 /** @} */
@@ -630,6 +637,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,
@@ -944,48 +966,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 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.  */
@@ -1279,7 +1317,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
@@ -1342,6 +1382,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
  * @{ */
@@ -1501,12 +1548,30 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
  * 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
@@ -1692,11 +1757,9 @@ struct wimlib_lzx_params {
 
                        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.  */
+                       /** 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
@@ -1704,18 +1767,21 @@ struct wimlib_lzx_params {
                         * 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.  */
+                        * Suggested value: 2.  */
                        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;
+                       /** 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;
 
-                       uint32_t slow_reserved2[4];
+                       /** 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
@@ -2718,6 +2784,45 @@ wimlib_join(const wimlib_tchar * const *swms,
            int wim_write_flags,
            wimlib_progress_func_t progress_func);
 
+/**
+ * @ingroup G_compression
+ *
+ * Decompresses a block of LZMS-compressed data.
+ *
+ * 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.
+ *
+ * This decompressor only implements "raw" decompression, which decompresses a
+ * single LZMS-compressed block.  This behavior is the same as that of
+ * Decompress() in the Windows 8 compression API when using a compression handle
+ * created with CreateDecompressor() with the Algorithm parameter specified as
+ * COMPRESS_ALGORITHM_LZMS | COMPRESS_RAW.  Presumably, non-raw LZMS data
+ * is a container format from which the locations and sizes (both compressed and
+ * uncompressed) of the constituent blocks can be determined.
+ *
+ * This function should not be called for blocks with compressed size equal to
+ * uncompressed size, since such blocks are actually stored uncompressed.
+ *
+ * @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.
+ *
+ * @return
+ *     0 on success; non-zero on failure.
+ */
+extern int
+wimlib_lzms_decompress(const void *compressed_data, unsigned compressed_len,
+                      void *uncompressed_data, unsigned uncompressed_len);
+
 /**
  * @ingroup G_compression
  *
@@ -2764,9 +2869,12 @@ wimlib_lzx_compress2(const void *chunk, unsigned chunk_size, void *out,
  * 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 algorithm
- *     and parameters.
+ *     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
@@ -2778,23 +2886,15 @@ wimlib_lzx_compress2(const void *chunk, unsigned chunk_size, void *out,
  * @return 0 on success; nonzero on error.
  *
  * @retval ::WIMLIB_ERR_INVALID_PARAM
- *     The compression parameters were invalid.
+ *     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(const struct wimlib_lzx_params *params,
+wimlib_lzx_alloc_context(uint32_t window_size,
+                        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
  *
@@ -2826,6 +2926,56 @@ 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
@@ -2949,7 +3099,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.
@@ -3332,6 +3483,61 @@ extern int
 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: 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.  Chunk sizes
+ * other than 32768 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
  *
@@ -3826,8 +4032,28 @@ wimlib_write_to_fd(WIMStruct *wim,
 /**
  * @ingroup G_compression
  *
- * This function is equivalent to wimlib_lzx_compress(), but instead compresses
- * the data using "XPRESS" compression.
+ * Compress a chunk of data using XPRESS 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.
+ *
+ * As of wimlib v1.6.0, 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.
+ *
+ * @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.
  */
 extern unsigned
 wimlib_xpress_compress(const void *chunk, unsigned chunk_size, void *out);
@@ -3835,8 +4061,26 @@ wimlib_xpress_compress(const void *chunk, unsigned chunk_size, void *out);
 /**
  * @ingroup G_compression
  *
- * This function is equivalent to wimlib_lzx_decompress(), but instead assumes
- * the data is compressed using "XPRESS" compression.
+ * Decompresses a chunk of XPRESS-compressed data.
+ *
+ * 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.
+ *
+ * @return
+ *     0 on success; non-zero on failure.
  */
 extern int
 wimlib_xpress_decompress(const void *compressed_data, unsigned compressed_len,