1use crate::error::{EBCCError, EBCCResult};
4
5#[derive(Debug, Clone, Copy, PartialEq)]
7pub enum EBCCResidualType {
8 Jpeg2000Only,
10 AbsoluteError(f32),
12 RelativeError(f32),
14}
15
16impl EBCCResidualType {
17 pub(crate) const fn as_residual(self) -> ebcc_sys::residual_t::Type {
18 match self {
19 Self::Jpeg2000Only => ebcc_sys::residual_t::NONE,
20 Self::AbsoluteError(_) => ebcc_sys::residual_t::MAX_ERROR,
21 Self::RelativeError(_) => ebcc_sys::residual_t::RELATIVE_ERROR,
22 }
23 }
24
25 pub(crate) const fn as_error(self) -> f32 {
26 match self {
27 Self::Jpeg2000Only => 0.0,
28 Self::AbsoluteError(error) | Self::RelativeError(error) => error,
29 }
30 }
31}
32
33#[derive(Debug, Clone, PartialEq)]
35pub struct EBCCConfig {
36 pub base_cr: f32,
38
39 pub residual_compression_type: EBCCResidualType,
41}
42
43impl Default for EBCCConfig {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49const DEFAULT_BASE_CR: f32 = 100.0;
50
51impl EBCCConfig {
52 #[must_use]
54 pub const fn new() -> Self {
55 Self {
56 base_cr: DEFAULT_BASE_CR,
57 residual_compression_type: EBCCResidualType::Jpeg2000Only,
58 }
59 }
60
61 #[must_use]
63 pub const fn jpeg2000_only(base_cr: f32) -> Self {
64 Self {
65 base_cr,
66 residual_compression_type: EBCCResidualType::Jpeg2000Only,
67 }
68 }
69
70 #[must_use]
72 pub const fn max_absolute_error_bounded(error: f32) -> Self {
73 Self {
74 base_cr: DEFAULT_BASE_CR,
75 residual_compression_type: EBCCResidualType::AbsoluteError(error),
76 }
77 }
78
79 #[must_use]
81 pub const fn relative_error_bounded(error: f32) -> Self {
82 Self {
83 base_cr: DEFAULT_BASE_CR,
84 residual_compression_type: EBCCResidualType::RelativeError(error),
85 }
86 }
87
88 #[must_use]
90 pub const fn with_base_cr(mut self, base_cr: f32) -> Self {
91 self.base_cr = base_cr;
92 self
93 }
94
95 pub fn validate(&self) -> EBCCResult<()> {
103 if self.base_cr <= 0.0 {
105 return Err(EBCCError::InvalidConfig(String::from(
106 "Base compression ratio must be positive",
107 )));
108 }
109
110 match self.residual_compression_type {
112 EBCCResidualType::AbsoluteError(error) | EBCCResidualType::RelativeError(error) => {
113 if error <= 0.0 {
114 return Err(EBCCError::InvalidConfig(String::from(
115 "Error bound must be positive",
116 )));
117 }
118 }
119 EBCCResidualType::Jpeg2000Only => {
120 }
122 }
123
124 Ok(())
125 }
126}