Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 103691

Summary: Misidentification of transparent pixels
Product: [Eclipse Project] Platform Reporter: David Walser <luigiwalser>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: CLOSED DUPLICATE QA Contact:
Severity: major    
Priority: P3 CC: andrej, ericwill, xixiyan
Version: 4.7Keywords: triaged
Target Milestone: ---   
Hardware: PC   
OS: Linux   
See Also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=345972
https://git.eclipse.org/r/139773
https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=e81fd8ac89325d0b32f0e23ada9c871649a5b724
Whiteboard:
Attachments:
Description Flags
SWT app to demonstrate the bug
none
GIF file referenced by the attached testcase
none
More correct SWT app to demonstrate the problem none

Description David Walser CLA 2005-07-13 13:54:34 EDT
I am going to attach a testcase for this and the smallfish.gif image file that 
the testcase opens. 
 
One thing it is supposed to do as it runs is change all transparent pixels to 
blue.  As it looks at each pixel in the ImageData (look at line 62) it 
compares it to the transparentPixel to see if it's the same. 
 
Running this example on a 24-bit display, it works fine.  On a 16-bit display, 
it doesn't.  Running through a debugger, I see that the problem is it 
misidentifies the actual transparent pixels in the image itself...it thinks 
the Green of the RGB is one less than it really is.
Comment 1 David Walser CLA 2005-07-13 13:55:39 EDT
Created attachment 24684 [details]
SWT app to demonstrate the bug
Comment 2 David Walser CLA 2005-07-13 13:56:17 EDT
Created attachment 24685 [details]
GIF file referenced by the attached testcase
Comment 3 David Walser CLA 2005-07-19 10:40:20 EDT
Created attachment 24977 [details]
More correct SWT app to demonstrate the problem
Comment 4 David Walser CLA 2006-02-04 17:17:27 EST
ImageData has gotten very buggy since I last was messing with this.  Now what I am seeing is the data.transparentPixel which is supposed to be 5395199 (#5252FF) is being set to -1 and the pixels which should be transparent in the image are being read as #E7E7E7, so this is a lot more odd.

The problems are worse on Windows and go beyond just the transparent pixels, hopefully I can give more details soon.
Comment 5 David Walser CLA 2006-02-06 07:07:42 EST
On a 24-bit display the pixels that are supposed to be transparent are being read as #808080, the #E7E7E7 was on a 16-bit display.
Comment 6 David Walser CLA 2006-02-06 11:21:43 EST
Just a note that what it shows the transparent pixels as is not consistent from one run to the next.  I have seen #808080 as I said before, as well as 0 and #E6E7E6
Comment 7 David Walser CLA 2006-02-06 13:12:00 EST
I tried this with another image and it is also setting data.transparentPixel to -1 and seeing the transparent pixels as #FFFFFF on Linux.  On Windows with this other image it works fine.
Comment 8 David Walser CLA 2006-02-22 16:12:51 EST
This bug is still valid with 3.2M5
Comment 9 David Walser CLA 2006-03-18 23:14:11 EST
I just looked at the code, and what broke it is the added try/catch block in the Image(Device, String) constructor.  I remember seeing in the New and Noteworthy that SWT was going to use OS image loading routines instead of Java code when it could, so I guess that's what this added code is about.  What I see in this code is that it doesn't even bother to try to set the transparentPixel field (as well as a few others), so it's obvious what caused the bug.  Please fix it.
Comment 10 Silenio Quarti CLA 2006-04-07 16:42:34 EDT
Hi David,

The transparentPixel problem caused by the GDI+ image loading has been fixed. Please try the next I-build. Note that I run your testcase from comment#3 on Windows and it causes an excpetion because you are trying to lookup colors that are not in the palette.

Now, your original problem. When an image is allocated there is no guarantee that color information (depth/palette) is going to be the same as the one in the loaded file format. The color info changes depending on the platform to a more suitable format for the current display format.

So if you are doing something like

  Image image = new Image(..., "file.gif");
  ImageData data = image.getImageData();

you have to handle an image data in any color format (index and direct palettes), but if do something like:

  ImageData data = new ImageData("file.gif");

the format is always the format stored in the file (i.e GIF are always indexed palette based).

Comment 11 David Walser CLA 2006-04-08 15:28:02 EDT
I'm not sure exactly what you're trying to tell me.

This bug is about SWT/gtk+, I've been tracking my problems on Windows in Bug 104365.  I just updated SWT from CVS and don't see anything changed from last time I checked.  Note that the workaround I described in comment #5 on Bug 101799 mostly works except for the problem described there.

Hopefully I can test newer SWT code on Windows soon and update you as to what I'm seeing there.  If the misidentification of transparent pixels bug has been fixed there, the bug I described in the original report for 104365 may show up again (the one where it crashes trying to getPixel) and that may even be what you referred to.  If you are seeing that, it is a bug (it's 104365) and still needs to be fixed.
Comment 12 David Walser CLA 2006-04-10 13:42:44 EDT
Yes I tested this morning (20060410)'s nightly build on Windows and it is crashing again, so the misidentification of transparent pixels bug is fixed, but the original Bug 104365 is still valid.  I have reported as such there.
Comment 13 Silenio Quarti CLA 2006-04-10 14:50:40 EDT
Sorry, I got consufed with both bugs.

Note the that image loaded in SWT/gtk+ with the latest code is not wrong. The transparent pixel is -1, but an alpha channel was generated for the image with alpha equals 0 for the transparentPixel and 255 for other pixels.
Comment 14 David Walser CLA 2006-04-10 14:55:57 EDT
With the alpha data that is generated, my workaround works, but what this suggests to me is that the transparentPixel field doesn't work anymore.
Comment 15 David Walser CLA 2006-04-18 11:34:45 EDT
Still valid with 3.2RC1 (and so is the Bug 101799 like problem).
Comment 16 Eric Williams CLA 2016-08-05 10:00:28 EDT
Not sure how relevant this bug is, but I can reproduce this using the snippet attached.
Comment 17 Xi Yan CLA 2019-03-29 15:26:16 EDT

*** This bug has been marked as a duplicate of bug 345972 ***
Comment 19 Xi Yan CLA 2019-04-09 10:09:09 EDT
There has been some recent change to the way transparency are handled. There are 3 ways to specifying transparency (see ImageData#gettransparencyType)

1) SWT.TRANSPARENCY_MASK
2) SWT.TRANSPARENCY_PIXEL
3) SWT.TRANSPARENCY_ALPHA

and we should not reply on transparencyPixel as the only means to check for transparency in the image. Please use the ImageData#getTransparencyMask API to check for where the image is transparent. 

i.e. adjust the snippet to: 

private static void colorize(ImageData data, byte orig[], float midratio) {
		ImageData transparentMask = data.getTransparencyMask();
		data.alphaData = null;
		for (int y = 0; y < data.height; y++)
			for (int x = 0; x < data.width; x++) {
				if (transparentMask.getPixel(x, y) == 0) {
					data.setPixel(x, y, data.palette.getPixel(new RGB(0, 0, 255)));
					continue;
				}