From 34b9b4cdce5450bf8cf9e100ec88583d0ec39158 Mon Sep 17 00:00:00 2001 From: Joshua May Date: Wed, 24 Jul 2024 19:03:04 +0200 Subject: [PATCH] Add support for decoding WebP images (#747) Closes #575 --- .github/workflows/main.yml | 2 +- Cargo.lock | 23 +++++++++ README.md | 2 +- crates/resvg/Cargo.toml | 3 +- crates/resvg/src/image.rs | 35 +++++++++++++ crates/resvg/tests/integration/render.rs | 2 + crates/resvg/tests/resources/image.webp | Bin 0 -> 2196 bytes .../tests/structure/image/embedded-webp.png | Bin 0 -> 30464 bytes .../tests/structure/image/embedded-webp.svg | 47 ++++++++++++++++++ .../tests/structure/image/external-webp.png | Bin 0 -> 30464 bytes .../tests/structure/image/external-webp.svg | 8 +++ crates/usvg/src/parser/image.rs | 13 +++-- crates/usvg/src/tree/mod.rs | 16 +++--- crates/usvg/src/writer.rs | 1 + 14 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 crates/resvg/tests/resources/image.webp create mode 100644 crates/resvg/tests/tests/structure/image/embedded-webp.png create mode 100644 crates/resvg/tests/tests/structure/image/embedded-webp.svg create mode 100644 crates/resvg/tests/tests/structure/image/external-webp.png create mode 100644 crates/resvg/tests/tests/structure/image/external-webp.svg diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ed3dfaa6a..f91fb60d8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,7 +41,7 @@ jobs: - name: Install toolchain uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.65.0 + toolchain: 1.67.1 - name: Build run: cargo build diff --git a/Cargo.lock b/Cargo.lock index 989aa3619..38190720b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "cfg-if" version = "1.0.0" @@ -129,6 +135,16 @@ dependencies = [ "weezl", ] +[[package]] +name = "image-webp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +dependencies = [ + "byteorder-lite", + "quick-error", +] + [[package]] name = "imagesize" version = "0.12.0" @@ -201,11 +217,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "resvg" version = "0.42.0" dependencies = [ "gif", + "image-webp", "log", "once_cell", "pico-args", diff --git a/README.md b/README.md index 5b105587d..ee6f888b1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Build Status](https://github.com/RazrFalcon/resvg/workflows/Build/badge.svg) [![Crates.io](https://img.shields.io/crates/v/resvg.svg)](https://crates.io/crates/resvg) [![Documentation](https://docs.rs/resvg/badge.svg)](https://docs.rs/resvg) -[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org) +[![Rust 1.67.1+](https://img.shields.io/badge/rust-1.67.1+-orange.svg)](https://www.rust-lang.org) *resvg* is an [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) rendering library. diff --git a/crates/resvg/Cargo.toml b/crates/resvg/Cargo.toml index 85ec077da..6a817db95 100644 --- a/crates/resvg/Cargo.toml +++ b/crates/resvg/Cargo.toml @@ -16,6 +16,7 @@ required-features = ["text", "system-fonts", "memmap-fonts"] [dependencies] gif = { version = "0.13", optional = true } +image-webp = { version = "0.1.3", optional = true } log = "0.4" pico-args = { version = "0.5", features = ["eq-separator"] } rgb = "0.8" @@ -40,4 +41,4 @@ memmap-fonts = ["usvg/memmap-fonts"] # Enables decoding and rendering of raster images. # When disabled, `image` elements with SVG data will still be rendered. # Adds around 200KiB to your binary. -raster-images = ["gif", "dep:zune-jpeg"] +raster-images = ["gif", "image-webp", "dep:zune-jpeg"] diff --git a/crates/resvg/src/image.rs b/crates/resvg/src/image.rs index e63e0a079..3f4f34958 100644 --- a/crates/resvg/src/image.rs +++ b/crates/resvg/src/image.rs @@ -70,6 +70,9 @@ mod raster_images { usvg::ImageKind::GIF(ref data) => { decode_gif(data).log_none(|| log::warn!("Failed to decode a GIF image.")) } + usvg::ImageKind::WEBP(ref data) => { + decode_webp(data).log_none(|| log::warn!("Failed to decode a WebP image.")) + } } } @@ -107,6 +110,38 @@ mod raster_images { Some(pixmap) } + fn decode_webp(data: &[u8]) -> Option { + let mut decoder = image_webp::WebPDecoder::new(std::io::Cursor::new(data)).ok()?; + let mut first_frame = vec![0; decoder.output_buffer_size()?]; + decoder.read_image(&mut first_frame).ok()?; + + let (w, h) = decoder.dimensions(); + let mut pixmap = tiny_skia::Pixmap::new(w, h)?; + + if decoder.has_alpha() { + rgba_to_pixmap(&first_frame, &mut pixmap); + } else { + rgb_to_pixmap(&first_frame, &mut pixmap); + } + + Some(pixmap) + } + + fn rgb_to_pixmap(data: &[u8], pixmap: &mut tiny_skia::Pixmap) { + use rgb::FromSlice; + + let mut i = 0; + let dst = pixmap.data_mut(); + for p in data.as_rgb() { + dst[i + 0] = p.r; + dst[i + 1] = p.g; + dst[i + 2] = p.b; + dst[i + 3] = 255; + + i += tiny_skia::BYTES_PER_PIXEL; + } + } + fn rgba_to_pixmap(data: &[u8], pixmap: &mut tiny_skia::Pixmap) { use rgb::FromSlice; diff --git a/crates/resvg/tests/integration/render.rs b/crates/resvg/tests/integration/render.rs index 6dfcb61da..987515e2a 100644 --- a/crates/resvg/tests/integration/render.rs +++ b/crates/resvg/tests/integration/render.rs @@ -1101,12 +1101,14 @@ use crate::render; #[test] fn structure_image_embedded_svg_without_mime() { assert_eq!(render("tests/structure/image/embedded-svg-without-mime"), 0); } #[test] fn structure_image_embedded_svg() { assert_eq!(render("tests/structure/image/embedded-svg"), 0); } #[test] fn structure_image_embedded_svgz() { assert_eq!(render("tests/structure/image/embedded-svgz"), 0); } +#[test] fn structure_image_embedded_webp() { assert_eq!(render("tests/structure/image/embedded-webp"), 0); } #[test] fn structure_image_external_gif() { assert_eq!(render("tests/structure/image/external-gif"), 0); } #[test] fn structure_image_external_jpeg() { assert_eq!(render("tests/structure/image/external-jpeg"), 0); } #[test] fn structure_image_external_png() { assert_eq!(render("tests/structure/image/external-png"), 0); } #[test] fn structure_image_external_svg_with_transform() { assert_eq!(render("tests/structure/image/external-svg-with-transform"), 0); } #[test] fn structure_image_external_svg() { assert_eq!(render("tests/structure/image/external-svg"), 0); } #[test] fn structure_image_external_svgz() { assert_eq!(render("tests/structure/image/external-svgz"), 0); } +#[test] fn structure_image_external_webp() { assert_eq!(render("tests/structure/image/external-webp"), 0); } #[test] fn structure_image_float_size() { assert_eq!(render("tests/structure/image/float-size"), 0); } #[test] fn structure_image_image_with_float_size_scaling() { assert_eq!(render("tests/structure/image/image-with-float-size-scaling"), 0); } #[test] fn structure_image_no_height_non_square() { assert_eq!(render("tests/structure/image/no-height-non-square"), 0); } diff --git a/crates/resvg/tests/resources/image.webp b/crates/resvg/tests/resources/image.webp new file mode 100644 index 0000000000000000000000000000000000000000..2d6c9ca584b1aa19229393727fc853f9aead72b9 GIT binary patch literal 2196 zcmV;F2y6FJNk&GD2mki{z3rzE5fjiORQ9hN zZAK(j+yC=_jHo3uE!wty0Bp8x8(++}w*&lr_51E5){G-?G~27quQQl!o6&1(_L}W2 zSD74-4p!11uWaPO-H-6xsGky$sZeFn`O7aY=f&z zMY0j(#gLs)1n{{NKzrN%b8=JLwr$(CZQHhO+qP}nwr$(L?{|Ka{R?W%9@KVY+uFQG z;a_U)V39KYQ42F-73!1w&UcebsO8Zs)|~;ySuxEUs?bniveyU00^Snn6QA? zgf*N2+})khp|no^lm1UY^U_gmOeNe+IN~2vk0m~gn5DCu z&^q;L(wJ=!m?EVg^Rdy>fMl{`A2g@Bwwa@K>Lq_AYTe@4`Uk)dpfI32V00mX4*-Bu z>rat5$OHqwQG2n|6@ZdhlJz0EI3)m}#QDtK4Q%+*A;~HaqjY**h38r+t8v-8PR&8S z{dd$by8i_;PW}T~vLF=BOXdKXr2cyR2MnX#cf6*caGF<_bho-HPa~t6)@CGYeWZBX zIk)Z?2#Xx=+_!j70;mH@YXLyZ&qTYgcoD-rgznu>3AR&H4f#j1LTwdDeggGZN?nZr zbd0P+0F=5O#ezJr{HS7WVZfQ=WUa3hSa}4!ts!d(=nW`6tNBs%wN8CVo(6yzfFYTI z@o9l95EaXMh}NYjL|M`z6Y%8_L<0aoqWze@Z{*$k015*3kmNMvfB=0U>IDdMWI9N4 zPhJ23kKTuBFFjp<$+UU{fS7<+4R66n%xUD6+8t zP{FaT=ZQ!hjhcc208cVH7mA+32t#=@0H`&}>T2}Vqv0NahoCY#Z*E$UMWK8uUIx(7 zH>9VN7uV=%M8mifK$3y@MndO8FeOMBO26r!>;VwU(9t#yl70ed817#IfDcp91N5Me2+qscU+OdY@ z_~K`aOp$R%F(PqfJ*JYMdmLN;U~;;RMS30aVX|v2 zVNTMtwjh~sKLNezHa3SNKJ>mXc(8`-eGEYI+UST@CyN&$^SOV&&?H^?dj$imihSb8sll3%~lP|;okk& z_zb50I4~CQ2u^C}n9D zE2Y-vumqSMlJ%fz8j=?}91$pAi~3PYZHWk&jjI9^lggG3O5?UDRWoZs6W5|Ft zRJ4&G`MG0KNUlMIn;N2TNU|$j)RrxWaJ4QmZ?(J>f@CXLl(Mu8$#W{BZb;6`DN4EA zPSSTgl57}@QjX3cxfmAFLQBg{B$vUWlv2?mk*t@B2tisaN2yvM89mybBp*0MDW(1i zOR_oy5yq!1O@T>HP8kSxeDlpWt02HckZcg8nup}Qmj6gzsUBz^xuat;E>T#l!(F3f_* zZWoawPyhfhA|z{~QAl1|Di)`K<4%-tI3fesmgKQVkZc0rbdufkYiU^A5wfBZ+!9XA zT99M|0H__37fubyN&z+{=?lo2G=uP2Vt1j<7%x*mau$vTN`~T{3d95euJb@rWlhMu ziEJ*Qbao=?1xT_Cq6C>>1{Y{`yzJMn-)s@MP6x^N0DLAo0#4(qdAa-U@X0kV&k9NR z0Ng~M0N9u0D}p>Zo}?FZlmN-~P#PC2$r1rjBO(_75lKE=Jem+B*WhMzBu`IrHg>by zcl(v(lq3gGEP@dE03a8ZfaJvdpZo;hi$QWAU=D<(c3~XUh6Mn7bj`Rt0RT-x?OZGg zwUuI?JJM*x{c?u}hiHldV0-SUXv9~#>WDHsq=Y7#8smir-aCFP6NrEMx;tyA&tMCQ7Vj8U-ko_B(j55ozEP=_>ob`xWn9kf~3MYZdm_i_;`djC%W%lxoZR`G7 WRxYzw9pZ*oewe(q4DYj{($8GO>k`BO literal 0 HcmV?d00001 diff --git a/crates/resvg/tests/tests/structure/image/embedded-webp.png b/crates/resvg/tests/tests/structure/image/embedded-webp.png new file mode 100644 index 0000000000000000000000000000000000000000..fdb3d7704ee50270b5461094c84c767ae68f0716 GIT binary patch literal 30464 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 SKH-vW0V+!GURNlZefS@3%7JYF literal 0 HcmV?d00001 diff --git a/crates/resvg/tests/tests/structure/image/embedded-webp.svg b/crates/resvg/tests/tests/structure/image/embedded-webp.svg new file mode 100644 index 000000000..b9e03765a --- /dev/null +++ b/crates/resvg/tests/tests/structure/image/embedded-webp.svg @@ -0,0 +1,47 @@ + + Embedded WebP + + + + + diff --git a/crates/resvg/tests/tests/structure/image/external-webp.png b/crates/resvg/tests/tests/structure/image/external-webp.png new file mode 100644 index 0000000000000000000000000000000000000000..fdb3d7704ee50270b5461094c84c767ae68f0716 GIT binary patch literal 30464 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 SKH-vW0V+!GURNlZefS@3%7JYF literal 0 HcmV?d00001 diff --git a/crates/resvg/tests/tests/structure/image/external-webp.svg b/crates/resvg/tests/tests/structure/image/external-webp.svg new file mode 100644 index 000000000..21dc2ebf7 --- /dev/null +++ b/crates/resvg/tests/tests/structure/image/external-webp.svg @@ -0,0 +1,8 @@ + + External WebP + + + + + diff --git a/crates/usvg/src/parser/image.rs b/crates/usvg/src/parser/image.rs index 3c0aa9472..e622e20dd 100644 --- a/crates/usvg/src/parser/image.rs +++ b/crates/usvg/src/parser/image.rs @@ -53,7 +53,7 @@ impl ImageHrefResolver<'_> { /// /// base64 encoded data is already decoded. /// - /// The default implementation would try to load JPEG, PNG, GIF, SVG and SVGZ types. + /// The default implementation would try to load JPEG, PNG, GIF, WebP, SVG and SVGZ types. /// Note that it will simply match the `mime` or data's magic. /// The actual images would not be decoded. It's up to the renderer. pub fn default_data_resolver() -> ImageHrefDataResolverFn<'static> { @@ -62,11 +62,13 @@ impl ImageHrefResolver<'_> { "image/jpg" | "image/jpeg" => Some(ImageKind::JPEG(data)), "image/png" => Some(ImageKind::PNG(data)), "image/gif" => Some(ImageKind::GIF(data)), + "image/webp" => Some(ImageKind::WEBP(data)), "image/svg+xml" => load_sub_svg(&data, opts), "text/plain" => match get_image_data_format(&data) { Some(ImageFormat::JPEG) => Some(ImageKind::JPEG(data)), Some(ImageFormat::PNG) => Some(ImageKind::PNG(data)), Some(ImageFormat::GIF) => Some(ImageKind::GIF(data)), + Some(ImageFormat::WEBP) => Some(ImageKind::WEBP(data)), _ => load_sub_svg(&data, opts), }, _ => None, @@ -98,9 +100,10 @@ impl ImageHrefResolver<'_> { Some(ImageFormat::JPEG) => Some(ImageKind::JPEG(Arc::new(data))), Some(ImageFormat::PNG) => Some(ImageKind::PNG(Arc::new(data))), Some(ImageFormat::GIF) => Some(ImageKind::GIF(Arc::new(data))), + Some(ImageFormat::WEBP) => Some(ImageKind::WEBP(Arc::new(data))), Some(ImageFormat::SVG) => load_sub_svg(&data, opts), _ => { - log::warn!("'{}' is not a PNG, JPEG, GIF or SVG(Z) image.", href); + log::warn!("'{}' is not a PNG, JPEG, GIF, WebP or SVG(Z) image.", href); None } } @@ -123,6 +126,7 @@ enum ImageFormat { PNG, JPEG, GIF, + WEBP, SVG, } @@ -298,7 +302,7 @@ pub(crate) fn get_href_data(href: &str, state: &converter::State) -> Option Option { let ext = path.extension().and_then(|e| e.to_str())?.to_lowercase(); @@ -309,12 +313,13 @@ fn get_image_file_format(path: &std::path::Path, data: &[u8]) -> Option Option { match imagesize::image_type(data).ok()? { imagesize::ImageType::Gif => Some(ImageFormat::GIF), imagesize::ImageType::Jpeg => Some(ImageFormat::JPEG), imagesize::ImageType::Png => Some(ImageFormat::PNG), + imagesize::ImageType::Webp => Some(ImageFormat::WEBP), _ => None, } } diff --git a/crates/usvg/src/tree/mod.rs b/crates/usvg/src/tree/mod.rs index cf97b5099..73f8fad2d 100644 --- a/crates/usvg/src/tree/mod.rs +++ b/crates/usvg/src/tree/mod.rs @@ -1424,6 +1424,8 @@ pub enum ImageKind { PNG(Arc>), /// A reference to raw GIF data. Should be decoded by the caller. GIF(Arc>), + /// A reference to raw WebP data. Should be decoded by the caller. + WEBP(Arc>), /// A preprocessed SVG tree. Can be rendered as is. SVG(Tree), } @@ -1431,12 +1433,13 @@ pub enum ImageKind { impl ImageKind { pub(crate) fn actual_size(&self) -> Option { match self { - ImageKind::JPEG(ref data) | ImageKind::PNG(ref data) | ImageKind::GIF(ref data) => { - imagesize::blob_size(data) - .ok() - .and_then(|size| Size::from_wh(size.width as f32, size.height as f32)) - .log_none(|| log::warn!("Image has an invalid size. Skipped.")) - } + ImageKind::JPEG(ref data) + | ImageKind::PNG(ref data) + | ImageKind::GIF(ref data) + | ImageKind::WEBP(ref data) => imagesize::blob_size(data) + .ok() + .and_then(|size| Size::from_wh(size.width as f32, size.height as f32)) + .log_none(|| log::warn!("Image has an invalid size. Skipped.")), ImageKind::SVG(ref svg) => Some(svg.size), } } @@ -1448,6 +1451,7 @@ impl std::fmt::Debug for ImageKind { ImageKind::JPEG(_) => f.write_str("ImageKind::JPEG(..)"), ImageKind::PNG(_) => f.write_str("ImageKind::PNG(..)"), ImageKind::GIF(_) => f.write_str("ImageKind::GIF(..)"), + ImageKind::WEBP(_) => f.write_str("ImageKind::WEBP(..)"), ImageKind::SVG(_) => f.write_str("ImageKind::SVG(..)"), } } diff --git a/crates/usvg/src/writer.rs b/crates/usvg/src/writer.rs index e2d5c6ec6..c36045fd8 100644 --- a/crates/usvg/src/writer.rs +++ b/crates/usvg/src/writer.rs @@ -1073,6 +1073,7 @@ impl XmlWriterExt for XmlWriter { ImageKind::JPEG(ref data) => ("jpeg", data.as_slice()), ImageKind::PNG(ref data) => ("png", data.as_slice()), ImageKind::GIF(ref data) => ("gif", data.as_slice()), + ImageKind::WEBP(ref data) => ("webp", data.as_slice()), ImageKind::SVG(ref tree) => { svg_string = tree.to_string(&WriteOptions::default()); ("svg+xml", svg_string.as_bytes())