22 个不稳定版本 (3 个重大变更)
1.1.0 |
|
---|---|
0.3.7 | 2024 年 7 月 20 日 |
0.3.4 | 2023 年 11 月 16 日 |
#13 in 游戏
每月下载量 166
465KB
2.5K SLoC
包含 (Windows DLL, 170KB) py/szs.dll, (Windows DLL, 170KB) c#/bindings/szs.dll
szs
用于 Nintendo GameCube/Wii 游戏中 SZS ("Yaz0") 压缩/解压缩的轻量级 crate。该库提供了 C、C++、C# 和 Python(工作进展中) 绑定。也支持 YAY0 ("SZP")。
Rust
以下代码示例展示了如何使用 Rust 将文件压缩为 SZS 格式
let src_data: Vec<u8> = "Hello, World!".as_bytes().to_vec();
match szs::encode(&src_data, szs::EncodeAlgo::Nintendo) {
Ok(encoded_data) => {
println!("Encoded into {} bytes", encoded_data.len());
}
Err(err) => {
println!("Encoding failed: {}", err);
}
}
同样,解压缩
match szs::decode(&encoded_data) {
Ok(decoded_data) => {
println!("Decoded {} bytes", decoded_data.len());
}
Err(err) => {
println!("Decoding failed: {}", err);
}
}
C# 绑定
以下 C# 绑定提供如下
public static void Main(string[] args)
{
byte[] data = ...;
szs.CompressionAlgorithm algorithm = szs.CompressionAlgorithm.Nintendo;
try
{
byte[] encodedData = szs.Encode(data, algorithm);
Console.WriteLine($"Encoded {encodedData.Length} bytes.");
}
catch (Exception e)
{
Console.WriteLine("Failed to compress: " + e.Message);
}
}
警告:szs
部分是用 C 实现的,这带来了自己的安全考虑。
算法
算法 | 用例 | 描述 |
---|---|---|
EncodeAlgo::Nintendo |
匹配解压缩项目 | 这是从 Mario Kart Wii 中反向工程得到的压缩算法。在实践中,它是一个带有第二意见机制的 Boyer-moore-horspool 搜索。 |
EncodeAlgo::Mk8 |
通用 FAST 预设。 |
这是从 Mario Kart 8 中反向工程得到的压缩算法。在实践中,它是一个滑动蒙特卡洛哈希表。(感谢 @aboood40091、@KillZGaming) |
EncodeAlgo::MkwSp |
MKW-SP | |
EncodeAlgo::CTGP |
CTGP 工作 | CTGP(反向工程。1:1 匹配) |
EncodeAlgo::最坏情况编码 |
INSTANT 预设。 |
最坏情况 |
EncodeAlgo::Haroohie |
Haroohie(感谢 @Gericom,改编自 MarioKartToolbox) | |
EncodeAlgo::CTLib |
CTLib(感谢 @narahiero,改编自 CTLib) | |
EncodeAlgo::LibYaz0 |
ULTRA 预设。 |
libyaz0(基于 wszst。感谢 @aboood40091) |
通常情况下,mk8
算法以最快的速度获得可接受的压缩效果。对于文件大小至关重要的场景,lib-yaz0
与 wszst ultra
在最小的文件大小上并列,但速度约快 25%。
与其他库的比较
-
- 性能:
EncodeAlgo::LibYaz0
提供了更优的压缩效果,并且在参考数据上的速度比yaz0-rs
快约 6 倍。 - 注意:
szs
部分实现为 C 语言,这带来了自己的安全考虑。
- 性能:
-
- 性能:
EncodeAlgo::MK8
与oead
的压缩和速度相匹配。 - 大小:
szs
是一个轻量级的几KB MIT 许可证的依赖项,而oead
是一个更大的多MB GPL 许可证的包。
- 性能:
-
- 性能
EncodeAlgo::LibYaz0
提供与wszst ultra
相等的压缩效果,但速度约快 30%,且不受 GPL 许可证的限制。EncodeAlgo::MK8
在压缩方面优于wszst fast
,并且速度快 4-5 倍。
- 性能
特殊功能:在列出的库中,只有 szs
提供了对 YAZ0
、YAZ1
和 YAY0
流格式的全面支持。
基准测试
大文件比较
NSMBU 8-43(解压后 63.9 MB)
方法 | 时间(平均 3 次运行) | 压缩率 | 文件大小 |
---|---|---|---|
最坏情况编码 | 0.03 秒 | 112.50% | 71.90 MB |
mk8 | 1.37 秒 | 29.43% | 18.81 MB |
ct-lib | 3.01 秒 | 29.74% | 19.01 MB |
haroohie | 5.79 秒 | 29.74% | 19.01 MB |
ctgp | 9.23 秒 | 40.91% | 26.14 MB |
lib-yaz0 | 16.09 秒 | 29.32% | 18.74 MB |
mkw-sp | 36.77 秒 | 29.74% | 19.01 MB |
mkw | 55.00 秒 | 29.40% | 18.79 MB |
mkw (C++) | 63.34 秒 | 29.40% | 18.79 MB |
与其他库的比较 | |||
oead 默认 | 0.61 秒 | 30.09% | 19.23 MB |
oead 最大级别 | 0.99 秒 | 29.96% | 19.15 MB |
wszst 快速 | 1.77 秒 | 35.62% | 22.76 MB |
wszst 标准 | 11.95 秒 | 29.74% | 19.01 MB |
wszst 超级 | 25.06 秒 | 29.32% | 18.74 MB |
* 平均 3 次运行;在 Windows 11 上的 x64 Clang (17.0.6) 构建进行了测试,测试在 Intel i9-13900KF 上进行
小文件比较
任务:压缩 N64 Bowser Castle(源文件大小:2,574,368)
方法 | 时间(平均 3 次运行) | 压缩率 | 文件大小 |
---|---|---|---|
最坏情况编码 | 0.00 秒 | 112.50% | 2.76 MB |
mk8 | 0.07 秒 | 56.75% | 1.39 MB |
ct-lib | 0.19 秒 | 57.24% | 1.41 MB |
ctgp | 0.21 秒 | 71.41% | 1.75 MB |
haroohie | 0.31 秒 | 57.23% | 1.41 MB |
lib-yaz0 | 1.09 秒 | 56.65% | 1.39 MB |
mkw-sp | 1.47 秒 | 57.23% | 1.41 MB |
mkw | 3.91 秒 | 56.87% | 1.40 MB |
mkw (C++) | 4.27 秒 | 56.87% | 1.40 MB |
与其他库的比较 | |||
oead 默认 | 0.03 秒 | 57.63% | 1.41 MB |
oead 最大级别 | 0.05 秒 | 57.52% | 1.41 MB |
wszst(快速) | 0.197 秒(通过 shell) | 65.78% | 1.61 MB |
wszst(标准) | 0.946 秒(通过 shell) | 57.23% | 1.40 MB |
wszst(超级) | 1.418 秒(通过 shell) | 56.65% | 1.38 MB |
yaz0-rs | 4.88 秒(通过 shell) | 56.87% | 1.39 MB |
* 平均 3 次运行;在 Windows 11 上的 x64 Clang (17.0.6) 构建进行了测试,测试在 Intel i9-13900KF 上进行
通常情况下,mk8
算法以最快的速度获得可接受的压缩效果。对于文件大小至关重要的场景,lib-yaz0
与 wszst ultra
在最小的文件大小上并列,但速度约快 25%。
(Windows)性能比较:Clang 与 MSVC
在 Windows 上,微软的编译器(MSVC)在大多数算法上似乎落后于 Clang,差距相当明显
方法 | Clang 时间(秒) | MSVC 时间(秒) | 性能提升(%) |
---|---|---|---|
lib-yaz0 | 15.24 | 19.08 | -25.20% |
mkw | 62.04 | 58.34 | 5.96% |
mkw-sp | 26.73 | 50.01 | -87.09% |
haroohie | 5.84 | 5.85 | -0.17% |
ct-lib | 2.91 | 2.81 | 3.44% |
mk8 | 1.34 | 1.62 | -20.90% |
ctgp | 5.22 | 5.88 | -12.64% |
* 平均 3 次运行;在 Windows 11 上的 x64 MSVC 构建进行了测试,测试在 Intel i9-13900KF 上进行
平均性能提升 -19.51%
建议
根据性能结果,Clang通常更受欢迎。要将Clang设置为szs
的编译器,在运行cargo build
之前,执行以下命令:
SET CXX=clang
此外,使用兼容的Clang/Rust版本将允许进行跨语言LTO优化。
示例(C绑定)
#include "szs.h"
// Calculate the upper bound for encoding.
u32 max_size = riiszs_encoded_upper_bound(sizeof(data));
// Allocate a buffer based on the calculated upper bound.
void* encoded_buf = malloc(max_size);
if (!buf) {
fprintf(stderr, "Failed to allocate %u bytes.\n", max_size);
return -1;
}
// Boyer-Moore-horspool variant
u32 algorithm = RII_SZS_ENCODE_ALGO_NINTENDO;
u32 actual_len = 0;
const char* ec = riiszs_encode_algo_fast(encoded_buf, max_size, data, sizeof(data), &actual_len, algorithm);
if (ec != NULL) {
fprintf(stderr, "Failed to compress: %s\n", ec);
riiszs_free_error_message(ec);
return -1;
}
printf("Encoded %u bytes.\n", actual_len);
// Optionally: shrink the dst_data to the actual size.
encoded_buf = realloc(encoded_buf, actual_len);
C++在C绑定之上封装
还提供了一个CMake示例。
#include `szs.h`
// Boyer-Moore-horspool variant
szs::Algo algorithm = szs::Algo::Nintendo;
auto encoded = szs::encode(data, algorithm);
if (!encoded)
std::println(stderr, "Failed to compress: {}.", encoded.error()); {
return -1;
}
std::vector<u8> szs_data = *encoded;
std::println("Encoded {} bytes.", szs_data.size());
许可证
此库根据MIT许可证发布。