-
Bug
-
Resolution: Unresolved
-
P5
-
None
-
5.0
FULL PRODUCT VERSION :
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
I believe this bug happens across all OSes
A DESCRIPTION OF THE PROBLEM :
When drawing a RenderedImage, if the Raster returned from RenderedImage.getTile( int, int ) is not an instance of WritableRaster, a RasterFormatException is thrown for any Raster not located at (0,0).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a RenderedImage implementation that returns an instance of java.awt.image.Raster from getData( int, int ), then attempt to draw that RenderedImage via java.awt.Graphics2D.drawRenderedImage( java.awt.image.RenderedImage, java.awt.geom.AffineTransform ).
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
RenderedImage is drawn.
ACTUAL -
First tile of RenderedImage is drawn, then an exception is thrown.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.awt.image.RasterFormatException: (parentX + width) is outside raster
at java.awt.image.WritableRaster.createWritableChild(WritableRaster.java:210)
at sun.java2d.SunGraphics2D.drawTranslatedRenderedImage(SunGraphics2D.java:2556)
at sun.java2d.SunGraphics2D.drawRenderedImage(SunGraphics2D.java:2415)
at RIBug$TestWin.paint(RIBug.java:216)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
at sun.awt.RepaintArea.paint(RepaintArea.java:224)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:248)
at java.awt.Component.dispatchEventImpl(Component.java:4009)
at java.awt.Container.dispatchEventImpl(Container.java:2019)
at java.awt.Window.dispatchEventImpl(Window.java:1764)
at java.awt.Component.dispatchEvent(Component.java:3781)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class RIBug {
private RIBug() {}
public static void main( String[] args ) {
final int imageWidth = 100;
final int imageHeight = 100;
final int numTilesX = 2;
final int numTilesY = 2;
final int tileWidth = 50;
final int tileHeight = 50;
final java.awt.image.SampleModel sampleModel =
new java.awt.image.ComponentSampleModel(
java.awt.image.DataBuffer.TYPE_BYTE, imageWidth,
imageHeight, 1, imageWidth, new int[] { 0, 1, 2 },
new int[] { 0, 0, 0 } );
final java.awt.image.ColorModel colorModel =
new java.awt.image.ComponentColorModel(
java.awt.color.ColorSpace.getInstance(
java.awt.color.ColorSpace.CS_sRGB ),
false, false, java.awt.image.ColorModel.OPAQUE,
sampleModel.getTransferType() );
final java.awt.image.Raster[][] tiles =
new java.awt.image.Raster[ numTilesX ][ numTilesY ];
byte[][] color = new byte[][] { {(byte)0xFF, 0x00, 0x00},
{0x00, (byte)0xFF, 0x00},
{0x00, 0x00, (byte)0xFF},
{(byte)0xFF, (byte)0xFF, (byte)0xFF} };
int colorIndex = 0;
byte[][] data;
for( int ty = 0; ty < numTilesY; ty++ ) {
for( int tx = 0; tx < numTilesX; tx++ ) {
data=new byte[sampleModel.getNumBands()][tileWidth*tileHeight];
for( int band = 0; band < sampleModel.getNumBands(); band++ )
for( int i = 0; i < data[band].length; i ++ )
data[band][i] = color[colorIndex][band];
tiles[tx][ty] = java.awt.image.Raster.createRaster(
sampleModel.createCompatibleSampleModel(
tileWidth, tileHeight ),
new java.awt.image.DataBufferByte(data,
tileWidth*tileHeight ),
new java.awt.Point( tx * tileWidth,
ty * tileHeight ) );
colorIndex++;
}
}
java.awt.image.RenderedImage ri = new java.awt.image.RenderedImage() {
public java.awt.image.WritableRaster copyData(
java.awt.image.WritableRaster wr ) {
if( wr == null )
return (java.awt.image.WritableRaster)getData();
for( int ty = this.getMinTileY();
ty < (this.getMinTileY()+this.getNumYTiles());
ty++ ) {
if( (ty * this.getTileHeight()) >
(wr.getMinY()+wr.getHeight()) ||
(ty * this.getTileHeight() + this.getTileHeight()) <
wr.getMinY() )
continue;
for( int tx = this.getMinTileX();
tx < (this.getMinTileX()+this.getNumXTiles());
tx++ ) {
if( (tx * this.getTileWidth()) >
(wr.getMinX()+wr.getWidth()) ||
(tx * this.getTileWidth() + this.getTileWidth()) <
wr.getMinX() )
continue;
java.awt.Rectangle dataRegion =
tiles[tx][ty].getBounds().intersection(
wr.getBounds() );
wr.setDataElements(0,0,
tiles[tx][ty].createChild( dataRegion.x,
dataRegion.y,
dataRegion.width,
dataRegion.height,
dataRegion.x,
dataRegion.y,
null ) );
}
}
return wr;
}
public java.awt.image.Raster getData( java.awt.Rectangle r ) {
return copyData( java.awt.image.Raster.createWritableRaster(
sampleModel.createCompatibleSampleModel(
r.width,
r.height ),
r.getLocation() ) );
}
public java.awt.image.Raster getData() {
return getData( new java.awt.Rectangle( this.getMinX(),
this.getMinY(),
this.getWidth(),
this.getHeight() ) );
}
public java.awt.image.Raster getTile( int tx, int ty ) {
return tiles[tx][ty];
}
public int getTileGridYOffset() {
return 0;
}
public int getTileGridXOffset() {
return 0;
}
public int getTileHeight() {
return tileHeight;
}
public int getTileWidth() {
return tileWidth;
}
public int getMinTileY() {
return 0;
}
public int getMinTileX() {
return 0;
}
public int getNumYTiles() {
return numTilesY;
}
public int getNumXTiles() {
return numTilesX;
}
public int getMinX() {
return tiles[getMinTileX()][getMinTileY()].getMinX();
}
public int getMinY() {
return tiles[getMinTileX()][getMinTileY()].getMinY();
}
public int getHeight() {
return sampleModel.getHeight();
}
public int getWidth() {
return sampleModel.getWidth();
}
public java.awt.image.SampleModel getSampleModel() {
return sampleModel;
}
public java.awt.image.ColorModel getColorModel() {
return colorModel;
}
public String[] getPropertyNames() {
return null;
}
public Object getProperty( String propertyName ) {
return java.awt.Image.UndefinedProperty;
}
public java.util.Vector<java.awt.image.RenderedImage> getSources() {
return new java.util.Vector();
}
};
TestWin win = new TestWin( ri );
win.setDefaultCloseOperation( TestWin.DISPOSE_ON_CLOSE );
win.setVisible( true );
}
private static class TestWin extends javax.swing.JDialog {
private java.awt.image.RenderedImage image;
public TestWin( java.awt.image.RenderedImage i ) {
image = i;
setSize( image.getWidth(), image.getHeight() );
}
public void paint( java.awt.Graphics g ) {
super.paint( g );
((java.awt.Graphics2D)g).drawRenderedImage( image,
java.awt.geom.AffineTransform.getTranslateInstance(
image.getMinX(), image.getMinY() ) );
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
With access to the source for the implementation of RenderedImage, I can ensure that the returned Raster is an instance of WritableRaster, however, if I cannot modify the source, this exception is unavoidable and unrecoverable with no workaround.
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
I believe this bug happens across all OSes
A DESCRIPTION OF THE PROBLEM :
When drawing a RenderedImage, if the Raster returned from RenderedImage.getTile( int, int ) is not an instance of WritableRaster, a RasterFormatException is thrown for any Raster not located at (0,0).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a RenderedImage implementation that returns an instance of java.awt.image.Raster from getData( int, int ), then attempt to draw that RenderedImage via java.awt.Graphics2D.drawRenderedImage( java.awt.image.RenderedImage, java.awt.geom.AffineTransform ).
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
RenderedImage is drawn.
ACTUAL -
First tile of RenderedImage is drawn, then an exception is thrown.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.awt.image.RasterFormatException: (parentX + width) is outside raster
at java.awt.image.WritableRaster.createWritableChild(WritableRaster.java:210)
at sun.java2d.SunGraphics2D.drawTranslatedRenderedImage(SunGraphics2D.java:2556)
at sun.java2d.SunGraphics2D.drawRenderedImage(SunGraphics2D.java:2415)
at RIBug$TestWin.paint(RIBug.java:216)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
at sun.awt.RepaintArea.paint(RepaintArea.java:224)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:248)
at java.awt.Component.dispatchEventImpl(Component.java:4009)
at java.awt.Container.dispatchEventImpl(Container.java:2019)
at java.awt.Window.dispatchEventImpl(Window.java:1764)
at java.awt.Component.dispatchEvent(Component.java:3781)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class RIBug {
private RIBug() {}
public static void main( String[] args ) {
final int imageWidth = 100;
final int imageHeight = 100;
final int numTilesX = 2;
final int numTilesY = 2;
final int tileWidth = 50;
final int tileHeight = 50;
final java.awt.image.SampleModel sampleModel =
new java.awt.image.ComponentSampleModel(
java.awt.image.DataBuffer.TYPE_BYTE, imageWidth,
imageHeight, 1, imageWidth, new int[] { 0, 1, 2 },
new int[] { 0, 0, 0 } );
final java.awt.image.ColorModel colorModel =
new java.awt.image.ComponentColorModel(
java.awt.color.ColorSpace.getInstance(
java.awt.color.ColorSpace.CS_sRGB ),
false, false, java.awt.image.ColorModel.OPAQUE,
sampleModel.getTransferType() );
final java.awt.image.Raster[][] tiles =
new java.awt.image.Raster[ numTilesX ][ numTilesY ];
byte[][] color = new byte[][] { {(byte)0xFF, 0x00, 0x00},
{0x00, (byte)0xFF, 0x00},
{0x00, 0x00, (byte)0xFF},
{(byte)0xFF, (byte)0xFF, (byte)0xFF} };
int colorIndex = 0;
byte[][] data;
for( int ty = 0; ty < numTilesY; ty++ ) {
for( int tx = 0; tx < numTilesX; tx++ ) {
data=new byte[sampleModel.getNumBands()][tileWidth*tileHeight];
for( int band = 0; band < sampleModel.getNumBands(); band++ )
for( int i = 0; i < data[band].length; i ++ )
data[band][i] = color[colorIndex][band];
tiles[tx][ty] = java.awt.image.Raster.createRaster(
sampleModel.createCompatibleSampleModel(
tileWidth, tileHeight ),
new java.awt.image.DataBufferByte(data,
tileWidth*tileHeight ),
new java.awt.Point( tx * tileWidth,
ty * tileHeight ) );
colorIndex++;
}
}
java.awt.image.RenderedImage ri = new java.awt.image.RenderedImage() {
public java.awt.image.WritableRaster copyData(
java.awt.image.WritableRaster wr ) {
if( wr == null )
return (java.awt.image.WritableRaster)getData();
for( int ty = this.getMinTileY();
ty < (this.getMinTileY()+this.getNumYTiles());
ty++ ) {
if( (ty * this.getTileHeight()) >
(wr.getMinY()+wr.getHeight()) ||
(ty * this.getTileHeight() + this.getTileHeight()) <
wr.getMinY() )
continue;
for( int tx = this.getMinTileX();
tx < (this.getMinTileX()+this.getNumXTiles());
tx++ ) {
if( (tx * this.getTileWidth()) >
(wr.getMinX()+wr.getWidth()) ||
(tx * this.getTileWidth() + this.getTileWidth()) <
wr.getMinX() )
continue;
java.awt.Rectangle dataRegion =
tiles[tx][ty].getBounds().intersection(
wr.getBounds() );
wr.setDataElements(0,0,
tiles[tx][ty].createChild( dataRegion.x,
dataRegion.y,
dataRegion.width,
dataRegion.height,
dataRegion.x,
dataRegion.y,
null ) );
}
}
return wr;
}
public java.awt.image.Raster getData( java.awt.Rectangle r ) {
return copyData( java.awt.image.Raster.createWritableRaster(
sampleModel.createCompatibleSampleModel(
r.width,
r.height ),
r.getLocation() ) );
}
public java.awt.image.Raster getData() {
return getData( new java.awt.Rectangle( this.getMinX(),
this.getMinY(),
this.getWidth(),
this.getHeight() ) );
}
public java.awt.image.Raster getTile( int tx, int ty ) {
return tiles[tx][ty];
}
public int getTileGridYOffset() {
return 0;
}
public int getTileGridXOffset() {
return 0;
}
public int getTileHeight() {
return tileHeight;
}
public int getTileWidth() {
return tileWidth;
}
public int getMinTileY() {
return 0;
}
public int getMinTileX() {
return 0;
}
public int getNumYTiles() {
return numTilesY;
}
public int getNumXTiles() {
return numTilesX;
}
public int getMinX() {
return tiles[getMinTileX()][getMinTileY()].getMinX();
}
public int getMinY() {
return tiles[getMinTileX()][getMinTileY()].getMinY();
}
public int getHeight() {
return sampleModel.getHeight();
}
public int getWidth() {
return sampleModel.getWidth();
}
public java.awt.image.SampleModel getSampleModel() {
return sampleModel;
}
public java.awt.image.ColorModel getColorModel() {
return colorModel;
}
public String[] getPropertyNames() {
return null;
}
public Object getProperty( String propertyName ) {
return java.awt.Image.UndefinedProperty;
}
public java.util.Vector<java.awt.image.RenderedImage> getSources() {
return new java.util.Vector();
}
};
TestWin win = new TestWin( ri );
win.setDefaultCloseOperation( TestWin.DISPOSE_ON_CLOSE );
win.setVisible( true );
}
private static class TestWin extends javax.swing.JDialog {
private java.awt.image.RenderedImage image;
public TestWin( java.awt.image.RenderedImage i ) {
image = i;
setSize( image.getWidth(), image.getHeight() );
}
public void paint( java.awt.Graphics g ) {
super.paint( g );
((java.awt.Graphics2D)g).drawRenderedImage( image,
java.awt.geom.AffineTransform.getTranslateInstance(
image.getMinX(), image.getMinY() ) );
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
With access to the source for the implementation of RenderedImage, I can ensure that the returned Raster is an instance of WritableRaster, however, if I cannot modify the source, this exception is unavoidable and unrecoverable with no workaround.