2013-06-13 5 views
0

Как часть моей домашней работы, я должен написать простой PNG-ридер в Python. Мне запрещено использовать любые библиотеки Python, которые работают с изображениями, и в результате у меня должен быть список списков (строк изображения) RGB-кортежей одиночных пикселей.Python PNG декодирование - кодирование Хаффмана

Декодер должен читать только самые основные изображения PNG, которые состоят только из блоков IHDR, IDAT и IEND, IDAT только с базовыми данными RGB. Моя программа до сих пор проверяет правильный заголовок PNG и распаковывает блок IDAT с помощью zlib.decompress().

На этом этапе я застрял в течение нескольких дней. Дескриптор zlib оставил данные изображения в состоянии, где у меня есть байтовое представление строк изображения следующим образом:

Каждая строка начинается с 1 байт, 0x00, 0x04, 0x02 или 0x01. Я обнаружил, что 0x00 означает, что строка находится в «исходных данных», что означает, что следующие байты представляют R, G или B пикселя и так далее до конца строки (нет фактического заголовка newline, но abother) байт"). 0x04 или 0x02, однако, как я читаю, закодированы в кодировке Хаффмана, и вот мой вопрос:

Как декодировать эти строки? Есть ли для этого функция python (как и для распаковки zlib для шага раздувания). Кроме того, последние 2 строки начинаются с 0x01, которые, как я читал о Deflate, должны означать «это последний блок в потоке». Почему у меня это в последних двух строках изображения, а не только в последнем? И данные последних двух строк также сбивают с толку, потому что некоторые пиксели явно находятся в «сыром» представлении, но некоторые нет.

Большое спасибо, я пытался найти свой ответ везде уже ...

Войта

+0

Я просто обнаружил, что это не кодировка Хаффмана, которую я вижу, это фильтры PNG. Наконец, я нашел способ извлечь RGB-значения из этих строк: http://www.w3.org/TR/PNG/#9Filters –

+0

Если это поможет, https://code.google.com/p/pngj /source/browse/pnjg/src/ar/com/hjg/pngj/PngReader.java – leonbloy

ответ

2

Хаффмана кодирования является частью сжатия выкачать, что zlib.decompress уже расстегивает для вас. Согласно section 4.5.4 of the PNG spec первый байт каждой линии сканирования является типом фильтра, а фильтры описаны в section 9.

+0

спасибо, вот что мне нужно! : –

+0

@VojtaHejda Рад слышать. Если вы примете этот ответ, нажав галочку, другие будут видеть, что на вопрос ответили. –

1

Этот первый байт данных для каждой строки не влияет на сжатие: он сообщает, какой предварительный фильтр был запущен на данных перед сжатием, и может быть от 0 до 4. Это описано в http://www.w3.org/TR/PNG-Filters.html. И BTW, вы можете обвинить меня - идея использования другого фильтра для каждой строки сканирования была моей. :-)

Смежные вопросы