ImageIO / Java Web Start bug: Workaround

Hi, I was using ImageIO for my project, and it all worked fine until I webstarted it. Then suddenly gif images started to look weird, while 24 bit pngs didn’t load at all, but instead caused an exception to be thrown.
That bothered me a lot, since I didn’t wanna go back to the toolkit/mediatracker combo because I was copying the image into a compatible bufferimage for hardware acceleration and wanted to do this without any dependencies to Components (Need an ImageListener for MediaTracker)
Finally last day brackeCoB from devshed.com posted the same problem, and his conclusion was that the images weren’t fully loaded.

So I tried the following workaround, that seems to do the trick:

Instead of


BufferedImage src = javax.imageio.ImageIO.read(ImageLoader.class.getClassLoader().getResourceAsStream(resource));
                  

I wrap the ressource stream in a BufferedInputStream:


BufferedImage src = javax.imageio.ImageIO.read(
                        new BufferedInputStream(ImageLoader.class.getClassLoader().getResourceAsStream(resource)));
                  

The problem seems to be that ImageIO doesn’t keep reading if it can’t get all of the data in one read().

I believe this is a known bug with java.io (not imageio, actually). I don’t have the bug id handy, though.

[quote]I believe this is a known bug with java.io (not imageio, actually). I don’t have the bug id handy, though.
[/quote]
Only the readFully method guarantees to read as much as you might expect. If you are using the normal read method, then it is permitted to return less than the number of bytes requested. Nothing in the documentation guarantees it to return the amount given by the ‘available’ method.

There is an RFE requesting that a ZIPInputStream should return all the data it can (and not just as much as is convenient for the implementation).

Simple workaround:

Store images uncompressed
gif /png are already compressed and will get euqal or maybe even bigger in size if zip’ped.
So I JARed my application without gfx, and used a zip packer to add the gfx with compression factor = zero. this worked well for all my apps.
(and its no “dirty” fix as JAR gets smaller most times…)

I found the same thing & solved it in much the same way. Your solution is neater then mine, so i’m going to pinch yours ;D

Then simply reimplement your MEdiaTracker:

// override your common paint method//add src to MediaTracker with the desired display sizes, that is important if it is worth to fit to component size (see scale Transform)!
public void paintComponent(Graphics g) {
  MediaTracker mt = new MEdiaTracker(this);
  mt.addImage((Image)src, this.hashCode(), src.getWidth(this), src.getHeight(this));
  // simply wait for loading and then display
  try{ mt.waitForID(this.hashCode()); g.drawImage(src, 0,0, this); } catch(Exception e) {}
  finally{
  g.dispose();
  }
}

::slight_smile: ::slight_smile: ::slight_smile: ::slight_smile:

[quote=“mudman,post:1,topic:21468”]

Thanks for necroing the thread ::slight_smile:

It’s a known bug. It was fixed. Use the BufferedInputStream wrap for backward compatibility.

MediaTracker… lol.