use std::io::Cursor;
use image::DynamicImage;
use crate::pipeline::PipelineError;
pub mod chromakey;
pub mod thumbnail;
const MAX_DIM: u32 = 16_000;
const MAX_ALLOC: u64 = 128 * 1024 * 1024;
pub fn load_with_limits(bytes: &[u8], code: &'static str) -> Result<DynamicImage, PipelineError> {
let (w, h) = image::ImageReader::new(Cursor::new(bytes))
.with_guessed_format()
.map_err(|e| PipelineError::new(code, format!("format detection: {e}")))?
.into_dimensions()
.map_err(|e| PipelineError::new(code, format!("image header read: {e}")))?;
if w > MAX_DIM || h > MAX_DIM {
return Err(PipelineError::new(
code,
format!("image dimensions {w}x{h} exceed maximum {MAX_DIM}x{MAX_DIM}"),
));
}
let approx_alloc = (w as u64) * (h as u64) * 4;
if approx_alloc > MAX_ALLOC {
return Err(PipelineError::new(
code,
format!(
"image would require ~{} MB decoded, exceeding limit of {} MB",
approx_alloc / 1_048_576,
MAX_ALLOC / 1_048_576,
),
));
}
image::ImageReader::new(Cursor::new(bytes))
.with_guessed_format()
.map_err(|e| PipelineError::new(code, format!("format detection: {e}")))?
.decode()
.map_err(|e| PipelineError::new(code, format!("image decode: {e}")))
}