GNOME Bugzilla – Bug 687650
Generated gradients have banding
Last modified: 2015-04-21 17:02:27 UTC
8 bits per component (24bit/pixel) is not sufficient to avoid banding in gradients, in particular not for subtle gradients. Some form of dithering strategy needs to be employed to avoid such artifacts. The simplest way of provoking such banding is to pick two of the darker neighbouring gray values in the color picker as gradient end points; the resulting wallpaper will be bands with abrupt transition rather than a smooth transition from one color to another.
Created attachment 228119 [details] [review] patch implementing random dither for gradient renderer
Very much in favor of this. Wallpapers usually expose color banding a lot due to the fact the two color stop aren't very far in terms of contrast and are very far in terms of distance.
Created attachment 228197 [details] [review] patch implementing random dither for gradient renderer New patch, that avoids excessive per pixel function call overhead for the dither noise.
Created attachment 228199 [details] [review] patch implementing random dither for gradient renderer accidentally removed a newly introduced define when cherry-picking the commit to master - also slight fixup of coding style.
*** Bug 553185 has been marked as a duplicate of this bug. ***
Created attachment 228318 [details] Screenshot of portion of horizontal gradient with/without patch applied (banding gets more apparent when the bands cover full height of screen)
Jimmac: in bug #676539 you ended up asking for the gradient selection ui code to be removed, with this patch landed; we could have some gradient presets as well. (personally I find a vertical grayscale going from dark grak in the top to black in the bottom to be a nice non-intrusive background once banding is gone).
I definitely don't want any new UI for defining custom gradients. What I want is some presets in the color section of the UI we should ship by default.
Review of attachment 228199 [details] [review]: Patch doesn't apply cleanly anymore, though here's a review: - add "gnome-bg: " to the commit subject - More inline functions use - More comments around the now non-obvious added code ::: libgnome-desktop/gnome-bg.c @@ +2538,3 @@ int n_channels = 3; + /* to avoid the overhead of three function calls per pixel dithered, Could you use inline functions to make this fast but more readable? @@ +2567,3 @@ guchar *d; d = dst + rowstride * i; + for (j = 0; j < width; j ++) { Can you split this up into a separate (even inline) function?
Seeing as the patch provider won't ever update the patch because: "the bug was never looked at by maintainers when the code was fresh; and I have created new and better methods since - you can have the bug as it is :]"
notes for people searching bugzilla for gradients and banding: A better method for doing dithering of higher bitdepths to 8bits per component, that is currently the most likely method to be used when going from high bit depths to lower bitdepths exist at http://pippin.gimp.org/a_dither/ the examples on that page are all dithering from 24bit RGB to 8bit RGB for the GIFs, I've added another example at http://pippin.gimp.org/a_dither/gradients.html which contains dithering from floating point to 24bit RGB (8bits per component). The code on that page is live editable, if levels=255 is changed to levels=127; the results are not obviously worse - and there is sufficient entropy added that it would survive quantization causing global color management. This is something that probably is desired for more than the background if one is using subtle gradients in a UI. The method can also be used on 8bpc RGB data rendered by cairo to reduce the additional banding caused if using 15bpp or 16bpp video modes.
So why aren't you implementing this around? :-)
If we could clone me or bug #171940 was resolved, this would be implemented in GIMP, GNOME and other software already. I neither run an up-to date GNOME desktop nor have a development environment configured for it, if someone else is implementing dithering code in GIMP, GTK+ or gnome-bg; there is running .js prototype code to look at on the referenced pages.