jai-imageio-core
  1. jai-imageio-core
  2. JAI_IMAGEIO_CORE-157

ImageRead in collection mode fails for animated gifs

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: current
    • Fix Version/s: milestone 1
    • Component/s: implementation
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      157

      Description

      ImageRead operation fails in collection mode. The following code fails to read
      the second image in a animated gif. It appears that for the first image in the
      file ImageIO is queried and returns an appropriate reader. When information
      about the second and subsequent images is requested ImageIO is queried again
      however this time the ImageInputStream is no longer at its original position.
      This causes no ImageReaders to be found.

      ImageIO itself is quite capable of reading the image. The following code shows
      this issue.

      Expected: The code should iterate through all the frames in an animated gif and
      display the height of each

      Actual: The code fails when attempting to get the height of the second frame.

      Note that if you uncomment the iis.seek(0) line then the code does work.

      ----------------------------------------------------------------------------
      import com.sun.media.jai.operator.ImageReadDescriptor;

      import java.io.IOException;
      import java.io.RandomAccessFile;
      import java.util.Collection;
      import java.util.Iterator;

      import javax.imageio.ImageIO;
      import javax.imageio.stream.ImageInputStream;
      import javax.media.jai.RenderedOp;

      public class AnimatedGIF {
      public static final void main(String[] args) throws IOException {
      if (args.length != 1)

      { System.err.println("you must provide the path to an animated gif"); System.exit(1); }

      RandomAccessFile fis = new RandomAccessFile(args[0], "r" );
      ImageInputStream iis = ImageIO.createImageInputStream(fis);
      Collection images = ImageReadDescriptor.createCollection(
      iis, null, Boolean.TRUE, Boolean.TRUE,
      Boolean.TRUE, null, null, null, null, null);
      Iterator imageIt = images.iterator();
      while (imageIt.hasNext())

      { // iis.seek(0); // uncomment this line to make this code work RenderedOp image = (RenderedOp) imageIt.next(); // see if the image can be read System.out.println(image.getHeight()); }

      }
      }
      -------------------------------------------------------------------------

      1. patch.patch
        13 kB
        matfud
      1. test2.gif
        0.3 kB

        Activity

        Hide
        matfud added a comment -

        Created an attachment (id=108)
        A simple two frame animated gif

        Show
        matfud added a comment - Created an attachment (id=108) A simple two frame animated gif
        Hide
        matfud added a comment -

        Please note that this is running in pure java mode (no native libs apart from
        those distributed as part of the JDK).

        jai-core.jar
        jai-codec.jar
        jai-imageio.jar

        and nothing else (no mlib, no .so files). Only one ImageReader is found for the
        GIF's in question and it appears to be the one shiped with the JDK.

        The same problem occurs with a variety of jai_imageio versions including todays
        CVS HEAD.

        Cheers

        Matt

        Show
        matfud added a comment - Please note that this is running in pure java mode (no native libs apart from those distributed as part of the JDK). jai-core.jar jai-codec.jar jai-imageio.jar and nothing else (no mlib, no .so files). Only one ImageReader is found for the GIF's in question and it appears to be the one shiped with the JDK. The same problem occurs with a variety of jai_imageio versions including todays CVS HEAD. Cheers Matt
        Hide
        matfud added a comment -

        JDK 1.5.0_10

        Show
        matfud added a comment - JDK 1.5.0_10
        Hide
        matfud added a comment -

        ImageRead in collection fails to work correctly because it creates a new
        ImageReader instance for each sub image in the collection. This can appear to
        work if the "Input" parameter is a File however it actually causes the source
        file to be parsed multiple times (quite expensive). If the "Input" parameter is
        a Stream then obtaining any information about images other then the first causes
        a failure (the stream has already been read).

        A fairly simple workaround for this problem is to allow the "Input" parameter to
        be null if a ImageReader is provided and if it already has its Input value set.
        This would allow the ImageReadCIF to create a single instance of an ImageReader
        and then pass that on to the "ImageRead" operation. The ImageRead operation
        could then reuse the ImageReader for all images in the collection.

        Show
        matfud added a comment - ImageRead in collection fails to work correctly because it creates a new ImageReader instance for each sub image in the collection. This can appear to work if the "Input" parameter is a File however it actually causes the source file to be parsed multiple times (quite expensive). If the "Input" parameter is a Stream then obtaining any information about images other then the first causes a failure (the stream has already been read). A fairly simple workaround for this problem is to allow the "Input" parameter to be null if a ImageReader is provided and if it already has its Input value set. This would allow the ImageReadCIF to create a single instance of an ImageReader and then pass that on to the "ImageRead" operation. The ImageRead operation could then reuse the ImageReader for all images in the collection.
        Hide
        matfud added a comment -

        A slight modification:

        Null does not work as a value for the "Input" parameter.

        I will modify the code to have a ImageReadDecriptor.NO_INPUT_PROVIDED public
        static variable. If this is provided as the "Input" parameter then the ImageRead
        operation will expect an ImageReader with its input already set to be provided.

        Show
        matfud added a comment - A slight modification: Null does not work as a value for the "Input" parameter. I will modify the code to have a ImageReadDecriptor.NO_INPUT_PROVIDED public static variable. If this is provided as the "Input" parameter then the ImageRead operation will expect an ImageReader with its input already set to be provided.
        Hide
        matfud added a comment -

        Created an attachment (id=129)
        Allow collection mode to read images correctly

        Show
        matfud added a comment - Created an attachment (id=129) Allow collection mode to read images correctly

          People

          • Assignee:
            bpb
            Reporter:
            matfud
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: