ArrayIndexOutOfBoundsException:4096在读取gif文件时

时间:2014-03-07 20:07:17

标签: java gif javax.imageio

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

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

抛出的异常看起来像

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)

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

2 个答案:

答案 0 :(得分:18)

更新3:解决方案

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

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

我希望这对你有帮助(:

初步回答

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

引用:

FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
according to specification
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
> There is not a requirement to send a clear code when the string table is full.

However, GIFImageReader requires the clear code when the string table is full.
GIFImageReader violates the specification, clearly.
In the real world, sometimes people finds such high compressed gif image.
so you should fix this bug.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
javac -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test.java
java -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
complete normally. no output
ACTUAL -
ArrayIndexOutOfBounds occurs.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4096
        at com.sun.imageio.plugins.gif.GIFImageReader.read(GIFImageReader.java:1
075)
        at javax.imageio.ImageIO.read(ImageIO.java:1400)
        at javax.imageio.ImageIO.read(ImageIO.java:1322)
        at GIF_OverflowStringList_Test.main(GIF_OverflowStringList_Test.java:8)


REPRODUCIBILITY :
This bug can be reproduced always.

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

更新1

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

enter image description here

更新2

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

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

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

答案 1 :(得分:3)

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

this link复制到PatchedGIFImageReader.java并按原样使用:

reader = new PatchedGIFImageReader(null);
reader.setInput(ImageIO.createImageInputStream(new FileInputStream(files[i])));
int ub = reader.getNumImages(true);
for (int x=0;x<ub;x++) {
    BufferedImage img = reader.read(x);
    //Do whatever with the new img bufferedimage

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

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

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