pdfrum_page/error.rs
1//! The crate's one error type.
2//!
3//! Almost nothing here fails: content parsing is infallible by contract
4//! (a bad operator becomes a diagnostic and is skipped), colorspace and
5//! function loading answer `Option` because "this file has no such
6//! colorspace" is a normal state of affairs in PDFium's world, and page
7//! building always produces a `Page`. `Error` is reserved for the two places
8//! where a caller genuinely cannot continue: evaluating a function against
9//! the wrong number of values, and decoding an image whose pixels cannot be
10//! produced at all.
11
12use pdfrum_object::ObjRef;
13
14/// What went wrong in a page-level operation that can actually fail.
15#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
16#[non_exhaustive]
17pub enum Error {
18 /// A function was evaluated with a number of inputs its `/Domain` does
19 /// not describe, or an output slice shorter than its `/Range`
20 /// (ISO 32000-1 ยง7.10.1).
21 #[error("function takes {expected} inputs and {outputs} outputs, got {got} and {got_outputs}")]
22 FunctionArity {
23 /// Inputs the function declares.
24 expected: usize,
25 /// Inputs the caller supplied.
26 got: usize,
27 /// Outputs the function declares.
28 outputs: usize,
29 /// Length of the caller's output slice.
30 got_outputs: usize,
31 },
32 /// A function's `/Domain` names an interval whose low bound exceeds its
33 /// high bound, which PDFium refuses to evaluate against.
34 #[error("function domain or range interval is inverted")]
35 FunctionInterval,
36 /// An image dictionary's `/Width`, `/Height` or `/BitsPerComponent` is
37 /// outside the range PDFium accepts.
38 #[error("image dimensions or bit depth are not usable: {what}")]
39 ImageBadDict {
40 /// Which value was rejected.
41 what: &'static str,
42 },
43 /// No colorspace could be resolved for a non-mask image, so its samples
44 /// cannot be turned into pixels.
45 #[error("image has no usable colorspace")]
46 ImageNoColorSpace,
47 /// The image's sample data could not be produced: a filter with no
48 /// decoder, a codec that rejected the stream, or a chain that decoded to
49 /// fewer bytes than one scanline needs.
50 #[error("image data could not be decoded: {what}")]
51 ImageUndecodable {
52 /// Which stage gave up.
53 what: &'static str,
54 },
55 /// The image is larger than `Limits::max_image_bytes` allows, or its
56 /// pitch computation overflowed.
57 #[error("image needs more than the configured byte budget")]
58 ImageTooLarge,
59 /// A JBIG2 or JPEG 2000 codec rejected its input.
60 #[error("{codec} could not decode the embedded image")]
61 CodecRejected {
62 /// `"JBIG2"` or `"JPX"`.
63 codec: &'static str,
64 },
65 /// An indirect object a page-level structure needed could not be fetched.
66 #[error("object {0:?} could not be resolved")]
67 Unresolved(ObjRef),
68}