GNOME Bugzilla – Bug 330692
odd-width semi-transparent icon files are slightly scrambled during load and save
Last modified: 2008-01-15 13:05:09 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.
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.
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
Created attachment 59085 [details] [review] patch for plug-ins\winicon\icoload.c incorrect bit shifts were being applied
Created attachment 59087 [details] [review] patch for plug-ins\winicon\icosave.c incorrect bit shifts were being applied
Setting milestone to 2.2 so that we do not forget to review this patch.
Created attachment 59320 [details] [review] combined patch against HEAD branch in unified diff format
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).