Bug 375616

Summary: Installer artwork dithering looks bad
Product: [openSUSE] openSUSE 11.0 Reporter: Hans Petter Jansson <hpj>
Component: InstallationAssignee: Jakub Steiner <jimmac>
Status: RESOLVED FIXED QA Contact: Jiri Srain <jsrain>
Severity: Minor    
Priority: P5 - None CC: guitarist198
Version: Alpha 3   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: Development Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Bug Depends on:    
Bug Blocks: 368624    
Attachments: comparing the two methods of overcoming color banding
color-reduction.c

Description Hans Petter Jansson 2008-03-31 21:07:56 UTC
The dithering used in the background for the Alpha 3 installer looks bad because the resolution used is so low. The random dithering makes it look "dirty". I think ordered dithering might look better.

By the way, maybe we need an "Artwork" bug component?
Comment 1 Josh J 2008-03-31 23:10:30 UTC
Bug 368624 is currently being used as a tracking bug for YaST Theming issues.  So you can just add 346718 to the Blocks textbox under dependencies if you create any new bugs under this category.  I have done this for you on this one.
Comment 2 Jakub Steiner 2008-04-02 07:57:20 UTC
HP, the dithering is required to avoid severe color banding that would otherwise occur on the 16bit display. The dithering is a far lesser evil than the terrible color banding. See http://jimmac.musichall.cz/images/blog/bandingVSdithering.png
Comment 3 Jakub Steiner 2008-04-02 08:04:35 UTC
I failed to mention various methods to do the dithering were tested. The problem here is that I'm not aware of a tool to do ordered dithering to 16 bit color. The way the image is dithered is that the gradient elements of the background are filtered using noise>spread filter in GIMP. Out of all the techniques, that gives the best result.

I also tested forcing 16 bit colors, but that doesn't actually give better results. I tried `gm convert -treedepth 5 -colors 65535 -dither in.png out.png`.
Comment 4 Jakub Steiner 2008-04-02 08:43:38 UTC
Reopening as there still may be methods to achieve better quality. I am told  GdkRGB does dithering for 16bit displays, would it be possible to get a quick conversion utility using GdkRGB?
Comment 5 Jakub Steiner 2008-04-02 09:05:28 UTC
gtk+/gdk/gdkrgb.c (gdk_rgb_convert_565_d)
Comment 6 Hans Petter Jansson 2008-04-02 18:50:47 UTC
GIMP does floyd-steinberg dithering, which IMO looks good at low resolutions, if you convert the image to an indexed palette. That doesn't do 16-bit, though... I'll see if I can write you a little utility when I get the time.
Comment 7 Hans Petter Jansson 2008-04-02 19:04:00 UTC
I put up a little comparison of GIMP's output using different to-indexed dithering approaches at http://hpjansson.org/temp/dither-tests/ . I think floyd-steinberg is the clear winner, so if we can somehow get that in the 16-bit image, I'd be very happy.
Comment 8 Jakub Steiner 2008-04-02 21:55:42 UTC
There's a good number of ditherting algorithms to 8 bit, but aopart from that imagemagick method I haven;t found a way to dither to 16 bit. A utility that would do this would be greatly appreciated. The gdk method is actually used in GIMP for the view I was told, so having this turned into a filter working on the drawable would be the best tool for me. Thanks.
Comment 9 Hans Petter Jansson 2008-04-11 05:17:15 UTC
Ask and ye shall receive. I finally found some time to write a plugin for you:

http://hpjansson.org/temp/gimp-dither-plugin-0.0.1.tar.gz

Install gimp-devel, then configure and install this package to /usr. Restart the gimp and you will get a "Dither to 16-bit mode (565)" filter under Filters->Misc. It works on the selected area, or if no area is selected, the entire image.

If you want to play with the algorithm (for instance, dither to 1 bit per channel, which looks surprisingly good on photos), edit src/render.c.

If you need other options, I might add some UI to it in the future :)
Comment 10 Jakub Steiner 2008-04-12 20:09:43 UTC
This is fantastic HPJ. I really appreciate it.

It works perfectly on 2.2. Would you be able to help me with making it compile against GIMP 2.4? I am using packages from GNOME:Community (http://download.opensuse.org/repositories/GNOME:Community/openSUSE_10.3) and it fails linking (got gimp-devel):

gcc  -g -O2 -Wall   -o dither interface.o main.o render.o -lgimpui-2.0 -lgimpwidgets-2.0 -lgimpmodule-2.0 -lgimp-2.0 -lgimpmath-2.0 -lgimpconfig-2.0 -lgimpcolor-2.0 -lgimpbase-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0   
/usr/lib/gcc/i586-suse-linux/4.2.1/../../../../i586-suse-linux/bin/ld: cannot find -lgimpui-2.0

I'm sure it's a trivial change in the Makefile, but I couln't figure it out.
Comment 11 Jakub Steiner 2008-04-12 20:20:22 UTC
Nevermind, the binary works fine under 2.4 as well. Hopefully I'll have something nicer for the installer.
Comment 12 Jakub Steiner 2008-04-12 21:05:44 UTC
I have redone the graphics and instead of the old method, simply dithered the 24bpp using the plugin. The advantage of the spread filter is that it actually helps clearing out color banding even at 24bpp, where the color banding is visible, although not dramatically so.

Ideally the subtle gradients would need to be done at 48bit (16bit/channel) and then dithered to 16bit right from there.

Attaching for comparison, but I've committed to yast svn as well.
Comment 13 Jakub Steiner 2008-04-12 21:07:14 UTC
Created attachment 207626 [details]
comparing the two methods of overcoming color banding
Comment 14 Hans Petter Jansson 2008-04-13 01:13:57 UTC
I think the Floyd-Steinberg dithered image looks crisper somehow. The old version looks like it's been blurred, particularly in the details.

Do you know how I would go about dithering directly from 48-bit? GIMP's API only seems to support 8 bits per channel:

http://developer.gimp.org/api/2.0/libgimp/libgimp-gimpdrawable.html

The package I uploaded links against GIMP 2.4 that ships with openSUSE Factory - I think there might be something wrong with the 10.3 community package that prevents it from linking properly.
Comment 15 Jakub Steiner 2008-04-13 13:35:53 UTC
GIMP doesn't do higher than 8 bit per channel indeed. The new GEGL library, that's being phased in trunk currently, does though. It comes with a simple graph evaluator/convertor, so if you managed to write a gegl operation, it would be usable before GIMP is ready. 

GEGL lives in gnome svn and the documentation is here -- http://gegl.org/operations.html

Again, big thanks for being into all this.
Comment 16 Hans Petter Jansson 2008-04-14 23:25:02 UTC
I'd love to write a GEGL operation to make the dithering even better, but I'm not sure I'll have the time to do so before the openSUSE 11.0 release. Do you think the current approach is acceptable?
Comment 17 Jakub Steiner 2008-04-15 21:54:03 UTC
I've only seen the installer with the new dithered graphic on a 24bit display (testing using a template), not in an actual run. I would wait with closing this bug yet, but it does feel less noisy than my older method at least.
Comment 18 Hans Petter Jansson 2008-04-22 06:18:37 UTC
Created attachment 209489 [details]
color-reduction.c

A GEGL operation that can do color reduction to a specific number of bits per channel (channels and alpha are adjustable individually - for "hicolor", choose 565* for RGBA respectively). It supports a 48-bit colorspace for input and output, so you can dither 48-bit images down to 24-bit for example (tested and works).

For color compensation it implements thresholding, Bayer, Floyd-Steinberg, random and random dithering with co-variant channels.

To use, drop the source file into gegl/operations/common/, compile and re-install gegl, and run Gimp 2.5 with gegl enabled. The simplest way of doing this is using jhbuild (Jakub, I assume you know how to do this since you brought up using GEGL before).

From inside GIMP, open the image you wish to play with, go to the "Colors" pulldown menu and choose "GEGL Operation...". From the dialog's combo-box, choose the "color-reduction" plugin.

To see the available color compensation strategies, hover the mouse cursor over the entry besides the "Dither" label. Since GEGL doesn't seem to support enums, you have to enter the name of the strategy as a string (default is threshold).
Comment 19 Hans Petter Jansson 2008-04-22 06:51:45 UTC
Here's an example of the various dithering methods in action, using 1 bit per channel (8-color palette or early EGA graphics :).

http://hpjansson.org/temp/meadow-dithered.png

From left to right - original, threshold, Bayer, Floyd-Steinberg, covariant random and random.
Comment 20 Hans Petter Jansson 2008-04-24 08:09:36 UTC
The color-reduction operation was committed upstream, but in the "workshop" dir, so you have to pass --enable-workshop (I think it was) to configure in order to build it. The jhbuild setup does not do this by default.
Comment 21 Jakub Steiner 2008-04-28 10:54:04 UTC
Closing this as it's been addressed with the floyd-steinberg dithering.