JDK-5005969 : Wide BufferedImage displays corrupted image
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.2,5.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-03-02
  • Updated: 2004-11-09
Description

Name: pr15447			Date: 03/01/2004


FULL PRODUCT VERSION :
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)

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

EXTRA RELEVANT SYSTEM CONFIGURATION :
Display settings: 1024x768, 32 bits per pixel

A DESCRIPTION OF THE PROBLEM :
When a wide BufferedImage of TYPE_TYPE_USHORT_565_RGB or TYPE_INT_RGB is painted garbage is displayed. In my test case this happens for images of 2017x100 pixels or wider. The BufferedImage seems to use a wrong mapping into the image data.
  Interestingly enough the BufferedImage is displayed correctly at first but the display becomes corrupted after subsequent redraws.
BufferedImages of TYPE_INT_ARGB are painted correctly.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the test case provided below with 1.5.0 beta 1.
Start the program.
Change the size of the window to trigger bug.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The window created by the test case should always display a black bar with yellow boxes.
ACTUAL -
When starting the test case the display is like expected.
After changing the window size garbage is displayed. Depending on the width of the BufferedImage the image is distorted or you only see coloured blocks on the screen.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.JFrame;
import javax.swing.Icon;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Component;
import java.awt.image.BufferedImage;
import java.awt.GraphicsEnvironment;

/**
 * Show bug with large BufferedImages in 1.5.0 beta1.
 * The problem first arises with a image size of 2017x100 or wider in this test.
 * Change window width or height (e.g. maximise) to exhibit strange behaviour:
 * - corrupted image display
 * The corruption happens for different images types like TYPE_USHORT_565_RGB
 * or TYPE_INT_RGB.
 * There is no corruption with TYPE_INT_ARGB on my 1024x768x32bit display.
 *
 * Tested with
 *  java version "1.5.0-beta"
 *  Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
 *  Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
 * on
 *  Windows XP Professional Edition
 * with a display setting of
 *  1024x768x32bit
 *
 * Everything works fine in 1.4.2_02 except when using createCompatibleImage.
 */
public class BugBufferedImage
implements Icon
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("BugBufferedImage");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new JLabel(new BugBufferedImage()));
        frame.pack();
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

    private BufferedImage image;

    /**
     * Create the image.
     */
    public BugBufferedImage()
    {
        image = new BufferedImage(15000, 100, BufferedImage.TYPE_USHORT_565_RGB);
//        image = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(15000, 100);
        System.out.println(image);
        Graphics g = image.getGraphics();
        g.setColor(Color.YELLOW);
        for ( int x = 10; x+30 < image.getWidth(); x += 150 )
            g.fillRect(x, 10, 30, 20);
    }

    public int getIconWidth()
    {
        return image.getWidth();
    }

    public int getIconHeight()
    {
        return image.getHeight();
    }

    public void paintIcon(Component c, Graphics g, int x, int y)
    {
        g.drawImage(image, x, y, c);
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Only use TYPE_INT_ARGB. But this uses twice as much memory as TYPE_USHORT_565_RGB. And I don't know if this is dependend on the current display settings.
(Incident Review ID: 239887) 
======================================================================

Comments
WORK AROUND Disable offscreen acceleration via property -Dsun.java2d.ddoffscreen=false . ###@###.### 2004-04-06
06-04-2004

EVALUATION Name: abR10136 Date: 03/12/2004 Original problem was reported for Toshiba Tecra 9100 (notebook) with S3 Graphics SuperSavage/IXC 1179 (DirectX 8.1). Unfortunately, I have no access to exactly such system (or even same videocard) - so i could not try to reproduce original setup. I tried Nvidia based system and they seems to be ok. But I found similar (perhaps the same) problem on systems using ATI Radeon videocards: we get garbage if image width fits in range [4080, 32768] (sideeffect of directx loops). If image width is greater than 32768 we failed to allocate d3d texture and fail back to generic blit procedure which work ok. ====================================================================== I can reproduce the bug with ATI Radeon 9800 with the following testcase: import java.awt.*; public class Test { static Image image; public static void main (String[] args) { Frame f = new Frame() { public void paint(Graphics g) { g.drawImage(image, getInsets().left, getInsets().top, null); } }; f.pack(); f.setSize(300, 150); image = f.createImage(5760, 100); int w = image.getWidth(null); int h = image.getHeight(null), c = 0; Color colors[] = {Color.red, Color.green, Color.blue }; Graphics gg = image.getGraphics(); gg.setColor(Color.red); gg.fillRect(0, 0, w, h); for (int x = 0; x < w-h/3; x+=h/3,c++) { gg.setColor(colors[c % 3]); gg.fillRect(x, 0, x+h/3, h); } f.setVisible(true); } } ###@###.### 2004-03-16 Not for tiger - not enough resources. Since this bug seems to be configuration specific, we'll address it the next update release. ###@###.### 2004-04-06
16-03-2004