|
Quick Lists
|
|
Bug ID:
|
4684046
|
|
Votes
|
7
|
|
Synopsis
|
Using CropImageFilter on PNG images fails
|
|
Category
|
java:classes_2d
|
|
Reported Against
|
1.4
|
|
Release Fixed
|
1.5(tiger-b31)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
|
|
Submit Date
|
13-MAY-2002
|
|
Description
|
When you use CropImageFilter to crop an image that was produced from a PNG image, from time to time the following exception is thrown in the ImageFetcher thread:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.ensureOpen(BufferedInputStream.java:120)
at java.io.BufferedInputStream.read(BufferedInputStream.java:199)
at sun.awt.image.PNGImageDecoder.produceImage(PNGImageDecoder.java:244)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:257)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:214)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:182)
I suspect there's a thread issue going on, because this isn't 100% repeatable and seems to vary wildly from run to run. However, I'm developing a Windows XP look and feel implementation which does a lot of image loading and cropping, and this happens often enough to cause my LAF to fail to work about 7 times in 10.
I can consistently reproduce this with the following code which loads 6 images and crops each one 1000 times:
package org.dubh.plaf.xp;
import java.awt.*;
import javax.swing.*;
import java.net.*;
import java.awt.image.*;
public class CropPNGBug
{
private final static String[] pngImages = new String[]
{
"image/olive/button.png",
"image/olive/button-enabled.png",
"image/olive/button-enabled-armed.png",
"image/olive/button-enabled-default.png",
"image/olive/button-enabled-down.png",
"image/olive/caption-active.png"
};
public static void main( String[] args )
{
Image[] images = new Image[ pngImages.length ];
for ( int i=0; i < pngImages.length; i++ )
{
URL u = CropPNGBug.class.getResource( pngImages[i] );
images[i] = new ImageIcon( u ).getImage();
}
// Now crop them all
for ( int i=0; i < images.length; i++ )
{
for ( int j=0; j < 1000; j++ )
{
CropImageFilter cif = new CropImageFilter( 0, 0, 5, 5 );
ImageIcon icon = new ImageIcon( createImage(
new FilteredImageSource( images[i].getSource(), cif ) ) );
}
}
}
private static Image createImage( ImageProducer ip )
{
return Toolkit.getDefaultToolkit().createImage( ip );
}
}
(you'll need to replace the array of image references with valid paths). Email me if you need the original images.
(Review ID: 146404)
======================================================================
|
|
Work Around
|
None, it's extremely erratic and non-predictable. I'm going to try using the Sixlegs PNG library instead of Sun's, since the exception is coming from the PNGImageDecoder, ultimately.
======================================================================
|
|
Evaluation
|
The reason of the problem is that the PNGImageDecoder does not check
the decoder status (is it aborted or not) inside the produceImage().
If system is busy (e.g., running large number of decoders)
decoding may be performing for relatively long period of time and
corresponding image consumer may be disposed (aborting associated
decoder and closing associated BufferedInputStream) before decoding
is finished.
As a result aborted decoder may try to read data from closed stream
and fail.
The solution is to hide exceptions was thrown by aborted decoder.
======================================================================
|
|
Comments
|
Submitted On 17-MAY-2002
cairn
Eventually worked round this by using a BufferedImage and
avoiding using CropImageFilter:
// Workaround nasty crop filter bugs.
BufferedImage i = new BufferedImage(
icon.getIconWidth(), icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB
);
icon.paintIcon( null, i.createGraphics(), 0, 0 );
return image.getSubimage( x, y, width, height );
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |