ArrayIndexOutOfBoundsException: 4096 при чтении gif файла

Я могу читать 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 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.

Ответ 2

Я столкнулся с той же самой проблемой, что и вы, но мне пришлось придерживаться интерфейса 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<ub;x++) {
    BufferedImage img = reader.read(x);
    //Do whatever with the new img bufferedimage

Обязательно измените имя пакета на все, что вы используете.

К сожалению, результаты могут отличаться, поскольку патч был исправлением в 1 минуту, которое в основном просто выходит из цикла, если оно проходит через буфер. Некоторые gifs он загружается отлично, другие имеют несколько визуальных артефактов.

Такова жизнь. Если кто-то знает лучшее исправление вместо моего, пожалуйста, скажите.