Skip to content

Commit

Permalink
Feature flag raster image formats (#50)
Browse files Browse the repository at this point in the history
## Notes

- Fixes #47
- Allows support for raster images to be completely disabled as well as
flagging individual formats (allows the `image` dependency to be
disabled entirely as `image` is surprisingly large even with no formats
enabled)

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>
  • Loading branch information
nicoburns authored Jan 4, 2025
1 parent bbfb55f commit 0dc8473
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 28 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
20 changes: 15 additions & 5 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,23 @@ pub(crate) fn render_group<F: FnMut(&mut Scene, &usvg::Node)>(
| 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);
Expand Down
35 changes: 18 additions & 17 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<image::Rgba<u8>, Vec<u8>>) -> Image {
let (width, height) = (image.width(), image.height());
let image_data: Vec<u8> = image.into_vec();
Expand Down Expand Up @@ -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<image::RgbaImage, image::ImageError> {
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())
}

0 comments on commit 0dc8473

Please sign in to comment.