Clean-room C implementation of the Windows Imaging (WIM) format. Creates, extracts, and inspects WIM archives compatible with Microsoft DISM, ImageX, and wimlib-imagex.
Not a fork of wimlib. Every component (XPRESS Huffman codec, SHA-1 deduplication, metadata serializer, bitstream encoder) was written from scratch based on format analysis alone.
cmake -B build
cmake --build build
# Capture a directory
./build/wimage capture /my/files backup.wim "My Backup" --compress=xpress --threads=4
# List contents
./build/wimage dir backup.wim
# Extract
./build/wimage apply backup.wim 1 /restore/here
# Verify integrity
./build/wimage capture /data archive.wim "Data" --check
./build/wimage verify archive.wimwimage capture <source> <wimfile> [name] [--compress=xpress|none] [--threads=N] [--check]
wimage apply <wimfile> [image] <target>
wimage info <wimfile> [--header] [--xml] [--blobs]
wimage dir <wimfile> [--detailed]
wimage verify <wimfile>
wimage extract <wimfile> <image> [paths...] [--dest-dir=DIR]
- XPRESS Huffman compression and decompression
- SHA-1 content-addressed deduplication
- Multi-threaded compression
- Integrity table generation and verification
- Full interoperability with wimlib-imagex and Microsoft DISM
libwim/ is a self-contained pure C11 library with zero external dependencies. Copy the directory into your project and compile:
#include "wim_read.h"
WimCtx ctx;
wim_ctx_init(&ctx);
wim_open(&ctx, "image.wim");
wim_select_image(&ctx, 1);
wim_extract_tree(&ctx, wim_get_root(&ctx, 1), "/output");
wim_close(&ctx);Designed for constrained environments: bootloaders, firmware, OS installers.
Linux x86_64, GCC -O3, OpenSSL SHA-1, SSE2 codec hot paths, 32-core host,
wimlib-imagex 1.13.6. Mixed synthetic data, ~75 % compression ratio.
Reproduced with scripts/test_smp_big.py.
| Tool | 256 MB | 512 MB | 1 GB |
|---|---|---|---|
| wimage SMP1 | 1061 | 1048 | 1084 |
| wimage SMP8 | 1389 | 1439 | 1393 |
| wimage SMP16 | 1357 | 1362 | 1373 |
| wimlib-imagex | 1164 | 1169 | 1186 |
Single-threaded wimage is within 10 % of wimlib (the 16-byte SSE2
match_len closes most of the old gap). At SMP8+ the persistent thread
pool + fused XPRESS emit pass beat wimlib by ~20 %.
| Direction | 256 MB | 512 MB | 1 GB |
|---|---|---|---|
| wimage decoder | 1024 | 1004 | 1004 |
| wimlib decoder | 1067 | 1089 | 1113 |
Wimage decompresses wimlib-compressed WIMs and vice-versa; SHA-1 of the
extracted file matches bit-for-bit in both directions. The match-copy
fast path uses _mm_loadu_si128/_mm_storeu_si128 when the match
offset is ≥ 16 bytes (the common case), bringing decode to within 6 %
of wimlib's hand-tuned decoder.
# Unit tests
cmake -B build -DENABLE_TESTS=ON && cmake --build build
./build/wimage_tests # 118 tests
# Integration tests (requires wimlib-imagex)
cd scripts && python3 test_compare.py && python3 test_random250.pyGPL-2.0-or-later