- •Лабораторная работа №1 «Алгоритм сжатия данных rle» цель работы
- •Порядок выполнения работы
- •Сжатие данных Основные понятия
- •Характеристики алгоритмов сжатия данных
- •Алгоритмы сжатия без потерь
- •Статистические алгоритмы сжатия
- •Алгоритмы kwe
- •Алгоритм арифметического кодирования
- •Словарные и словарно-статистические алгоритмы сжатия
- •Алгоритмы сжатия, использующие исключение повторов
- •Вопросы для защиты отчета по лабораторной работе
Словарные и словарно-статистические алгоритмы сжатия
В 1977 году израильские ученые А.Лемпел и Я.Зив опубликовали работу, в которой привели разработанный ими алгоритм сжатия данных, названный позже LZ. На основе этого алгоритма в дальнейшем было разработано множество алгоритмов, учитывающих технические возможности компьютеров. В алгоритмах LZ учитываются корреляционные связи между символами, что позволяет значительно увеличить коэффициент сжатия.
Сущность алгоритма сжатия данных LZ состоит в том, что повторяющиеся последовательности символов заменяются указателями на позиции, где они в тексте уже ранее появлялись. Одной из форм такого указателя может быть пара (n, m), которая ссылается на последовательность символов длиной m символов, начинающуюся с позиции n. В большинстве реализаций алгоритма Лепеля – Зива позиция в паре кодируется как смещение (разность) между позициями кодируемой строки и строки, на которую произведена ссылка.
Из-за ограниченного объема оперативной памяти компьютера обычно используется вариант алгоритма Лемпеля – Зива со скользящим окном, когда максимальное значение смещения ограничено некоторым значением.
Сжатие данных происходит следующим образом. В сжатые данные выдаются либо символы сжимаемых данных, либо ссылки на уже просмотренную часть сообщения. Эти ссылки указывают, что текущие символы некоторым количеством m совпадают с теми, что уже были прочитаны, начиная с позиции n. Распаковка начинается с начала сообщения.
Алгоритмы сжатия, использующие исключение повторов
Алгоритмы сжатия, использующие исключение повторов (RLE = Run-Length Encoding) чрезвычайно просты и ориентированы на быстрое сжатие данных, содержащих много идущих подряд одинаковых символов.
В основу алгоритмов RLE положен принцип выявления групп подряд идущих одинаковых символов и замены их структурой, в которой указывается код символа и число повторов, т.е. группа идущих подряд одинаковых символов заменяется на пару кодов вида <код символа; число повторов>. Максимальное число одинаковых символов, которое можно закодировать одной такой парой, определяется длиной кода числа повторов.
Проблему при сжатии алгоритмами RLE представляют данные, содержащие незначительное количество повторяющихся символов. К одиночным символам также приходится добавлять счетчик повторов, что вместо сжатия дает увеличение объема данных. Поэтому в практических реализациях алгоритмы RLE несколько усложняются, чтобы уменьшить увеличение объема сжатых данных в случае не очень подходящих данных.
В качестве примера рассмотрим реализацию RLE а графическом формате PCX. Группа повторяющихся байтов заменяется на байт-счетчик и байт данных. В байте-счетчике старшие два бита содержат единицы, в младших шести битах хранится число повторов. Неповторяющиеся значения, меньшие 0C0h = 0C016 = 110000002, записываются в сжатые данные без изменений. Для неповторяющихся значений, больших 0C016 = 110000002, (т.е. с двумя единицами в старших разрядах) такой подход недопустим, так как при распаковке такой байт будет восприниматься как байт-счетчик повторов. Поэтому такие байты при записи в сжатый поток предваряются байтом-счетчиком с числом повторов, равным единице (11000001 = С116). Рассмотрим пример.
Исходные данные: 00;00;00; 00;01;00;FE;FF;FF;FF.
Сжатые данные: С4;00;01;00;С1;FE;C3;FF.
В приведенном примере из строки длиной 10 байтов получена упакованная строка длиной 8 байтов. Видно, что один байт FE кодируется двумя байтами С1;FE, поэтому некоторые данные при таком сжатии могут вырасти в объеме до двух раз. Например:
Исходные данные: CF;FF;CF;FF;CF;FF.
Сжатые данные: C1;CF;C1;FF; C1;CF;C1;FF;C1;CF;C1;FF.
Распаковка производится следующим образом. Из входного потока читается байт и проверяются его старшие два бита. Если они равны единице, то из этого байта выделяются шесть младших битов, которые используются как счетчик. Далее из входного потока считывается байт и его значение записывается в выходной поток столько раз, сколько указано счетчиком. Если же в старших битах не две единицы, то этот байт непосредственно копируется в выходной поток. Рассмотрим пример.
Сжатые данные: C5;10;C4;FF;00;01;C1;CF;C1;EF.
Распакованные данные: 10;10;10;10;10;FF;FF;FF;FF;00;01;CF;EF.
Рассмотрим ещё пример на СЖАТИЕ.
Исходные данные: 01 BD 2F 15 4F DB E0 10 15 FD EO 1E D1 00 1A 0A 10 1C 61 EF 01 D0 11 33 33 33 33 33 33 33 34
Последовательно проверяем каждый байт, и формируем сжатый поток согласно алгоритму RLE.
01 – первый байт исходных данных. Следующий за ним байт BD, это означает, что первый байт не входит в цепочку повторяющихся байтов. Старшие два бита байта 01 не равны единицам. Следовательно, первый байт исходных данных переписываем в сжатый поток без изменений.
BD 2F 15 4F – следующие за первым байты, аналогично первому, переписываем в сжатый поток без изменения.
Два следующих байта DB16=110110112 и E016=111000002 – это байты, старшие два бита которых содержат единицы. Поэтому, эти байты, при записи в сжатый поток, предваряем байтами-счетчиками, с числом повторов равным единице (C116=110000012).
10 15 – эти байты не содержат единицы в старших битах и не входят в цепочку повторяющихся байтов. Переписываем их в сжатый поток без изменения.
Два следующих бита FD16=111111012 E016=111000002 – это байты, старшие два бита которых содержат единицы. Поэтому, эти байты, при записи в сжатый поток, предваряем байтами-счетчиками, с числом повторов равным единице (C116=110000012).
1E – этот байт не содержит единиц в старших битах и не входит в цепочку повторяющихся байтов. Переписываем его в сжатый поток без изменения.
Следующий байт D116=110100012 – это байт, старшие два бита которого содержат единицы. Поэтому, этот байт, при записи в сжатый поток, предваряем байтом-счетчиком, с числом повторов равным единице (C116=110000012).
00 1A 0A 10 1C 61 – эти байты не содержат единицы в старших битах и не входят в цепочку повторяющихся байтов. Переписываем их в сжатый поток без изменения.
Следующий байт EF16=111011112 – это байт, старшие два бита которого содержат единицы. Поэтому, этот байт, при записи в сжатый поток, предваряем байтом-счетчиком, с числом повторов равным единице (C116=110000012).
01 – этот байт не содержит единиц в старших битах и не входит в цепочку повторяющихся байтов. Переписываем его в сжатый поток без изменения.
Следующий байт D016=110100002 – это байт, старшие два бита которого содержат единицы. Поэтому, этот байт, при записи в сжатый поток, предваряем байтом-счетчиком, с числом повторов равным единице (C116=110000012).
11 – этот байт не содержит единиц в старших битах и не входит в цепочку повторяющихся байтов. Переписываем его в сжатый поток без изменения.
Далее идёт группа повторяющихся байтов 33 33 33 33 33 33 33, её заменяем на байт-счетчик и байт данных C7 33.
Последний байт 34 не содержит единицы в старших битах, переписываем его в сжатые данные без изменения.
Сжатые данные: 01 BD 2F 15 4F C1 DB C1 E0 10 15 C1 FD C1 EO 1E C1 D1 00 1A 0A 10 1C 61 C1 EF 01 C1 D0 11 C7 33 34
Пример выполнения РАСПАКОВКА
Сжатые данные: 01 10 11 A2 B2 C2 D2 C1 FF D3 21
Последовательно проверяем каждый байт.
01 10 11 А2 B2 – не являются байтами-счетчиками, их записываем в распакованные данные без изменения.
Следующий байт С216=110000102 – это байт-счетчик (с числом повторов равным двум), байт значения которого D2. В распакованные данные записываем D2 D2.
Затем идет С1 – это байт-счетчик (с числом повторов равным единице), байт значения которого FF. В распакованные данные записываем FF.
D3 – это байт-счетчик (т.к. D316=110100112, с числом повторов равным 0100112=1910), байт, значение которого 21. В распакованные данные записываем девятнадцать раз байт 21.
Распакованные данные: 01 10 11 A2 B2 D2 D2 FF 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21
