ewx: (Default)
Richard Kettlewell ([personal profile] ewx) wrote2007-03-07 01:15 pm
Entry tags:

More Firefox color woe

I complained a while ago about Firefox's broken color management on Macs. It turns out it's even more broken than that, and not only on Macs.

My home page has a gray background, set to 808080 hex in CSS. Embedded in it are some PNG images, again with a background color of 808080. So they should blend seamlessly into one another, right (whatever properties the browser thinks the monitor has, supposing it has an opinion at all)?

Display that page in Firefox 2.0 on Linux and here's (zoomed in) what you get:

Picking over that capture in the Gimp reveals that:

  • The CSS-configured background is actually rendered as a solid 848284
  • The background gray in the image is actually rendered as a randomly dithered pattern composed of 847d84 and 7b827b - at this magnification it looks visibly pink and green to my eyes though it's just a (visibly) different shade of gray without magnification.

(I initially spotted this on a Mac last night but assumed it was the same problem as before, perhaps compounded by using different interfaces for drawing background and images, but if it happens on Linux then too then it must be something fundamental to Firefox's treatment of color, probably far away from where you'd put color management support if the program actually had any).

simont: A picture of me in 2016 (Default)

[personal profile] simont 2007-03-07 01:21 pm (UTC)(link)
How very odd. I'm looking at that page in Firefox 1 on Linux, and that's fine – it's all 808080 wherever I look. Perhaps FF2 has done something odd.
ext_22879: (Default)

[identity profile] nja.livejournal.com 2007-03-07 01:30 pm (UTC)(link)
Looks fine to me too (2.0.0.2, Windows XP). 808080 all over.
ext_8103: (Default)

[identity profile] ewx.livejournal.com 2007-03-07 01:42 pm (UTC)(link)
Out of curiosity, what bit depth are you running at? This here is a 16-bit display, and it occurs to me to wonder if that's connected. (The inconsistency between HTML and PNG colors is still nuts if so, but it'd be nice to tie down when it happens.)
simont: A picture of me in 2016 (Default)

[personal profile] simont 2007-03-07 01:50 pm (UTC)(link)
This display is 24-bit.

A 16-bit display, not 15? Well, no wonder it can't do pure greys sensibly then. That would certainly seem like a plausible cause to me. And it doesn't seem too surprising to me, either, that the CSS renderer and the PNG renderer disagree on the best way to approximate a pure grey with the available colours: the PNG renderer is already going to be prepared to dither where necessary, whereas the CSS renderer would have to go to some effort to include dithering code so it will just approximate to the nearest solid colour.
ext_8103: (Default)

that the CSS renderer and the PNG renderer disagree

[identity profile] ewx.livejournal.com 2007-03-07 02:04 pm (UTC)(link)
It's not like matching up images and backgrounds is some unusual thing that nobody ever does on the web!
simont: A picture of me in 2016 (Default)

Re: that the CSS renderer and the PNG renderer disagree

[personal profile] simont 2007-03-07 02:15 pm (UTC)(link)
Yes, but you're asking for a certain amount of heuristic intelligence in the PNG renderer. On the one hand, it does want to dither most of the time, because its fundamental aim is to display the (typically 24-bit) image it's given as faithfully as possible on the limited-depth screen it has. But on the other hand, you're asking it to recognise that in some situations dithering isn't the best thing it could be doing, and to refrain from it at that point. Presumably this will involve a layering violation to tell the PNG renderer not only what colour background it's got (which it needs anyway for alpha blending) but also what colour background it was supposed to be; and then the PNG renderer has to look round the edges of the image to find the latter colour, and render it consistently as the former where it appears. I know that wouldn't appeal to me if I were writing either the PNG renderer or the top-level CSS renderer that called it.

The other alternative is to have the dithering done universally, so that the PNG renderer outputs 24-bit data all the time and some top-level piece of code deals in a uniform way with converting it to the available colour depth. That doesn't strike me as a nice answer either, because even on a 16-bit display it doesn't seem obviously right to dither the entire window without better cause than that.

Having mentioned alpha blending ... it suddenly occurs to me, actually, to ask why you're trying to match up those backgrounds at all. PNG has an alpha channel, so why haven't you just set the parts of the image which want to be the same colour as the surrounding page to transparent? That might perfectly well actually work better.
ext_8103: (Default)

Re: that the CSS renderer and the PNG renderer disagree

[identity profile] ewx.livejournal.com 2007-03-07 02:39 pm (UTC)(link)
The last bit is easy to answer - at the time I draw the original versions of those images, IE didn't implement PNG's alpha channel correctly. It wouldn't be a bad time to check again I suppose.

Re: that the CSS renderer and the PNG renderer disagree

[identity profile] covertmusic.livejournal.com 2007-03-07 07:35 pm (UTC)(link)
IE5/6 don't by default, but you can subvert that with a little bit of browser-aware Javascript. I'll dig out the link if it's useful to you.

What it does is attach a proprietary filter, via CSS2 DOM events, to PNGs in IE only; this changes the particular renderer used for them to one which supports alpha channels. Grotesque, innit? :)
ext_8103: (Default)

Re: that the CSS renderer and the PNG renderer disagree

[identity profile] ewx.livejournal.com 2007-03-07 02:45 pm (UTC)(link)

The good cause for following the 'other alternative' is precisely the need to match up images and backgrounds. Like I say, this isn't some obscure edge case I'm trying to use here, it's something pretty widespread on the web.

Whether the globally used mechanism is dithering or just picking the nearest available color is another question, but it should certainly be the same mechanism for different sources of color.

Firefox seems to have no compunction about using visually bad (but computationally cheap) methods of scaling images, so it's not like cheap-and-cheerful color approximation would downgrade something that was otherwise a good graphical display tool.

(I can't remember why I ended up with a 16-bit display on this machine; I'll see what goes wrong with 24 bits, or whether it likes 15 bits, at some point. But having a workaround doesn't mean that the implementation is OK.)

simont: A picture of me in 2016 (Default)

[personal profile] simont 2007-03-07 02:49 pm (UTC)(link)
(Thinking about it more carefully, I doubt 15 bits would be a huge improvement. There would still be a visible gap between the poor approximation to solid-808080 attained by rounding it up to solid-848484, and the better approximation attained by dithering between 848484 and 7b7b7b. You wouldn't get the various exciting off-greys any more, but the visible dividing line would still be there.)

Re: that the CSS renderer and the PNG renderer disagree

[identity profile] aardvark179.livejournal.com 2007-03-07 03:01 pm (UTC)(link)
The CSS side of things seems to be doing something entirely sensible (for 16bit colour), but the reporting of it makes it sound odd. Once you've done a good colour conversion to 16 bits that grey falls into the interval whose upper bound is 848294.

The PNG renderer appears to be attempting to maintain the luminance for each pixel, and maintain the colour averaged over a set of pixels. That's a pretty smart thing to do given the lower spatial frequency of our colour perception, but obviously isn't going to match the CSS.

I think an alpha channel is the way to go here. IE will almost certainly ignore it a show the grey, while Firefox and co will use it to let the background show through properly.
sparrowsion: (cat5)

[personal profile] sparrowsion 2007-03-07 01:51 pm (UTC)(link)
It's looking OK to me too (Iceweasel 2.0.0.2) at a depth of 24.

[identity profile] naath.livejournal.com 2007-03-07 01:32 pm (UTC)(link)
The page looks fine in FF2 under XP. The picture in this post is giving me headaches (the pink and green dithering).

[identity profile] sbp.livejournal.com 2007-03-07 01:54 pm (UTC)(link)
Fine in Firefox/2.0.0.1 (Ubuntu-edgy) and Konqueror 3.5.5 in KDE 3.5.5
24 bit.

[identity profile] pjc50.livejournal.com 2007-03-07 03:17 pm (UTC)(link)
808080 is supposed to be a "web-safe" colour, isn't it? This looks like a bug to report to the FF maintainers. Not that I expect it to be fixed ...
ext_78: A picture of a plush animal. It looks a bit like a cross between a duck and a platypus. (Default)

[identity profile] pne.livejournal.com 2007-03-07 06:03 pm (UTC)(link)
As I remember it, the 216 web-safe colours involve components of 00, 33, 66, 99, cc, and ff.

In which case, no, 808080 is not supposed to be web-safe -- the closest greys would be 666666 and 999999.

[identity profile] uisgebeatha.livejournal.com 2007-03-07 03:27 pm (UTC)(link)
Looks fine in Firefox 2 on XP, on 1280 x 1024 uber-32-bit resolution admittedly.

That pink-green combo makes my eyes bleed.

[identity profile] nmg.livejournal.com 2007-03-07 03:27 pm (UTC)(link)
Looks okay to me using FF2.0.0.2 under XP and under MacOS 10.4 on a MacBook Pro.

[identity profile] new-brunette.livejournal.com 2007-03-07 04:47 pm (UTC)(link)
I see what you see - i.e. it fails for me, FF2.0.0.2, MacOS 10.4.8, MacBook, colours "millions"

[identity profile] imc.livejournal.com 2007-03-07 04:56 pm (UTC)(link)
I get solid #808080 using Firefox 1 or 2 on a 24-bit display.

Using Firefox 1.5.0.10 on a 16-bit display, xv tells me the background is a solid #808080 but the grey portion of the image is #788078 and #807c80. I believe xv is telling me the literal values displayed on screen while gimp is translating them to an #ffffff-based system, so that my values are the same as yours once that's taken into account.

So what it seems is happening is that the CSS-styled background colour is being simply truncated to fit into the screen's bit-depth while the image is being properly mapped to the correct colours and then dithered. (I wonder if dithering is strictly necessary on a 16-bit display. Can you turn it off?)