How can I prevent the MediaTracker waitForID method from blocking?

Hi everyone:

I am writing an application that deals with various image file formats with the help of the JIMI package (available at http://java.sun.com/products/jimi/). Everything works fine except for the Targa format. When I generate an Image object as follows (url is a valid URL object):

Image image = Jimi.getImage(url);

ImageIcon icon =new ImageIcon(image);

the program execution blocks at the second line above. I searched the ImageIcon source code for some clues, which led me to the following ImageIcon method (tracker is a MediaTracker object, a static property of ImageIcon):

(01)protectedvoid loadImage(Image image){

(02)synchronized(tracker){

(03)tracker.addImage(image, 0);

(04)try{

(05)tracker.waitForID(0, 0);

(06)}catch (InterruptedException e){

(07)System.out.println("INTERRUPTED while loading Image");

(08)}

(09)loadStatus = tracker.statusID(0,false);

(10)tracker.removeImage(image, 0);

(11)

(12)width = image.getWidth(imageObserver);

(13)height = image.getHeight(imageObserver);

(14)}

(15)}

The program blocks at line (05) above. I peeked into the MediaTracker class source code, which brought me to determine that the image loading process never finishes. The symptoms are as follows:

(1) When I perform a c.checkImage(image, null) where c is some Component, I always get a result of 7, which translates to the following combination of ImageObserver constants:

WIDTH | HEIGHT | PROPERTIES

As matter of fact, the dimensions are indeed determined correctly. However, when the loading process terminates, the checkImage result includes ALLBITS or FRAMEBITS in case of success, ABORT or ERROR in case of failure. None of these bits is ever turned on whenever I try to load a Targa image.

(2) When I get to the MediaTracker source code, I see that when none of the four bytes above is set, the internal MediaTracker status has the MediaTracker.LOADING bit turned on (nothing abnormal here). And the waitForID method terminates precisely only when this bit is turned off!

Logically, if the loading process fails for some reason, I should expect to get an error response so that I can go further in code execution. However, since the loading process never terminates, everything stays blocked at the waitForID method invocation.

Is there an efficient way to detect such a hidden loading error without letting my program go into the waitForID endless loop? In other words, going back to the first two lines of code of this message, how could I detect that an Image loading process will not terminate before calling the ImageIcon constructor?

Thanks in advance for any useful help...

Jean-Franois Morin

[3293 byte] By [jfmorin] at [2007-9-26 4:00:07]
# 1

The MediaTracker documentation states that if an error occurs during the loading of the image then it is considered complete so waitForID should exit alright.

You'll have to ensure that the image is loaded before giving it to ImageIcon so you can trap failed image loading:

Image image = Jimi.getImage(url);

MediaTracker mt = new MediaTracker(this); // Or some component

mt.addImage(image, 0);

try

{

mt.waitForID(0, 10000); // Give it ten seconds to load

}

catch(Exception e)

{

// oh dear

}

if(mt.checkID(0) || (mt.getErrorsID(0) != null))

{

// didn't load correctly - try another image perhaps?

}

// Don't forget to tidy up!

mt.removeImage(image, 0);

ImageIcon icon = new ImageIcon(image);

Hope this helps.

KPSeal at 2007-6-29 12:54:47 > top of Java-index,Desktop,Core GUI APIs...
# 2

Hi:

I tried precisely your suggestion before posting my message to the forum yesterday. I just forgot to mention it... Maybe I was afraid of increasing my message length more and more...

I already know that this solution prevents the MediaTracker from blocking. However...

(1) If they reach a troublesome image (like a Targa), the users of my application might not be pleased by its freezing for 10 seconds. Actually, this image loading module is part of an architecture for database applications from which my development team and I produce applications for various customers. Images are used, in particular, in Oracle BLOB support.

(2) If I use a smaller timeout delay, I have no guarantee that any image, whatever its length, will load properly (Targa excluded, of course). According to tests I performed yesterday, I am virtually sure that the 10-second delay will be busted very easily by pictures larger than 1 Mb. I cannot overlook this potential problem: an Oracle BLOB can contain up to 2 terabytes of data!

On the other side, I don't want to focus too much the attention on the JIMI Targa import filter because I know that a revised version of the JIMI and JAI packages will be part of JDK 1.4. This is why I am trying to figure out what is happening in the MediaTracker and Toolkit classes, which are much more fundamental than the Jimi ones...

Thanks anyway...

Best regards,

Jean-Franois Morin

jfmorin at 2007-6-29 12:54:47 > top of Java-index,Desktop,Core GUI APIs...