use super::ZgfxError;
use super::compressor::Compressor;
use super::wrapper::{ZGFX_SEGMENTED_MAXSIZE, wrap_compressed, wrap_uncompressed};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompressionMode {
Never,
Auto,
Always,
}
pub fn compress_and_wrap_egfx(
data: &[u8],
compressor: &mut Compressor,
mode: CompressionMode,
) -> Result<Vec<u8>, ZgfxError> {
match mode {
CompressionMode::Never => Ok(wrap_uncompressed(data)),
CompressionMode::Auto => {
let compressed = compressor.compress(data)?;
if compressed.len() <= ZGFX_SEGMENTED_MAXSIZE {
let wrapped_compressed = wrap_compressed(&compressed);
let wrapped_uncompressed = wrap_uncompressed(data);
if wrapped_compressed.len() < wrapped_uncompressed.len() {
Ok(wrapped_compressed)
} else {
Ok(wrapped_uncompressed)
}
} else {
Ok(wrap_uncompressed(data))
}
}
CompressionMode::Always => {
let compressed = compressor.compress(data)?;
if compressed.len() <= ZGFX_SEGMENTED_MAXSIZE {
Ok(wrap_compressed(&compressed))
} else {
Ok(wrap_uncompressed(data))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mode_never_produces_uncompressed() {
let mut compressor = Compressor::new();
let data = b"Test data";
let wrapped = compress_and_wrap_egfx(data, &mut compressor, CompressionMode::Never).unwrap();
assert_eq!(wrapped[0], 0xE0);
assert_eq!(wrapped[1], 0x04); }
#[test]
fn mode_always_produces_compressed() {
let mut compressor = Compressor::new();
let data = b"Test data";
let wrapped = compress_and_wrap_egfx(data, &mut compressor, CompressionMode::Always).unwrap();
assert_eq!(wrapped[0], 0xE0);
assert_eq!(wrapped[1], 0x24); }
#[test]
fn mode_auto_compresses_repetitive_data() {
let mut compressor = Compressor::new();
let data = b"AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCC";
let wrapped = compress_and_wrap_egfx(data, &mut compressor, CompressionMode::Auto).unwrap();
assert_eq!(wrapped[0], 0xE0);
assert_eq!(wrapped[1], 0x24);
}
#[test]
fn round_trip_all_modes() {
use super::super::Decompressor;
let data = b"Test data with some repetition: AAAA BBBB CCCC";
let mut decompressor = Decompressor::new();
for mode in [CompressionMode::Never, CompressionMode::Auto, CompressionMode::Always] {
let mut compressor = Compressor::new();
let wrapped = compress_and_wrap_egfx(data, &mut compressor, mode).unwrap();
let mut output = Vec::new();
decompressor.decompress(&wrapped, &mut output).unwrap();
assert_eq!(&output, data, "Round-trip failed for mode {mode:?}");
}
}
}