Кодировка LZW и формат файла GIF

Я пытаюсь понять, как создать .gif файл в C ++. Пока я думаю, что понимаю все, кроме как LZW кодирование работает. Это файл, который я сгенерировал с метками:

47 49 46 38 39 61 -header
0A 00 01 00 91 00 -logical screen descriptor
00 00 FF 00 FF 00 -color table [green,red,yellow,black]
00 FF FF 00 00 00
00 21 F9 04 00 00 -graphics control extension
00 00 00 2C 00 00 -image descriptor
00 00 0A 00 01 00 -(10 pixels wide x 1 pixel tall)
00 02 04 8A 05 00 -encoded image
3B                -terminator

И здесь снова без наклеек для копирования / вставки: 47 49 46 38 39 61 05 00 04 00 91 00 00 00 FF 00 FF 00 00 FF FF 00 00 00 00 21 F9 04 00 00 00 00 00 2C 00 00 00 00 0A 00 01 00 00 02 04 8A 05 00 3B

У меня много проблем с пониманием того, как 02 04 8A 05 переводит на изображение yryryggyry, Я знаю 02 минимальный размер кода, а 04 длина блока изображения, и я думаю, что я определил четкие и EOI коды, но я не понимаю код между ними.

8A       05
10001010 00000101
100|01010 00000|101
^      ????     ^
clear code      EOI code

До сих пор я получил больше информации от .gif Спецификация:
http://www.w3.org/Graphics/GIF/spec-gif89a.txt

И этот сайт был также полезен:
http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp

Спасибо

РЕДАКТИРОВАТЬ*

Я посмотрел видео с YouTube, связанное в комментариях, и закодировал изображение вручную для цветного потока «yryryggyry»:

Color table-012=gry

2   1   2   1   2   0   0   2   1   2
010 001 010 001 010 000 000 010 001 010

current next output dict
010     001  010    21 6
001     010  001    12 7
010     001  -      -
001     010  110    121 8
010     000  010    212 9
000     000  000    00  10
000     010  1010   002 11
010     001  -      -
001     010  110    -
010     -    010    -

outputs-100 010 001 110 010 000 1010 110 010 101

01010101 4th 55
10101000 3rd A8
00101100 2nd 2C
01010100 1st 54

Code-54 2C A8 55

Должно быть, я сделал ошибку, потому что этот код создает изображение «yr» вместо «yryryggyry»

Я попытаюсь повторить работу, чтобы увидеть, получу ли я другой ответ

3

Решение

Возможно, вы допустили ошибку в строке 4:
001 010 110 121 8

В строке 3 «010» игнорируется, поэтому сначала нужно добавить его в строку 4.
А в строке 4 речь идет о:

current  next  output    dict
010 001  010   010 001   212   8

Вот мое решение (также созданное вручную):

LZW для yryryggyry

Наконец выяснили почему:

Когда вы кодируете данные, вы увеличиваете размер кода, как только вы записываете код, равный 2 ^ (текущий размер кода) -1. Если вы декодируете из кодов в индексы, вам нужно увеличить размер кода, как только вы добавите значение кода, равное 2 ^ (текущий размер кода) -1, в таблицу кодов. То есть в следующий раз, когда вы берете следующий раздел битов, вы получаете еще один.

Автор означает, что вам нужно увеличить размер слова, когда вы собираетесь вывести 2 ^ (текущий размер кода) — 1, но может быть другое объяснение, которое также кажется разумным:

Когда вы добавляете элемент # (2 ^ текущий размер кода) в таблицу кодов, следующий вывод должен увеличить размер слова.

Также правильно в примере автора, и это объяснение, которое я предпочитаю.

Вот ваш пример («Ырырыгыры»):

output sequence:
#4 #2 #1 #6 #2 #0 #0 #8 #5

Когда вы собираетесь вывести # 6, вы добавляете «yry» в вашу кодовую таблицу, которая имеет индекс # 8.

Так как 8 = 2 ^ текущий размер слова

(current word size = 2(original) + 1(reserved) = 3)

Следующий вывод должен увеличить размер слова, поэтому # 2 становится словом из 4 битов.

И окончательная последовательность вывода:

4   100
2   010
1   001
6   110
2   0010
0   0000
0   0000
8   1000
5   0101

После кодирования они становятся

54 2C 00 58

Таким образом, блок данных

02            -minimum word size
04            -data length
54 2c 00 58   -data
00            -data block terminator
1

Другие решения


По вопросам рекламы [email protected]