
- •Введение
- •Теоретическая часть
- •1.1. Принципы сжатия данных
- •1.2 Характеристики алгоритмов сжатия и их применимость
- •1.2.1 Коэффициент сжатия
- •1.2.2 Допустимость потерь
- •2. Алгоритмы сжатия данных
- •2.1 Алгоритм rle
- •Пример реализации
- •2.2 Алгоритм lz77
- •Пример реализации
- •2.3 Алгоритм унарного кодирования
- •Заключение
- •Литература
1.2.2 Допустимость потерь
Основным критерием различия между алгоритмами сжатия является описанное выше наличие или отсутствие потерь. В общем случае алгоритмы сжатия без потерь универсальны в том смысле, что их применение безусловно возможно для данных любого типа, в то время как возможность применения сжатия с потерями должна быть обоснована. Для некоторых типов данных искажения не допустимы в принципе. В их числе
символические данные, изменение которых неминуемо приводит к изменению их семантики: программы и их исходные тексты, двоичные массивы и т. п.;
жизненно важные данные, изменения в которых могут привести к критическим ошибкам: например, получаемые с медицинской измерительной аппаратуры или контрольных приборов летательных, космических аппаратов и т. п.;
многократно подвергаемые сжатию и восстановлению промежуточные данные при многоэтапной обработке графических, звуковых и видеоданных.
2. Алгоритмы сжатия данных
Различные алгоритмы могут требовать различного количества ресурсов вычислительной системы, на которых они реализованы:
оперативной памяти (под промежуточные данные);
постоянной памяти (под код программы и константы);
процессорного времени.
В целом, эти требования зависят от сложности и «интеллектуальности» алгоритма. Общая тенденция такова: чем эффективнее и универсальнее алгоритм, тем большие требования к вычислительным ресурсам он предъявляет. Тем не менее, в специфических случаях простые и компактные алгоритмы могут работать не хуже сложных и универсальных. Системные требования определяют их потребительские качества: чем менее требователен алгоритм, тем на более простой, а следовательно, компактной, надёжной и дешёвой системе он может быть реализован.
Рассмотрим несколько алгоритмов сжатия данных.
2.1 Алгоритм rle
Групповое кодирование – Run Length Encoding (RLE) – один из самых старых и самых простых алгоритмов архивации. Сжатие в RLE происходит за счет замены цепочек одинаковых байт на пары "счетчик, значение". Лучший, средний и худший коэффициенты сжатия – 1/32, 1/2, 2/1.
Одна из реализаций алгоритма такова: ищут наименее часто встречающийся байт, называют его префиксом и делают замены цепочек одинаковых символов на тройки "префикс, счетчик, значение". Если же этот байт встречается в исходном файле один или два раза подряд, то его заменяют на пару "префикс, 1" или "префикс, 2". Остается одна неиспользованная пара "префикс, 0", которую можно использовать как признак конца упакованных данных.
При кодировании *.exe-файлов можно искать и упаковывать последовательности вида AxAyAzAwAt..., которые часто встречаются в ресурсах (строки в кодировке Unicode).
Несмотря на то, что кодер RLE, как правило, дает очень незначительное сжатие, он может работать очень быстро. А скорость работы декодера RLE вообще близка к скорости простого копирования блока информации. Алгоритм RLE схематично может быть описан следующим образом:
Кодер RLE
ТекущийСимвол := ДайОчереднойСимвол()
ТекущееСостояние := НЕТ_ПОВТОРОВ
ТекущаяДлина := 0
Пока ТекущийСимвол <> EOF
Буфер := ДайОчереднойСимвол()
Если Буфер = ТекущийСимвол
Если ТекущееСостояние = НЕТ_ПОВТОРОВ
Выдать ( НЕТ_ПОВТОРОВ )
Выдать ( ТекущаяДлина )
Выдать ( ТекущаяДлина предыдущих символов сообщения )
ТекущаяДлина := 2
ТекущееСостояние := ПОВТОРЫ
Иначе
ТекущаяДлина := ТекущаяДлина + 1
Конец если
Иначе
Если ТекущееСостояние = НЕТ_ПОВТОРОВ
ТекущаяДлина := ТекущаяДлина + 1 Иначе
Выдать ( ПОВТОРЫ )
Выдать ( ТекущаяДлина )
Выдать ( ТекущийСимвол )
ТекущаяДлина := 1
ТекущееСостояние := НЕТ_ПОВТОРОВ
Конец если
Конец если
ТекущийСимвол := Буфер
Конец пока
Декодер RLE
ТекущийКод := ДайКодФрагмента()
Пока ТекущийКод <> EOF
ТекущаяДлина := ДайДлинуФрагмента()
Если ТекущийКод = НЕТ_ПОВТОРОВ
Выдать ( ТекущаяДлина, следующих символов сообщения )
Иначе
Выдать ( ТекущаяДлина, ДайОчереднойСимвол() )
Конец если
ТекущийКод := ДайКодФрагмента()
Конец пока
К положительным сторонам алгоритма, можно отнести то, что он не требует дополнительной памяти при работе, и быстро выполняется. Алгоритм применяется в форматах РСХ, TIFF, ВМР. Интересная особенность группового кодирования в PCX заключается в том, что степень архивации для некоторых изображений может быть существенно повышена всего лишь за счет изменения порядка цветов в палитре изображения.