JDK-4953566 : IIS.mark() / reset() does not work properly with PNG ImageReader
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-11-13
  • Updated: 2006-11-06
  • Resolved: 2005-12-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6 b63Fixed
I am reading a PNG image using a PNG ImageReader. I am marking the initial position of the ImageInputStream through IIS.mark() call just before invoking the reader.read() method. This read process is aborted when it completes 50% by calling abort() in one of the listener methods. After this, I am resetting the position of the ImageInputStream to the initial marked position by calling IIS.reset(). Then I am using the same reader to the read the image till completion. This results in an IIOException. Call to IIS.reset() throws an exception saying the initially marked position has been discarded. Caching is disabled at begining of the application.

PNG ImageReader actually calls IIS.flushBefore() which actually flushes the portion of the image input stream that was marked earlier. This does not seem to be happening with other image formats. However, there is an issue with JPEG where the abort flag is not cleared properly and causes every subsequent read operation to be aborted when abort() is called once. A separate bug has been filed on this. (4885702)

This is reproducible on all platforms since JDK1.4.

I have attached a sample testcase. Execute the testcase and pass a png image. You would see the exception given below when calling the reset() on the IIS.

Here is the exception:
javax.imageio.IIOException: Previous marked position has been discarded!
at javax.imageio.stream.ImageInputStreamImpl.reset(ImageInputStreamImpl.java:780)
at RasterListenerTest.<init>(RasterListenerTest.java:45)
at RasterListenerTest.main(RasterListenerTest.java:67)

EVALUATION After further discussion, it is clear that ImageReaders should be allowed to call ImageInputStream.flushBefore() as part of the decoding process ("if ImageReaders are not allowed to call it, who is?" says one of the original designers of the API). So it seems that applications should not assume that a marked position will remain valid after a call to one of the ImageReader methods. I suppose we could close this as "not a bug", but we should probably update the documentation somewhere (mark()?) so that developers are not surprised if they stumble across this behavior in the future.

EVALUATION This is blocking some performance test development, so it should be investigated sooner rather than later. The ImageInputStream.flushBefore() method was created for a valid reason, but the original authors probably did not consider the case mentioned in this bug report. We could remove the flushBefore() calls from the PNGImageReader, and that would solve the problem, but it doesn't prevent other plugins from using the flushBefore() method and causing similar problems for application code. I'm not sure if there's a good solution here.