21个版本
0.3.2 | 2024年6月17日 |
---|---|
0.3.1 | 2024年2月20日 |
0.2.3 | 2022年8月13日 |
0.1.0 |
|
0.0.1 |
|
54 在 压缩 类别中
每月 78 次下载
用于 chd-capi
235KB
4K SLoC
chd-rs
在纯Safe Rust中重新实现CHD文件格式,与libchdr直接兼容。
chd-rs旨在成为内存安全、文档完善、从头开始实现的CHD库,可通过chd.cpp进行验证,同时易于阅读和使用作为在其它语言中本地实现该格式的文档。它是独立的,并且只需Rust编译器即可构建,无需完整的C/C++工具链。
性能具有竞争力,但在基准测试中略慢于libchdr,这是由于使用了更成熟的(但完全正确)纯Rust压缩编解码器实现。Deflate(zlib)压缩由flate2支持,LZMA由lzma-rs支持,而FLAC解压缩由claxon支持。虽然性能很重要,但重点是可读性和正确性。
用法
使用Chd
的Chd::open
方法打开,然后从0迭代到chd.header().hunk_count()
来读取块。
目标缓冲区的大小必须恰好为chd.header().hunk_size()
,以使用hunk.read_hunk_in
进行解压缩,该方法接受输出切片和存储压缩数据的缓冲区。
fn main() -> Result<()> {
let mut f = BufReader::new(File::open("image.chd")?;
let mut chd = Chd::open(&mut f, None)?;
let hunk_count = chd.header().hunk_count();
let hunk_size = chd.header().hunk_size();
// buffer to store decompressed hunks
let mut out_buf = chd.get_hunksized_buffer();
// buffer for temporary compressed
let mut temp_buf = Vec::new();
for hunk_num in 0..hunk_count {
let mut hunk = chd.hunk(hunk_num)?;
hunk.read_hunk_in(&mut temp_buf, &mut out_buf)?;
}
}
为了更符合人体工程学但速度较慢的使用,chd::read
提供了在块级别实现Read
和Seek
的缓冲适配器。文件级别的缓冲适配器也可用。
借用迭代器
通过unstable_lending_iterators
,块和元数据可以稍微更符合人体工程学地迭代,尽管需要使用while let
循环。此API在泛型关联类型和LendingIterator
特质稳定之前是不稳定的。
[dependencies]
chd = { version = "0.2", features = ["unstable_lending_iterators"] }
然后可以像这样迭代块。
fn main() -> Result<()> {
let mut f = BufReader::new(File::open("image.chd")?);
let mut chd = Chd::open(&mut f, None)?;
// buffer to store decompressed hunks
let mut out_buf = chd.get_hunksized_buffer();
// buffer for temporary compressed
let mut temp_buf = Vec::new();
let mut hunk_iter = chd.hunks();
while let Some(mut hunk) = hunk_iter.next() {
hunk.read_hunk_in(&mut temp_buf, &mut out_buf)?;
}
}
在Chd::metadata
中存在类似的API用于元数据。
验证块校验和
默认情况下,chd-rs出于性能考虑不会验证解压缩块的校验和。应启用功能verify_block_crc
以验证块校验和。
[dependencies]
chd = { version = "0.2", features = ["verify_block_crc"] }
支持的编解码器
chd-rs支持以下压缩编解码器,比libchdr的覆盖范围更广。对于实现细节,请参阅chd::compression
模块。
V1-4 编解码器
⚠️V1-4的支持没有像V5支持那样经过严格的测试。 ⚠️
- 无(
CHDCOMPRESSION_NONE
) - Zlib(
CHDCOMPRESSION_ZLIB
) - Zlib+(
CHDCOMPRESSION_ZLIB
)
V5 编解码器
- 无(
CHD_CODEC_NONE
) - LZMA(
CHD_CODEC_LZMA
) - Deflate(
CHD_CODEC_ZLIB
) - FLAC(
CHD_CODEC_FLAC
) - Huffman(
CHD_CODEC_HUFF
) - Zstandard(
CHD_CODEC_ZSTD
) - CD LZMA(
CHD_CODEC_CD_LZMA
) - CD Deflate(
CHD_CODEC_CD_ZLIB
) - CD FLAC(
CHD_CODEC_CD_FLAC
) - CD Zstandard(
CHD_CODEC_CD_ZSTD
) - AV Huffman(
CHD_CODEC_AVHUFF
)
编解码器和Huffman API
默认情况下,编解码器和静态Huffman实现不是作为公共API的一部分公开,但可以通过codec_api
和huffman_api
功能分别启用。这些API可能会更改,但应认为它们主要稳定。
特别是,HuffmanDecoder
的类型签名将在generic_const_exprs
稳定后发生变化。
rchdman
命令行工具
作为一个概念证明,chd-rs实现了chdman的极其基本的重实现,用于只读目的。以下功能在rchdman中可用。
info
显示CHD的信息。verify
验证CHD的完整性。不验证元数据的完整性。extractraw
从CHD输入文件中提取原始文件。dumpmeta
将元数据从CHD输出到标准输出或文件。
rchdman的结果应与chdman相同。rchdman旨在简单,不包括多线程或其他功能,因此通常比chdman慢。没有计划在rchdman中实现写入操作。
性能
默认情况下,chd-rs 使用纯 Rust 编解码器,但如果需要最大性能,可以启用 max_perf
。这启用了 flate2 的 zlib-ng 后端,以及在自定义的 lzma-rs 分支 中使用实验性 API,以牺牲更高的内存使用为代价来提高性能。结合 codegen-units=1
和 Profile Guided Optimization,chd-rs 的性能与 libchdr 相当,差距在 1% 以内。
未启用 max_perf
时,chd-rs 已经在无需链接 zlib-ng 等C库的情况下,性能达到 libchdr 的 15%。
libchdr
API
⚠️C API 尚未经过充分测试。使用时请自行承担风险。 ⚠️
chd-rs 提供了一个与 chd.h 兼容的 C API。以下是 ABI 兼容性的详细信息,但作为动态库编译时未经过测试。更多详情请参见 /chd-rs-capi。
依赖项
~1.7–3MB
~56K SLoC