РЕДАКТИРОВАТЬ: Это относится к фактическому блоку потока данных в IDAT (и единственный блок IDAT в этом). Я успешно перемещаюсь по соответствующим критическим частям, от IHDR до IEND — проблема заключается в навигации между реальными блоками.
Итак, я работаю над небольшим любимым проектом из любопытства, пишу загрузчик PNG и сначала экспериментирую с несжатыми файлами, чтобы понять его суть. Для типа сжатия 00 (без сжатия) он должен быть размером 2^16 - 1
, 65535 или меньше, если последний блок находится под вопросом.
Так, Я правильно загружаю первый блок и попробуйте добавить смещение длины последнего блока (которое является переменным, 65535 или меньше, если последний). Таким образом, я ожидаю, что смещение 65535-го должно попадать прямо в первый байт следующего блока, поскольку последний был прочитан с 0 до не включительно 65535 или 65534-й байт, который является последним байтом первого блока. Но по какой-то странной причине мой несжатый PNG-файл (вывод с Photoshop) считывает поддельные данные о том, какой должен быть второй проход блока (он помечает его как сжатый и окончательный с помощью динамических кодов Хаффмана и, следовательно, варианта алгоритма сжатия LZ77, на другом изображении он выводит 77 для типа сжатия и т. д. с отметкой байта 100 КБ из файла размером 1 МБ).
Так что, возможно, я ошибся в неправильном байте? Это должно быть действительно тривиально, но я не могу видеть, где я терплю неудачу, вот соответствующий бит:
unsigned int accumulatedOffset = 0;
CBlock cblock; // initializes length to 0
do {
accumulatedOffset += cblock.length; // Adds 65535 on second pass
// Extract block header
unsigned char bheader = IDATChunk[Description::BlockHeaderOffset + accumulatedOffset];
// The second pass reads from the wrong byte, it seems.
} while(...)
Я что-то пропустил для второго прохода?
Ах, спасибо за редактирование. Итак, вы говорите о дефляционных блоках.
Если у вас есть все сохраненные блоки deflate, формат будет:
00 rs pq ~rs ~pq [ pqrs bytes ] ... same thing repeated ... 01 rs pq ~rs ~pq [ pqrs bytes ]
где ~
означает обратное или дополнение.
Обратите внимание, что это будет следовать за заголовком zlib и сопровождаться трейлером zlib. Увидеть RFC 1950.
Других решений пока нет …