Сбой декомпрессии zlib

Я пишу приложение, которое должно распаковывать данные, сжатые другим приложением (которое находится вне моего контроля - я не могу внести в него исходный код). Приложение-производитель использует zlib для сжатия данных с использованием механизма z_stream. Он часто использует Z_FULL_FLUSH (возможно, слишком часто, на мой взгляд, но это другое дело). Это стороннее приложение также может распаковать свои собственные данные, поэтому я уверен, что сами данные верны.

В моем тесте я использую это стороннее приложение для сжатия следующего простого текстового файла (в шестнадцатеричном формате):

48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a

Сжатые байты, которые я получаю из приложения, выглядят следующим образом (опять же, в шестнадцатеричном формате):

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Если я попытаюсь сжать одни и те же данные, я получаю очень похожие результаты:

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

Есть два отличия, которые я вижу:

Во-первых, четвертый байт F2, а не F3, поэтому бит дефлятора "final block" не был установлен. Я предполагаю, что это связано с тем, что интерфейс потока никогда не знает, когда будет конец входящих данных, поэтому никогда не устанавливает этот бит?

Наконец, последние четыре байта во внешних данных 00 00 FF FF, тогда как в моих тестовых данных это 24 E9 04 55. Поиск вокруг я нашел на этой странице

http://www.bolet.org/~pornin/deflate-flush.html

... что это сигнатура синхронизации или полной очистки.

Когда я пытаюсь и распаковываю свои собственные данные с помощью функции decompress(), все работает отлично. Однако при попытке и распаковывании внешних данных вызов функции decompress() завершается с кодом возврата Z_DATA_ERROR, что указывает на поврежденные данные.

У меня есть несколько вопросов:

  • Должен ли я использовать функцию zlib "uncompress" для распаковки данных, сжатых с помощью метода z_stream?

  • В приведенном выше примере, каково значение последних четырех байтов? Учитывая, что как поток сжатого снаружи потока, так и мой собственный поток тестовых данных имеют одинаковую длину, что представляют собой мои последние четыре байта?

Приветствия

Ответ 1

Благодаря авторам zlib, я нашел ответ. Третье приложение создает потоки zlib, которые не были выполнены правильно:

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Это частичный поток zlib, состоящий из заголовка zlib и частичный поток спуска. Есть два блоков, ни один из которых не является последним блок. Второй блок - пустой сохраненный блок, используемый как маркер, когда Промывка. Декодер zlib будет правильно декодировать то, что есть, и затем продолжить поиск данных после эти байты.

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

Это полный поток zlib, состоящий из заголовка zlib, одного блок, отмеченный как последний блок, и zlib трейлер. Прицеп - это Контрольная сумма Adler-32 несжатого данных.

Итак, моя декомпрессия терпит неудачу - возможно, потому, что отсутствует CRC, или код декомпрессии продолжает искать больше данных, которые не существуют.