After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 755200 - ICO exporter: Windows displays glitchy black pixels in 32-bit alpha images exported by GIMP
ICO exporter: Windows displays glitchy black pixels in 32-bit alpha images ex...
Status: RESOLVED FIXED
Product: GIMP
Classification: Other
Component: Plugins
2.8.14
Other All
: Normal normal
: 2.8
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2015-09-18 04:25 UTC by Matt Giuca
Modified: 2015-09-19 00:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Sample image to export as .ico. (165 bytes, image/png)
2015-09-18 04:25 UTC, Matt Giuca
  Details
The file currently generated by GIMP from this image. (4.19 KB, image/x-icon)
2015-09-18 04:39 UTC, Matt Giuca
  Details
The file generated by GIMP after my patch. (4.19 KB, image/x-icon)
2015-09-18 04:39 UTC, Matt Giuca
  Details
Screenshot of Windows properties dialog on alphagradient-before.ico (21.02 KB, image/png)
2015-09-18 04:41 UTC, Matt Giuca
  Details
Screenshot of Windows properties dialog on alphagradient-after.ico (20.99 KB, image/png)
2015-09-18 04:42 UTC, Matt Giuca
  Details
Screenshot of Windows 10 taskbar (before and after) (2.74 KB, image/png)
2015-09-18 04:42 UTC, Matt Giuca
  Details
Patch to fix ICO exporter. (1.99 KB, patch)
2015-09-18 04:44 UTC, Matt Giuca
committed Details | Review

Description Matt Giuca 2015-09-18 04:25:52 UTC
Created attachment 311595 [details]
Sample image to export as .ico.

TL;DR: There is a bug in certain parts of Windows rendering ICOs with 32-bit images (with partial transparency). The ICOs exported by GIMP trigger this bug due to the way GIMP generates the AND mask. I think this is a bug in Windows, not GIMP, but there is an easy fix to the exporter that makes the problem go away. The code was rarely triggered on older versions of Windows, but on Windows 10, the bug affects taskbar icon rendering, making it much more severe.

Steps to reproduce:
1. Open the attached file alphagradient.png. (This is a 32x32 image with a gradient from transparent to opaque blue.)
2. Export as alphagradient.ico. Ensure that you choose to export as "32 bpp, 8-bit alpha, no palette".
3. In Windows, right-click alphagradient.ico -> Properties.

Expected: Gradient from transparent to 100% blue.
Actual: Gradient from transparent to 50% black, then from 50% blue to 100% blue.
(I will attach screenshots in follow-up comments.)
(I tested on Windows 7 and 10; this probably goes way back though.)

For bonus points, on Windows 10, set it as the icon to a shortcut and pin the shortcut to the taskbar. Note the bug manifests there also.

Explanation:

In the ICO file format, 32-bit images have both a 1-bit mask and an 8-bit alpha channel. Generally, Windows ignores the 1-bit mask and just gets its transparency information from the 8-bit alpha channel. But in *certain places* in Windows, it uses a different algorithm, equivalent to this:

    For each pixel with color (r, g, b, a) and mask bit m:
        If m (transparent mask):
            Composite with (0, 0, 0, a)
        Else (opaque mask):
            Composite with (r, g, b, a)

So basically:
- If your mask is transparent and alpha == 0, the pixel is fully transparent (good).
- If your mask is transparent and alpha > 0, the pixel is BLACK (bad).
- If your mask is opaque, the pixel is rendered correctly (good).

Now GIMP's ICO exporter sets the mask to 1 (transparent) whenever alpha <50% (which is good for when the exported image does not have an alpha channel). This means that any pixels with <50% alpha will become black when viewed in certain places in Windows. The correct behaviour is to set the mask to 0 (opaque) whenever alpha > 0. Only set the mask to 1 (transparent) when alpha == 0.

(Aside: I ran into this because I used GIMP to update the Chrome icon on Windows; see https://code.google.com/p/chromium/issues/detail?id=526622#c35)

I will follow up with screenshots of the bug and a patch to fix GIMP's exporter.
Comment 1 Matt Giuca 2015-09-18 04:39:27 UTC
Created attachment 311596 [details]
The file currently generated by GIMP from this image.
Comment 2 Matt Giuca 2015-09-18 04:39:45 UTC
Created attachment 311597 [details]
The file generated by GIMP after my patch.
Comment 3 Matt Giuca 2015-09-18 04:41:43 UTC
Created attachment 311598 [details]
Screenshot of Windows properties dialog on alphagradient-before.ico
Comment 4 Matt Giuca 2015-09-18 04:42:02 UTC
Created attachment 311599 [details]
Screenshot of Windows properties dialog on alphagradient-after.ico
Comment 5 Matt Giuca 2015-09-18 04:42:23 UTC
Created attachment 311600 [details]
Screenshot of Windows 10 taskbar (before and after)
Comment 6 Matt Giuca 2015-09-18 04:44:07 UTC
Created attachment 311601 [details] [review]
Patch to fix ICO exporter.

I've attached a number of screenshots showing how Windows renders the icon (before and after my patch).

Also attached the patch.
Comment 7 Michael Natterer 2015-09-18 17:02:43 UTC
Thanks, you win the prize for the best bug report, including patch, of the
month :) Pushed to master and gimp-2-8:

commit 32e8a4e116b6706b4199a948d19631342d27d9d8
Author: Matt Giuca <mgiuca@chromium.org>
Date:   Fri Sep 18 18:58:12 2015 +0200

    plug-ins: Fix generation of the AND mask for 32-bit ICO images
    
    Previously, the mask would be transparent if the alpha was <50%.
    However, this causes pixels to become black in some places in Windows
    (notably, the taskbar on Windows 10). Therefore, always set the mask
    to opaque if a pixel is partially or fully opaque.
    
    (cherry picked from commit 07dfe4a5ebcf59ccf70a0775e406990aa1776dcb)

 plug-ins/file-ico/ico-save.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
Comment 8 Matt Giuca 2015-09-19 00:39:20 UTC
Great! Thanks for the quick turnaround time, Michael.