数组索引OutOfBounds异常:读取gif文件时为4096

2022-09-01 14:33:51

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

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)

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


答案 1

更新 3:解决方案

我最终开发了自己的GifDecoder,并在Apache许可证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.

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

更新 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


答案 2

我遇到了与你完全相同的问题,但我不得不坚持使用ImageIO接口,这是其他库无法做到的。除了 Jack 的精彩回答之外,我只是用几行代码修补了现有类,并让它稍微工作一下。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<ub;x++) {
    BufferedImage img = reader.read(x);
    //Do whatever with the new img bufferedimage

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

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

这就是生活。如果有人知道比我更好的修复方法,请告诉。


推荐