Skip to main content

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}