Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6393174

Exception when Graphics2D.drawImage draws in XOR a scaled image

XMLWordPrintable

    • 2d
    • 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() {
         }
       }
      }

            flar Jim Graham
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: