Функции zlib компрессии


FPublisher

Web-технологии: База знаний

Документация PHP

Компрессионные фильтры

В то время, как Компрессионные обвёртки обеспечивают способ создания gzip- и bz2-совместимых файлов в локальной файловой системе, они не предоставляют общих средств средств для компрессии в сетевых потоках, как не предоставляют и средств для создания потока без компрессии с последующим превращением в компрессируемый. Для этих целей к любым потоковым ресурсам в любое время могут применяться компрессионные фильтры.

Замечание: Компрессионные фильтры не генерируют заголовков и окончаний, которые используют утилиты командной строки, такие как gzip. Они просто компрессируют (сжимают) и декомпрессируют (разжимают) порции данных в компрессируемом потоке данных.

zlib.deflate (компрессия) и zlib.inflate (декомпрессия) являются реализациями компрессионных методов, описаных в » RFC 1951. Фильтр deflate принимает три аргумента, переданных в виде ассоциативного массива. level определяет, какой уровень компрессии использовать (1-9). Повышение этого значения приведёт к уменьшению объёмов данных за счёт увеличения времени обработки. Существуют так же два специальных уровня компрессии: 0 (для отключения компрессии) и -1 (внутреннее значение по умолчанию библиотеки zlib — на текущий момент равно 6). window — это логарифм размера окна диапазона сжатия, где база логарифма составляет 2. Высокие значения (вплоть до 15 — 32768 байт) приводят к улучшению компрессии за счёт роста необходимой памяти, в то время как низкие значения (вплоть дл 9 — 512 байт) приводят к ухудшению компрессии за счёт уменьшения необходимой памяти. Значением аргумента window по умолчанию на текущий момент является 15. memory определяет масштаб резервируемой памяти. Допустимые значения находятся в диапазоне от 1 (минимальное резервирование) до 9 (максимальное резервирование). Такое резервирование памяти влияет только на скорость и не влияет на размер генерируемых данных..

Замечание: Так как уровень компрессии является наиболее часто используемым аргументом, вы можете передать только его в качестве обычного целого числа (integer), вместо того чтобы передавать массив из одного элемента.

Компрессионные фильтры zlib.* доступны с версии PHP 5.1.0, если включена поддержка zlib. Они так же доступны в качестве обратного порта для версий 5.0.x путём установки пакета » zlib_filter из » PECL. Эти фильтры не доступны в PHP 4.

Пример #1 zlib.deflate и zlib.inflate

= array( ‘level’ => 6 , ‘window’ => 15 , ‘memory’ => 9 );

$original_text = «This is a test.\nThis is only a test.\nThis is not an important string.\n» ;
echo «The original text is » . strlen ( $original_text ) . » characters long.\n» ;

$fp = fopen ( ‘test.deflated’ , ‘w’ );
stream_filter_append ( $fp , ‘zlib.deflate’ , STREAM_FILTER_WRITE , $params );
fwrite ( $fp , $original_text );
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘test.deflated’ ) . » bytes long.\n» ;
echo «The original text was:\n» ;
/* Use readfile and zlib.inflate to decompress on the fly */
readfile ( ‘php://filter/zlib.inflate/resource=test.deflated’ );

The original text is 70 characters long.
The compressed file is 56 bytes long.
The original text was:
This is a test.
This is only a test.
This is not an important string.

Пример #2 Упрощённое использование zlib.deflate

= «This is a test.\nThis is only a test.\nThis is not an important string.\n» ;
echo «The original text is » . strlen ( $original_text ) . » characters long.\n» ;

$fp = fopen ( ‘test.deflated’ , ‘w’ );
/* Here «6» indicates compression level 6 */
stream_filter_append ( $fp , ‘zlib.deflate’ , STREAM_FILTER_WRITE , 6 );
fwrite ( $fp , $original_text );
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘test.deflated’ ) . » bytes long.\n» ;

The original text is 70 characters long.
The compressed file is 56 bytes long.

bzip2.compress и bzip2.decompress работают точно так же, как и фильтры zlib, онисанные выше. Фильтр bzip2.compress принимает два аргумента в виде элементов ассоциативного массива: blocks является целочисленным (integer) значением в диапазоне от 1 до 9 и указывает на количество 100-килобайтовых блоков памяти для резервирования в качестве рабочего пространства. work — это так же целочисленное (integer) значение в диапазоне от 0 до 250, определяющее сколько усилий нужно потратить на обычный метод компрессии перед переключением на медленный, но более надёжный метод. Изменение этого параметра влияет только на скорость компрессии. Ни размер сжатого результата, ни используемый объём памяти не изменяются при помощи этой настройки. Значение 0 указывает библиотеке bzip использовать собственное внутреннее значение по умолчанию. Фильтр bzip2.decompress принимает всего один аргумент, который может быть передан либо как обычное boolean-значение, либо как элемент small ассоциативного массива. Когда small установлен в TRUE, библиотека bzip совершит декомпрессию с минимальным расходом памяти за счёт понижения скорости.

Компрессионные фильтры bzip2.* доступны с версии PHP 5.1.0, если включена поддержка bz2. Они так же доступны в качестве обратного порта для версий 5.0.x путём установки пакета » bz2_filter из » PECL. Эти фильтры не доступны в PHP 4.

Пример #3 bzip2.compress и bzip2.decompress

= array( ‘blocks’ => 9 , ‘work’ => 0 );

echo «The original file is » . filesize ( ‘LICENSE’ ) . » bytes long.\n» ;

$fp = fopen ( ‘LICENSE.compressed’ , ‘w’ );
stream_filter_append ( $fp , ‘bzip2.compress’ , STREAM_FILTER_WRITE , $param );
fwrite ( $fp , file_get_contents ( ‘LICENSE’ ));
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘LICENSE.compressed’ ) . » bytes long.\n» ;

The original text is 3288 characters long.
The compressed file is 1488 bytes long.


Zlib-совместимые потоки сжатия?

Являются ли System.IO.Compression.GZipStream или System.IO.Compression.Deflate совместимыми с сжатием zlib?

Из MSDN о System.IO.Compression.GZipStream:

Этот класс представляет формат данных gzip, который использует стандартный алгоритм для сжатия и декомпрессии без потерь.

Функции gz * в zlib, с другой стороны, используют формат gzip.

Итак, zlib и GZipStream должны взаимодействовать, но только если вы используете функции zlib для обработки формата gzip.

System.IO.Compression.Deflate и zlib, как сообщается, не совместимы.

Если вам нужно обрабатывать zip файлы (вероятно, нет, но кому-то это может понадобиться), вам нужно использовать SharpZipLib или другую стороннюю библиотеку.

DotNetZip включает в себя DeflateStream, ZlibStream и GZipStream для обработки RFC 1950, 1951 и 1952. Все используют Алгоритм DEFLATE, но байты кадрирования и заголовка различны для каждого из них.

В качестве преимущества потоки в DotNetZip не отображают анонимность расширения размера данных

Я столкнулся с этой проблемой с объектами Git. В этом конкретном случае они хранят объекты как дефлированные капли с заголовком Zlib, который задокументирован в RFC 1950. Вы можете сделать совместимый blob, создав файл, который содержит:

  • Два байта заголовка (CMF и FLG из RFC 1950) со значениями 0x78 0x01
    • CM = 8 = deflate
    • CINFO = 7 = 32Kb окно
    • FCHECK = 1 = контрольные суммы для этого заголовка
  • Выход С# DeflateStream
  • Контрольная сумма Adler32 входных данных в формат DeflateStream , в формате big-endian (сначала MSB)

Я сделал свою собственную реализацию Adler

И это было в значительной степени.

Я использовал GZipStream для сжатия вывода из .NET XmlSerializer, и он отлично справился с распаковкой результата с помощью gunzip (в cygwin), winzip и другого GZipStream.

Для справки, вот что я сделал в коде:

Затем, чтобы распаковать в С#

Илон Маск рекомендует:  Что такое код gmp_sub

Использование утилиты «file» в cygwin показывает, что действительно существует разница между тем же файлом, сжатым с помощью GZipStream, и с GNU GZip (вероятно, информация заголовка, как указано другими в этом потоке). Однако это различие, по-видимому, практически не имеет значения.

Функции сжатия Zlib

Этот модуль позволяет работать со сжатыми файлами gzip (.gz) стандартным методом, наподобие функций файловой системы (исключение составляют только сокеты).

Замечание: В версии 4.0.4 появился новый протокол ‘zlib:’ для доступа прямого к сжатым файлам через обычные функции f*() (для этого нужно было добавить ‘zlib:’ в начало пути к файлу при вызове fopen() .

В версии 4.3.0, префикс изменился на ‘zlib://’ для предотвращения многозначности в случае файлов, содержащих ‘:’ в имени.

Требуется библиотека времени выполнения C, предоставляющая функцию fopencookie() . Насколько нам известно, такой библиотекой является только GNU libc.


Поддержка Zlib при стандартной сборке PHP отсутствует. Чтобы изменить это, добавьте ключ —with-zlib[=DIR] при запуске сценария ./configure

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

Замечание: Т.к. библиотека zlib отсутствует в Windows, она встроена в PHP начиная с версии 4.3.0.

Поведение этих функций зависит от установок в php.ini .

Модуль zlib предоставляет возможность сжатия передаваемых страниц (в т.ч. динамических) на лету, если браузер это поддерживает. За сжатие отвечают три параметра в конфигурационном файле php.ini .

Таблица 1. Конфигурационные параметры, касающиеся Zlib

Параметр Значение по умолчанию Переменная окружения
zlib.output_compression «Off» PHP_INI_ALL
zlib.output_compression_level «-1» PHP_INI_ALL
zlib.output_handler «» PHP_INI_ALL

Краткое разъяснение конфигурационных директив.

Сжимать ли страницы. Если значение равно «On» в php.ini или в настройках Apache, страницы будут сжиматься если обозреватель посылает заголовок «Accept-Encoding: gzip» или «deflate». при этом в вывод будут добавлены заголовки «Content-Encoding: gzip» (соответственно «deflate») и «Vary: Accept-Encoding».

Аргументы также могут быть целого типа, так вы можете установить размер буфера (дискретизации) вывода (по умолчанию 4 Кб).

Если zlib.output_compression активировано здесь, указывать дополнительные обработчики вывода (output handlers) нельзя. Этот параметр делает то же, что и output_handler , но в другом порядке.

Данное расширение не определяет никакие типы ресурсов.

Перечисленные ниже константы определены данным расширением и могут быть доступны только в том случае, если PHP был собран с поддержкой этого расширения или же в том случае, если данное расширение подгружается во время выполнения.

Здесь открывается временный файл, в него записывается строка, затем дважды печатается содержимое этого файла.

Пример 1. Небольшой пример использования Zlib

Функции zlib компрессии

В то время, как Компрессионные обёртки обеспечивают способ создания gzip- и bz2-совместимых файлов в локальной файловой системе, они не предоставляют общих средств для компрессии в сетевых потоках, как и не предоставляют средств для создания потока без компрессии с последующим превращением в компрессируемый. Для этих целей к любым потоковым ресурсам в любое время могут применяться компрессионные фильтры.

Замечание: Компрессионные фильтры не генерируют заголовков и окончаний, которые используют утилиты командной строки, такие как gzip. Они просто компрессируют (сжимают) и декомпрессируют (разжимают) порции данных в компрессируемом потоке данных.

zlib.deflate (компрессия) и zlib.inflate (декомпрессия) являются реализациями компрессионных методов, описаных в » RFC 1951. Фильтр deflate принимает три аргумента, переданных в виде ассоциативного массива. level определяет, какой уровень компрессии использовать (1-9). Повышение этого значения приведёт к уменьшению объёмов данных за счёт увеличения времени обработки. Существуют так же два специальных уровня компрессии: 0 (для отключения компрессии) и -1 (внутреннее значение по умолчанию библиотеки zlib — на текущий момент равно 6). window — это логарифм с основанием 2 от размера окна диапазона сжатия. Высокие значения (вплоть до 15 — 32768 байт) приводят к улучшению компрессии за счёт роста необходимой памяти, в то время как низкие значения (вплоть до 9 — 512 байт) приводят к ухудшению компрессии за счёт уменьшения необходимой памяти. Значением аргумента window по умолчанию на текущий момент является 15. memory определяет масштаб резервируемой памяти. Допустимые значения находятся в диапазоне от 1 (минимальное резервирование) до 9 (максимальное резервирование). Такое резервирование памяти влияет только на скорость и не влияет на размер генерируемых данных..

Замечание: Так как уровень компрессии является наиболее часто используемым аргументом, вы можете передать только его в качестве обычного целого числа (integer), вместо того чтобы передавать массив из одного элемента.

Компрессионные фильтры zlib.* доступны с версии PHP 5.1.0, если включена поддержка zlib. Они так же доступны в качестве обратного порта для версий 5.0.x путём установки пакета » zlib_filter из » PECL. Эти фильтры не доступны в PHP 4.

Пример #1 zlib.deflate и zlib.inflate

= array( ‘level’ => 6 , ‘window’ => 15 , ‘memory’ => 9 );

$original_text = «This is a test.\nThis is only a test.\nThis is not an important string.\n» ;
echo «The original text is » . strlen ( $original_text ) . » characters long.\n» ;

$fp = fopen ( ‘test.deflated’ , ‘w’ );
stream_filter_append ( $fp , ‘zlib.deflate’ , STREAM_FILTER_WRITE , $params );
fwrite ( $fp , $original_text );
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘test.deflated’ ) . » bytes long.\n» ;
echo «The original text was:\n» ;
/* Use readfile and zlib.inflate to decompress on the fly */
readfile ( ‘php://filter/zlib.inflate/resource=test.deflated’ );

The original text is 70 characters long.
The compressed file is 56 bytes long.
The original text was:
This is a test.
This is only a test.
This is not an important string.


Пример #2 Упрощённое использование zlib.deflate

= «This is a test.\nThis is only a test.\nThis is not an important string.\n» ;
echo «The original text is » . strlen ( $original_text ) . » characters long.\n» ;

$fp = fopen ( ‘test.deflated’ , ‘w’ );
/* Here «6» indicates compression level 6 */
stream_filter_append ( $fp , ‘zlib.deflate’ , STREAM_FILTER_WRITE , 6 );
fwrite ( $fp , $original_text );
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘test.deflated’ ) . » bytes long.\n» ;

The original text is 70 characters long.
The compressed file is 56 bytes long.

bzip2.compress и bzip2.decompress работают точно так же, как и фильтры zlib, описанные выше. Фильтр bzip2.compress принимает два аргумента в виде элементов ассоциативного массива: blocks является целочисленным (integer) значением в диапазоне от 1 до 9 и указывает на количество 100-килобайтовых блоков памяти для резервирования в качестве рабочего пространства. work — это так же целочисленное (integer) значение в диапазоне от 0 до 250, определяющее сколько усилий нужно потратить на обычный метод компрессии перед переключением на медленный, но более надёжный метод. Изменение этого параметра влияет только на скорость компрессии. Ни размер сжатого результата, ни используемый объём памяти не изменяются при помощи этой настройки. Значение 0 указывает библиотеке bzip использовать собственное внутреннее значение по умолчанию. Фильтр bzip2.decompress принимает всего один аргумент, который может быть передан либо как обычное boolean-значение, либо как элемент small ассоциативного массива. Когда small установлен в TRUE, библиотека bzip совершит декомпрессию с минимальным расходом памяти за счёт понижения скорости.

Компрессионные фильтры bzip2.* доступны с версии PHP 5.1.0, если включена поддержка bz2. Они так же доступны в качестве обратного порта для версий 5.0.x путём установки пакета » bz2_filter из » PECL. Эти фильтры не доступны в PHP 4.

Пример #3 bzip2.compress и bzip2.decompress

= array( ‘blocks’ => 9 , ‘work’ => 0 );

echo «The original file is » . filesize ( ‘LICENSE’ ) . » bytes long.\n» ;

$fp = fopen ( ‘LICENSE.compressed’ , ‘w’ );
stream_filter_append ( $fp , ‘bzip2.compress’ , STREAM_FILTER_WRITE , $param );
fwrite ( $fp , file_get_contents ( ‘LICENSE’ ));
fclose ( $fp );

echo «The compressed file is » . filesize ( ‘LICENSE.compressed’ ) . » bytes long.\n» ;

The original text is 3288 characters long.
The compressed file is 1488 bytes long.

CXLI. Функции сжатия Zlib

Этот модуль позволяет работать со сжатыми файлами gzip (.gz) стандартным методом, наподобие функций файловой системы (исключение составляют только сокеты).

Замечание: В версии 4.0.4 появился новый протокол ‘zlib:’ для доступа прямого к сжатым файлам через обычные функции f*() (для этого нужно было добавить ‘zlib:’ в начало пути к файлу при вызове fopen() .

В версии 4.3.0, префикс изменился на ‘zlib://’ для предотвращения многозначности в случае файлов, содержащих ‘:’ в имени.

Требуется библиотека времени выполнения C, предоставляющая функцию fopencookie() . Насколько нам известно, такой библиотекой является только GNU libc.

Поддержка Zlib при стандартной сборке PHP отсутствует. Чтобы изменить это, добавьте ключ —with-zlib[=DIR] при запуске сценария ./configure

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

Замечание: Т.к. библиотека zlib отсутствует в Windows, она встроена в PHP начиная с версии 4.3.0.

Поведение этих функций зависит от установок в php.ini .

Модуль zlib предоставляет возможность сжатия передаваемых страниц (в т.ч. динамических) на лету, если браузер это поддерживает. За сжатие отвечают три параметра в конфигурационном файле php.ini .

Таблица 1. Конфигурационные параметры, касающиеся Zlib

Параметр Значение по умолчанию Переменная окружения
zlib.output_compression «Off» PHP_INI_ALL
zlib.output_compression_level «-1» PHP_INI_ALL
zlib.output_handler «» PHP_INI_ALL

Краткое разъяснение конфигурационных директив.

Сжимать ли страницы. Если значение равно «On» в php.ini или в настройках Apache, страницы будут сжиматься если обозреватель посылает заголовок «Accept-Encoding: gzip» или «deflate». при этом в вывод будут добавлены заголовки «Content-Encoding: gzip» (соответственно «deflate») и «Vary: Accept-Encoding».

Аргументы также могут быть целого типа, так вы можете установить размер буфера (дискретизации) вывода (по умолчанию 4 Кб).


Если zlib.output_compression активировано здесь, указывать дополнительные обработчики вывода (output handlers) нельзя. Этот параметр делает то же, что и output_handler , но в другом порядке.

Данное расширение не определяет никакие типы ресурсов.

Перечисленные ниже константы определены данным расширением и могут быть доступны только в том случае, если PHP был собран с поддержкой этого расширения или же в том случае, если данное расширение подгружается во время выполнения.

Здесь открывается временный файл, в него записывается строка, затем дважды печатается содержимое этого файла.

Пример 1. Небольшой пример использования Zlib

zlib метод\уровень сжатия

19.09.2013, 10:09

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

Метод сжатия Хаффмана
Есть Метод сжатия Хаффмана или нет и как его использовать ? покажите если можите ? ну те кто уже.

Метод сжатия Хаффмана
Ктонибуть ответит по существу по теме ?

ZLib
Хай. Вобщем проблема такая: Нужно реализовать прогу архивации/разархивации, из нескольких либ.

19.09.2013, 10:10 [ТС] 2 Вложения
zlibs.rar (22.5 Кб, 33 просмотров)
19.09.2013, 13:54 [ТС] 3 19.09.2013, 14:05 4
19.09.2013, 14:05
19.09.2013, 18:43 [ТС] 5
19.09.2013, 18:48 6
19.09.2013, 18:50 [ТС] 7
19.09.2013, 18:51 8
19.09.2013, 18:52 [ТС] 9
19.09.2013, 18:53 10
19.09.2013, 18:57 [ТС] 11
19.09.2013, 19:01 12
19.09.2013, 19:13 [ТС] 13

1)уровень компрессии
#define Z_NO_COMPRESSION 0
#define Z_BEST_SPEED 1
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)

2)стратегия компрессии
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0


3)тип сжимаемых данных
#define Z_BINARY 0
#define Z_TEXT 1
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2

Нужно узнать как это менять, все 3
И если можно — смысл этого в частности стратегии

>>
Зачем нужны дублирующие функции — каково их предназначение ?

19.09.2013, 19:35 14
19.09.2013, 19:38 [ТС] 15
19.09.2013, 19:51 16

Здесь все ответы и примеры: ZLib Usage Example

Добавлено через 8 минут
Вдогонку: вы бы озвучили ваши цели.

На ZLib свет клином не сошелся — довольно пухлая и весьма древняя библиотека со скромным, по нынешним временам, сжатием. Плохо совместима со своими же старыми версиями ( IMHO, формат ZIP держится «на плаву» только по инерции (ни сильного сжатия, ни коррекции ошибок).

Записки программиста

Примеры сжатия данных в C/C++ при помощи zlib

Продолжая серию постов о полезных библиотеках в мире C/C++, стоило бы упомянуть хотя бы одну библиотеку для сжатия данных. Библиотек таких великое множество. Среди них, пожалуй, наиболее распространенной, своего рода стандартом де-факто, является zlib. Поэтому о ней далее речь и пойдет.

Пользуясь случаем, напомню, что в предыдущих сериях вы видели:

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

uLongf compress_buff_size = compressBound ( file_size ) ;
void * compress_buff = malloc ( compress_buff_size ) ;
if ( compress_buff == NULL )
<
fprintf ( stderr ,
«malloc(compress_buff_size) failed, »
«compress_buff_size = %lu \n » ,
compress_buff_size ) ;
exit ( 1 ) ;
>

uLongf compressed_size = compress_buff_size ;
res = compress ( compress_buff, & compressed_size, file_buff, file_size ) ;
if ( res ! = Z_OK )
<
fprintf ( stderr , «compress(. ) failed, res = %d \n » , res ) ;
exit ( 1 ) ;
>

Процедура compressBound возвращает максимальный размер, какого могут оказаться данные в сжатом виде, а compress непосредственно производит сжатие. В результате в compress_buff будут записаны данные в сжатом виде, а в compressed_size — их размер.

Разжатие производится по аналогии:

Компрессия и декомпрессия больших объемов данных производится чуть сложнее, но ненамного:

/* Компрессия */
bool compress_file ( FILE * src, FILE * dst )
<
uint8_t inbuff [ CHUNK_SIZE ] ;
uint8_t outbuff [ CHUNK_SIZE ] ;
z_stream stream = < 0 >;

int flush ;
do <
stream. avail_in = fread ( inbuff, 1 , CHUNK_SIZE, src ) ;
if ( ferror ( src ) )
<
fprintf ( stderr , «fread(. ) failed! \n » ) ;
deflateEnd ( & stream ) ;
return false ;
>

flush = feof ( src ) ? Z_FINISH : Z_NO_FLUSH ;
stream. next_in = inbuff ;

do <
stream. avail_out = CHUNK_SIZE ;
stream. next_out = outbuff ;
deflate ( & stream, flush ) ;
uint32_t nbytes = CHUNK_SIZE — stream. avail_out ;

if ( fwrite ( outbuff, 1 , nbytes, dst ) ! = nbytes ||
ferror ( dst ) )
<
fprintf ( stderr , «fwrite(. ) failed! \n » ) ;
deflateEnd ( & stream ) ;
return false ;
>
> while ( stream. avail_out == 0 ) ;
> while ( flush ! = Z_FINISH ) ;

/* Декомпрессия */
bool decompress_file ( FILE * src, FILE * dst )
<
uint8_t inbuff [ CHUNK_SIZE ] ;
uint8_t outbuff [ CHUNK_SIZE ] ;
z_stream stream = < 0 >;

int result = inflateInit ( & stream ) ;
if ( result ! = Z_OK )
<
fprintf ( stderr , «inflateInit(. ) failed! \n » ) ;
return false ;
>

do <
stream. avail_in = fread ( inbuff, 1 , CHUNK_SIZE, src ) ;
if ( ferror ( src ) )
<
fprintf ( stderr , «fread(. ) failed! \n » ) ;
inflateEnd ( & stream ) ;
return false ;
>

if ( stream. avail_in == 0 )
break ;


stream. next_in = inbuff ;

do <
stream. avail_out = CHUNK_SIZE ;
stream. next_out = outbuff ;
result = inflate ( & stream, Z_NO_FLUSH ) ;
if ( result == Z_NEED_DICT || result == Z_DATA_ERROR ||
result == Z_MEM_ERROR )
<
fprintf ( stderr , «inflate(. ) failed: %d \n » , result ) ;
inflateEnd ( & stream ) ;
return false ;
>

uint32_t nbytes = CHUNK_SIZE — stream. avail_out ;

if ( fwrite ( outbuff, 1 , nbytes, dst ) ! = nbytes ||
ferror ( dst ) )
<
fprintf ( stderr , «fwrite(. ) failed! \n » ) ;
inflateEnd ( & stream ) ;
return false ;
>
> while ( stream. avail_out == 0 ) ;
> while ( result ! = Z_STREAM_END ) ;

inflateEnd ( & stream ) ;
return result == Z_STREAM_END ;
>

Долго и нудно разжевывать этот код мне что-то лень. Думаю, вы в состоянии самостоятельно в нем разобраться. В крайнем случае всегда можно почитать /usr/include/zlib.h — в нем есть подробные комментарии ко всем процедурам.

Полная версия исходников к этому посту лежит на GitHub. Для сборки проекта я использовал Autotools. Не помню, зачем мне нужен был именно Autotools, так как код писался давно. В README.md есть инструкция по сборке, плюс обратите внимание на пост Основы сборки проектов при помощи Autotools.

Как обычно, буду рад вашим вопросам и дополнениям.

Новый алгоритм Zopfli улучшает сжатие zlib на 3-8%

Один из сотрудников Google в свободное время разработал новый алгоритм сжатия Zopfli, который на 3,7-8,3% эффективнее, чем стандартная библиотека zlib на максимальном уровне сжатия. Изначально алгоритм создавался для формата сжатия без потерь WebP, но его можно применять и для другого контента.

Новый алгоритм является реализацией стандартных алгоритмов Deflate, поэтому он совместим с zlib и gzip, а разархивирование данных уже поддерживается всеми браузерами. Достаточно подключить Zopfli на сервере. Например, его можно использовать с веб-сервером Nginx без изменений в модуле gzip, просто указав новый «прекомпрессор».

Правда, сжатие с помощью Zopfli требует примерно в 100 раз больше ресурсов, чем gzip, зато декомпрессия в браузере осуществляется с той же скоростью.

В статье (pdf) автор объясняет, за счёт каких оптимизаций удалось достигнуть повышения уровня сжатия. Как известно, Deflate использует комбинацию алгоритма Хаффмана и алгоритма LZ77. Первый кодирует символы сообщения кодами переменной длины, в зависимости от частоты встречаемости этих символов. Второй работает по принципу «скользящего окна», когда второе и последующие вхождения некоторой строки символов в сообщении заменяются ссылками на её первое вхождение. Существующие реализации Deflate применяют различные эвристики для поиска подходящих вхождений и оптимизации анализа данных перед кодированием, чтобы понять, какой метод лучше применять в каждом случае, с построением хеш-таблицы. Уровень сжатия (от -1 до -9) определяет количество времени и ресурсов, которое выделяется для использования эвристик, обычно путём изменения размеров строк для поиска в хеш-таблице.

Как сказано в статье автора, Zopfli использует более ресурсоёмкие техники сжатия, основанные на моделировании энтропии и алгоритме поиска кратчайшего пути в графе всех возможных представлений Deflate.

Zopfli позволяет указывать уровни сжатия от 5 до 2000. В статье (pdf) приводится сравнение уровня сжатия в разных тестах.

На реальных файлах, например, несжатом jQuery, сравнение архиваторов выглядит примерно так:

Правда, по времени Zopfli проигрывает всем, он работает примерно в 81 раз медленнее самого быстрого алгоритма gzip-9. Опять же нужно подчеркнуть, что декомпрессия в браузере осуществляется с такой же скоростью.

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 , так что Deflate «окончательный блок» бит не установлен. Я предполагаю , что это происходит потому , что интерфейс поток никогда не знает , когда конец входных данных будет, поэтому никогда не устанавливает этот бит?

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


. что это подпись синхронизации или полного смыва.

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

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

Должен ли я быть в состоянии использовать функцию ZLIB «распаковывать» распаковывать данные, которые были сжаты с помощью метода z_stream?

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

Zlib-совместимые потоки сжатия?

Являются ли System.IO.Compression.GZipStream или System.IO.Compression.Deflate совместимыми с сжатием zlib?

Из MSDN о System.IO.Compression.GZipStream:

Этот класс представляет формат данных gzip, который использует стандартный алгоритм для сжатия и декомпрессии без потерь.

Функции gz * в zlib, с другой стороны, используют формат gzip.

Итак, zlib и GZipStream должны взаимодействовать, но только если вы используете функции zlib для обработки формата gzip.

System.IO.Compression.Deflate и zlib, как сообщается, не совместимы.

Если вам нужно обрабатывать zip файлы (вероятно, нет, но кому-то это может понадобиться), вам нужно использовать SharpZipLib или другую стороннюю библиотеку.

DotNetZip включает в себя DeflateStream, ZlibStream и GZipStream для обработки RFC 1950, 1951 и 1952. Все используют Алгоритм DEFLATE, но байты кадрирования и заголовка различны для каждого из них.

В качестве преимущества потоки в DotNetZip не отображают анонимность расширения размера данных

Я столкнулся с этой проблемой с объектами Git. В этом конкретном случае они хранят объекты как дефлированные капли с заголовком Zlib, который задокументирован в RFC 1950. Вы можете сделать совместимый blob, создав файл, который содержит:

  • Два байта заголовка (CMF и FLG из RFC 1950) со значениями 0x78 0x01
    • CM = 8 = deflate
    • CINFO = 7 = 32Kb окно
    • FCHECK = 1 = контрольные суммы для этого заголовка
  • Выход С# DeflateStream
  • Контрольная сумма Adler32 входных данных в формат DeflateStream , в формате big-endian (сначала MSB)

Я сделал свою собственную реализацию Adler

И это было в значительной степени.

Я использовал GZipStream для сжатия вывода из .NET XmlSerializer, и он отлично справился с распаковкой результата с помощью gunzip (в cygwin), winzip и другого GZipStream.

Для справки, вот что я сделал в коде:

Затем, чтобы распаковать в С#

Использование утилиты «file» в cygwin показывает, что действительно существует разница между тем же файлом, сжатым с помощью GZipStream, и с GNU GZip (вероятно, информация заголовка, как указано другими в этом потоке). Однако это различие, по-видимому, практически не имеет значения.

Илон Маск рекомендует:  Iis настройка расширенного формата журнала w3c
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL