lovell / sharp-libvips

Packaging scripts to prebuild libvips and its dependencies - you're probably looking for https://github.com/lovell/sharp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

librsvg: latest version no longer depends on gdk-pixbuf but adds ~1MB to binary size

lovell opened this issue · comments

I didn't notice it at the time, but as part of commit eb6fede librsvg was upgraded to 2.57.91, which includes a major change to the way inline images within SVG files are handled.

https://gitlab.gnome.org/GNOME/librsvg/-/blob/main/NEWS

Librsvg no longer uses gdk-pixbuf for loading raster images; all image loading uses Rust code now. Older versions of librsvg would use the traditional libpng and libjpeg-turbo libraries, and gdk-pixbuf's own GIF decoder. Starting with this version of librsvg, it only uses Rust crates for image codecs.

...the only supported formats for the element are PNG, JPEG, GIF, WEBP, and SVG

It looks like rust-based decoders are being used instead, which adds ~1MB to binary sizes.

Before:

 9852590 Jan 21 11:02 librsvg-2.a
16243944 Jan 21 11:03 libvips-cpp.so.42.17.1

After:

12419718 Feb 11 17:56 librsvg-2.a
17189896 Feb 11 17:57 libvips-cpp.so.42.17.1

We should investigate to see what, if anything, can be reduced/removed.

Thoughts of the top of my head:

  • Can we now remove gdk-pixbuf and libpng? Anything else?
  • Can we specify a minimal image rust crate with only required decoders?
  • Do we investigate a switch to resvg?

Ah, bummer, I should have noticed this earlier. A short-term solution would be to downgrade librsvg to v2.57.2.

  • Can we now remove gdk-pixbuf and libpng? Anything else?

Unfortunately, gdk-pixbuf is still required by the legacy pixbuf-based C API of librsvg (rsvg_pixbuf_*) on which the rsvg_handle_get_pixbuf()/rsvg_handle_get_pixbuf_sub() functions depend.
https://gitlab.gnome.org/GNOME/librsvg/-/blob/a9b4bfdd3e919535c12fed3947aa746d0b5dddce/librsvg-c/Cargo.toml#L16

Perhaps it's possible to feature-gate these APIs? /cc @federicomenaquintero

Updating rsvg/Cargo.toml so the image dependency is built with only JPEG and PNG support appears to reduce the size of the static librsvg by about 20%.

- image = "0.24.7"
+ image = { version="0.25.0", default-features=false, features=["jpeg", "png"] }
10575270 librsvg-2.a
16472904 libvips-cpp.so.42.17.2

I've temporarily pinned librsvg to version 2.57.2 for now via commit e5cb076

Commit libvips/build-win64-mxe@3c20642 pins librsvg to version 2.57.3 within the Windows build scripts.

I'll look into turning gdk-pixbuf into an optional dependency within librsvg this weekend.

Hi! I have a few related questions for you:

  • How is the size increase of the library a problem? I'm not denying that it presents a problem for you; I'd just like to know why. (My take: code has to go somewhere, and it is unfortunate that backwards compatibility makes us keep the entirety of gdk-pixbuf around. Depending on the parts of the stack you use, if you want a minimal / custom stack, you may of course need to look into disabling things yourselves... and I'm happy to help on my side; read on).
  • Making gdk-pixbuf an optional feature for librsvg is certainly interesting, for people who don't need rsvg_handle_render_pixbuf() and friends. I'd be happy to review an MR for this; the recent switch to Meson makes all this much easier. @kleisauke is this what you are thinking about?
  • In librsvg we just got an MR to make it possible to include AVIF support in image-rs, as it "just happened" if one installed the gdk-pixbuf module for AVIF in the past. I don't know if that MR's scheme for tweaking image-rs is the final scheme we'll be using, but this sets clear precedent for wanting to tweak how image-rs is built for librsvg. I'd also like to make it possible to have a super-locked-down version with only PNG/JPEG per the SVG spec. @lovell is this what you are thinking about?

(If you want, we can move this discussion to the librsvg bug tracker.)

Hola Federico, thank you for dropping by, it's always a pleasure to read your thoughts.

Many people use sharp in serverless or similar PaaS environments that often have limitations on deployment size (e.g. AWS Lambda zip files are limited to 50MB max). When building C-based dependencies -Os is the default unless there's a proven benefit in using -O3.

These binaries are downloaded from the npmjs registry at least 7 times every second, which means librsvg currently enjoys an additional ~4.7 million downloads per week and might well be one of your biggest consumers. Anything we can do to minimise the download and therefore energy cost of these binaries should be seen as a good thing. I am however very much aware that this can and does start to push complexity into build logic.

I'd also like to make it possible to have a super-locked-down version with only PNG/JPEG per the SVG spec.

Yes please, this is what I was trying to emulate by tweaking features of the image crate in the Cargo.toml file.

My philosophy for image formats is pretty much: "Rule 1 of open-source: no is temporary, yes is forever."

Making gdk-pixbuf an optional feature for librsvg is certainly interesting, for people who don't need rsvg_handle_render_pixbuf() and friends. I'd be happy to review an MR for this; the recent switch to Meson makes all this much easier. @kleisauke is this what you are thinking about?

Yes exactly. I just opened MR https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/956 for this.

Tested using these changesets:
main...kleisauke:librsvg-meson
https://github.com/libvips/build-win64-mxe/compare/librsvg-meson

Thanks for the detailed work on that!

If I may bother you further - @lovell's request is pretty much https://gitlab.gnome.org/GNOME/librsvg/-/issues/1061 - maybe you'd be interested in some more image-rs related shenanigans?

I could look at upstreaming that next weekend. For now, I can confirm that building librsvg 2.58.90 without gdk-pixbuf and @lovell's change fixes this issue. See e.g. commit kleisauke@d39d58c.

16395024 libvips-cpp.so.42.17.2

https://github.com/kleisauke/libvips-packaging/actions/runs/8680523623/job/23801286756#step:4:14423

(however, CI is encountering issues when cross-compiling the zune-jpeg crate. I think(?) we need to pass the CC env to Cargo invocations, just like pkg-config here)

I just opened MR https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/967 for this.

(however, CI is encountering issues when cross-compiling the zune-jpeg crate. I think(?) we need to pass the CC env to Cargo invocations, just like pkg-config here)

It looks like commit etemesi254/zune-image@5846e3c will fix this.