jxl_coding/
error.rs

1/// The error type for JPEG XL entropy decoders.
2#[derive(Debug)]
3#[non_exhaustive]
4pub enum Error {
5    /// Bitstream-level error.
6    Bitstream(jxl_bitstream::Error),
7    /// LZ77 decoder is being used where it's not allowed.
8    Lz77NotAllowed,
9    /// Decoded ANS distribution is invalid.
10    InvalidAnsHistogram,
11    /// ANS stream checksum verification has failed.
12    InvalidAnsStream,
13    /// Hybrid integer configuration is invalid.
14    InvalidIntegerConfig {
15        split_exponent: u32,
16        msb_in_token: u32,
17        lsb_in_token: Option<u32>,
18    },
19    /// Decoded permutation is invalid.
20    InvalidPermutation,
21    /// Decoded Brotli histogram is invalid.
22    InvalidPrefixHistogram,
23    /// Prefix code symbol is too large.
24    PrefixSymbolTooLarge(usize),
25    /// Decoded cluster ID is invalid.
26    InvalidCluster(u32),
27    /// Distribution cluster has a hole.
28    ClusterHole {
29        num_expected_clusters: u32,
30        num_actual_clusters: u32,
31    },
32    /// LZ77 repeat symbol encountered without decoding any symbols.
33    UnexpectedLz77Repeat,
34    /// Decoded LZ77 symbol is invalid.
35    InvalidLz77Symbol,
36}
37
38impl std::error::Error for Error {
39    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
40        match self {
41            Self::Bitstream(err) => Some(err),
42            _ => None,
43        }
44    }
45}
46
47impl std::fmt::Display for Error {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self {
50            Self::Bitstream(err) => write!(f, "error from bitstream: {}", err),
51            Self::Lz77NotAllowed => write!(f, "LZ77-enabled decoder when it is not allowed"),
52            Self::InvalidAnsHistogram => write!(f, "invalid ANS distribution"),
53            Self::InvalidAnsStream => write!(f, "ANS stream verification failed"),
54            Self::InvalidIntegerConfig {
55                split_exponent,
56                msb_in_token,
57                lsb_in_token,
58            } => write!(
59                f,
60                "invalid hybrid integer configuration; {} + {msb_in_token} > {split_exponent}",
61                lsb_in_token.unwrap_or(0)
62            ),
63            Self::InvalidPermutation => write!(f, "invalid permutation"),
64            Self::InvalidPrefixHistogram => write!(f, "invalid Brotli prefix code"),
65            Self::PrefixSymbolTooLarge(size) => write!(f, "prefix code symbol too large ({size})"),
66            Self::InvalidCluster(id) => write!(f, "invalid cluster ID {id}"),
67            Self::ClusterHole {
68                num_expected_clusters,
69                num_actual_clusters,
70            } => write!(
71                f,
72                "distribution cluster has a hole; expected {num_expected_clusters}, actual {num_actual_clusters}"
73            ),
74            Self::UnexpectedLz77Repeat => write!(
75                f,
76                "LZ77 repeat symbol encountered without decoding any symbols"
77            ),
78            Self::InvalidLz77Symbol => write!(f, "Invalid LZ77 symbol"),
79        }
80    }
81}
82
83impl From<jxl_bitstream::Error> for Error {
84    fn from(err: jxl_bitstream::Error) -> Self {
85        Self::Bitstream(err)
86    }
87}
88
89impl Error {
90    pub fn unexpected_eof(&self) -> bool {
91        if let Error::Bitstream(e) = self {
92            return e.unexpected_eof();
93        }
94        false
95    }
96}