Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 104365 - failing to allocate colors on 16 or 32 bit display
Summary: failing to allocate colors on 16 or 32 bit display
Status: RESOLVED INVALID
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-19 12:00 EDT by David Walser CLA
Modified: 2006-04-11 10:04 EDT (History)
1 user (show)

See Also:


Attachments
Changed example (4.43 KB, text/plain)
2006-04-10 18:42 EDT, Silenio Quarti CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description David Walser CLA 2005-07-19 12:00:11 EDT
Ok, running a program I attached to another bug:   
https://bugs.eclipse.org/bugs/attachment.cgi?id=24977   
(from Bug 103691) 
 
on Windows there's two problems.  One line 61 or so, there's this: 
data.setPixel(x, y, data.palette.getPixel(new RGB(0, 0, 255))); 
 
on Windows, the getPixel call is crashing, and when it does it's on line 155 
of PaletteData.java, which is in the else block if the if (isDirect) 
statement.  It should not be in the else block there, for anything above 
15-bit, SWT is supposed to use a direct palette. 
 
No matter, I tried a workaround: 
color = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE); 
data.setPixel(x, y, data.palette.getPixel(color.getRGB())); 
 
So that way it'll use whatever SWT has allocated for COLOR_BLUE in its indexed 
palette, even if it doesn't happen to be 0,0,255.  Yet, it crashes just the 
same.
Comment 1 David Walser CLA 2006-02-06 07:13:39 EST
Ok, this bug seems to be fixed, but still following onto Bug 103691 I am now seeing that bug on Windows as well.  I am seeing data.transparentPixel being set to 1 and the actual transparent pixels being read as 0.  This is not the only problem I'm seeing with this on Windows though, more on this later...
Comment 2 David Walser CLA 2006-02-06 13:03:20 EST
On Windows this appears to work OK with images other than the smallfish.gif that is linked in the Bug 103691.  With smallfish.gif, other than the transparent pixels not being identified properly, running the example code there, the black pixels are also being turned transparent or white.
Comment 3 David Walser CLA 2006-02-22 16:26:21 EST
The misidentification of transparent pixels is still happening with 3.2M5
Comment 4 David Walser CLA 2006-03-20 11:05:22 EST
Ok, going back to what I said in Comment #1 referring to what I see with smallfish.gif:

The transparent pixels are coming up with a pixel value of 0, which they shouldn't be because that's not what they are in the image.  data.palette.getRGB(pixel) for a pixel value of 0 gives [0,0,0], as it should, but for some reason those pixels are displaying as white, not black which is what their color is according to what I see while debugging.

For the black pixels turning white (which I mentioned in Comment #2), I figured out what's happening there.  The pixels come out with a pixel value of 255 (which is strange), but data.palette.getRGB(pixel) for a pixel value of 255 also gives [0,0,0], which is black, which is what they are.  But then, my code goes and does data.palette.getPixel(new RGB(0,0,0])) which gives a pixel value of 0 (which makes sense) rather than 255 (which would match, but doesn't make sense anyway).  Then, as I said in the last paragraph, pixel values of 0 are being displayed white instead of black.
Comment 5 David Walser CLA 2006-04-10 13:42:47 EDT
It looks like the misidentification of transparent pixels has been fixed, but it had been masking the original bug here (as I suspected it might).  The original bug is still valid.  It is crashing when trying to do the getPixel() call.  I tested this morning (20060410)'s nightly build.
Comment 6 Silenio Quarti CLA 2006-04-10 14:07:09 EDT
I think you are assuming that the depth of the image is going to be the same as the depth of the display on all platofrms. This is not true on Windows. If you look at the ImageData depth field (just before you call colorize()), you will see that it' value is 8 and the palette is an indexed palette (even though the display depth is 16 or 32). The depth of an image may be different from the depth of the display.

The color blue (0, 0, 255) is not the indexed palette, that is why you get the exception. This is the correct behavior.
Comment 7 David Walser CLA 2006-04-10 15:01:45 EDT
This is not correct behavior.  I could see the pixel not being in the palette being a problem if I just tried to setPixel(new RGB(0,0,255)), but I am using getPixel() so that I can get a pixel that is actually in the palette.  If exact blue isn't in the palette, it should give me the closest one.

Furthermore, with an Image being allocated and the ImageData being taken from that, in all of my tests the resulting data comes out 24-bit (it would be 8-bit if I had just opened an ImageData from the image file directly).

All I'm trying to do is turn the transparent pixels in the image to blue, it can't be correct behavior for this to be impossible.
Comment 8 Silenio Quarti CLA 2006-04-10 18:42:01 EDT
Created attachment 38233 [details]
Changed example

>This is not correct behavior.  I could see the pixel not being in the palette
>being a problem if I just tried to setPixel(new RGB(0,0,255)), but I am using
>getPixel() so that I can get a pixel that is actually in the palette.  Ifexact
>blue isn't in the palette, it should give me the closest one.

I aggree with you that a closest match could be an answer, but that is not what the PaletteData.getPixel() implementation does since day one. We cannot really change this behavior now, but new API could be added to return the closest match.

>Furthermore, with an Image being allocated and the ImageData being taken from
>that, in all of my tests the resulting data comes out 24-bit (it would be 8bit
>if I had just opened an ImageData from the image file directly).

Have you tried this on Windows with the latest 3.2 stream (or 3.1)? Note that for while there was bug in the 3.2 stream that made all images created with new Image(Device, String) be 32 bit depth. This bug has been fixed.

>All I'm trying to do is turn the transparent pixels in the image to blue, it
>can't be correct behavior for this to be impossible.

Is the attached sample what we are looking for?
Comment 9 David Walser CLA 2006-04-11 10:04:51 EDT
Ok, apparently it was just on Linux that allocating an Image made it 24-bit, you're right that on Windows it makes it 8-bit, which causes the problem.  I see your solution is to just make a new 24-bit ImageData and write into that.  That works.  Sorry for my tone earlier and thanks for your help.  This is probably a better solution than getting a closest match.  I'll mark this bug as invalid, but maybe you can considering adding a closest match API, some users might find it helpful.  Thanks again.