JDK-6353518 : Creation of a WritableRaster with a custom DataBuffer causes erroneous Exception
  • Type: Bug
  • Status: Resolved
  • Resolution: Fixed
  • Component: client-libs
  • Sub-Component: 2d
  • Priority: P4
  • Affected Version: 5.0,9
  • OS: windows_xp
  • CPU: x86
  • Submit Date: 2005-11-21
  • Updated Date: 2016-04-28
  • Resolved Date: 2016-03-31
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 Availabitlity Release.

To download the current JDK release, click here.
JDK 9
9 b116Resolved
Description
FULL PRODUCT VERSION :
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Client VM (build 1.5.0_03-b07, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
An attempt to create a WritableRaster via Raster.createWritableRaster(SampleModel sm, DataBuffer db, Point location) using a custom DataBuffer causes an erroneous RasterFormatException.
Apparently the reason for this bug is that IntegerComponentRaster insists on beeing passed an instance of DataBufferInt rather than just a DataBuffer with a DataType of TYPE_INT.
This is quite annoying since DataBufferInt is declared final and thus cannot be extended.

Also note that none of the specified reasons for a RasterFormatException apply: width and height are within bounds and my DataBuffer has only one bank.



ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.awt.image.RasterFormatException: IntegerComponentRasters must haveinteger DataBuffers

	at sun.awt.image.IntegerComponentRaster.<init>(IntegerComponentRaster.java:155)

	at sun.awt.image.IntegerInterleavedRaster.<init>(IntegerInterleavedRaster.java:111)

	at sun.awt.image.IntegerInterleavedRaster.<init>(IntegerInterleavedRaster.java:78)

	at java.awt.image.Raster.createWritableRaster(Raster.java:994)

	at RasterBug.<init>(RasterBug.java:17)

	at RasterBug.main(RasterBug.java:69)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.image.*;
import java.awt.*;

public class RasterBug
{
	public RasterBug()
	{
		int w = 100, h = 100;
		ColorModel cm = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
		SampleModel sm = cm.createCompatibleSampleModel(w,h);
		System.out.println(sm+", WIDTH="+sm.getWidth()+", HEIGHT="+sm.getHeight());
		DataBuffer db = new MyDataBufferInt(w * h);
		System.out.println(db+", BANKS="+db.getNumBanks());

		try {
			WritableRaster wr = Raster.createWritableRaster(sm, db, new Point(0,0));
			BufferedImage bim = new BufferedImage(cm, wr, true, null);
			System.out.println(bim);
		} catch(Exception ex) {
			ex.printStackTrace();
		}

		try {
			//workaround
			WritableRaster wr = new MyWritableRaster(sm, db, new Point(0,0));
			BufferedImage bim = new BufferedImage(cm, wr, true, null);
			System.out.println(bim);
		} catch(Exception ex) {
			ex.printStackTrace();
		}
	}

	// copied from DataBufferInt
	private final class MyDataBufferInt extends DataBuffer
	{
		int data[];
		int bankdata[][];
		public MyDataBufferInt(int size)
		{
			super(TYPE_INT,size);
			data = new int[size];
			bankdata = new int[1][];
			bankdata[0] = data;
		}
		public int getElem(int i) {
			return data[i+offset];
		}
		public int getElem(int bank, int i) {
			return bankdata[bank][i+offsets[bank]];
		}
		public void setElem(int i, int val) {
			data[i+offset] = val;
		}
		public void setElem(int bank, int i, int val) {
			bankdata[bank][i+offsets[bank]] = (int)val;
		}
	}

	private final class MyWritableRaster extends WritableRaster
	{
		public MyWritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin)
		{
			super(sampleModel, dataBuffer, origin);
		}
	}

	public static void main(String[] args)
	{
		RasterBug bimbug = new RasterBug();
	}

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Using WritableRaster does work, requires extending the WritableRaster class though because the constuctor methods are protected.

Comments
Please re-open if - if fix is in progress or on the plan to fix soon - if this is a P3 (file as P3, not P4)
2014-03-18