Я пытаюсь понять, как создать .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»
Я попытаюсь повторить работу, чтобы увидеть, получу ли я другой ответ
Возможно, вы допустили ошибку в строке 4:
001 010 110 121 8
В строке 3 «010» игнорируется, поэтому сначала нужно добавить его в строку 4.
А в строке 4 речь идет о:
current next output dict
010 001 010 010 001 212 8
Вот мое решение (также созданное вручную):
Наконец выяснили почему:
Когда вы кодируете данные, вы увеличиваете размер кода, как только вы записываете код, равный 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