Лисья Нора

Оглавление


§ Структура заголовка

Формат 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 необходимо объяснить более подробно.
В случае, если 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: Размер таблицы, аналогично глобальной палитре
Следует отметить, что за дескриптором изображения может идти только палитра, а не упакованные данные. Для этой цели существует другой блок.
Пример: [2C] [00 00 Слева] [00 00 Справа] [0A 00 Ширина] [0A 00 Высота] [00 Флаги]

§ Блок с упакованными данными

Общий вид блока такой:
02-08 LZW Minimum code size
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 Этот байт указывает, что это именно блок текста
XX Размер последующего блока с данными
... Некие бинарные данные, которые идут до текста
NN Длина последующего текста
... Текст
00 Окончание
Пример: [21 01] [0C=Размер блока] [00 00 00 00 64 00 64 00 14 14 01 00 = Блок данных] [0B=Размер текста] [68 65 6C 6C 6F 20 77 6F 72 6C 64 = Текст] [00=END]
Это довольно странный блок, как по мне. Не вижу его смысла.

§ Блок комментария

Позволяет вставлять в GIF совершенно произвольный текст.
21 Магическая константа
FE Тип блока (FEh): комментарий
NN Количество символов 1-255 текста
... Текст, размер указывается в NN
00 Окончание блока
Вот и вся структура.
Пример: [21 FE] [09=Размер] [62 6C 75 65 62 65 72 72 79] [00=END].

§ Расширение приложений

Существует также специальный блок для расширения возможностей GIF, например, для создания анимированных зацикленных изображений.
21 Магический код
FF Тип блока: Application Extension
0B Длина блока (11 байт)
"NETSCAPE" байт 4..11
"2.0" биты 12..14
03 Длина суб-блока (три байта далее)
01 Всегда это значение
XX XX Число от 0 до 65535, количество раз, сколько анимация должна быть повторена
00 Конец блока
Этот блок должен строго идти сразу же за описанием глобальной палитры (если есть), то есть, сразу же за заголовком.

§ Завершение

Если декомпрессор встретит вместо магического кода блока значение 3B, то завершает распаковку GIF-файла.