diff --git a/crates/jxl/src/decode.rs b/crates/jxl/src/decode.rs index 7568da7ac..4b23d8d2f 100644 --- a/crates/jxl/src/decode.rs +++ b/crates/jxl/src/decode.rs @@ -56,7 +56,7 @@ fn decode_inner(bytes: &[u8], limits: DecodeLimits, output_color: OutputColor) - } let pixels = u64::from(width).saturating_mul(u64::from(height)); if pixels > limits.max_pixels { - return Err(Error::LimitExceeded(format!("{width}×{height} image exceeds the {} pixel limit", limits.max_pixels))); + return Err(Error::PixelLimitExceeded { width, height, max_pixels: limits.max_pixels }); } // `JxlImageBuilder::read` feeds the full input. Continue in bounded chunks so trailing frame diff --git a/crates/jxl/src/lib.rs b/crates/jxl/src/lib.rs index 141239171..02ba61b34 100644 --- a/crates/jxl/src/lib.rs +++ b/crates/jxl/src/lib.rs @@ -100,6 +100,16 @@ pub enum Error { /// The image exceeds a caller supplied size or allocation limit. #[error("JPEG XL: limit exceeded: {0}")] LimitExceeded(String), + /// The encoded dimensions exceed the caller's pixel-count limit. + #[error("JPEG XL: image dimensions {width}×{height} exceed the {max_pixels} pixel limit")] + PixelLimitExceeded { + /// Encoded image width. + width: u32, + /// Encoded image height. + height: u32, + /// Maximum accepted pixel count. + max_pixels: u64, + }, /// The image layout or samples are unsupported. #[error("JPEG XL: invalid image: {0}")] InvalidImage(String), diff --git a/crates/jxl/tests/roundtrip.rs b/crates/jxl/tests/roundtrip.rs index 4aff84de1..3df1e90f2 100644 --- a/crates/jxl/tests/roundtrip.rs +++ b/crates/jxl/tests/roundtrip.rs @@ -70,7 +70,7 @@ fn decoder_enforces_input_and_pixel_limits() { let input_limit = DecodeLimits { max_input_bytes: encoded.len() - 1, ..DecodeLimits::default() }; assert!(matches!(decode(&encoded, input_limit), Err(craft_jxl::Error::LimitExceeded(_)))); let pixel_limit = DecodeLimits { max_pixels: 0, ..DecodeLimits::default() }; - assert!(matches!(decode(&encoded, pixel_limit), Err(craft_jxl::Error::LimitExceeded(_)))); + assert!(matches!(decode(&encoded, pixel_limit), Err(craft_jxl::Error::PixelLimitExceeded { width: 1, height: 1, max_pixels: 0 }))); } #[test]