12:08
Формат GIF — Лисья нора
§ Структура заголовка
Формат 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 цветов в палитре
§ Глобальная таблица цветов
После заголовка, который занимает 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 257CLR — это номер кода, при котором происходит сброс словаря 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-файла.