Главная > Сжатие данных, изображений и звука
<< Предыдущий параграф Следующий параграф >>
Пред.
След.
Макеты страниц

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

Также, советуем воспользоваться поиском по сайту, мы уверены, что вы сможете найти больше информации по нужной Вам тематике

2.4. LZW

Это весьма популярный вариант алгоритма LZ78, который был разработан Терри Уэлчем (Terry Welch) в 1984 ([Welch 84] и [Phillips 92]). Его главной особенностью является удаление второго поля из метки. Метка LZW состоит только из указателя на место в словаре. Для лучшего понимания алгоритма LZW мы временно забудем, что словарь является деревом и будем предполагать, что словарь - это просто массив, состоящий из строк разной длины. Метод LZW начинается инициализацией словаря всеми символами исходного алфавита. В общем случае 8-битного алфавита, первые 256 записей (отдельные символы с номерами от 0 до 255) заносятся в словарь до поступления сжимаемых данных. Поскольку словарь уже частично заполнен, первые поступившие символы всегда будут обнаружены в словаре, поэтому метка может состоять всего лишь из указателя, и нет надобности дополнительно хранить код символа, как в алгоритмах LZ77 и LZ78.

(Алгоритм LZW запатентован и для его использования необходима лицензия. Издание патентов для программного обеспечения обсуждается в [Salomon 00].)

Метод LZW накапливает поступающие на вход символы в строке I. После каждого нового символа, добавленного в строку I, кодер ищет I в словаре. Если строка обнаружена, то процесс удлинения I продолжается. В некоторый момент добавление нового символа х приводит к необнаружению строки Iх (символ х был добавлен к I). Тогда кодер (1) записывает в выходной файл указатель в словаре на строку I, (2) сохраняет строку Iх (которая теперь будет называться фразой) в словаре на следующей допустимой позиции и (3) инициализирует (присваивает) строке I новое значение х. Чтобы проиллюстрировать процесс кодирования, мы еще раз воспользуемся последовательностью «sir_sid_eastman_easily_teases_sea_sick_seals». Получаем следующие шаги.

I

В

словаре?

Новая запись

Выход

I

В

словаре?

Новая запись

Выход

s

да

 

 

y

да

 

 

si

нет

256-si

115 (s)

y_

нет

274-у_

121 (у)

i

да

 

 

_

да

 

 

ir

нет

257-ir

105 (i)

_t

нет

275-_t

32 (_)

r

да

 

 

t

да

 

 

r_

нет

258-r_

114 (r)

te

нет

276-te

116 (t)

_

да

 

 

e

да

 

 

_s

нет

259-_s

32 (_)

ea

да

 

 

s

да

 

 

eas

нет

277-eas

263 (ea)

si

да

 

 

s

да

 

 

sid

нет

260-sid

256 (si)

se

нет

278-se

115 (s)

d

да

 

 

e

да

 

 

d_

нет

261-d_

100 (d)

es

нет

279-es

101 (e)

_

да

 

 

s

да

 

 

_e

нет

262-_e

32 (_)

s_

нет

280-s_

115 (s)

e

да

 

 

_

да

 

 

ea

нет

263-ea

101 (e)

_s

да

 

 

a

да

 

 

_se

нет

281-_se

259 (_s)

as

нет

264-as

97 (a)

e

да

 

 

s

да

 

 

ea

да

 

 

st

нет

265-st

115 (s)

ea_

нет

282-ea_

263 (ea)

t

да

 

 

_

да

 

 

tm

нет

266-tm

116 (t)

_s

да

 

 

m

да

 

 

_si

нет

283-_si

259 (_s)

ma

нет

267-ma

109 (m)

i

да

 

 

a

да

 

 

ic

нет

284-ic

105 (i)

аn

нет

268-an

97 (a)

с

да

 

 

n

да

 

 

ck

нет

285-ck

99 (c)

n_

нет

269-n_

110 (n)

k

да

 

 

_

да

 

 

k_

нет

286-k_

107 (k)

_e

да

 

 

_

да

 

 

_ea

нет

270-_ea

262 (_e)

_s

да

 

 

a

да

 

 

_se

да

 

 

as

да

 

 

_sea

нет

287-_sea

281 (_se)

asi

нет

271-asi

264 (as)

a

да

 

 

i

да

 

 

al

нет

288-al

97 (a)

il

нет

272-il

105 (i)

l

да

 

 

l

да

 

 

ls

нет

289-ls

108 (l)

ly

нет

273-ly

108 (l)

s

 

да

 

115 (s)

 

 

 

 

s ,eof

нет

 

 

Табл. 2.6. Кодирование строки «sir_sid_eastman_...»

0. Инициализируем словарь записями от 0 до 255 всеми 8-битовыми символами.

1. Первый входной символ s обнаруживается в словаре под номером 115 (это его код ASCII). Следующий входной символ i, но строки si нет в словаре. Кодер делает следующее: (1) он выдает на выход ссылку 115, (2) сохраняет si в следующей доступной позиции словаря (запись номер 256) и (3) инициализирует I строкой i.

2. На вход поступает символ r, но строки ir нет в словаре. Кодер (1) записывает на выход 105 (ASCII код i), (2) сохраняет в словаре ir (запись 257) и (3) инициализирует I строкой r.

0

NULL

110

n

262

_e

276

te

1

S0H

 

263

ea

277

eas

 

115

s

264

as

278

se

32

SP

116

t

265

st

279

es

 

 

266

tm

280

s_

97

а

121

У

267

ma

281

_se

98

b

 

 

268

аn

282

ea_

99

с

255

255

269

n_

283

_si

100

d

256

si

270

_ea

28-1

ic

101

е

257

ir

271

asi

285

ck

 

258

r_

272

il

286

k_

107

k

259

_s

273

ly

287

_sea

108

l

260

sid

274

y_

288

al

109

m

261

d_

275

_t

289

ls

Табл. 2.7. Словарь LZW.

Табл. 2.6 суммирует все шаги процесса. В табл. 2.7 приведены некоторые исходные записи из словаря LZW плюс записи, добавленные в процессе кодирования данной строки. Полный выходной файл имеет следующий вид (входят только числа, но не символы в скобках):

115 (s), 105 (i), 114 (r), 32 (_), 256 (si), 100 (d), 32 (_), 101 (е), 97 (а), 115 (s), 116 (t), 109 (m), 97 (a), 110 (n), 262 (_e), 264 (as), 105 (i), 108 (1), 121 (y), 32 (_), 116 (t), 263 (ea), 115 (s), 101 (e), 115 (s), 259 (_s), 263 (ea), 259 (_s), 105 (i), 99 (c), 107 (k), 280 (_se), 97 (a), 108 (1), 115 (s), eof.

На рис. 2.8 приведена запись этого алгоритма на псевдокоде. Через  обозначается пустая строка, а через  - конкатенация (соединение) двух строк  и .

Инструкция алгоритма «добавить  в словарь» будет обсуждаться особо. Ясно, что на практике словарь может переполниться, поэтому эта инструкция должна также содержать тест на переполнение словаря и некоторые действия при обнаружении переполнения.

Поскольку первые 256 записей занесены в словарь в самом начале, указатели на словарь должны быть длиннее 8 бит. В простейшей реализации указатели занимают 16 бит, что допускает 64К записей в словаре (). Такой словарь, конечно, быстро переполнится. Такая же проблема возникает при реализации алгоритма LZ78, и любое решение, допустимое для LZ78, годится и для LZW. Другое интересное свойство этого алгоритма заключается в том, что строки в словаре становятся длиннее на один символ на каждом шаге. Это означает, что требуется много времени для появления длинных строк в словаре, а значит и эффект сжатия будет проявляться медленно. Можно сказать, что LZW медленно приспосабливается к входным данным.

095.jpg

Рис. 2.8. Алгоритм LZW.

Пример: Применим алгоритм LZW для кодирования строки символов «alf_eats_alfalf а». Последовательность шагов отображена в табл. 2.9. Кодер выдает на выход файл:

97 (а), 108 (1), 102 (f), 32 (_), 101 (е), 97 (а), 116 (t), 115 (s), 32 (_), 256 (al), 102 (f), 265 (alf), 97 (a),

а в словаре появляются следующие новые записи:

(256: al), (257: lf), (258: f_), (259: _е), (260: ea), (261: at), (262: ts), (263: s_), (264: _a), (265: alf), (266: fa), (267: alfa).

Пример: Проанализируем сжатие строки «аааа...» алгоритмом LZW. Кодер заносит первую «а» в I, ищет и находит а в словаре. Добавляет в I следующую а, находит, что строки Iх (=аа) нет в словаре. Тогда он добавляет запись 256: аа в словарь и выводит метку 97 (а) в выходной файл. Переменная I инициализируется второй «а», вводится третья «а», Iх вновь равна аа, которая теперь имеется в словаре. I становится аа, появляется четвертая «а». Строка Iх равна ааа, которых нет в словаре. Словарь пополняется этой строкой, а на выход идет метка 256 (аа). I инициализируется третьей «а», и т.д. и т.п. Дальнейший процесс вполне ясен.

В результате строки а, аа, ааа, аааа... добавляются в словарь в позиции 256, 257, 258, ..., а на выход подается последовательность

97 (а), 256 (аа), 257 (ааа), 258 (аааа), ....

Значит, выходной файл состоит из указателей на все более и более длинные последовательности символов а, и к указателей обозначают строку, длина которой равна .

I

В

словаре ?

Новая запись

Выход

I

В

словаре?

Новая запись

Выход

а

да

 

 

s_

нет

263-s_

115 (s)

al

нет

256-а1

97 (а)

_

да

 

 

1

да

 

 

нет

264-_а

32 (_)

lf

нет

257-lf

108 (1)

а

да

 

 

f

да

 

 

al

да

 

 

f_

нет

258-f_

102 (f)

alf

нет

265-alf

256 (al)

_

да

 

 

f

да

 

 

_e

нет

259-_е

32 (w)

fa

нет

266-fa

102 (f)

e

да

 

 

a

да

 

 

ea

нет

260-еа

101 (е)

al

да

 

 

a

да

 

 

alf

да

 

 

at

нет

261-at

97 (а)

alfa

нет

267-alfa

265 (alf)

t

да

 

 

a

да

 

 

ts

нет

262-ts

116 (t)

a,eof

нет

 

97 (a)

s

да

 

 

 

 

 

 

Табл. 2.9. Кодирование LZVV для «alf_eats_alfalfa»

Предположим, что входной файл состоит из 1 миллиона символов а. Мы можем найти длину сжатого файла, решив квадратное уравнение  относительно неизвестной . Решение будет . Выходит, что файл длиной 8 миллионов бит будет сжат в 1414 указателей длины не менее 9 бит (а на самом деле, 16 бит). Фактор сжатия или  или .

Результат потрясающий, но такие файлы попадаются весьма редко (заметим, что этот конкретный файл можно сжать, просто записав в выходной файл «1000000 а» без использования LZW).

 

Categories

1
Оглавление
email@scask.ru