Closed Bug 630657 Opened 9 years ago Closed 8 years ago

SVG masks are rendered incorrectly

Categories

(Core :: SVG, defect)

defect
Not set

Tracking

()

RESOLVED FIXED
mozilla10

People

(Reporter: bugzilla, Assigned: longsonr)

References

()

Details

(Keywords: dev-doc-complete)

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13

The extreme values (i.e. fully opaque and fully transparent) seem to work fine, but everything in between is wrong.

Minefield 4.0b11pre (2011-02-01) is also affected. Same thing goes for Firefox 3.6 on Linux.

Inkscape and Opera get it right. Firefox, Chrome, and Batik get it wrong. Looks like it's some kind of popular mistake to make. I'm certain that Inkscape's and Opera's output is correct, because it makes masks useful and because it also matches the results I get if I do the math myself.

E.g. if we take the 4th quad:

Mask: 191 191 191 -> 191/255=0.7490196078431372549019607843

Color: 255 0 0

Background: 255 255 255

(1-0.75)*255+0.75*255=255.00
(1-0.75)*255+0.75*0=63.75
(1-0.75)*255+0.75*0=63.75

Result: 255 64 64 (same as Opera and Inkscape)

Firefox: 255 122 122 (I do not know how it arrived there)

Reproducible: Always
Haven't you forgotten to to convert the colours from sRGB to linearRGB, before applying the mask in your calculation?

http://www.w3.org/TR/SVG/painting.html#RenderingProperties
I didn't apply any kind of gamma curve to my luminance value, therefore it was linear to begin with.

Using a layer mask in Photoshop also behaves the very same way.

Same thing if you draw some TGA image which uses that mask image as alpha channel.

This is really the way it should behave. Anything else isn't very useful.
> I didn't apply any kind of gamma curve to my luminance value, therefore it was
> linear to begin with.

The default color space for colors in SVG is sRGB, not linear RGB.  Then see where http://www.w3.org/TR/SVG/masking.html#MaskElement says:

    A linear luminance value is computed from the color channel values. This
    can be done, for example, by first converting the original image color
    values (potentially in the sRGB color space) to the linear RGB color space
    (see Rendering properties). Then, using non-premultiplied linear RGB color
    values, apply the luminance-to-alpha coefficients (as defined in the
    ‘feColorMatrix’ filter primitive)...

So in your case, the mask is (191, 191, 191) in sRGB.  That's (133, 133, 133) in linearRGB.  Then the luminance is 133, and the corresponding alpha value is 0.52.

  (1-0.52)*255 + 0.52 * 0 = 122.34

Which is where the 122 comes from.

So in fact Inkscape and Opera are doing this wrong given your SVG.
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago
Resolution: --- → INVALID
If you are indeed reading the specs right, then the specs are wrong. Masking isn't a new thing and it works this (my) way everywhere else. Throwing some gamma curve into the mix makes it completely unpredictable.

E.g. if I use some 50% gray (127 127 127) as mask, I do of course expect a 50% alpha.

>So in fact Inkscape and Opera are doing this wrong given your SVG.

Safari (4+5 Win32 and 3 on iPhone), too. Right now we got a 50/50 split between Inkscape/Opera/Safari and Firefox/Chrome/Batik. The former mimics the well-known intuitive behavior and the latter is something unique and weird.

I just got an IE9 screenshot. IE9 also renders it the same way as Inkscape, Opera, and Safari.
Over here (Mac 10.6), Safari 5, Chrome, and Firefox render the testcase the same way (the right way per spec, as far as I can tell).  Opera renders differently (in the way you seem to expect).

If you think the spec is wrong, please mail www-svg@w3.org about that?
Oh, and the point is I have no idea why Safari has different behavior here depending on OS.  ;)
Unless they mistakenly apply their default color management settings to SVG and those differ by OS or something?
>If you think the spec is wrong, please mail www-svg@w3.org about that?

Erik Dahlstrom already did that:

http://lists.w3.org/Archives/Public/public-svg-wg/2011JanMar/0103.html

And yes, it does indeed like it's an issue with the specs. Otherwise we wouldn't have this 50/50 split.
> Otherwise we wouldn't have this 50/50 split.

Sure we would.  Implementors implement things wrong (esp. by copying other implementors) all the time.

Erik's mail is proposing the same spec change you are, yes.  But it's definitely a spec change, not a spec clarification.
Reopening as the SVG specification has changed.
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: INVALID → ---
Duplicate of this bug: 689506
Attached patch patchSplinter Review
Assignee: nobody → longsonr
Status: REOPENED → ASSIGNED
Attachment #563029 - Flags: review?(dholbert)
OS: Windows XP → All
Hardware: x86 → All
Comment on attachment 563029 [details] [diff] [review]
patch

r=jwatt
Attachment #563029 - Flags: review?(dholbert) → review+
Version: unspecified → Trunk
Try run for d0f7a70d98c2 is complete.
Detailed breakdown of the results available here:
    https://tbpl.mozilla.org/?tree=Try&rev=d0f7a70d98c2
Results (out of 69 total builds):
    success: 65
    warnings: 4
Builds available at http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/longsonr@gmail.com-d0f7a70d98c2
masks used to operate in the linearRGB colour space. After this patch they can operate in either linearRGB or sRGB. The default is, however sRGB so this is not a backwards compatible change.

This reflects a change in the SVG specification from 1.1 to 1.1 Second Edition...

For any graphics object that is used as a mask, the mask value at any point is computed from the color channel values and alpha channel value as follows. First a luminance value is computed from the color channel values:

    If the computed value of ‘color-interpolation’ on the ‘mask’ element is linearRGB, first convert the original image color values (potentially in the sRGB color space) to the linear RGB color space (see Rendering properties). Then, using non-premultiplied linear RGB color values, apply the luminance-to-alpha coefficients (as defined in the ‘feColorMatrix’ filter primitive) to convert the linear RGB color values to linear luminance values.
    If the computed value of ‘color-interpolation’ on the ‘mask’ element is sRGB then the luminance value is calculated by taking the non-premultiplied RGB color values, applying the luminance-to-alpha coefficients (as defined in the ‘feColorMatrix’ filter primitive) to convert the RGB color values to luminance values.
Flags: in-testsuite+
Keywords: dev-doc-needed
Whiteboard: comment 15 describes change
https://hg.mozilla.org/mozilla-central/rev/f8e26a743569

I accidentally pushed this patch to mozilla-central while it was living on inbound.  On the next merge, it will be merged.  Sorry for the mess!
Status: ASSIGNED → RESOLVED
Closed: 9 years ago8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla10
Added a note about this change to:

https://developer.mozilla.org/en/CSS/mask

And mentioned on Firefox 10 for developers.
Whiteboard: comment 15 describes change
You need to log in before you can comment on or make changes to this bug.