Технологии

Альфа-канал и RLE: как TGA устроен внутри

TGA — один из самых простых форматов изображений, и это отличный повод заглянуть «под капот» без страха утонуть в деталях. Разберём по байтам: заголовок из 18 байт, типы 2 и 10, алгоритм RLE на пальцах, как хранится прозрачность и что за загадочная подпись TRUEVISION-XFILE прячется в конце файла.

Прозрачные кристаллы с цветными бликами — визуальная метафора альфа-канала и устройства данных в TGA
Прозрачность и простая структура — два кита, на которых стоит формат TGA. Фото: Pexels

Анатомия файла: три части

Если заглянуть внутрь файла .tga специальной программой, которая показывает его «сырое» содержимое (так называемый шестнадцатеричный редактор), видно, что формат на удивление логичен. Любой TGA-файл (в современной версии 2.0) состоит из трёх крупных частей:

  1. Заголовок — короткий блок в начале, описывающий картинку.
  2. Данные изображения — собственно пиксели, со сжатием или без.
  3. Footer — необязательный «хвост» в конце с метаданными и подписью формата.

Никаких контрольных сумм на каждый блок, как в PNG, и никакой энтропийной магии, как в JPEG. Эта простота — фирменная черта TGA; если хочется понять, откуда она взялась исторически, загляните в статью «Что такое TGA».

Не пугайтесь байтов

Дальше будут конкретные смещения и значения, но идея проста: заголовок говорит, что за картинка, данные хранят пиксели, а footer добавляет метаданные. Понять формат можно и без программирования.

Заголовок из 18 байт

Сердце формата — компактный заголовок ровно из 18 байт. В нём упаковано всё, что нужно декодеру, чтобы правильно прочитать пиксели. Вот ключевые поля:

Байт 0 — ID Length
Длина текстового описания после заголовка (0–255)
Байт 1 — Color Map Type
Есть ли палитра (0 — нет, 1 — да)
Байт 2 — Image Type
Тип изображения и сжатие (2, 10 и др.)
Байты 8–11 — Origin
Координаты начала отсчёта (X, Y)
Байты 12–15 — Размеры
Ширина и высота изображения
Байт 16 — Pixel Depth
Бит на пиксель: 8, 16, 24 или 32
Байт 17 — Descriptor
Биты альфа-канала и порядок строк

Любопытная особенность: в самом начале файла нет «магической» сигнатуры. Большинство форматов начинаются с опознавательных байтов (PNG — с ‰PNG, JPEG — с FF D8), а TGA сразу стартует с длины описания. Поэтому надёжно опознать TGA по началу файла нельзя — приходится либо смотреть на подпись в footer (см. ниже), либо доверять расширению.

Типы изображения: 2, 10 и другие

Второй байт заголовка — Image Type — пожалуй, самое важное поле. Именно оно решает, как именно хранятся пиксели. Значений несколько:

ТипЧто этоСжатие
1Цвет из палитрыНет
2Полноцветное (true-color)Нет
3Оттенки серогоНет
9Цвет из палитрыRLE
10Полноцветное (true-color)RLE
11Оттенки серогоRLE

На практике вы почти всегда встретите два значения: тип 2 (несжатый true-color) и тип 10 (тот же true-color, но сжатый RLE). Остальные типы — наследие 1980-х, когда память была дорогой и изображения часто хранили через палитру. Заметьте симметрию: типы 9, 10 и 11 — это ровно типы 1, 2 и 3 плюс RLE.

Сетка синих кубиков — пиксели, которые TGA хранит либо подряд, либо сжатыми пакетами RLE
Пиксели TGA: тип 2 пишет их подряд, тип 10 группирует одинаковые в пакеты RLE. Фото: Pexels

RLE-сжатие на пальцах

RLE (Run-Length Encoding) в TGA устроен очень наглядно — это простой и давно известный способ сжатия (тот же, что применяли, например, на старых компьютерах Mac). Изображение кодируется не пиксель за пикселем, а пакетами. Каждый пакет начинается с одного служебного байта. У него есть самый первый, «главный» бит (в технике его зовут старшим), и именно он решает, что будет дальше:

1

Старший бит = 1: пакет-повтор

Оставшиеся 7 бит задают число N. Дальше идёт один пиксель, который надо повторить N+1 раз. Так «синий ×40» занимает всего несколько байт.

2

Старший бит = 0: «сырой» пакет

Оставшиеся 7 бит задают N. Дальше идут N+1 разных пикселей подряд, каждый записан как есть — для участков, где всё пёстрое.

3

Повторяем до конца

Декодер читает пакет за пакетом, пока не наберёт всю строку (а затем и всё изображение).

Гениальность в том, что декодеру не нужно ничего «угадывать»: первый бит каждого пакета прямо говорит, повтор это или набор разных пикселей. Поэтому RLE распаковывается мгновенно. Минус — он эффективен только там, где есть длинные ряды одинаковых пикселей: на иконках, логотипах, ровных фонах. На фотографии, где почти каждый пиксель уникален, RLE может даже чуть-чуть увеличить размер (из-за управляющих байтов). Подробнее о том, как это влияет на вес файла, — в сравнении «TGA против PNG».

Первый бит каждого RLE-пакета — это вопрос «повторять или читать дальше?». Вся хитрость сжатия TGA умещается в один бит.

Альфа-канал: 8 бит на прозрачность

Теперь о прозрачности. Сколько бит уходит на альфа-канал, зависит от глубины цвета пикселя:

  • 32 бита: 8 бит на красный, 8 на зелёный, 8 на синий и 8 на альфу. Это 256 уровней прозрачности — плавные полупрозрачные тени, стекло, дым.
  • 16 бит: по 5 бит на цвет и всего 1 бит на альфу — пиксель либо полностью виден, либо полностью прозрачен, без полутонов.
  • 24 бита: только цвет, альфа-канала нет.

Сколько именно бит отведено под прозрачность, записано в младших битах байта 17 (Image Descriptor). Там же лежит флаг порядка строк — он-то и отвечает за классическую проблему «перевёрнутого» TGA: старые файлы хранят строки снизу вверх, и если декодер это поле проигнорирует, картинка окажется вверх ногами.

Полупрозрачная зелёная объёмная структура — наглядно про слои и уровни прозрачности альфа-канала
8-битный альфа-канал даёт 256 уровней прозрачности — от полной видимости до невидимости. Фото: Pexels

В 1989 году вышла версия формата 2.0, которая добавила в конец файла необязательный footer длиной 26 байт. Это и есть граница между старым TGA 1.0 и современным 2.0. Footer хранит:

  • Смещение к области расширений (4 байта) — там лежат дата, имя автора, настройка яркости (гамма) и маленькая картинка-превью.
  • Смещение к области разработчика (4 байта) — место для произвольных данных конкретной программы.
  • Подпись — ASCII-строка TRUEVISION-XFILE. с завершающим нулевым байтом (18 байт).

Та самая подпись TRUEVISION-XFILE — это «опознавательный знак» TGA 2.0. Поскольку в начале файла сигнатуры нет, именно по этой строке в конце программы понимают, что перед ними честный TGA версии 2.0, а не обрезок или файл старой версии.

18байт в заголовке
26байт в footer 2.0
1989год версии 2.0

Зачем это знать на практике

Понимание внутренней кухни TGA — это не только эрудиция. Оно помогает в реальных ситуациях:

  • Осознанный экспорт. Зная про типы 2 и 10, вы понимаете, что галочка «RLE» при сохранении — это выбор между «меньше размер» и «совсем без сжатия», и оба варианта без потерь.
  • 32 против 24 бит. Нужна прозрачность — сохраняйте 32 бита (с альфой). Не нужна — 24 бита сэкономят место.
  • «Перевёрнутая» картинка. Теперь вы знаете, что виноват флаг порядка строк в дескрипторе, и проблема лечится отражением по вертикали.

А если задача проще — просто открыть или опубликовать TGA, — глубоко в байты лезть не нужно: достаточно конвертировать файл в PNG, и все эти заголовки, типы и footer декодер обработает за вас.

Не хотите разбираться в байтах? Просто откройте TGA

Бесплатный конвертер FormatZ прочитает заголовок, распакует RLE и сохранит альфа-канал — а вам отдаст готовый PNG за пару секунд.

Конвертировать TGA в PNG

Нужно собрать TGA из картинки с нужной глубиной и сжатием? Используйте PNG → TGA. Полный список преобразований — на странице форматов. А чтобы увидеть, где вся эта анатомия применяется на деле, прочитайте «TGA в играх и графике».

Это значение второго байта заголовка, которое говорит, как хранятся пиксели. Тип 2 — несжатое полноцветное изображение (true-color). Тип 10 — то же самое, но сжатое алгоритмом RLE. Есть и другие типы: 1 и 9 для изображений с палитрой, 3 и 11 — для оттенков серого.
RLE кодирует строки пикселей пакетами. Каждый пакет начинается с управляющего байта: если старший бит равен 1, это «повтор» — следующий пиксель повторяется N+1 раз; если 0, это «сырой» пакет — дальше идут N+1 разных пикселей подряд. Так одинаковые пиксели хранятся компактно, а сжатие остаётся без потерь.
В 32-битном TGA на альфа-канал отводится 8 бит — это 256 уровней прозрачности. В 16-битном варианте на альфу приходится всего 1 бит (пиксель либо виден, либо нет). Число бит прозрачности записано в младших битах поля «дескриптор изображения» в заголовке.
Footer — это необязательный «хвост» из 26 байт в конце файла, добавленный в TGA версии 2.0 (1989). Он содержит смещения к области расширений и области разработчика, а заканчивается подписью «TRUEVISION-XFILE.» с нулевым байтом. По этой подписи можно отличить TGA 2.0 от старой версии 1.0.
Это помогает осознанно выбирать настройки при сохранении (сжатие RLE или нет, 24 или 32 бита), понимать, откуда берётся прозрачность и почему файл такой большой, и диагностировать проблемы вроде перевёрнутого изображения. А чтобы просто открыть TGA, достаточно конвертировать его в PNG.