diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-30 14:52:18 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-30 14:52:18 +0100 |
| commit | e1e93938a148402d67cb06c25c674aa973598b03 (patch) | |
| tree | 63bb134c73fee1f4e619ff3b4739b217cf69b712 /src | |
| parent | bdf06c9c61c3a9e0e9104d012828583638797edc (diff) | |
Memoize image size computation
Diffstat (limited to 'src')
| -rw-r--r-- | src/image.rs | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/image.rs b/src/image.rs index ae4d165f..235b9ef6 100644 --- a/src/image.rs +++ b/src/image.rs @@ -25,24 +25,7 @@ impl Image { /// /// Extracts the width and height. pub fn new(data: Buffer, format: ImageFormat) -> StrResult<Self> { - let (width, height) = match format { - ImageFormat::Vector(VectorFormat::Svg) => { - let opts = usvg::Options::default(); - let tree = usvg::Tree::from_data(&data, &opts.to_ref()) - .map_err(format_usvg_error)?; - - let size = tree.svg_node().size; - let width = size.width().ceil() as u32; - let height = size.height().ceil() as u32; - (width, height) - } - ImageFormat::Raster(format) => { - let cursor = io::Cursor::new(&data); - let reader = image::io::Reader::with_format(cursor, format.into()); - reader.into_dimensions().map_err(format_image_error)? - } - }; - + let (width, height) = determine_size(&data, format)?; Ok(Self { data, format, width, height }) } @@ -144,6 +127,28 @@ pub enum DecodedImage { Svg(usvg::Tree), } +/// Determine the image size in pixels. +#[comemo::memoize] +fn determine_size(data: &Buffer, format: ImageFormat) -> StrResult<(u32, u32)> { + match format { + ImageFormat::Raster(format) => { + let cursor = io::Cursor::new(&data); + let reader = image::io::Reader::with_format(cursor, format.into()); + Ok(reader.into_dimensions().map_err(format_image_error)?) + } + ImageFormat::Vector(VectorFormat::Svg) => { + let opts = usvg::Options::default(); + let tree = usvg::Tree::from_data(&data, &opts.to_ref()) + .map_err(format_usvg_error)?; + + let size = tree.svg_node().size; + let width = size.width().ceil() as u32; + let height = size.height().ceil() as u32; + Ok((width, height)) + } + } +} + /// Format the user-facing raster graphic decoding error message. fn format_image_error(error: image::ImageError) -> String { match error { |
