use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DecodeError {
Parse(ParseError),
Format(FormatError),
Segment(SegmentError),
Huffman(HuffmanError),
Region(RegionError),
Template(TemplateError),
Symbol(SymbolError),
Overflow,
Unsupported,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseError {
UnexpectedEof,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FormatError {
InvalidHeader,
ReservedBits,
MissingPageInfo,
UnknownPageHeight,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SegmentError {
UnknownType,
InvalidReferredCount,
InvalidReference,
MissingEndMarker,
MissingPatternDictionary,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HuffmanError {
InvalidCode,
InvalidSelection,
MissingTables,
UnexpectedOob,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RegionError {
InvalidCombinationOperator,
InvalidDimension,
GrayScaleOutOfRange,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TemplateError {
Invalid,
InvalidAtPixel,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SymbolError {
NoSymbols,
TooManySymbols,
OutOfRange,
UnexpectedOob,
Invalid,
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Parse(e) => write!(f, "{e}"),
Self::Format(e) => write!(f, "{e}"),
Self::Segment(e) => write!(f, "{e}"),
Self::Huffman(e) => write!(f, "{e}"),
Self::Region(e) => write!(f, "{e}"),
Self::Template(e) => write!(f, "{e}"),
Self::Symbol(e) => write!(f, "{e}"),
Self::Overflow => write!(f, "arithmetic overflow"),
Self::Unsupported => write!(f, "unsupported feature"),
}
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnexpectedEof => write!(f, "unexpected end of input"),
}
}
}
impl fmt::Display for FormatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidHeader => write!(f, "invalid JBIG2 file header"),
Self::ReservedBits => write!(f, "reserved bits must be zero"),
Self::MissingPageInfo => write!(f, "missing page information segment"),
Self::UnknownPageHeight => write!(f, "page height unknown with no stripe segments"),
}
}
}
impl fmt::Display for SegmentError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnknownType => write!(f, "unknown or reserved segment type"),
Self::InvalidReferredCount => write!(f, "invalid referred-to segment count"),
Self::InvalidReference => write!(f, "segment refers to larger segment number"),
Self::MissingEndMarker => write!(f, "missing end marker for unknown-length region"),
Self::MissingPatternDictionary => write!(f, "missing required pattern dictionary"),
}
}
}
impl fmt::Display for HuffmanError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidCode => write!(f, "invalid Huffman code"),
Self::InvalidSelection => write!(f, "invalid Huffman table selection"),
Self::MissingTables => write!(f, "not enough referred Huffman tables"),
Self::UnexpectedOob => write!(f, "unexpected out-of-band value"),
}
}
}
impl fmt::Display for RegionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidCombinationOperator => write!(f, "invalid combination operator"),
Self::InvalidDimension => write!(f, "invalid dimension value"),
Self::GrayScaleOutOfRange => write!(f, "gray-scale value exceeds pattern count"),
}
}
}
impl fmt::Display for TemplateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Invalid => write!(f, "invalid template value"),
Self::InvalidAtPixel => write!(f, "invalid adaptive template pixel location"),
}
}
}
impl fmt::Display for SymbolError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoSymbols => write!(f, "no symbols available"),
Self::OutOfRange => write!(f, "symbol ID out of range"),
Self::UnexpectedOob => write!(f, "unexpected out-of-band value"),
Self::TooManySymbols => write!(f, "symbol dictionary contains too many symbols"),
Self::Invalid => write!(f, "invalid symbol encountered"),
}
}
}
impl core::error::Error for DecodeError {}
impl core::error::Error for ParseError {}
impl core::error::Error for FormatError {}
impl core::error::Error for SegmentError {}
impl core::error::Error for HuffmanError {}
impl core::error::Error for RegionError {}
impl core::error::Error for TemplateError {}
impl core::error::Error for SymbolError {}
impl From<ParseError> for DecodeError {
fn from(e: ParseError) -> Self {
Self::Parse(e)
}
}
impl From<FormatError> for DecodeError {
fn from(e: FormatError) -> Self {
Self::Format(e)
}
}
impl From<SegmentError> for DecodeError {
fn from(e: SegmentError) -> Self {
Self::Segment(e)
}
}
impl From<HuffmanError> for DecodeError {
fn from(e: HuffmanError) -> Self {
Self::Huffman(e)
}
}
impl From<RegionError> for DecodeError {
fn from(e: RegionError) -> Self {
Self::Region(e)
}
}
impl From<TemplateError> for DecodeError {
fn from(e: TemplateError) -> Self {
Self::Template(e)
}
}
impl From<SymbolError> for DecodeError {
fn from(e: SymbolError) -> Self {
Self::Symbol(e)
}
}
pub type Result<T> = core::result::Result<T, DecodeError>;
macro_rules! bail {
($err:expr) => {
return Err($err.into())
};
}
macro_rules! err {
($err:expr) => {
Err($err.into())
};
}
pub(crate) use bail;
pub(crate) use err;