что такое сжатие lzw

LZW алгоритм

Пакует и распаковывает строку алгоритмом сжатия Лемпель-Зив-Велч (LZW)

что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

LZW сжатие текста

Запакованную предыдущим калькулятором строку или файл можно передать в следующий калькулятор для проверки распаковки. Кроме битового массива или файла необходимо задать способ формирования начального словаря (выбрать ту же самую кодировку или задать словарь явно).

что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

LZW распаковка

Алгоритм Lempel-Ziv-Welch

Алгоритм сжатия без потерь LZ78 был опубликован в 1978-году Авраамом Лемпелем и Яаковом Зивом и затем был доработан Терри Велчем в 1984. После публикации Велча алгоритм получил название LZW по перым буквам фамилий авторов (Lempel, Ziv, Welch). Алгоритм был запатентован, но к настоящему времени сроки действия всех патентов истекли, что дает нам прекрасную возможность опубликовать свою реализацию тут.

Описание алгоритма LZW

Для декодирования сформированных таким способом данных, не нужно хранить словарь, он воссоздается сам в процессе работы алгоритма распаковки:

В оригинале статьи Велча предполагалось кодировать фразу в словаре кодом фиксированного размера 12 бит, однако для небольших сообщений такой подход может даже увеличить длину закодированного сообщения. Поэтому довольно часто используют динамическую длину кода, изменяемую всякий раз при достижении предела словаря.

Управление размером словаря

В описанном выше алгоритме сжатия размер словаря ничем не ограничен. На практике это может приводить к проблемам при упаковке больших объемах данных.
Известны модификации алгоритма, пытающихся исправить эту проблему:

Особенности нашей реализации

Начальный словарь

Многобайтовые кодировки

— первый байт символа евро,

— второй байт символа евро,

— два первых байта символа евро,

— первый байт символа евро, код в utf-8 = 226

— первый байт символа рубля, код в utf-8 = 226.

Заполнение концовки нулями

Алгоритм сжатия может выдать битовый массив, размер которого не кратен 8. В этом случае калькулятор упаковки дозаполняет выходной массив нулевыми битами. Так как наша реализация алгоритма использует переменный размер слова, такой подход может породить проблемы, если вручную заданный начальный словарь очень мал.
Например, вот с такими параметрами конечное сообщение составит всего 18 бит и 6 бит придется дополнить нулями, чтобы сохранить все сообщение в двоичном файле. Так как с указанными параметрами, размер слова составляет всего 4 бита, то при распаковке будет считано лишнее слово, и если бы мы создавали исходный словарь с кодом первого символа = 0, то распаковался бы лишний символ. Мы решаем эту проблему путем добавления в словарь нулевого символа, который принято интерпретировать, как конец строки. При использовании 8-битной кодировки в качестве начального словаря эта проблема никогда не возникнет, так как размер слова всегда как минимум 8 бит.

Источник

Что такое сжатие lzw

Mark R. Nelson
Перевод: Запольский С.А.

Собственно исходный Lempel/Ziv подход к сжатию данных был впервые обнародован в 1977г., а усовершенствованный (Terry Welch) вариант был опубликован в 1984г. Алгоритм на удивление прост. Если в двух словах, то LZW-сжатие заменяет строки символов некоторыми кодами. Это делается без какого-либо анализа входного текста. Вместо этого при добавлении каждой новой строки символов просматривается таблица строк. Сжатие происходит, когда код заменяет строку символов. Коды, генерируемые LZW-алгоритмом, могут быть любой длины, но они должны содержать больше бит, чем единичный символ. Первые 256 кодов (когда используются 8-битные символы) по умолчанию соответствуют стандартному набору символов. Остальные коды соответствуют обрабатываемым алгоритмом строкам.


Сжатие.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

СТРОКА = очередной символ из входного потока
WHILE входной поток не пуст DO
СИМВОЛ = очередной символ из входного потока
IF СТРОКА+СИМВОЛ в таблице строк THEN
СТРОКА = СТРОКА+СИМВОЛ
ELSE
вывести в выходной поток код для СТРОКА
добавить в таблицу строк СТРОКА+СИМВОЛ
СТРОКА = СИМВОЛ
END of IF
END of WHILE
вывести в выходной поток код для СТРОКА

Рис. 1 Алгоритм сжатия

Этот процесс повторяется до тех пор, пока вторая подстрока, состоящая из прочитанных символов «/» и «W», не сопоставится со строковым номером 256. В этом случае система выводит код 256 и добавляет трехсимвольную подстроку в таблицу. Этот процесс продолжается до тех пор, пока не исчерпается входной поток и все коды не будут выведены.

Входная строка : /WED/WE/WEE/WEB/WET

Вход(символы)Выход(коды)Новые коды и соответствующие строки
/W/256 = /W
EW257 = WE
DE258 = ED
/D259 = D/
WE256260 = /WE
/E261 = E/
WEE260262 = /WEE
/W261263 = E/W
EB257264 = WEB
/B265 = B/
WET260266 = /WET
T

Рис. 2 Процесс сжатия

Выходной поток для заданной строки показан на рис. 2, также как и полученная в результате таблица строк. Как вы можете заметить, эта таблица быстро заполняется, т.к. новая строка добавляется в таблицу каждый раз, когда генерируется код. В этом явно вырожденном примере было выведено пять закодированных подстрок и семь символов. Если использовать 9-битные коды для вывода, то 19-символьная входная строка будет преобразована в 13.5-символьная выходную строку. Конечно, этот пример был выбран только для демонстрации. В действительности сжатие обычно не начинается до тех пор, пока не будет построена достаточно большая таблица, обычно после прочтения порядка 100 входных байт.


Распаковка.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

Алгоритму сжатия соответствует свой алгоритм распаковки. Он получает выходной поток кодов от алгоритма сжатия и использует его для точного восстановления входного потока. Одной из причин эффективности LZW-алгоритма является то, что он не нуждается в хранении таблицы строк, полученной при сжатии. Таблица может быть точно восстановлена при распаковке на основе выходного потока алгоритма сжатия. Это возможно потому, что алгоритм сжатия выводит СТРОКОВУЮ и СИМВОЛЬНУЮ компоненты кода прежде чем он поместит этот код в выходной поток. Это означает, что сжатые данные не обременены необходимостью тянуть за собой большую таблицу перевода.

читать СТАРЫЙ_КОД
вывести СТАРЫЙ_КОД
WHILE входной поток не пуст DO
читать НОВЫЙ_КОД
СТРОКА = перевести НОВЫЙ_КОД
вывести СТРОКУ
СИМВОЛ = первый символ СТРОКИ
добавить в таблицу перевода СТАРЫЙ_КОД+СИМВОЛ
СТАРЫЙ_КОД = НОВЫЙ_КОД
END of WHILE

Рис. 3 Алгоритм распаковки

На рис. 4 приведена схема работы алгоритма на основе сжатых данных, полученных в выше приведенном примере. Важно отметить, что построение таблицы строк алгоритмом распаковки заканчивается как раз тогда, когда построена таблица строк алгоритма сжатия.

Входные коды : / W E D 256 E 260 261 257 B 260 T

ВходСТАРЫЙ КОДСТРОКАСИМВОЛНовый вход таблицы
///
W/WW256 = /W
EWEE257 = WE
DEDD258 = ED
256D/W/259 = D/
E256EE260 = /WE
260E/WE/261 = E/
261260E/E262 = /WEE
257261WEW263 = E/W
B257BB264 = WEB
260B/WE/265 = B/
T260TT266 = /WET

Рис. 4 Процесс распаковки

Выходной поток идентичен входному потоку алгоритма сжатия. Отметим, что первые 256 кодов уже определены для перевода одиночных символов, также как и в алгоритме сжатия.


Ловушка.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

Простой пример иллюстрирует это. Предположим, строка «JOEYN» определена в таблице с кодом 300. Когда последовательность «JOEYNJOEYNJOEY» появляется в таблице, выходной поток алгоритма сжатия выглядит подобно тому, как показано на рис. 5.

Вход(символы)Выход(коды)Новые коды и соотв. строки
JOEYN288 = JOEY300 = JOEYN
AN301 = NA
...
...
...
JOEYNJ300 = JOEYN400 = JOEYNJ
JOEYNJO400401 = JOEYNJO

Рис. 5 Некоторые проблемы

Когда распаковщик просматривает входной поток, он сначала декодирует код 300, затем выводит строку «JOEYN» и добавляет определение для, скажем, кода 399 в таблицу, хотя он уже мог там быть. Затем читает следующий входной код, 400, и обнаруживает, что его нет в таблице. Это уже проблема. К счастью, это произойдет только в том случае, если распаковщик встретит неизвестный код. Так как это фактически единственная коллизия, то можно без труда усовершенствовать алгоритм.

Модифицированный алгоритм предусматривает специальные действия для еще неопределенных кодов. В примере на рис. 6 распаковщик обнаруживает код 400, который еще не определен. Так как этот код не известен, то декодируется значение СТАРОГО_КОДА, равное 300. Затем распаковщик добавляет значение СИМВОЛА, равное «J», к строке. Результатом является правильный перевод кода 400 в строку «JOEYNJ».

читать СТАРЫЙ_КОД
вывести СТАРЫЙ_КОД
СИМВОЛ = СТАРЫЙ_КОД
WHILE входной поток не пуст DO
читать НОВЫЙ_КОД
IF NOT в таблице перевода НОВЫЙ_КОД THEN
СТРОКА = перевести СТАРЫЙ_КОД
СТРОКА = СТРОКА+СИМВОЛ
ELSE
СТРОКА = перевести НОВЫЙ_КОД
END of IF
вывести СТРОКУ
СИМВОЛ = первый символ СТРОКИ
добавить в таблицу перевода СТАРЫЙ_КОД+СИМВОЛ
СТАРЫЙ_КОД = НОВЫЙ_КОД
END of WHILE

Рис. 6 Модифицированный алгоритм распаковки


Реализация.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

Концепции, использованные в алгоритме сжатия, настолько просты, что весь алгоритм может быть записан в несколько строк. Но так как управление построением таблицы требует некоторых специальных действий, реализация несколько более сложна. В демонстрационной программе, приведенной ниже, использовались коды длиной 12, 13 и 14 бит. При длине кода 12 бит потенциально возможно хранить до 4096 строк в таблице. Каждый раз, когда читается новый символ, таблица строк должна просматриваться для сопоставления. Если сопоставление не найдено, новая строка должна быть добавлена в таблицу. Здесь возникают две проблемы. Во-первых, таблица строк может достаточно быстро стать очень большой. Даже если длина строк в среднем ограничивается 3 или 4 символами каждая, верхний предел длин строк может легко превысить 7 или 8 байт на код. К тому же количество памяти, необходимой для хранения строк, заранее не известно, так как оно зависит от общей длины строк.

Вторая проблема заключается в организации поиска строк. Каждый раз, когда читается новый символ, необходимо организовать поиск для новой строки вида СТРОКА+СИМВОЛ. Это означает поддержку отсортированного списка строк. В этом случае поиск для каждой строки включает число сравнений порядка log2 от общего числа строк. Использование 12-битных слов потенциально позволяет выполнять не более 12 сравнений для каждого кода.

Первая проблема может быть решена хранением строк как комбинаций код/символ. Так как каждая строка в действительности является представлением комбинации уже существующего кода и добавочного символа, можно хранить каждую строку как отдельный код плюс символ. Например в разобранном выше примере строка «/WEE» хранится как код 260 и символ «E». Это позволяет использовать для хранения только 3 байта вместо 5 (включающих дополнительный байт для конца строки). Идя назад, можно определить, что код 260 хранится как код 256 плюс добавочный символ «E». Наконец, код 256 хранится как «/» плюс «W».

Выполнение сравнения строк является немного более трудным. Новый метод хранения увеличивает время, необходимое для сравнения строк, но он не влияет на число сравнений. Эта проблема решается использованием алгоритма хэширования для хранения строк. Это означает, что код 256 не хранится в каком-либо массиве по адресу 256, а хранится в массиве по адресу, сформированному на основе самой строки. При определении места хранения данной строки можно использовать тестовую строку для генерации хэш-адреса и затем найти целевую строку однократным сравнением. Так как код для любой данной строки нельзя узнать в дальнейшем иначе как по его позиции в массиве, необходимо хранить код для данной строки совместно с данными строки. В демонстрационной программе для этого используются элементы трех массивов : code_value[i], prefix_code[i] и append_character[i].

Когда необходимо добавить новый код в таблицу, используется хэшфункция в процедуре find_match для генерации корректного i. Процедура find_match генерирует адрес и затем проверяет, не использовался ли он уже. Если это так, то find_match выполняет вторую пробу и так до тех пор, пока не найдется свободное место.

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

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

Проблема появляется, когда чтение входного потока прерывается при достижении конца потока. Для этого частного случая в программе зарезервирован последний определяемый код MAX_VALUE как признак конца данных. Это не является необходимым при чтении файла, но может помочь при чтении буфера сжатых данных из памяти. Затраты на потерю одного определяемого кода весьма малы сравнительно со всем процессом.


Результаты.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

Достаточно трудно охарактеризовать результативность какой-либо техники сжатия данных. Степень сжатия определяется различными факторами. LZW-сжатие выделяется среди прочих, когда встречается с потоком данных, содержащим повторяющиеся строки любой структуры. По этой причине он работает весьма эффективно, когда встречает английский текст. Уровень сжатия может достигать 50% и выше. Соответственно, сжатие видеоформ и копий экранов показывает еще большие результаты.

Трудности при сжатии файлов данных несколько больше. В зависимости от данных, результат сжатия может быть как хорошим, так и не очень удовлетворительным. В некоторых случаях «сжатый» файл может превосходить по своим размерам исходный текст. Небольшой эксперимент даст Вам представление о том, хорошо или плохо упаковываются Ваши данные.


Ваша реализация.что такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzwчто такое сжатие lzw. Смотреть фото что такое сжатие lzw. Смотреть картинку что такое сжатие lzw. Картинка про что такое сжатие lzw. Фото что такое сжатие lzw

Программа, приведенная в статье, является рабочей. Она была написана, однако, с иллюстративной целью и не очень эффективна. Например, процедуры, организующие входные и выходные потоки, невелики по размерам и легки для понимания, но увеличивают накладные расходы. Вы можете попробовать увеличить скорость программы, совершенно переписав эти процедуры с использованием кодов фиксированной длины, скажем 12 бит.

Одной из проблем является то, что приведенная программа не адаптируется к различной длине файлов. Использование 14- или 15-битных кодов дает лучшую степень сжатия на больших файлах (это объясняется тем, что для них строятся большие таблицы строк), но хуже работает с маленькими файлами. Такие программы, как «ARC», решают эту проблему использованием кодов переменной длины. Например, когда величина next_code находится между 256 и 511, «ARC» читает и выводит 9-битные коды. Когда величина next_code становится настолько большой, что необходимы 10-битные коды, процедуры сжатия и распаковки увеличивают размер кода. Это значит, что 12- и 15-битные варианты программы работают хорошо и на маленьких файлах.

Другой проблемой больших файлов является то, что с увеличением числа прочитанных байтов степень сжатия может начать ухудшаться. Причина проста : так как размер таблицы строк фиксирован, после занесения определенного числа строк их уже просто некуда добавить. Но построенная таблица нужна только для той части файла, по которой она была построена. Оставшиеся части файла могут иметь другие характеристики и в действительности нужна уже несколько отличная таблица.

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

Процедура распаковки определяет этот момент тем, что упаковщик записывает в свой выходной поток специальный код. Альтернативным способом является определение наиболее часто встречающихся строк и чистка остальных. Адаптивная техника, подобная этой, может, однако, встретить трудности реализации в программах разумного размера.

И, наконец, можно брать вырабатываемые LZW-методом коды и пропускать их через адаптирующийся кодирующий фильтр Хаффмана. Это дает несколько большую степень сжатия, но стоимость такой работы более высока, также как и время обработки.

Коротко

Приведенная программа была написана и тестирована на MS-DOS машине и успешно скомпилирована и выполнена с использованием обычного компилятора «C». Она должна нормально работать на любой машине, поддерживающей 16-битный целые и 32-битные длинные целые языка «C».

Реализация компиляторов «C» для MS-DOS обычно создает сложности при использовании массивов больших, чем 64К байт, не позволяя использовать 15- или 16-битные коды в программе. На машинах с другими процессорами, таких как VAX, эти сложности преодолеваются и облегчается использование кодов большей длины.

Отметим, что перевод этого кода на язык ассемблера любой машины, поддерживающей 16- и 32-битную математику, не встретит затруднений и позволит улучшить некоторые характеристики.

Источник

Алгоритм Лемпеля — Зива — Велча

Алгоритм Лемпеля — Зива — Велча

Алгори́тм Ле́мпеля — Зи́ва — Ве́лча (Lempel-Ziv-Welch, LZW) — это универсальный алгоритм сжатия данных без потерь, созданный Абрахамом Лемпелем (Abraham Lempel), Якобом Зивом (Jacob Ziv) и Терри Велчем (Terry Welch). Он был опубликован Велчем в 1984 году, в качестве улучшенной реализации алгоритма LZ78, опубликованного Лемпелем и Зивом в 1978 году. Алгоритм разработан так, чтобы его можно было быстро реализовать, но он не обязательно оптимален, поскольку он не проводит никакого анализа входных данных.

Содержание

Описание

Данный алгоритм при сжатии (кодировании) динамически создаёт таблицу преобразования строк: определённым последовательностям символов (словам) ставятся в соответствие группы бит фиксированной длины (обычно 12-битные). Таблица инициализируется всеми 1-символьными строками (в случае 8-битных символов — это 256 записей). По мере кодирования, алгоритм просматривает текст символ за символом, и сохраняет каждую новую, уникальную 2-символьную строку в таблицу в виде пары код/символ, где код ссылается на соответствующий первый символ. После того как новая 2-символьная строка сохранена в таблице, на выход передаётся код первого символа. Когда на входе читается очередной символ, для него по таблице находится уже встречавшаяся строка максимальной длины, после чего в таблице сохраняется код этой строки со следующим символом на входе; на выход выдаётся код этой строки, а следующий символ используется в качестве начала следующей строки.

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

Алгоритм

Применение

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

Алгоритм был реализован в программе compress, которая стала более или менее стандартной утилитой Unix-систем приблизительно в 1986 году. Несколько других популярных утилит-архиваторов также используют этот метод или близкие к нему.

В 1987 году алгоритм стал частью стандарта на формат изображений GIF. Он также может (опционально) использоваться в формате TIFF.

В настоящее время, алгоритм содержится в стандарте PDF.

Пример

Данный пример показывает алгоритм LZW в действии, показывая состояние выходных данных и словаря на каждой стадии, как при кодировании, так и при раскодировании сообщения. С тем чтобы сделать изложение проще, мы ограничимся простым алфавитом — только заглавные буквы, без знаков препинания и пробелов. Сообщение, которое нужно сжать, выглядит следующим образом:

Маркер # используется для обозначения конца сообщения. Тем самым, в нашем алфавите 27 символов (26 заглавных букв от A до Z и #). Компьютер представляет это в виде групп бит, для представления каждого символа алфавита нам достаточно группы из 5 бит на символ. По мере роста словаря, размер групп должен расти, с тем чтобы учесть новые элементы. 5-битные группы дают 2 5 = 32 возможных комбинации бит, поэтому, когда в словаре появится 33-е слово, алгоритм должен перейти к 6-битным группам. Заметим, что, поскольку используется группа из всех нолей 00000, то 33-я группа имеет код 32. Начальный словарь будет содержать:

Кодирование

Без использования алгоритма LZW, при передаче сообщения как оно есть — 25 символов по 5 бит на каждый — оно займёт 125 бит. Сравним это с тем, что получается при использовании LZW:

Таким образом, используя LZW мы сократили сообщение на 29 бит из 125 — это почти 22 %. Если сообщение будет длиннее, то элементы словаря будут представлять всё более и более длинные части текста, благодаря чему повторяющиеся слова будут представлены очень компактно.

Декодирование

Теперь представим что мы получили закодированное сообщение, приведённое выше, и нам нужно его декодировать. Прежде всего, нам нужно знать начальный словарь, а последующие записи словаря мы можем реконструировать уже на ходу, поскольку они являются просто конкатенацией предыдущих записей.

Единственная небольшая трудность может возникнуть, если новое слово словаря пересылается немедленно. В приведённом выше примере декодирования, когда декодер встречает первый символ, T, он знает, что слово 27 начинается с T, но чем оно заканчивается? Проиллюстрируем проблему следующим примером. Мы декодируем сообщение ABABA:

На первый взгляд, для декодера это неразрешимая ситуация. Мы знаем наперёд, что словом 47 должно быть ABA, но как декодер узнает об этом? Заметим, что слово 47 состоит из слова 29 плюс символ идущий следующим. Таким образом, слово 47 заканчивается на «символ идущий следующим». Но, поскольку это слово посылается немедленно, то оно должно начинаться с «символа идущего следующим», и поэтому оно заканчивается тем же символом что и начинается, в данном случае — A. Этот трюк позволяет декодеру определить, что слово 47 это ABA.

В общем случае, такая ситуация появляется, когда кодируется последовательность вида cScSc, где c — это один символ, а S — строка, причём слово cS уже есть в словаре.

Патенты

Unisys, GIF и PNG

20 июня 2003 года истёк срок оригинального американского патента, что означает, что Unisys не может больше собирать по нему лицензионные отчисления. Аналогичные патенты в Европе, Японии и Канаде истекли в 2004 году.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *