Skip to content
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

Specify color space (sRGB?) #37

Open
eliasnaur opened this issue Dec 22, 2021 · 8 comments
Open

Specify color space (sRGB?) #37

eliasnaur opened this issue Dec 22, 2021 · 8 comments

Comments

@eliasnaur
Copy link

eliasnaur commented Dec 22, 2021

I didn't see a mention of either "color space" nor "srgb" in https://github.com/google/iconvg/blob/main/spec/iconvg-spec.md, and neither did I find references in the original IVG spec. I believe the (implicit) color space should be specified, and because colors are limited to 32 bit, I suggest the common sRGB color space. As a corollary, conformant rasterizers must blend and compute gradients in linear RGB space.

@nigeltao
Copy link
Collaborator

We could add a metadata chunk to hold ICC profiles and, lacking one, sRGB seems the obvious default.

As for blend and compute (with or without gamma correction before and after linear interpolation), I suspect that the implementations (the Cairo, Skia and golang.org/x/image/vector vector graphics libraries) will lead and the spec will follow.

See also golang/go#11420

@eliasnaur
Copy link
Author

We could add a metadata chunk to hold ICC profiles and, lacking one, sRGB seems the obvious default.

FWIW, I don't care as much for the ability to change color profile as I do for specifying gamma-correct blending and interpolation. I suspect supporting just sRGB correctly would be fine.

As for blend and compute (with or without gamma correction before and after linear interpolation), I suspect that the implementations (the Cairo, Skia and golang.org/x/image/vector vector graphics libraries) will lead and the spec will follow.

See also golang/go#11420

I'm pretty sure sure golang.org/x/image/vector doesn't blend in linear colorspace. Does that mean the iconvg spec will specify gamma-incorrect blending/interpolation? As per the linked #11420, it would be unfortunate to have a new format not specify gamma-correct blending and interpolation.

@nigeltao
Copy link
Collaborator

We could add a metadata chunk to hold ICC profiles and, lacking one, sRGB seems the obvious default.

Another option: we could make "no ICC profile in the IconVG metadata" to mean linearRGB.

I'm pretty sure sure golang.org/x/image/vector doesn't blend in linear colorspace.

Yeah, golang.org/x/image/vector doesn't do gamma correction. I had a quick look and I think Cairo also doesn't do this. As for Skia, I skimmed https://skia.org/docs/user/color/ and https://skia.org/docs/user/api/skpaint_overview/ but I'm still not sure.

it would be unfortunate to have a new format not specify gamma-correct blending and interpolation.

Gamma-correction can hurt performance (decode times), though. At least on the CPU. Trade-offs...

We also already have one Cairo gradient workaround, for alpha premultiplication. It possibly wouldn't hurt to have a second workaround, for gamma. That'd just address interpolation, though, and not blending (I don't think CAIRO_OPERATOR_OVER is gamma-aware). It'd also be unfortunate if the new format is unable to be rasterized with Cairo.

FWIW, https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperty and https://www.w3.org/TR/SVG2/painting.html#ColorInterpolation is what the SVG 1.1 and SVG 2 specs says about color interpolation. IIUC "auto" means that the author doesn't really care what the user-agent does.

If authors really do care, another workaroundy idea is to declare that IconVG works solely in linearRGB and "export to IconVG" tools should approximate sRGB (or whatever color profile) how they see fit (e.g. adding explicit gradient stops), just like how "export to IconVG" already has to flatten stroked paths to simple paths.

@nigeltao
Copy link
Collaborator

As a corollary, conformant rasterizers must blend and compute gradients in linear RGB space.

I'm pretty sure sure golang.org/x/image/vector doesn't blend in linear colorspace

The terminology can be confusing. Personally, I would say that golang.org/x/image/vector does blend in linear color space because it assumes that inputs and outputs are already linear. Although by context, it looks like you use "blend in linear color space" to mean converting between linear and something else (sRGB) before and after calculating a weighted average.

How about using the terms "naive interpolation" and "sophisticated interpolation"? When interpolating e.g. the R (red) value between two colors C0 and C1 with weights W0 and W1:

Naive means:
Dst.R = W0*C0.R + W1*C1.R

Sophisticated means:
Dst.R = H(W0*G(C0.R) + W1*G(C1.R))

for some gamma correction function G and its inverse H.

@eliasnaur
Copy link
Author

Right, since package image (ala #11420) assumes linear colors, package vector can be said to interpolate correctly.

However, using the terms "naive" and "sophisticated" interpolation seems misleading to me, unless IconVG specify linear colors even for 8-bit color channels, a decision (almost) no other image format has taken. As the example from #11420 shows, incorrect blending is not just a quality issue; rather, it can result in dramatically different colors. In other words, if IconVG don't specify blending algorithm or specify "naive blending", "sophisticated" ("correct") rasterizers will be forced to use incorrect blending to match results from incorrect rasterizers.

I worry that IconVG will have the same issues as fonts authored using editors and rasterizers with incorrect blending, a problem described in https://freetype.org/freetype2/docs/hinting/text-rendering-general.html.

@pjanx
Copy link

pjanx commented Jan 8, 2022

Cairo completely disregards gamma or any other details of colour spaces.

The underlying library for software pixops, pixman, does have an 8-bit sRGB mode, though it's quite slow and not exposed.

The sanest way of using Cairo is probably to use the new CAIRO_FORMAT_RGBA128F and give it linear data, then convert that to sRGB on the output by external means, if necessary.

@eliasnaur
Copy link
Author

FWIW, Skia supports color spaces and defaults to sRGB.

@eliasnaur
Copy link
Author

An article that argues sRGB is better thought of as a (lossy) encoding rather than a color space: https://webcolorisstillbroken.com/.

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

No branches or pull requests

3 participants