szs is a WIP crate for compressing and decompressing SZS formats used in the Nintendo GameCube and Wii games. The library provides C bindings, making it useful in both Rust and C/C++ based projects.
Warning: The library is not currently in a fully functional state. Use at your own risk. 0.1.0 will start the release series. Warning: These algorithms are currently implemented in the C programming language, and not in Rust. While they have been rigorously validated, please use at your own risk. A Rust rewrite is planned.
Task: Compress N64 Bowser Castle (Source filesize: 2,574,368) | Method | Time Taken | Compression Rate | |--------|------------|------------------| | worst-case-encoding | 0s | 112.50% | | ctgp | 0.31s | 71.41% | | Haroohie | 0.58s | 57.23% | | mkw-sp | 3.76s | 57.23% | | nintendo | 5.93s | 56.87% | | Comparison with other libraries: | | | | Haroohie (C#) | 0.71s | 57.23% | | wszst (fast) | 0.387s (via shell) | 65.78% | | wszst (standard) | 1.776s (via shell) | 57.23% | | wszst (ultra) | 2.727s (via shell) | 56.65% | | yaz0-rs | 11.34s (via shell) | 56.87% |
In most cases, the Haroohie
algorithm gets the best compression the fastest, although wszst ultra is able to get the smallest filesizes if absolutely necessary.
The following snippet demonstrates how to compress a file as a SZS format using Rust:
```rs
// Sample source bytes to be encoded.
let srcdata: Vec
// Calculate the upper bound for encoding. let maxlen = encodedupperbound(srcdata.len() as u32);
// Allocate a buffer based on the calculated upper bound.
let mut dstdata: Vec
// Boyer-Moore-horspool variant let algo_number: u32 = 0;
match encodealgofast(&mut dstdata, &srcdata, algonumber) { Ok(encodedlen) => { println!("Encoded {} bytes", encodedlen); // Optionally: shrink the dstdata to the actual size. dstdata.truncate(encodedlen as usize); } Err(EncodeAlgoError::Error(errmsg)) => { println!("Encoding failed: {}", errmsg); } } ```
```c
szs.h
// Calculate the upper bound for encoding. u32 maxsize = riiszsencodedupperbound(sizeof(data));
// Allocate a buffer based on the calculated upper bound. void* encodedbuf = malloc(maxsize); if (!buf) { fprintf(stderr, "Failed to allocate %u bytes.\n", max_size); return -1; }
// Boyer-Moore-horspool variant u32 algorithm = RIISZSENCODEALGONINTENDO;
u32 actuallen = 0; const char* ec = riiszsencodealgofast(encodedbuf, maxsize, data, sizeof(data), &actuallen, algorithm); if (ec != NULL) { fprintf(stderr, "Failed to compress: %s\n", ec); riiszsfreeerrormessage(ec); return -1; } printf("Encoded %u bytes.\n", actuallen); // Optionally: shrink the dstdata to the actual size. encodedbuf = realloc(encodedbuf, actual_len); ```
```cpp
szs.h
// Boyer-Moore-horspool variant
szs::Algo algorithm = szs::Algo::Nintendo;
auto encoded = szs::encodealgo(data, algorithm);
if (!encoded)
std::println(stderr, "Failed to compress: {}.", encoded.error()); {
return -1;
}
std::vector
This library is published under the MIT license.