Мы — долго запрягаем, быстро ездим, и сильно тормозим.
|
||||||||||||||||||||
www.lissyara.su
—> документация
|
|
представляет собой один байт; а прямоугольник типа :
|
представляет собой переменное число байт.
Байты хранимые на компьютере не имеют "порядка бит" ("bit order"),
так как они всегда рассматриваются как единое целое (как единица
хранения информации). Однако, байт рассматриваемый как целое от 0
до 255 имеет наиболее значимый и наименее значащие биты, и так как
мы пишем наиболее значимую цифру слева, то мы также будем писать
байты с наиболее значимым битом слева. В нижеприведенных диаграммах,
мы нумеруем биты в байтах так что бит 0 является наименее значимым
битом, т.е., биты нумеруются следующим образом:
|
В компьютере, числа могут занималь несколько байт. Все много-байтовые
номера в формате описываемом здесь хранятся с наименее значимым байтом
первым (с меньшим адресом). Например, десятичное число 520 хранится как:
|
3.1.1. Packing into bytes (Упаковка в байты)
Данный документ не касается вопроса в каком порядке биты байта
передаются в среду хранения битов, так как конечный описываемый здесь
формат является байтовым а не бит ориентированным.
Однако, ниже мы описываем формат сжатого блока, как последовательность
элементов данных различной битовой длины, а не как последовательность
байтов. Поэтому мы должны определить, как упаковать эти элементы данных
в байты, чтобы сформировать финальную последовательность сжатых байт:
* элементы данных упакованы в байты в порядке увеличения номера
  бита в пределах байта, то есть начиная с наименее значимого
  бита байта.
* элементы данных, отличные от кодов Huffman-а упакованы,
  начиная с наименее значимого бита элемента данных.
* Huffman коды упакованы, начиная с наиболее значимого бита кода.
Другими словами, если распечатать сжатые данные как последовательность
байтов, начиная с первого байта с *правой* границы и продвигаясь к
*левой*, с наиболее-значимым битом каждого байта, расположенным слева
как обычно, можно было бы разобрать результат с права на лево на
элементы фиксированной-ширины в правильном порядке MSB-TO-LSB бит
и на коды Huffman с реверсивным порядком бит (то есть, первый бит
кода в LSB позиции).
3.2. Формат сжатого блока
3.2.1. Synopsis of prefix and Huffman coding
Прекфиксное кодирование представляет символы из априорно известного
алфавита битовыми последовательностями (кодами), один код на каждый
символ, в такой манере, что различные символы могут быть представлены
битовыми последовательностями различной длины, но программа разбора
может всегда разобрать кодированные строки однгозначно символ за
символом.
Мы определям префиксный код в терминах бинарного дерева в котором
два ребра исходящие из не листового узла помечаются как 0 и как 1,
а листовые узлы однозначно соответствуют символам алфавита; при этом
код для символа представляет собой последовательность 0-ей и 1-ек,
которыми помечены ребра, ведущие от корня к листу дерева, помеченному
символом алфавита. Например:
|
Программа разбора может декодировать следующий символ из кодированного
входного потока, спускаясь вниз по дереву от корня, на каждом шаге
выбирая ребро соответсвующее следующему входному биту.
При заданном алфавите с известной частотой символов, алгоритм
Huffman-а позволяет конструировать оптимальные префикстные коды.
(представляя строки как частоты символов и используя наименьшее
количество бит из всех префиксных кодов для данного алфавита).
Такой код называется кодом Huffman-а. (см. ссылку [1] в главе 5,
для дополнительной информации относительно кодов Huffman-а.)
Отметим что для формата "deflate", коды Huffman-а для различных
алгоритмов не должны превышать определенную максимальную длину.
Данное ограниченние затрудняет алгоритм вычисления длины кодов
из частоты появления. Детальное описание приведено в разделе 5.
3.2.2. Use of Huffman coding in the "deflate" format
В формате "deflate" коды Huffman-а, используемые для каждого алфавита
имеют два дополнительных правила:
* Все коды заданной битовой длины имеют лексикографически
последовательные значения, в том же самом порядке, как и символы
которые они представляют;
* Более короткие коды лексиграфичеси предшествуют более длинным
  кодам.
Cледуя этим правилам мы должны записать выше приведенный пример
следующим образом, предполагая что порядок алфавита ABCD:
|
Т.е., 0 предшествует 10, которое предшествует 11x, а 110 и 111
лексиграфически следуют друг за другом.
Следуя данному правилу, мы можем определить коды Huffman-а для
алфавита задавая только длины кодов для каждого символа алфавита;
этого достаточно для определения фактических кодов. В нашем примере,
коды полностью определены последовательностью длин кодов (2, 1, 3, 3).
Ниже приведен алгоритм, который генерирует коды. Длины кодов
первоначально расположены в tree[I].Len; генерируемые коды
располагаются в tree[I].Code.
1) Подсчитываем колво кодов для каждой битовой длины кода.
    bl_count [N] - число кодов длины N, N >= 1.
2) Ищется числовое значения наименьшего кода для каждой кодовой
длины:
|
3) Назначаются числовые значения для всех кодов, используя
последовательные значения для всех кодов одной и тойже длины,
с базовыми значениями, определенными на шаге 2. Кодам, которые н
никогда не используются (которые имеют битовую длину равную ноль)
значение не назначается.
|
Пример:
Рассмотрим алфавит ABCDEFGH, с битовыми длинами (3, 3, 3, 3,
3, 2, 4, 4). После шага 1, мы имеем:
|
Шаг номер 2. расчитанные значения для next_code дают:
|
Шаг номер 3. генерирует следующие значения для кодов:
|
3.2.3. Детали формата блока
Каждый блок сжатых данных начинается с 3 битового заголовка, содержащего
следующие данные:
|
Отметим что биты заголовка не обязательно начинаются на границе байта,
так как блок не обязательно занимает целое число байтов.
BFINAL установливается только для последнего блока данных.
BTYPE определяет, как данные сжаты, следующим образом:
00 - нет компрессии
01 - сжат используя фиксированные коды Huffman-а
10 - сжат используя динамические коды Huffman-a
11 - зарезервировано (ошибка)
Единственная разница между двумя случаями компрессии состоит в том как определяются коды Huffman-а алфавита символ/длина и алфавита расстояние.
Во всех случаях, алгоритм декодирования данных следующий:
|
  Отметим, что ссылка на дубликат строки может обращатся к предыдущему блоку,
то есть, обратное расстояние может пересекать одну или более границ блока.
Однако расстояние не может обращаться к данным расположенным перед началом
выходного потока.
(Приложения использующие предустановленный словарь могут отбрасывать
часть выходного потока; расстояние может указывать на такие части выходного
потока в любом случае) Отметим также что строка ссылка может перекрывать
текущую позицию; например, если последние 2 байта декодрованы как X и Y,
а строка ссылка как <длина = 5, расстояние = 2> то данная ссылка
дает в выходной поток X,Y,X,Y,X.
  Теперь определим каждый метод сжатия.
3.2.4. Не-сжатые блоки (BTYPE=00)
Любые биты ввода до следующей границы байта игнорируются.
Остальная часть блока содержит следующую информацию:
|
LEN количество байт данных в блоке. NLEN дополнение LEN до единиц.
3.2.5. Сжатые блоки (коды для длины и расстояния)
Как отмечалось выше, кодируемые блоки данных формате "deflate"
состоят из последовательностей символов, из трех концептуально
различных алфавитов: либо литеральные байты из алфавита значений
байта (0.. 255), либо пара <длина, обратное расстояние>, где длина
находится в диапазоне до 258 а расстояние от 1 до 32,768. Фактически,
литеральный алфавит и алфавиты длины слиты в единый алфавит (0.. 285),
где значения 0.. 255 представляют литеральные байты, значение 256
указывает конец-блока, а значения 257.. 285 представляют коды длины
(возможно вместе с дополнительными битами после кода символа)
следующим образом:
|
Дополнительные биты (extra bits) должны интерпретироваться как машинные
целые, хранимые с наиболее значимым битом первым, т.е., биты 1110
представляют значение 14.
|
3.2.6. Компрессия с фиксированными кодами Huffman (BTYPE=01)
Коды Huffman для этих двух алфавитов предустановлены, и не
представлены явно в данных. Длины кода Huffman для алфавита
литерала/длины:
|
Как было описано выше, длины кода достаточно для генерации
фактических кодов; коды приведены в таблице для дополнительной ясности.
Значения 286-287 литерального символа/длины фактически не никогда не
появятся в сжатых данных.
Коды расстояния 0-31, представляются (фиксированной-длиной) 5 битами,
с возможными дополнительными битами как показано в таблице, в
параграфе 3.2.5, выше. Обратите внимание, что расстояния кодированные
значениями 30-31, никогда не будут встречаться в сжатых данных.
3.2.7. Сжатие с динамическими кодами Huffman (BTYPE=10)
Коды Huffman-а для этих двух алфавитов появляются в блоке
непосредственно после битов заголовка и перед сжатыми данными,
причем сначала идет код литерала/длины а затем код расстояния.
Каждый код определен последовательностью длин кода, как описано
выше в параграфе 3.2.2. Для большей компактности, коды длины сжаты,
используя код Huffman. Алфавит для длин следующий:
|
Длина кода 0 указывает, что соответствующий символ в алфавите
литерала/длина или в алфавите расстояния не встречается в блоке, и
не должен участвовать в алгоритме построения кода Huffman-а,
приведенном выше. Если используется только один код расстояния,
это кодируется используя один бит, (не нулевыми битами); в данном
случае единственная длина единица, c одним неиспользованным кодом.
Теперь мы можем определить формат блока:
5 битов: HLIT, # кодов литерала/длины - 257 (257 - 286)
5 битов: HDIST,# кодов расстояния - 1 (1 - 32)
4 бита : HCLEN,# кодов длины - 4 (4 - 19)
(HCLEN + 4) x 3 бита: длины кода для алфавита длины, данного
только что выше, в порядке: 16, 17, 18, 0, 8, 7, 9,
6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
Данные длины кодов интерпретируются как 3 битовые (0-7)
  целые числа; длина 0 обозначает что соответствующий символ
  (литеральный символ/длина или расстояния) не используется.
HLIT + 257 кодовых длин для алфавита литерала/длины,
закодированных используя код Huffman для длин
HDIST + 1 кодовых длин для алфавита расстояния,
закодированного с использованием кода Huffman-а для длины
Фактические сжатые данные блока, кодированные с использованием
кодов Huffman для литеральных символов/длины и расстояния
Символ 256 из алфавита литеральных символов/длины (конец данных),
закодированный с использованием кода Huffman-а для литерального
символа/длины
The code length repeat codes can cross from HLIT + 257 to the
HDIST + 1 code lengths. In other words, all code lengths form
a single sequence of HLIT + HDIST + 258 values.
3.3. Compliance
Компрессор может накладывать дополнительные ограничения на диапазоны
значений, указанные в предыдущем разделе и при этом оставаться
совместимым с данным форматом; например, может быть введено
ограничение на диапазон обратных указателей, те обратные указатели
не могут превосходить некоторое значение меньшее чем 32КБ. Подобным
образом компрессор может ограничивать размер блоков так, чтобы
сжимаемый блок поместился в память.
Совместимый декомпрессор должен воспринимать полные диапазоны значений,
определенных в предыдущем разделе, а также должен воспринимать блоки
произвольного размера.
4. Compression algorithm details
В то время как намерением данного документа явлеется определение
формат "deflate" сжатых данных не ссылаясь на какой то конкретный
алгоритма сжатия, данных формат похож на форматы, используемые
LZ77 (Lempel-Ziv с 1977, смотри ссылку [2]); так как много
реализаций LZ77 запатентованы, настоятельно рекомендуется, чтобы
реализатор компрессора придерживался общего алгоритма, описанного
здесь, о котором известно, что он не будет запатентован сам по себе.
Материал приведенный в данном разделе - не часть определения
спецификации, и компрессор не должен следовать ниже описанному,
чтобы быть совместимым.
Компрессор заканчивает блок, когда он определяет, что старт нового
блока с новыми деревьями был бы полезен, или когда размер блока
выходит за пределы буфера компрессора.
Для обнаружения продублированных строк компрессор использует цепочечную
hash таблицу, используя hash функцию, которая работает c 3-байтовых
последовательностями. В любой точке во время компрессии, проверяются
следующие 3 бйта XYZ (не обязательно все различные, конечно). Сначала,
компрессор исследует hash цепочку на наличие XYZ. Если цепочка пуста,
компрессор просто записывает X как литеральный байт и продвигается
на один байт во входном потоке. Если hash цепочка - не пуста, то это
указывает что последовательность XYZ (или, если при неудаче, некоторые
другие 3 байта с тем же самым значением hash функции) недавно
встречалились, компрессор сравнивает все строки в XYZ hash цепочке с
фактической входной последовательностью данных, и выбирает самое
длинное соответствие.
Компрессор ищет hash цепочки, начинающиеся с наиболее недавних строк,
отдавая преимущество маленьким расстояниям и позволяя таким образом
воспользоваться преимуществом Huffman кодирования. hash цепочки
односвязанны. Удаления из цепочек не происходит; алгоритм просто
откидывает элементы цепочки, которые слишком стары. для того чтобы
избежать наихудшего случая, очень длинные hash-цепочки произвольно
усекаются по некоторой длине, определенной во время выполнения.
Чтобы улучшать общее сжатие, компрессор опционально задерживает выбор
совпадения ("ленивое совпадение" или "lazy match"): после того, как
найдено совпадение длиной N , компрессор ищет более длинное совпадение,
начиная со следующего входного байта.
Если это находится более длинное совпадение, то записывается один
литеральный байт, а затем записывается ссылка на более длинное
совпадение.
Параметры времени исполнения также управляют процедурой "lazy match".
Если отношение сжатия наиболее важно, компрессор делает попытку
законченного второго поиска независимо от длины первого совпадения.
В нормальном случае, если текущее совпадение - достаточно длинное,
компрессор уменьшает время, затрачиваемое на поиск более длинного
совпадения, таким образом ускоряя процесс. Если скорость более важна,
компрессор вставляет новые строки в hash таблицу мусора только, когда
никакое соответствие не было найдено, или когда совпадение - не "слишком
длинное ". Это приводит к деградации коэфициента сжатия, но приводит к
экономии времени, так как обходится меньшим количествам процедур
вставки и меньшим количествам процедур поиска.
5. References
[1] Huffman, D. A., "A Method for the Construction of Minimum
Redundancy Codes", Proceedings of the Institute of Radio
Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
[2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
Compression", IEEE Transactions on Information Theory, Vol. 23,
No. 3, pp. 337-343.
[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
[5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
[6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
Comm. ACM, 33,4, April 1990, pp. 449-459.
6. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data. See
reference [3], for example.
7. Source code
Source code for a C language implementation of a "deflate" compliant
compressor and decompressor is available within the zlib package at
ftp://ftp.uu.net/pub/archiving/zip/zlib/.
8. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
Adler wrote the related software described in this specification.
Glenn Randers-Pehrson converted this document to RFC and HTML format.
9. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
2004. Translated to Russian by Dmitriy Cherkashin <dch@ucrouter.ru>.
Этот информационный блок появился по той простой причине,
что многие считают нормальным, брать чужую информацию не уведомляя автора
(что не так страшно), и не оставляя линк на оригинал и автора — что более существенно.
Я не против распространения информации — только за. Только условие простое — извольте
подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой,
незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
Если соизволите поставить автора в известность — то вообще почёт вам и уважение.
© lissyara 2006-10-24 08:47 MSK