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 330692 - odd-width semi-transparent icon files are slightly scrambled during load and save
odd-width semi-transparent icon files are slightly scrambled during load and ...
Status: RESOLVED FIXED
Product: GIMP
Classification: Other
Component: Plugins
2.2.x
Other All
: Normal normal
: 2.2
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2006-02-10 17:04 UTC by Felix Pahl
Modified: 2008-01-15 13:05 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
an example file with odd-width and mixed transparency (10.75 KB, image/png)
2006-02-10 17:12 UTC, Felix Pahl
  Details
patch for plug-ins\winicon\icoload.c (1007 bytes, patch)
2006-02-10 17:17 UTC, Felix Pahl
none Details | Review
patch for plug-ins\winicon\icosave.c (863 bytes, patch)
2006-02-10 17:18 UTC, Felix Pahl
none Details | Review
combined patch against HEAD branch in unified diff format (1.89 KB, patch)
2006-02-14 10:20 UTC, Sven Neumann
none Details | Review

Description Felix Pahl 2006-02-10 17:04:29 UTC
Please describe the problem:
The winicon plugin has 

Steps to reproduce:
1. Open an image with odd width (in my case 119) which contains transparent and
opaque pixels together on the same lines.
2. Save it as a .ico file (any bpp).
3. View the result in another image viewer (e.g. Windows image preview)

Actual results:
The transparency is slightly locally scrambled.

Expected results:
The transparency should be as in the original image.

Does this happen every time?
yes.

Other information:
Note that you won't notice a problem when you view the scrambled file in GIMP;
the bug is the same in the load and save operations and cancels out.

The problem is due to incorrect calculations in the functions that get and set
bits and nibbles in the winicon plugin. Here are context diffs for the source
files icoload.c and icosave.c that should fix the problem. (I didn't build the
entire program so I'm not 100% sure.)

=============================================
*** icoload.c	Fri Nov 26 18:37:26 2004
--- icoload_fixed.c	Fri Feb 10 17:53:00 2006
***************
*** 279,285 ****
    line = bit / line_width;
    offset = bit % line_width;
  
!   result = (data[line * width32 * 4 + offset/8] & (1 << (7 - (bit % 8))));
  
    return (result ? 1 : 0);
  }
--- 279,285 ----
    line = bit / line_width;
    offset = bit % line_width;
  
!   result = (data[line * width32 * 4 + offset/8] & (1 << (7 - (offset % 8))));
  
    return (result ? 1 : 0);
  }
***************
*** 300,308 ****
    line = nibble / line_width;
    offset = nibble % line_width;
  
!   result = (data[line * width32 * 4 + offset/2] & (0x0F << (4 * (1 - nibble %
2))));
  
!   if (nibble % 2 == 0)
      result = result >> 4;
  
    return result;
--- 300,308 ----
    line = nibble / line_width;
    offset = nibble % line_width;
  
!   result = (data[line * width32 * 4 + offset/2] & (0x0F << (4 * (1 - offset %
2))));
  
!   if (offset % 2 == 0)
      result = result >> 4;
  
    return result;
=============================================
*** icosave.c	Sat Apr  9 21:46:24 2005
--- icosave_fixed.c	Fri Feb 10 17:55:19 2006
***************
*** 295,301 ****
    offset = bit_num % line_width;
    bit_val = bit_val & 0x00000001;
  
!   data[line * width32 * 4 + offset/8] |= (bit_val << (7 - (bit_num % 8)));
  }
  
  
--- 295,301 ----
    offset = bit_num % line_width;
    bit_val = bit_val & 0x00000001;
  
!   data[line * width32 * 4 + offset/8] |= (bit_val << (7 - (offset % 8)));
  }
  
  
***************
*** 316,322 ****
    offset = nibble_num % line_width;
    nibble_val = nibble_val & 0x0000000F;
  
!   data[line * width8 * 4 + offset/2] |= (nibble_val << (4 * (1 - (nibble_num %
2))));
  }
  
  
--- 316,322 ----
    offset = nibble_num % line_width;
    nibble_val = nibble_val & 0x0000000F;
  
!   data[line * width8 * 4 + offset/2] |= (nibble_val << (4 * (1 - (offset % 2))));
  }
  
  
=============================================

As far as I can tell, this has nothing to do with Bug 172503. I verified that
when I make the above modifications, icoload.c generates the correct ARGB color
values, but even without the fix they are only locally scrambled, due to the
wrong bit shifts, and this cannot account for the more serious problems
described in Bug 172503.
Comment 1 Felix Pahl 2006-02-10 17:08:16 UTC
Sorry, I forgot to fill in the description properly.

I'm attaching three files: a file sonne.png that you can use as an example, and the two patches I prematurely included in the text. The bug report form should make it clear that it will be possible to attach files later in the process.
Comment 2 Felix Pahl 2006-02-10 17:12:01 UTC
Created attachment 59084 [details]
an example file with odd-width and mixed transparency

Save this as a .ico file from GIMP to reproduce the problem
Comment 3 Felix Pahl 2006-02-10 17:17:33 UTC
Created attachment 59085 [details] [review]
patch for plug-ins\winicon\icoload.c

incorrect bit shifts were being applied
Comment 4 Felix Pahl 2006-02-10 17:18:41 UTC
Created attachment 59087 [details] [review]
patch for plug-ins\winicon\icosave.c

incorrect bit shifts were being applied
Comment 5 Sven Neumann 2006-02-13 22:09:57 UTC
Setting milestone to 2.2 so that we do not forget to review this patch.
Comment 6 Sven Neumann 2006-02-14 10:20:43 UTC
Created attachment 59320 [details] [review]
combined patch against HEAD branch in unified diff format
Comment 7 Sven Neumann 2006-02-14 10:26:38 UTC
Applied to both branches. Thank you very much for your patches.

2006-02-14  Sven Neumann  <sven@gimp.org>

	* plug-ins/winicon/icoload.c
	* plug-ins/winicon/icosave.c: applied patches from Felix Pahl.
	Fixes incorrect bit shifts that caused scrambled transparency
	(bug #330692).