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)

в чем может быть проблема и каково решение?

2 ответа

Решение

Обновление 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 Runtime Environment (сборка 1.7.0_02-b13)
Java HotSpot(TM) 64-разрядная серверная виртуальная машина (сборка 22.0-b10, смешанный режим)

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ВЕРСИИ ОС:
Microsoft Windows [Версия 6.1.7601]

ОПИСАНИЕ ПРОБЛЕМЫ:
согласно спецификации
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
> Не требуется отправлять четкий код, когда таблица строк заполнена.

Однако GIFImageReader требует очистки кода, когда таблица строк заполнена.
GIFImageReader явно нарушает спецификацию.
В реальном мире иногда люди находят такие сжатые картинки.
поэтому вы должны исправить эту ошибку.

ШАГИ, КОТОРЫЕ СЛЕДУЮТ, ЧТОБЫ СДЕЛАТЬ ВОПРОС:
javac -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test.java
java -cp .;PATH_TO_COMMONS_CODEC GIF_OverflowStringList_Test

ОЖИДАЕМЫЕ ПРОТИВ АКТУАЛЬНОГО ПОВЕДЕНИЯ:
ОЖИДАЕМЫЙ -
завершить нормально. нет выхода
ФАКТИЧЕСКИЙ -
ArrayIndexOutOfBounds происходит.

СООБЩЕНИЯ ОБ ОШИБКАХ / СЛЕДУЮЩИЕ СЛЕДЫ, ЧТО ПРОИСХОДИТ:
Исключение в потоке "main" java.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)


ВОСПРОИЗВОДИТЕЛЬНОСТЬ:
Эту ошибку можно воспроизвести всегда.

Отчет об ошибке также предоставляет код для воспроизведения ошибки.

Обновление 1

И вот изображение, которое вызывает ошибку в моем собственном коде:

введите описание изображения здесь

Обновление 2

Я попытался прочитать то же изображение с помощью Apache Commons Imaging, что привело к следующему исключению:

java.io.IOException: AddStringToTable: коды: 4096 размер_кода: 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<ub;x++) {
    BufferedImage img = reader.read(x);
    //Do whatever with the new img bufferedimage

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

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

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

Другие вопросы по тегам