JDK-4688381 : IndexColorModel fails to find Transparent Black in getDataElements
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.2.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2002-05-21
  • Updated: 2002-10-16
  • Resolved: 2002-10-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Description
If an IndexColorModel is created with some transparent black entries (i.e. 0x0)
but no transparent pixel is specified, then the getDataElements does not
return that pixel value when given a transparent black rgb value.

-- Begin TransparentLookupTest.java --

import java.awt.image.IndexColorModel;
import java.awt.image.DataBuffer;

public class TransparentLookupTest {
    public static void main(String argv[]) {
	// Create a 6x6x6 color cube
	int[] cmap = new int[256];
	int i=0;
	for (int r=0; r < 256; r += 51) {
	    for (int g=0; g < 256; g += 51) {
		for (int b=0; b < 256; b += 51) {
		    cmap[i++] = (r<<16)|(g<<8)|b;
		}
	    }
	}

	testFindTP(new IndexColorModel(8, 256, cmap, 0, true, -1,
				       DataBuffer.TYPE_BYTE));
    }

    public static void testFindTP(IndexColorModel icm) {
	byte pix[] = (byte[]) icm.getDataElements(0, null);
	int rgb = icm.getRGB(pix[0] & 0xff);
	if (rgb != 0) {
	    throw new RuntimeException("Transparent black (0x00) resolves to ("+
				       Integer.toHexString(rgb)+")");
	}
    }
}

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b04
2004-06-14

EVALUATION It looks like the code to "find" a transparent entry in the getDataElements method is using the test "colormap[i] < 1<<24" which is sort of clever in that it is relying on the fact that the alpha field is the most significant field in the colormap representation. Unfortunately, opaque colors all have the sign bit set so they are negative numbers and they trigger the test prematurely. The fix is to extract and test the alpha field explicitly. In diagnosing this, I discovered a couple of things. First, if this loop finds an entry, it sets it as the transparent pixel if there is none already. This means that the return value of getTransparentPixel() can change after the ColorModel is constructed which is probably bad. The constructors should probably search for a TP as they are copying the data into the internal structures and then that value should never change. Second, the loop was looking for a pixel with alpha == 0 and returning a random pixel if none was found. If there is no TP, then the pixel with the smallest alpha should be returned. ###@###.### 2002-05-20
2002-05-20