Expand description
A very overengineered rust crate for compressing and decompressing data in the RefPack format utilized by many EA games of the early 2000s
RefPack is a nonstandardized format that varied greatly in exact encoding and implementation.
refpack uses a Format system to specify different encoding formats. This is implemented via
generic trait parameters that get monomorphized down to static dispatch.
Put simply, this means that you get the benefit of being able to use any format however you like without any performance overhead from dynamic dispatch, as well as being able to implement your own arbitrary formats that are still compatible with the same compression algorithms.
More details on the refpack format can be found at the niotso wiki. The short explanation is that RefPack is a compression scheme loosely based on LZ77 compression.
The Original Refpack Implementation was referenced to ensure proper compatibility
Usage
refpack-rs exposes two functions: compress and decompress, along with easy variants
with easier but less flexible of usage.
compress and decompress take mutable references to a buffer to read and write from,
that implements std::io::Read and std::io::Write, respectively.
decompress will read from the buffer until it encounters a stopcode (byte within (0xFC..=0xFF)),
while compress will read in the provided length.
all compression and decompression functions accept one generic argument constrained to the
Format trait. Implementations should be a unit or “unconstructable”
(one inaccessible () member to prevent construction), and define a pair of how to interpret
Implementations
| Format | Games | Control | Header |
|---|---|---|---|
| Reference | Various 90s Origin Software and EA games | Reference | Reference |
| TheSims12 | The Sims, The Sims Online, The Sims 2 | Reference | Maxis |
| Simcity4 | Simcity 4 | Simcity4 | Maxis |
| TheSims34 | The Sims 3, The Sims 4 | Reference | SimEA |
Example
use std::io::Cursor;
use std::io::Seek;
use refpack::format::Reference;
let mut source_reader = Cursor::new(b"Hello World!".to_vec());
let mut out_buf = Cursor::new(vec![]);
refpack::compress::<Reference>(source_reader.get_ref().len(), &mut source_reader, &mut out_buf).unwrap();The easy variants are compress_easy and decompress_easy, which take a &[u8] and return
a Result<Vec<u8>, RefPackError>.
Internally they simply call compress and decompress with a Cursor to the input and
output buffers, however they are more convenient to use in many cases.
Re-exports
pub use crate::data::compression::compress;pub use crate::data::compression::easy_compress;pub use crate::data::decompression::decompress;pub use crate::data::decompression::easy_decompress;
Modules
- things relating the actual compressed data block. Anything past the header info, the actual compression algorithms themselves, control codes, etc.
- Possible compression formats to utilize
- Module for things relating to the header of the data which include decompressed length, sometimes flags or a magic number, and sometimes compressed length.
Enums
- Possible errors returned by compression and decompression functions
Type Definitions
- Wrapper for Result specified to RefPackError