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

Формат 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 бита) означают цветовое разрешение, вычисляемое по формуле 2^{n+1} . Если 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: Размер таблицы, аналогично глобальной палитре
Следует отметить, что за дескриптором изображения может идти только палитра, а не упакованные данные. Для этой цели существует другой блок.
Пример: [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-файла.