-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b81
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
In XOR mode, calling the method
Graphics2D.drawImage(Image img, int x, int y,
int width, int height,
ImageObserver observer);
with a "width" and/or "height" argument smaller than the actual size of the image produces an exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the attached program:
javac -classpath . ImageXOR.java
2. Run:
java -classpath . ImageXOR
==> You should see an exception in the console.
Release Regression From : 5.0
The above release value was the last known release where this bug was non-existent. Since then there has been a regression.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An image should be drawn in XOR mode.
ACTUAL -
An exception occurs each time Graphics.drawImage is called (see stack below).
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: Cannot construct MaskBlit for XOR mode
at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)
at sun.java2d.loops.GraphicsPrimitiveMgr.locate(Unknown Source)
at sun.java2d.loops.MaskBlit.locate(Unknown Source)
at sun.java2d.loops.MaskBlit.getFromCache(Unknown Source)
at sun.java2d.pipe.DrawImage.renderImageXform(Unknown Source)
at sun.java2d.pipe.DrawImage.transformImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at sun.awt.image.ImageRepresentation.drawToBufImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at ImageXOR$1.paint(ImageXOR.java:95)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown S
ource)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.awt.MediaTracker;
/**
* Demonstrates a regression concerning the drawing
* of images in XOR mode.
*
* Compile:
* javac -classpath . ImageXOR.java
*
* Run:
* java -classpath . ImageXOR
*
* Stack trace of the exception:
* Exception in thread "AWT-EventQueue-0" java.lang.InternalError:
* Cannot construct MaskBlit for XOR mode
* at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)
* at sun.java2d.loops.GraphicsPrimitiveMgr.locate(Unknown Source)
* at sun.java2d.loops.MaskBlit.locate(Unknown Source)
* at sun.java2d.loops.MaskBlit.getFromCache(Unknown Source)
* at sun.java2d.pipe.DrawImage.renderImageXform(Unknown Source)
* at sun.java2d.pipe.DrawImage.transformImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at sun.awt.image.ImageRepresentation.drawToBufImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at ImageXOR.paint(ImageXOR.java:49)
* at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
* at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
* at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
* at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
* at java.awt.event.InvocationEvent.dispatch(Unknown Source)
* at java.awt.EventQueue.dispatchEvent(Unknown Source)
*
* Platform information:
* > java -version
* java version "1.6.0-beta"
* Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
* Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode, sharing)
*
* OS: Windows XP SP2.
*
* The same code works fine with previous versions of the JDK (for instance 1.5).
*/
public class ImageXOR
extends JFrame
{
public ImageXOR()
{
final Image img = loadImage();
if (img == null)
return;
getContentPane().add(new JComponent() {
public void paint(Graphics g) {
if (img == null)
return;
g.setColor(Color.green);
g.setXORMode(Color.white);
int width = getWidth();
int height = getHeight();
g.fillRect(0, 0, width, height);
int wImage = img.getWidth(null);
int hImage = img.getHeight(null);
int x = (width - wImage) / 2;
int y = (height - hImage) / 2;
// This version of Graphics.drawImage works fine:
// g.drawImage(img, x, y, null);
//
// This version of Graphics.drawImage works fine if
// width and height are those of the image (49x38 in this example):
// g.drawImage(img, x, y, wImage, hImage, null);
//
// This version of Graphics.drawImage produces the exception
// "java.lang.InternalError:
// Cannot construct MaskBlit for XOR mode"
// at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)"
// with width/height different than those of the image
// (49x38 in this example):
g.drawImage(img, x, y, wImage - 1, hImage - 1, null);
}
});
}
// loads the image
private Image loadImage()
{
URL url = getClass().getResource("image.png");
if (url == null) {
System.out.println("null URL");
return null;
}
Image img = getToolkit().createImage(url);
final MediaTracker tracker = new MediaTracker(this);
tracker.addImage(img, 0);
try {
tracker.waitForAll();
}
catch(java.lang.Exception e) {
e.printStackTrace();
}
return img;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new ImageXOR();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1) Use Graphics2D.drawImage(Image img, int x, int y, ImageObserver observer) instead.
or
2) Provide width/height arguments equal to the actual size of the image.
or
3) Do not use XOR mode.
Another testcase provided by Jan Bösenberg (INCORS GmbH)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* Class to reproduce a bug (?) with custom composites
*
* JRE 1.6 b72 throw as java.lang.InternalError: Cannot construct
general op for MaskBlit(...) Any CompositeContext
*/
public class CompositeBugTest {
public static void main(String[] args) {
JFrame frame = new JFrame("Composite Test");
frame.setContentPane(new JPanelImage());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.validate();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class JPanelImage extends JPanel {
private Image image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
public JPanelImage() {
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (g instanceof Graphics2D) {
Graphics2D g2D = (Graphics2D) g;
g2D.setComposite(new TestComposite());
// using drawImage(image, 0, 0, null) works without problems
g2D.drawImage(image, 0, 0, 200, 200, null);
} else {
assert false;
}
}
}
private static class TestComposite implements Composite {
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel, RenderingHints hints) {
return new TestCompositeContext();
}
}
private static class TestCompositeContext implements CompositeContext {
public void compose(Raster src1, Raster src2, WritableRaster dstOut) {
}
public void dispose() {
}
}
}
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
In XOR mode, calling the method
Graphics2D.drawImage(Image img, int x, int y,
int width, int height,
ImageObserver observer);
with a "width" and/or "height" argument smaller than the actual size of the image produces an exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the attached program:
javac -classpath . ImageXOR.java
2. Run:
java -classpath . ImageXOR
==> You should see an exception in the console.
Release Regression From : 5.0
The above release value was the last known release where this bug was non-existent. Since then there has been a regression.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An image should be drawn in XOR mode.
ACTUAL -
An exception occurs each time Graphics.drawImage is called (see stack below).
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: Cannot construct MaskBlit for XOR mode
at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)
at sun.java2d.loops.GraphicsPrimitiveMgr.locate(Unknown Source)
at sun.java2d.loops.MaskBlit.locate(Unknown Source)
at sun.java2d.loops.MaskBlit.getFromCache(Unknown Source)
at sun.java2d.pipe.DrawImage.renderImageXform(Unknown Source)
at sun.java2d.pipe.DrawImage.transformImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at sun.awt.image.ImageRepresentation.drawToBufImage(Unknown Source)
at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
at ImageXOR$1.paint(ImageXOR.java:95)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown S
ource)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.awt.MediaTracker;
/**
* Demonstrates a regression concerning the drawing
* of images in XOR mode.
*
* Compile:
* javac -classpath . ImageXOR.java
*
* Run:
* java -classpath . ImageXOR
*
* Stack trace of the exception:
* Exception in thread "AWT-EventQueue-0" java.lang.InternalError:
* Cannot construct MaskBlit for XOR mode
* at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)
* at sun.java2d.loops.GraphicsPrimitiveMgr.locate(Unknown Source)
* at sun.java2d.loops.MaskBlit.locate(Unknown Source)
* at sun.java2d.loops.MaskBlit.getFromCache(Unknown Source)
* at sun.java2d.pipe.DrawImage.renderImageXform(Unknown Source)
* at sun.java2d.pipe.DrawImage.transformImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at sun.awt.image.ImageRepresentation.drawToBufImage(Unknown Source)
* at sun.java2d.pipe.DrawImage.scaleImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at sun.java2d.SunGraphics2D.drawImage(Unknown Source)
* at ImageXOR.paint(ImageXOR.java:49)
* at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
* at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
* at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
* at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
* at java.awt.event.InvocationEvent.dispatch(Unknown Source)
* at java.awt.EventQueue.dispatchEvent(Unknown Source)
*
* Platform information:
* > java -version
* java version "1.6.0-beta"
* Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
* Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode, sharing)
*
* OS: Windows XP SP2.
*
* The same code works fine with previous versions of the JDK (for instance 1.5).
*/
public class ImageXOR
extends JFrame
{
public ImageXOR()
{
final Image img = loadImage();
if (img == null)
return;
getContentPane().add(new JComponent() {
public void paint(Graphics g) {
if (img == null)
return;
g.setColor(Color.green);
g.setXORMode(Color.white);
int width = getWidth();
int height = getHeight();
g.fillRect(0, 0, width, height);
int wImage = img.getWidth(null);
int hImage = img.getHeight(null);
int x = (width - wImage) / 2;
int y = (height - hImage) / 2;
// This version of Graphics.drawImage works fine:
// g.drawImage(img, x, y, null);
//
// This version of Graphics.drawImage works fine if
// width and height are those of the image (49x38 in this example):
// g.drawImage(img, x, y, wImage, hImage, null);
//
// This version of Graphics.drawImage produces the exception
// "java.lang.InternalError:
// Cannot construct MaskBlit for XOR mode"
// at sun.java2d.loops.MaskBlit.makePrimitive(Unknown Source)"
// with width/height different than those of the image
// (49x38 in this example):
g.drawImage(img, x, y, wImage - 1, hImage - 1, null);
}
});
}
// loads the image
private Image loadImage()
{
URL url = getClass().getResource("image.png");
if (url == null) {
System.out.println("null URL");
return null;
}
Image img = getToolkit().createImage(url);
final MediaTracker tracker = new MediaTracker(this);
tracker.addImage(img, 0);
try {
tracker.waitForAll();
}
catch(java.lang.Exception e) {
e.printStackTrace();
}
return img;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new ImageXOR();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1) Use Graphics2D.drawImage(Image img, int x, int y, ImageObserver observer) instead.
or
2) Provide width/height arguments equal to the actual size of the image.
or
3) Do not use XOR mode.
Another testcase provided by Jan Bösenberg (INCORS GmbH)
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* Class to reproduce a bug (?) with custom composites
*
* JRE 1.6 b72 throw as java.lang.InternalError: Cannot construct
general op for MaskBlit(...) Any CompositeContext
*/
public class CompositeBugTest {
public static void main(String[] args) {
JFrame frame = new JFrame("Composite Test");
frame.setContentPane(new JPanelImage());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.validate();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class JPanelImage extends JPanel {
private Image image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
public JPanelImage() {
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (g instanceof Graphics2D) {
Graphics2D g2D = (Graphics2D) g;
g2D.setComposite(new TestComposite());
// using drawImage(image, 0, 0, null) works without problems
g2D.drawImage(image, 0, 0, 200, 200, null);
} else {
assert false;
}
}
}
private static class TestComposite implements Composite {
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel, RenderingHints hints) {
return new TestCompositeContext();
}
}
private static class TestCompositeContext implements CompositeContext {
public void compose(Raster src1, Raster src2, WritableRaster dstOut) {
}
public void dispose() {
}
}
}