adfun.ru
 
BIGLIB
  большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно
 
АСТРОЛОГИЯ
  книги по астрологии
 
КРИМИНАЛ
  книги про криминал
 
ДЕТЕКТИВЫ
  детективы известных
   писателей
 
ФАНТАСТИКА
  фентези, фантастика,   фантастические повести
 
ПРИКЛЮЧЕНИЯ
  книги про приключения,   путешествия
 
ПОЛИТИКА
  книги про политиков,   репрессии
 
ПСИХОЛОГИЯ
  разнообразная литература   по психологии
 
КЛАССИКА
  классическая литература
 
КОМПЬЮТЕРНАЯ
  ЛИТЕРАТУРА
  про компютерное железо,   документация, языки   программирования
 
РЕЛИГИЯ, АТЕИЗМ
  книги про религию
 
ФИЛОСОФИЯ
  книги, которые заставляют   задуматься над   окружающим тебя миром.
 
ЭНЦИКЛОПЕДИИ
  самые интересные   энциклопедии на
   разные темы
 
МЕДИЦИНА
  медицинские книги,   методички,
   народные лечебники
 
КУЛИНАРИЯ
  рецепты тортов,   консервирование,
  все о спиртных
  напитках.
 
СТИХИ
  стихи популярных и не   очень авторов
 
ТВОРЧЕСТВО
  народное творчество,   стихи, песни и т.д.
 
ЮМОР
  анекдоты, приколы,   смешные истории
 
ЛЮБОВНЫЙ РОМАН
  мир высоких чувств и   любовных грез
 
ЭРОТИКА
  эротические рассказы,   книги о технике секса,   кама-сутра и др.




adfun.ru
Rambler's Top100 Rambler's Top100
    НА ГЛАВНУЮ
    РЕФЕРАТЫ
    ТОСТЫ
    ТЕСТЫ
    АВТО
    ДЛЯ СТУДЕНТА
    КНИГИ
    КОНТАКТ
 
Объяснение LZW и GIF
Автор "Steve Blackstock"
Размер 18503 Байт
Страница 1 из 2
СКАЧАТЬ КНИГУ ЦЕЛИКОМ

                              - 1 -

                        Steve Blackstock

                      ОБЪЯСНЕНИЕ LZW И GIF

      Я надеюсь,  что этот  маленький документ  поможет просветить
тех, кто хочет знать немного больше об алгоритме сжатия Lempel-Ziv
Welch и, конкретно, о его реализации для формата GIF.

     Перед  тем,  как  мы  начнем,  немного о терминологии в свете
данного документа:
"Символ":   фундаментальный элемент  данных.   В обычных текстовых
        файлах  это  отдельный  байт.  В  растровых  изображениях,
        которыми   вы   заинтересовались,   это   индекс,  который
        указывает  цвет  данного  пиксела.  Я  буду  ссылаться  на
        произвольный символ как на "K".
"Поток символов": поток символов такой, как файл данных.
"Цепочка":   несколько последовательных  символов.   Длина цепочки
        может изменяться от 1 до очень большого числа символов.  Я
        могу указывать произвольную цепочку как "[...]K".
"Префикс":  почти  то же самое,  что цепочка, но  подразумевается,
        что  префикс  непосредственно   предшествует  символу,   и
        префикс может иметь  нулевую длину.   Я буду ссылаться  на
        произвольный префикс, как на "[...]".
"Корень": односимвольная цепочка. Для большинства целей это просто
        символ, но иногда это может  быть иначе.  Это [...]K,  где
        [...] пуста.
"Код":   число,  определяемое  известным  количеством бит, которое
        кодирует цепочку.
"Поток  кодов":   выходной  поток  кодов,  таких  как   "растровые
        данные".
"Элемент": код и его цепочка.
"Таблица  цепочек":  список  элементов  обычно, но не обязательно,
        уникальных.

     Этого должно быть достаточно для понимания документа.

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

     В  данный  момент  давайте  рассмотрим  обычное кодирование и
декодирование с помощью LZW-алгоритма. В GIF используется вариация
этого алгоритма.

     При  сжатии  и  раскрытии  LZW  манипулирует тремя объектами:
потоком символов,  потоком кодов  и таблицей  цепочек. При  сжатии
поток  символов  является  входным  и  поток кодов - выходным. При
раскрытии  входным  является  поток  кодов,  а  поток  символов  -
выходным.  Таблица  цепочек  порождается   и  при  сжатии  и   при
раскрытии, однако она никогда не передается от сжатия к  раскрытию
и наоборот.

                              - 2 -

     Первой  вещью,  которую  мы  делаем  при  LZW-сжатии является
инициализация  нашей  цепочки  символов.  Чтобы  сделать  это, нам
необходимо выбрать  код размера  (количество бит)  и знать сколько
возможных значений могут  принимать наши символы.  Давайте положим
код размера равным 12 битам, что означает возможность  запоминания
0FFF, или 4096, элементов  в нашей таблице цепочек.  Давайте также
предположим, что  мы имеем  32 возможных  различных символа.  (Это
соответствует,  например,  картинке  с  32  возможными цветами для
каждого  пиксела.)  Чтобы  инициализировать  таблицу, мы установим
соответствие кода #0 символу #0, кода #1 to символу #1, и т.д., до
кода #31 и символа #31. На  самом деле мы указали, что каждый  код
от 0  до 31  является корневым.  Больше в  таблице не будет других
кодов, обладающих этим свойством.

     Теперь  мы  начнем  сжатие  данных. Давайте сначала определим
нечто,  называемое  "текущим  префиксом".  Этот  префикс  мы будем
постоянно  помнить  и  проводить  сравнение   с  ним  здесь  и   в
дальнейшем. Я буду обозначать его как "[.c.]". Изначально  текущий
префикс ничего не содержит. Давайте также определим также "текущую
цепочку",  которая  образуется   текущим  префиксом  и   следующим
символом в потоке символов. Я буду обозначать текущую цепочку  как
"[.c.]K", где K  - некоторый символ.

     Теперь посмотрите на первый символ в потоке символов. Назовем
его  P.  Сделаем  [.c.]P  текущей  цепочкой.  (В данной точке это,
конечно, корень P.) Теперь выполним поиск в таблице цепочек, чтобы
определить  входит  ли   в  нее  [.c.]P.    Конечно,  сейчас   это
произойдет,  поскольку  в  нашу  таблицу  при  инициализации  были
помещены все  корни. В  этом случае  мы ничего  не делаем.  Теперь
делаем текущим префиксом [.c.]P.

     Берем следующий символ  из потока символом.   Назовем его  Q.
Добавим текущий префикс,  чтобы сформировать [.c.]Q,  т.е. текущую
цепочку.  Выполняем  поиск  в  таблице  цепочек,  чтобы определить
входит ли в нее [.c.]Q. В данном случае этого, конечно, не  будет.
Ага!   Вот  теперь  нам  нужно  кое-что  сделать.   Добавим [.c.]Q
(которая в данном случае есть PQ) в таблицу цепочек под кодом #32,
и выведем  код для  [.c.] в  поток кодов.   Теперь начнем  опять с
текущего   префикса,   соответствующего   корню   P.    Продолжаем
добавление символов  к [.c.],  чтобы сформировать  [.c.]K, до  тех





пор, пока мы не сможем найти [.c.]K в таблице цепочек. Затем выводим код для [.c.] и добавляем [.c.]K в таблицу цепочек. На псевдо коде алгоритм будет описан приблизительно так: [1] Инициализация таблицы цепочек; [2] [.c.] <- пусто; [3] K <- следующий символ в потоке символов; [4] Входит ли [.c.]K в таблицу цепочек? (да: [.c.] <- [.c.]K; go to [3]; ) (нет: добавить [.c.]K в таблицу цепочек; вывести код для [.c.] в поток кодов; [.c.] <- K; go to [3]; ) - 3 - Насколько это просто! Конечно, когда мы выполняем шаг [3] и в входном потоке не остается больше символов, вы выводите код для [.c.] и покидаете таблицу. Все сделано. Хотите пример? Давайте предположим, что мы имеем 4-символьный алфавит: A,B,C,D. Поток символов выглядит как ABACABA. Давайте сожмем его. Сначала мы инициализируем нашу таблицу цепочек: #0=A, #1=B, #2=C, #3=D. Первый символ есть A, который входит в таблицу цепочек, следовательно [.c.] становится равным A. Далее мы берем AB, которая не входит в таблицу, следовательно мы выводим код #0 (для [.c.]), и добавляем AB в таблицу цепочек с кодом #4. [.c.] становится равным B. Далее мы берем [.c.]A = BA, которая не входит в таблицу цепочек, следовательно выводим код #1, и добавляем BA в таблицу цепочек с кодом #5. [.c.] становится равным A. Далее мы берем AC, которая не входит в таблицу цепочек. Выводим код #0, и добавляем AC в таблицу цепочек с кодом #6. Теперь [.c.] равно C. Далее мы берем [.c.]A = CA, которая не входит в таблицу. Выводим #2 для C, и добавляем CA к таблице под кодом #7. Теперь [.c.]=A. Далее мы берем AB, которая ВХОДИТ в таблицу цепочек, следовательно [.c.] становится равным AB, и мы ищем ABA, которой нет в таблице цепочек, поэтому мы выводим код для AB, который равен #4, и добавляем ABA в таблицу цепочек под кодом #8. [.c.] равно A. Мы не можем более взять символов, поэтому мы выводим код #0 для A и заканчиваем. Следовательно, поток кодов равен #0#1#0#2#4#0. Несколько слов (три) следует сказать об эффективности: используйте стратегию хеширования. Поиск в таблице цепочек может быть сопряжен со значительными вычислениями и хеширование значительно снижает эти затраты. Обратите внимание, что "прямое LZW" сжатие работает с риском переполнения таблицы цепочек - получается код, который не может быть представлен числом битов, ранее установленных для кодов. Существует несколько путей для того, чтобы справиться с этой проблемой и GIF реализует самый простой из них. Мы будем делать также. Важным моментом, на который стоит обратить внимание, является то, что в любой точке во время сжатия выполняется условие: если [...]K входит в таблицу цепочек, то [...] тоже входит в нее. Это обстоятельство приводит к эффективному методу запоминания цепочек в таблице. Вместо того, чтобы запоминать в таблице всю цепочку, используйте тот факт, любая цепочка может быть представлена как префикс плюс символ: [...]K. Если вы вносите [...]K в таблицу, вы знаете, что [...] уже находится в ней, и поэтому вы можете запомнить код для [...] плюс замыкающий символ K. Это все, о чем следует заботиться при сжатии. Раскрытие, возможно более сложно концептуально, однако программная реализация его проще. - 4 - Опишем как это делается. Мы опять начинаем с инициализации таблицы цепочек. Эта таблица образуется исходя из тех знаний, которыми мы располагаем о порождаемом в конце концов потоке символов, например, о возможных значениях символов. В GIF-файлах эта информация находится в заголовке, как число возможных значений пикселов. Однако, прелесть LZW состоит в том, что это все, что нам нужно. Сжатие было выполнено таким образом, что мы никогда не встретим в потоке кодов код, который мы не могли бы преобразовать в цепочку. Нам необходимо определить нечто, называемое "текущим кодом", на что мы будем ссылаться как "", и "старым кодом", на который будем ссылаться как "". Чтобы начать распаковку возьмем первый код. Теперь он становится . Этот код будет инициализировать таблицу цепочек в качестве корневого. Выводим корень в поток символов. Делаем этот код старым кодом . (*) Теперь берем следующий код и присваиваем его . Возможно, что этот код не входит в таблицу цепочек, но давайте пока предположим, что он там есть. Выводим цепочку, соответствующую в поток символов. Теперь найдем первый символ в цепочке, которую вы только что получили. Назовем его K. Добавим его к префиксу [...], сгенерированному посредством , чтобы получить новую цепочку [...]K. Добавим эту цепочку в таблицу цепочек и установим старый код равным текущему коду . Повторяйте от того места, которое я обозначил звездочкой и вы все сделаете. Прочтите этот абзац еще раз, если вы только "пробежались" по нему!!! Теперь давайте рассмотрим ту возможность, что не входит в таблицу цепочек. Вернемся обратно к сжатию и постараемся


Страницы : [1] 2


adfun.ru









Форум раскрутка сайта и интернет-реклама
реклама - рекламное агентство -
Интернет PR агентство чат и форум
волчат знакомства - сайт знакомств
бесплатные компьютерные игры
фото знакомства
новые стеклопакеты -
качественное остекление балконов
портал - пластиковые окна -
закажите окна пвх в Москве

частная стоматология в Москве:
надежная стоматологическая клиника
протезирование зубов и
отбеливание зубов в стоматологии
Музыка - скачать mp3 музыка
каталог партнерские программы
ручной бесплатный обмен ссылками цифровые камеры цифровые фотоаппараты -
цифровые видеокамеры

театры - заказ билетов в театр -
магазин - продажа компьютеров
в Москве форум Испания - жилье -
недвижимость в испании

турфирма - испания туры
Переводы - бюро переводов
Законы - закон о товарных знаках,
Грузовые перевозки. АсМАП. Дальнобой закон о рекламе
Интернет казино
реклама на форуме и контекстная реклама
на Яндексе Баннерная сеть и
интернет каталог сайтов Holiday.Ru
Форумы политика, лучшие анекдоты
знакомства.