2014-10-01 2 views
2

В настоящее время я разрабатываю собственный формат файла на основе формата файла png. Я сделан до сих пор, за исключением того, что он не работает: -p Декомпрессионный декомпрессор, который я реализовал, работает как шарм, но декодер png не хочет выполнять красиво, поэтому я взглянул на оригинальный файл png.IDAT Chunk of PNG Формат файла

В стандарте указано, что после заголовка IDAT сжатые данные следуют незамедлительно. Так как данные представляют собой поток дефляции, первый символ после IDAT равен 0x78 == 01111000, что означает, что один блок (несжатый), а не последний.

Странно, однако - мне трудно представить, что кодер PNG не использует динамическое кодирование huffman для сжатия фильтрованных необработанных данных изображения. В стандарте дефляции говорится, что остальная часть текущего байта пропускается в режиме один.

Итак, следующие четыре байта указывают размер несжатого блока и его одного дополнения. Но 0x59FD не является одним из дополнений к 0xECDA. Даже если я испортил порядок байтов: 0xFD59 не является одним из дополнений к 0xDAEC.

Ну, выбитый байт следует за ним. 0x97 считается первым байтом несжатых, но все еще фильтрованных необработанных данных изображения png и как таковой должен быть тип фильтра. Но 0x97 == 10010111 не является допустимым типом фильтра. Событие, если я испортил порядок упаковки бит 11101001 == 0xe9 по-прежнему не имеет допустимого типа фильтра.

Я больше не фокусировался на RFC 1951, так как до сих пор я могу раздувать все типы файлов, используя мою реализацию декомпрессора дефлята, поэтому я подозреваю, что некоторые недоразумения с моей стороны соответствуют стандарту PNG.

Я читал RFC 2083 снова и снова, но данные, которые я вижу здесь, не соответствуют RFC, для меня это не имеет смысла, там должна быть недостающая часть!

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

Было бы разумно, если бы 0x78 (первый байт после IDAT) считывался из MSB в LSB, но RFC 1951 говорит иначе. Другая идея (более вероятно для меня) заключается в том, что есть некоторые данные между строкой IDAT и началом сжатого потока дефляции, но RFC 2083 говорит иначе. Макет ясно

4 байт Размер 4 байт ChunkName (IDAT) [Размер] Б (сжатый поток Deflate) 4 байта CRC Контрольная сумма

Таким образом, первый байт после IDAT должен быть первый байт сжатого потока выкачать - который указывает блок несжатых данных режима 1. Это означает, что 0x97 должен быть первым байтом несжатых, но фильтрованных данных PNG изображения, что означает, что 0x97 является типом фильтра для первой строки - это недопустимо ...

Я просто не понимаю, я глуп или какие??

Резюме: Возможность 1: Существуют ряд других данных между IDAT и эффективным началом потока сжатого выкачать, который, если делает, чтобы быть правдой, не meantioned в RFC2083, ни в одной книге я прочитал о сжатии изображений ,

Возможность 2: Число 0x78 интерпретируется MSB -> LSB, который будет указывать на блок режима 3 (динамическое кодирование Хаффмана), но это противоречит с RF1951, которая очень четко упаковки битов: (LSB -> MSB)

Я уже знаю, недостающий кусок должен быть чем-то очень глупо, и я чувствую, что urgend нужно продавать свою душу, если там была только кнопка удаления в Stack Overflow :-p

enter image description here

ответ

3

Два исправления который может помочь вам добраться до вас:

  1. Число флагов zlib составляет 2, а не 1 - см. RFC 1950. Первый - CMF, следующий FLG.

В ваших данных:

78 DA 

---CMF--- ---FLG--- 
0111.1000 1101.0101 
CINF -CM- +-|| 
      | |+- FCHECK 
      | +-- FDICT 
      +---- FLEVEL 

CINF 7, что указывает на стандартное окно сжатия 32Kb.
CM 8, что указывает на алгоритм сжатия, в самом деле, выкачать.
FCHECK - всего лишь контрольная сумма; Я не проверял, правильно ли это (но я бы поспорил, что это так).
FDICT ясно, что означает, что сохраненный словарь не сохранен.
FLEVEL 3, что указывает на максимальное сжатие.

Смотрите также Trying to understand zlib/deflate in PNG files, особ. др. Ответ Адлера.

  1. LEN и NLEN предназначены только для несжатых блоков; вот почему вы их не нашли. (Кроме того, частично, потому что вы смотрели на неправильные байтах (ы).)

Следующих байты в потоке EC; побитовое, это 1110 1100, но не забудьте прочитать бит от низкого до высокого. Таким образом, следующий бит считывания 0, а это означает не окончательными, а следующие 2 бита чтения являются 10 (в таком порядке!), Что указывает на регулярный динамический блок данных кодируется по алгоритму Хаффмана.

+0

я не понял, поток Deflate заворачивают в ZLib контейнере. Я принял его чистый поток спуска. Поэтому я теперь просто пропустил два байта и вуаля - работает импортер png! :-) Большое спасибо! – Silverdust

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