summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPgBiel <9021226+PgBiel@users.noreply.github.com>2025-02-10 07:39:04 -0300
committerGitHub <noreply@github.com>2025-02-10 10:39:04 +0000
commit3fba256405c4aae9f121a07ddaa29cc10b825fc9 (patch)
treea6c85d201a84ab13e305dce570e56c6a77546406
parente4f8e57c534db8a31d51e0342c46b913a7e22422 (diff)
Don't crash on image with zero DPI (#5835)
-rw-r--r--crates/typst-layout/src/image.rs2
-rw-r--r--crates/typst-library/src/visualize/image/raster.rs6
2 files changed, 8 insertions, 0 deletions
diff --git a/crates/typst-layout/src/image.rs b/crates/typst-layout/src/image.rs
index d963ea50..3e5b7d8b 100644
--- a/crates/typst-layout/src/image.rs
+++ b/crates/typst-layout/src/image.rs
@@ -95,6 +95,8 @@ pub fn layout_image(
} else {
// If neither is forced, take the natural image size at the image's
// DPI bounded by the available space.
+ //
+ // Division by DPI is fine since it's guaranteed to be positive.
let dpi = image.dpi().unwrap_or(Image::DEFAULT_DPI);
let natural = Axes::new(pxw, pxh).map(|v| Abs::inches(v / dpi));
Size::new(
diff --git a/crates/typst-library/src/visualize/image/raster.rs b/crates/typst-library/src/visualize/image/raster.rs
index d43b1548..0883fe71 100644
--- a/crates/typst-library/src/visualize/image/raster.rs
+++ b/crates/typst-library/src/visualize/image/raster.rs
@@ -160,6 +160,8 @@ impl RasterImage {
}
/// The image's pixel density in pixels per inch, if known.
+ ///
+ /// This is guaranteed to be positive.
pub fn dpi(&self) -> Option<f64> {
self.0.dpi
}
@@ -334,6 +336,9 @@ fn apply_rotation(image: &mut DynamicImage, rotation: u32) {
}
/// Try to determine the DPI (dots per inch) of the image.
+///
+/// This is guaranteed to be a positive value, or `None` if invalid or
+/// unspecified.
fn determine_dpi(data: &[u8], exif: Option<&exif::Exif>) -> Option<f64> {
// Try to extract the DPI from the EXIF metadata. If that doesn't yield
// anything, fall back to specialized procedures for extracting JPEG or PNG
@@ -341,6 +346,7 @@ fn determine_dpi(data: &[u8], exif: Option<&exif::Exif>) -> Option<f64> {
exif.and_then(exif_dpi)
.or_else(|| jpeg_dpi(data))
.or_else(|| png_dpi(data))
+ .filter(|&dpi| dpi > 0.0)
}
/// Try to get the DPI from the EXIF metadata.