diff --git a/CHANGELOG.md b/CHANGELOG.md index a3cbace..facb3fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ You can find its changes [documented below](#050-2024-11-20). This release has an [MSRV][] of 1.75. +### Changed + +- Feature flag raster image formats (enabled by default) ([#50] by [@nicoburns]) + ## [0.5.0][] (2024-11-20) This release has an [MSRV][] of 1.75. @@ -107,6 +111,7 @@ This release has an [MSRV][] of 1.75. [@MarijnS95]: https://github.com/MarijnS95 [@DasLixou]: https://github.com/DasLixou +[#50]: https://github.com/linebender/vello_svg/pull/50 [#42]: https://github.com/linebender/vello_svg/pull/42 [#34]: https://github.com/linebender/vello_svg/pull/34 [#31]: https://github.com/linebender/vello_svg/pull/31 diff --git a/Cargo.toml b/Cargo.toml index 5203b73..5df2f54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,16 +99,17 @@ workspace = true vello = { workspace = true } thiserror = "1.0.69" usvg = "0.44.0" -image = { version = "0.25.5", default-features = false, features = [ - "webp", - "png", - "jpeg", - "gif", -] } +image = { version = "0.25.5", default-features = false, features = [ "webp", "png", "jpeg", "gif"], optional = true } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.49" [features] +default = ["image_format_png", "image_format_gif", "image_format_jpeg", "image_format_webp"] # Enables the wgpu feature on vello, which is disabled by default wgpu = ["vello/wgpu"] +image = ["dep:image"] +image_format_png = ["image", "image/png"] +image_format_jpeg = ["image", "image/jpeg"] +image_format_gif = ["image", "image/gif"] +image_format_webp = ["image", "image/webp"] diff --git a/src/render.rs b/src/render.rs index 1c70674..125fd68 100644 --- a/src/render.rs +++ b/src/render.rs @@ -104,13 +104,23 @@ pub(crate) fn render_group( | usvg::ImageKind::PNG(_) | usvg::ImageKind::GIF(_) | usvg::ImageKind::WEBP(_) => { - let Ok(decoded_image) = util::decode_raw_raster_image(img.kind()) else { + #[cfg(feature = "image")] + { + let Ok(decoded_image) = util::decode_raw_raster_image(img.kind()) + else { + error_handler(scene, node); + continue; + }; + let image = util::into_image(decoded_image); + let image_ts = util::to_affine(&img.abs_transform()); + scene.draw_image(&image, image_ts); + } + + #[cfg(not(feature = "image"))] + { error_handler(scene, node); continue; - }; - let image = util::into_image(decoded_image); - let image_ts = util::to_affine(&img.abs_transform()); - scene.draw_image(&image, image_ts); + } } usvg::ImageKind::SVG(svg) => { render_group(scene, svg.root(), transform, error_handler); diff --git a/src/util.rs b/src/util.rs index 26011cd..031ddb2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,9 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT use vello::kurbo::{Affine, BezPath, Point, Rect, Stroke}; -use vello::peniko::{Blob, Brush, Color, Fill, Image}; +use vello::peniko::{Brush, Color, Fill}; use vello::Scene; +#[cfg(feature = "image")] +use vello::peniko::{Blob, Image}; + pub fn to_affine(ts: &usvg::Transform) -> Affine { let usvg::Transform { sx, @@ -89,6 +92,7 @@ pub fn to_bez_path(path: &usvg::Path) -> BezPath { local_path } +#[cfg(feature = "image")] pub fn into_image(image: image::ImageBuffer, Vec>) -> Image { let (width, height) = (image.width(), image.height()); let image_data: Vec = image.into_vec(); @@ -202,24 +206,21 @@ pub fn default_error_handler(scene: &mut Scene, node: &usvg::Node) { ); } +#[cfg(feature = "image")] pub fn decode_raw_raster_image( img: &usvg::ImageKind, ) -> Result { - let res = match img { - usvg::ImageKind::JPEG(data) => { - image::load_from_memory_with_format(data, image::ImageFormat::Jpeg) - } - usvg::ImageKind::PNG(data) => { - image::load_from_memory_with_format(data, image::ImageFormat::Png) - } - usvg::ImageKind::GIF(data) => { - image::load_from_memory_with_format(data, image::ImageFormat::Gif) - } - usvg::ImageKind::WEBP(data) => { - image::load_from_memory_with_format(data, image::ImageFormat::WebP) - } + // All `image::ImageFormat` variants exist even if the feature in the image crate is disabled, + // but `image::load_from_memory_with_format` will fail with an Unsupported error if the + // image crate feature flag is disabled. So we don't need any of our own feature handling here. + let (data, format) = match img { + usvg::ImageKind::JPEG(data) => (data, image::ImageFormat::Jpeg), + usvg::ImageKind::PNG(data) => (data, image::ImageFormat::Png), + usvg::ImageKind::GIF(data) => (data, image::ImageFormat::Gif), + usvg::ImageKind::WEBP(data) => (data, image::ImageFormat::WebP), usvg::ImageKind::SVG(_) => unreachable!(), - }? - .into_rgba8(); - Ok(res) + }; + + let dyn_image = image::load_from_memory_with_format(data, format)?; + Ok(dyn_image.into_rgba8()) }