use crate::codec::Codec;
use crate::codec::CODEC_RICEPP;
use crate::error::CoreError;
const RICEPP_CODEC_ID: u16 = 0x08;
pub struct RiceppCodec {
config: omnizip_ricepp::CodecConfig,
}
impl RiceppCodec {
#[must_use]
pub fn new(config: omnizip_ricepp::CodecConfig) -> Self {
Self { config }
}
#[must_use]
pub fn fits_default() -> Self {
Self::new(omnizip_ricepp::CodecConfig::default())
}
}
impl Default for RiceppCodec {
fn default() -> Self {
Self::fits_default()
}
}
impl Codec for RiceppCodec {
fn id(&self) -> u8 {
CODEC_RICEPP
}
fn name(&self) -> &'static str {
"ricepp"
}
fn min_compress_size(&self) -> usize {
1024
}
fn compress(&self, plaintext: &[u8]) -> Result<Vec<u8>, CoreError> {
omnizip_ricepp::compress(plaintext, self.config).map_err(ricepp_err)
}
fn decompress(&self, compressed: &[u8], _expected_len: u32) -> Result<Vec<u8>, CoreError> {
omnizip_ricepp::decompress(compressed).map_err(ricepp_err)
}
}
fn ricepp_err(e: omnizip_codecs::OmnizipError) -> CoreError {
let _ = RICEPP_CODEC_ID;
CoreError::Corrupt {
reason: format!("ricepp: {e}"),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trips_synthetic_pixel_data() {
let pixels: Vec<u16> = (0..256).map(|i| i * 17).collect();
let mut bytes = Vec::with_capacity(pixels.len() * 2);
for p in &pixels {
bytes.extend_from_slice(&p.to_be_bytes());
}
let codec = RiceppCodec::fits_default();
let compressed = codec.compress(&bytes).expect("compress");
let recovered = codec
.decompress(&compressed, bytes.len() as u32)
.expect("decompress");
assert_eq!(recovered, bytes);
}
#[test]
fn rejects_input_with_wrong_pixel_width() {
let codec = RiceppCodec::fits_default();
let result = codec.compress(&[0u8; 11]);
assert!(result.is_err());
}
}