Формат GIF сложный, но не настолько сложный, как тот же JPEG. Попробую найти закономерности в его структуре.
00 6 "GIF89a" Строка магических символов, 6 байт
06 2 Ширина 16-битное Little Endian число, которое обозначает общую ширину картинки
08 2 Высота Аналогично, но высота картинки
0A 1 Logical Screen Desc Байт описания логического дескриптора экрана
7: Глобальная цветовая таблица
6..4: Цветовое разрешение
3: Флаг сортировки
2..0: Размер глобальной цветовой таблицы
0B 1 Индекс цвета фона Номер цвета, который будет фоновым
0C 1 Pixel Aspect Ratio
По байт Logical Screen Descriptor необходимо объяснить более подробно.
Старший бит (7) это бит присутствия глобальной таблицы цвета. Если он 0, то таблицы нет, иначе она есть и находится в заголовке. Существуют также локальные таблицы цвета, которые прикреплены к каждому фрейму GIF
Биты 6..4 (3 бита) означают цветовое разрешение, вычисляемое по формуле . Если n=7, то количество цветов будет равно 256, если n=0, то всего лишь 2 цвета – черный и белый (могут меняться в палитре)
Флаг сортировка (3-й бит) означает, что цвета в таблице отсортированы по наиболее встречаемым, то есть чем ближе к началу, тем цвет более частый или более важный в изображении. Флаг по сути, не имеет смысла, поэтому можно его оставлять 0.
Размер таблицы определяется точно так же, как и цветовое разрешение, то есть 7 будет означать 256 цветов в палитре
В случае, если Pixel Aspect Ratio задан не 0, то он вычисляется по формуле (N + 15) / 64, однако этот байл бесполезен и не играет никакой роли.
§ Глобальная таблица цветов
После заголовка, который занимает 13 байт, может идти глобальная таблица цветов (палитра), если она задана, конечно.
Размер таблицы зависит от заданного в заголовке размера:
Размер | Цветов | Реальный размер
0 2 6
1 4 12
2 8 24
3 16 48
4 32 96
5 64 192
6 128 384
7 256 768
То есть, если указан размер в дескрипторе, например, 7, то тогда будет описываться 256 цветов, что займет 768 байт. На каждый цвет приходится по 3 байта, которые идут в таком порядке: Red, Green, Blue – то есть, первый байт будет описывать красную компоненту, второй байт зеленую и третий – синюю.
§ Расширенный блок
GIF по сути, состоит из блоков с данными. За палитрой могут идти различные блоки данных, которые начинаются с определенного байта и всегда заканчиваются 00. Одним из важных блоков данных является блок с расширенной информацией. Его формат такой:
21 Всегда 21h, код блока расширения
F9 Наименование блока, тоже всегда F9h
04 Размер блока, тут тоже 4
XX Упакованное поле с параметрами
7..5: Зарезервировано, должно быть 000
4..2: Метод утилизации, без понятия что это такое
1: Пользовательский флаг (неизвестно для чего)
0: Флаг наличия прозрачного цвета
XX XX Время задержки, 16 битное беззнаковое число
XX Индекс прозрачного цвета в изображений
00 Всегда 0, завершение блока
Назначение некоторых флагов мне неизвестно, так что они должны быть равны 0. На всякий случай.
§ Дескриптор изображения
Основной блок, который описывает изображение, которое и будет выведено. Формат блока:
2C Всегда 2Ch, код блока дескриптора изображения
XX XX Точка X (слева), куда будет выведено изображения на общий холст
YY YY Точка Y (сверху)
WW WW Ширина выводимого изображения
HH HH Высота
XX Упакованное поле флагов
7: Локальная палитра, если 1, то за блоком дескриптора следует палитра для картинки
6: Чересстрочный флаг, если установлен, то изображение выводится через строку, а не последовательно
5: Sort flag, точно так же, не играет роли, как в глобальной палитре
4..3: Резервировано, должно быть 0
2..0: Размер таблицы, аналогично глобальной палитре
Следует отметить, что за дескриптором изображения может идти только палитра, а не упакованные данные. Для этой цели существует другой блок.
NN Количество байт от 1 до 255, которые следуют далее
..... Байты с упакованными данными LZW
00 Стоп-байт
Один блок с данными начинается с кодов от 02 до 08, которые говорят о том, каким образом упакованы пиксели.
S Цвета CLR EOI
2 0-3 4 5
3 0-7 8 9
4 0-15 16 17
5 0-31 32 33
6 0-63 64 65
7 0-127 128 129
8 0-255 256 257
CLR – это номер кода, при котором происходит сброс словаря LZW, а EOI – номер кода, при котором завершается вывод изображения. Но по поводу того, как упаковываются данные в LZW, требуется написать отдельную статью.
Пример: [02 = 2 бита на цвет] [16h = Длина данных] [8C 2D 99 87 2A 1C DC 33 A0 02 75 EC 95 FA A8 DE 60 8C 04 91 4C 01 = Данные] [00=END]
§ Блок текста
В GIF также можно вставлять блоки с текстом. Но только этот блок плохо поддерживается ПО, и даже не читаются некоторыми редакторами. Они описываются следующей структурой:
21 Магическое значение
01 Этот байт указывает, что это именно блок текста