chd-rs
Reimplementation of the CHD file format in pure Safe Rust, drop-in compatible with libchdr.
chd-rs aims to be a memory-safe, well documented, and clean from-scratch implementation of CHD, verifiable against chd.cpp while being easier to read and use as documentation to implement the format natively in other languages. It is standalone and can be built with just a Rust compiler, without the need for a full C/C++ toolchain.
Performance is competitive but a little slower than libchdr in benchmarks from using more immature (but fully correct) pure Rust implementations of compression codecs. Deflate (zlib) compression is backed by flate2, LZMA is backed by lzma-rs (modified slightly to allow headerless decoding of LZMA chunks), and FLAC decompression is backed by claxon. While performance is not ignored, the focus is on readability and correctness.
Usage
Open a ChdFile
with ChdFile::open
, then iterate hunks from 0 to chd.header().hunk_count()
to
read hunks.
The size of the destination buffer must be exactly chd.header().hunk_size()
to decompress with
hunk.read_hunk_in
, which takes the output slice and a buffer to hold compressed data.
For more ergonomic but slower usage, chd::read
provides buffered adapters that implement Read
and Seek
at the
hunk level. A buffered adapter at the file level is also available.
Lending Iterators
With unstable_lending_iterators
, hunks and metadata can be slightly more ergonomically iterated over
albeit with a while let
loop. This API is unstable until Generalized Associated Types
and the LendingIterator
trait is stabilized.
[]
= { = "0.1", = ["unstable_lending_iterators"] }
Then hunks can be iterated like so.
A similar API exists for metadata in ChdFile::metadata
.
Verifying Hunk Checksums
By default, chd-rs does not verify the checksums of decompressed hunks for performance. The feature verify_block_crc
should be enabled
to verify hunk checksums.
[]
= { = "0.1", = ["verify_block_crc"] }
Supported Codecs
chd-rs supports the following compression codecs, with wider coverage than libchdr. For implementation details,
see the chd::compression
module.
V1-4 Codecs
⚠️V1-4 support has not been as rigorously tested as V5 support. ⚠️
- None (
CHDCOMPRESSION_NONE
) - Zlib (
CHDCOMPRESSION_ZLIB
) - Zlib+ (
CHDCOMPRESSION_ZLIB
)
V5 Codecs
- None (
CHD_CODEC_NONE
) - LZMA (
CHD_CODEC_LZMA
) - Deflate (
CHD_CODEC_ZLIB
) - FLAC (
CHD_CODEC_FLAC
) - Huffman (
CHD_CODEC_HUFF
) - CD LZMA (
CHD_CODEC_CD_LZMA
) - CD Deflate (
CHD_CODEC_CD_ZLIB
) - CD FLAC (
CHD_CODEC_CD_FLAC
) - AV Huffman (
CHD_CODEC_AVHUFF
)
Codecs and Huffman API
By default, the codecs and static Huffman implementations are not exposed as part of the public API,
but can be enabled with the codec_api
and huffman_api
features respectively. These APIs are subject
to change but should be considered mostly stable.
In particular the type signature for HuffmanDecoder
is subject to change once generic_const_exprs
is stabilized.
rchdman
command line tool
As a proof of concept, chd-rs implements an extremely basic reimplementation of chdman for read-only purposes. The following functions are available with rchdman.
info
Displays information about a CHD.verify
Verify the integrity of a CHD. Metadata integrity is not verified.extractraw
Extract the raw file from a CHD input file.dumpmeta
Dump metadata from the CHD to stdout or to a file.
The results from rchdman should be identical from chdman. rchdman is intended to be basic and does not implement multithreading or other functions, so in general it is slower than chdman. There are no plans to implement write-operations into rchdman.
libchdr
API
⚠️The C API has not been heavily tested. Use at your own risk. ⚠️
chd-rs provides a C API compatible with chd.h. ABI compatibility is detailed below but is untested when compiling as a dynamic library. See /chd-rs-capi for more details.