use crate::error::{EBCCError, EBCCResult};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EBCCResidualType {
Jpeg2000Only,
AbsoluteError(f32),
RelativeError(f32),
}
impl EBCCResidualType {
pub(crate) const fn as_residual(self) -> ebcc_sys::residual_t::Type {
match self {
Self::Jpeg2000Only => ebcc_sys::residual_t::NONE,
Self::AbsoluteError(_) => ebcc_sys::residual_t::MAX_ERROR,
Self::RelativeError(_) => ebcc_sys::residual_t::RELATIVE_ERROR,
}
}
pub(crate) const fn as_error(self) -> f32 {
match self {
Self::Jpeg2000Only => 0.0,
Self::AbsoluteError(error) | Self::RelativeError(error) => error,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct EBCCConfig {
pub base_cr: f32,
pub residual_compression_type: EBCCResidualType,
}
impl Default for EBCCConfig {
fn default() -> Self {
Self::new()
}
}
impl EBCCConfig {
#[must_use]
pub const fn new() -> Self {
Self {
base_cr: 10.0,
residual_compression_type: EBCCResidualType::Jpeg2000Only,
}
}
#[must_use]
pub const fn jpeg2000_only(base_cr: f32) -> Self {
Self {
base_cr,
residual_compression_type: EBCCResidualType::Jpeg2000Only,
}
}
#[must_use]
pub const fn max_absolute_error_bounded(base_cr: f32, error: f32) -> Self {
Self {
base_cr,
residual_compression_type: EBCCResidualType::AbsoluteError(error),
}
}
#[must_use]
pub const fn relative_error_bounded(base_cr: f32, error: f32) -> Self {
Self {
base_cr,
residual_compression_type: EBCCResidualType::RelativeError(error),
}
}
pub fn validate(&self) -> EBCCResult<()> {
if self.base_cr <= 0.0 {
return Err(EBCCError::InvalidConfig(String::from(
"Base compression ratio must be positive",
)));
}
match self.residual_compression_type {
EBCCResidualType::AbsoluteError(error) | EBCCResidualType::RelativeError(error) => {
if error <= 0.0 {
return Err(EBCCError::InvalidConfig(String::from(
"Error bound must be positive",
)));
}
}
EBCCResidualType::Jpeg2000Only => {
}
}
Ok(())
}
}