rosetta_squint_decode/limits.rs
1use crate::error::{DecodeError, DecodeErrorKind};
2use crate::types::Format;
3
4/// Maximum number of pixels (width * height) accepted by any decoder.
5/// Images whose declared dimensions exceed this limit are rejected with
6/// `DecodeErrorKind::ImageTooLarge` before any size-proportional allocation.
7/// 256 MiB / 1 byte-per-channel = 268_435_456 pixels.
8pub const MAX_PIXELS: usize = 256 * 1024 * 1024; // 268_435_456
9
10/// Check that `width * height` does not exceed `MAX_PIXELS`.
11///
12/// Uses `checked_mul` so that on 32-bit targets the multiplication cannot
13/// silently overflow; on 64-bit targets the product always fits in `usize` but
14/// we still want the cap check.
15pub fn check_dimensions(width: usize, height: usize, format: Format) -> Result<(), DecodeError> {
16 let pixels = width.checked_mul(height).ok_or_else(|| {
17 DecodeError::new(
18 DecodeErrorKind::ImageTooLarge,
19 Some(format),
20 format!("width*height overflow ({}x{})", width, height),
21 )
22 })?;
23 if pixels > MAX_PIXELS {
24 return Err(DecodeError::new(
25 DecodeErrorKind::ImageTooLarge,
26 Some(format),
27 format!(
28 "declared dimensions {}x{} = {} pixels exceeds MAX_PIXELS = {}",
29 width, height, pixels, MAX_PIXELS
30 ),
31 ));
32 }
33 Ok(())
34}