ArrayIndexOutOfBoundsException:4096在读取gif文件时

我能读取png文件。 但是在读取gif文件时获取ArrayIndexOutOfBoundsException:4096。

byte[] fileData = imageFile.getFileData(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileData); RenderedImage image = ImageIO.read(byteArrayInputStream) 

抛出的exception看起来像

 java.lang.ArrayIndexOutOfBoundsException: 4096 at com.sun.imageio.plugins.gif.GIFImageReader.read(Unknown Source) at javax.imageio.ImageIO.read(Unknown Source) at javax.imageio.ImageIO.read(Unknown Source) 

可能是什么问题,解决方案是什么?

更新3:解决方案

我最终开发了自己的GifDecoder,并在Apache License 2.0下将其作为开源发布。 你可以从这里得到它: https : //github.com/DhyanB/Open-Imaging 。 它不会受到ArrayIndexOutOfBoundsException问题的影响并提供良好的性能。

任何反馈都非常感谢。 特别是,我想知道它是否适用于您的所有图像,如果您对它的速度感到满意。

我希望这对你有帮助(:

初步答案

也许这个错误报告与相同的问题有关或描述: https : //bugs.openjdk.java.net/browse/JDK-7132728 。

引用:

 完整产品版本:
 java版“1.7.0_02”
 Java(TM)SE运行时环境(版本1.7.0_02-b13)
 Java HotSpot(TM)64位服务器VM(内置22.0-b10,混合模式)

其他操作系统版本信息:
 Microsoft Windows [版本6.1.7601]

问题描述:
根据规范
 http://www.w3.org/Graphics/GIF/spec-gif89a.txt
 >当字符串表已满时,无需发送清除代码。

但是,当字符串表已满时,GIFImageReader需要清除代码。
 GIFImageReader显然违反了规范。
在现实世界中,人们有时会发现如此高压缩的gif图像。
所以你应该修复这个bug。

以下重现问题的步骤:
 javac -cp .; PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test.java
 java -cp .; PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test

预期与实际行为:
预期 - 
正常完成。 没有输出
实际 - 
发生ArrayIndexOutOfBounds。

发生的错误信息/堆栈跟踪:
线程“main”中的exceptionjava.lang.ArrayIndexOutOfBoundsException:4096
        在com.sun.imageio.plugins.gif.GIFImageReader.read(GIFImageReader.java:1)
 075)
        在javax.imageio.ImageIO.read(ImageIO.java:1400)
        在javax.imageio.ImageIO.read(ImageIO.java:1322)
        在GIF_OverflowStringList_Test.main(GIF_OverflowStringList_Test.java:8)


可重复性:
这个bug总是可以复制。 

错误报告还提供了重现错误的代码。

更新1

这是一个导致我自己的代码中的错误的图像:

在此处输入图像描述

更新2

我尝试使用Apache Commons Imaging读取相同的图像,这导致以下exception:

  java.io.IOException:AddStringToTable:codes:4096 code_size:12
    在org.apache.commons.imaging.common.mylzw.MyLzwDecompressor.addStringToTable(MyLzwDecompressor.java:112)
    在org.apache.commons.imaging.common.mylzw.MyLzwDecompressor.decompress(MyLzwDecompressor.java:168)
    在org.apache.commons.imaging.formats.gif.GifImageParser.readImageDescriptor(GifImageParser.java:388)
    在org.apache.commons.imaging.formats.gif.GifImageParser.readBlocks(GifImageParser.java:251)
    在org.apache.commons.imaging.formats.gif.GifImageParser.readFile(GifImageParser.java:455)
    在org.apache.commons.imaging.formats.gif.GifImageParser.readFile(GifImageParser.java:435)
    在org.apache.commons.imaging.formats.gif.GifImageParser.getBufferedImage(GifImageParser.java:646)
    在org.apache.commons.imaging.Imaging.getBufferedImage(Imaging.java:1378)
    在org.apache.commons.imaging.Imaging.getBufferedImage(Imaging.java:1292) 

这与我们对ImageIO的问题非常相似,所以我在Apache Commons JIRA上报告了这个错误: https : //issues.apache.org/jira/browse/IMAGING-130 。

我遇到了你遇到的完全相同的问题,但是我不得不坚持使用ImageIO接口,而其他库都没有。 除了杰克的好答案之外,我只需用几行代码修补现有的GIFImageReader类,并使其略微有效。

将此链接复制到PatchedGIFImageReader.java并使用如下:

 reader = new PatchedGIFImageReader(null); reader.setInput(ImageIO.createImageInputStream(new FileInputStream(files[i]))); int ub = reader.getNumImages(true); for (int x=0;x 

务必将包名更改为您正在使用的任何名称。

不幸的是,结果可能会有所不同,因为补丁是一个1分钟的错误修正,如果超过缓冲区,它基本上只会退出循环。 一些GIF加载很好,其他人有一些视觉文物。

这就是人生。 如果有人知道更好的解决方案而不是我的,请告诉我们。