Skip to content

svgload: introduce rgb128 parameter for SVG 128-bit load support #4523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

kstanikviacbs
Copy link

With the increasing demand for high quality images - a need of rendering SVG with increased color-depth (more than 8 bit) has also appeared.

Given Cairo introduced support for new data format unlocking this option for libvips - CAIRO_FORMAT_RGBA128F: https://www.cairographics.org/news/cairo-1.17.2/ - this PR is an attempt to introduce rgb128 flag into svgload to enable high-bit SVG rendering if needed.

Copy link
Member

@jcupitt jcupitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to work well! I marked a few style things that I think need changing.

meson.build Outdated
@@ -657,6 +664,7 @@ build_summary = {
'enable Analyze7 load': [get_option('analyze')],
'enable PPM load/save': [get_option('ppm')],
'enable GIF load': [get_option('nsgif')],
'enable SVG 128-bit rendering': [svg_128bit_support]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably go -- it's not really a build option.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, removed.

@jcupitt
Copy link
Member

jcupitt commented May 19, 2025

I tested with a sample SVG:

$ vips svgload lion.svg x.v --rgb128

And I get:

image

Very nice!

@jcupitt
Copy link
Member

jcupitt commented May 19, 2025

... and thank you for doing this work, Konrad, good job.

@kstanikviacbs kstanikviacbs force-pushed the svgload_128bit_support branch 3 times, most recently from 3e74ffb to 9ca1b76 Compare May 19, 2025 19:52
@kstanikviacbs kstanikviacbs force-pushed the svgload_128bit_support branch from 9ca1b76 to c6ffae0 Compare May 19, 2025 19:54
@kstanikviacbs
Copy link
Author

Thanks for your review @jcupitt . I did my best to apply all your great suggestions. Please take a look again at your convenience.

@kleisauke
Copy link
Member

Commit kleisauke@c4d898f has some minor formatting improvements and fixes the compilation when HAVE_128BIT_SVG_RENDERING is undefined, e.g.:

../libvips/foreign/svgload.c: In function ‘vips_foreign_load_svg_load’:
../libvips/foreign/svgload.c:707:13: error: ‘svg’ undeclared (first use in this function)
  707 |         if (svg->rgb128) {
      |             ^~~
../libvips/foreign/svgload.c:707:13: note: each undeclared identifier is reported only once for each function it appears in
../libvips/foreign/svgload.c:708:28: error: ‘class’ undeclared (first use in this function)
  708 |                 vips_error(class->nickname, "128-bit rendering is not supported with this version");
      |                            ^~~~~

Feel free to cherry-pick.

@kstanikviacbs
Copy link
Author

Commit kleisauke@c4d898f has some minor formatting improvements and fixes the compilation when HAVE_128BIT_SVG_RENDERING is undefined, e.g.:

../libvips/foreign/svgload.c: In function ‘vips_foreign_load_svg_load’:
../libvips/foreign/svgload.c:707:13: error: ‘svg’ undeclared (first use in this function)
  707 |         if (svg->rgb128) {
      |             ^~~
../libvips/foreign/svgload.c:707:13: note: each undeclared identifier is reported only once for each function it appears in
../libvips/foreign/svgload.c:708:28: error: ‘class’ undeclared (first use in this function)
  708 |                 vips_error(class->nickname, "128-bit rendering is not supported with this version");
      |                            ^~~~~

Feel free to cherry-pick.

Thanks @kleisauke ! I cherry-picked whole your commit.

@jcupitt
Copy link
Member

jcupitt commented May 20, 2025

Great! It's looking rather neat now, I think.

We need two more things:

  • doc comments near the bottom of svgload.c: you need to add rgb128 to the list of optional arguments for vips_svgload*(), and vips_svgload() needs a paragraph explaining what the flag does, eg. "Setting @rgb128 TRUE enables 128-bit scRGB output."
  • this is an API change, so we need a line in the main CHANGELOG
  • don't forget to credit yourself!

@jcupitt
Copy link
Member

jcupitt commented May 20, 2025

Sorry to bring this up so late, but I wonder if rgb128 is the best name for this flag? It's RGBA, not RGB, and it's 128 bits per pixel not per band element (the size measure we use elsewhere).

Savers use bitdepth to control the write depth of images. Maybe we should have a bitdepth parameter which defaults to 8 but can be set to 32? Can anyone think of another loader with a similar setting?

Does anyone have any thoughts on this?

@kstanikviacbs
Copy link
Author

kstanikviacbs commented May 20, 2025

Sorry to bring this up so late, but I wonder if rgb128 is the best name for this flag? It's RGBA, not RGB, and it's 128 bits per pixel not per band element (the size measure we use elsewhere).

Savers use bitdepth to control the write depth of images. Maybe we should have a bitdepth parameter which defaults to 8 but can be set to 32? Can anyone think of another loader with a similar setting?

Does anyone have any thoughts on this?

That's a very good point. I was also thinking about it for a while. I did some quick research and haven't found any loaders exposing such option. On one hand - bitdepth seems to follow naming convention touching such aspects and following it seems natural. On the other though - if we have only two options (8 and 32) for now (and probably this won't change soon) keeping it as bool is also a bit less misleading to me, this might be all about the parameter name we should change, perhaps something like: high_bit_depth flag with documented 32-bit value?

I'm happy to refactor it to be bitdepthanyway if that's what you guys prefer.

@kstanikviacbs
Copy link
Author

Great! It's looking rather neat now, I think.

We need two more things:

* doc comments near the bottom of `svgload.c`: you need to add `rgb128` to the list of optional arguments for `vips_svgload*()`, and `vips_svgload()` needs a paragraph explaining what the flag does, eg. "Setting @rgb128 TRUE enables 128-bit scRGB output."

* this is an API change, so we need a line in the main CHANGELOG

* don't forget to credit yourself!

Thanks! I'd postpone applying this for a while till we have a conclusion re: rgb128 :)

@@ -5784,6 +5784,7 @@ class VImage : public VObject {
* - **access** -- Required access pattern for this file, VipsAccess.
* - **fail_on** -- Error level to fail on, VipsFailOn.
* - **revalidate** -- Don't use a cached result for this operation, bool.
* - **rgb128** -- Enable 128-bit rendering
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These doc comments are generated automatically, so you don't need to include them in a PR.

This text will be replaced by the _("Enable 128-bit SVG rendering") in the ARG declaration next time this script runs:

https://github.com/libvips/libvips/blob/master/cplusplus/gen-operators.py

(no need for you to do anything, just a note)

* Processes ''n'' pixels in the ''p'' buffer.
* The data is assumed to be RGBA (R, G, B, A) 32-bit floats per pixel.
*/
void vips__rgba128f_unpremultiplied(float *p, int n) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This need to go through clang-format. libvips style is:

void
vips__rgba128f_unpremultiplied(float *p, int n) 
{
    ...
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I've just realised this name is wrong :( I should have said this before.

The other converters are named as eg. vips__premultiplied_bgra2rgba(), meaning "from cairo-style premultiplied bgra to libvips rgba".

Your converter is premultiplied rgba128 to libvips scrgba, so it should be called vips__premultiplied_rgb1282scrgba().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants