Технологии

Многостраничный TIFF, сжатие LZW и слои: устройство формата

Снаружи TIFF — просто тяжёлый файл с картинкой. Внутри — на удивление продуманная конструкция: восемь байт заголовка, картотека «тегов», цепочка страниц и несколько способов сжатия без потерь. Разберём её по винтикам — без академической зауми, но честно: после этой статьи вы поймёте, почему один .tif хранит десятки страниц, как LZW ужимает файл, ничего не теряя, и чем BigTIFF отличается от обычного.

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

Анатомия TIFF: заголовок → IFD → пиксели

Любой TIFF читается по одной простой схеме: маленький заголовок указывает на каталог, а каталог указывает на пиксели. Всего три уровня — но именно эта связка ссылками делает формат таким гибким.

Файл открывается 8-байтовым заголовком. Первые два байта — порядок байтов: II (от Intel, младший байт первым) или MM (от Motorola, старший первым). Дальше идёт «магическое число» 42 — подпись, по которой программа понимает, что перед ней действительно TIFF, а не что-то другое. Последние четыре байта заголовка — это адрес: смещение до первого каталога изображения внутри файла.

Этот каталог называется IFD (Image File Directory, каталог изображения). Думайте о нём как об оглавлении одной картинки: он не содержит самих пикселей, а перечисляет, что это за изображение и где лежат его данные. Сам IFD устроен предельно регулярно: сначала идёт двухбайтовый счётчик — сколько в нём записей, затем строго по 12 байт на каждую запись (это и есть теги), а в самом конце — 4 байта со ссылкой на следующий IFD (или нули, если он последний).

Ключевая идея

TIFF — это не монолит, а конструктор из блоков, связанных адресами. Заголовок знает, где первый IFD; IFD знает, где пиксели и где следующий IFD. Поэтому данные могут лежать в файле в любом порядке — программа всё равно найдёт их по ссылкам.

Теги: почему формат называется «помеченным»

Буква T в TIFF — это Tagged, «помеченный». В этом вся суть. Каждая характеристика изображения записана отдельным тегом — короткой записью «параметр → значение». Ширина? Тег. Высота? Тег. Тип сжатия, разрешение в DPI, цветовая модель, ориентация, число бит на канал, адреса пиксельных данных — всё это отдельные пронумерованные теги.

Каждый тег занимает ровно 12 байт и состоит из четырёх частей: номер тега (что это за параметр), тип данных (число, строка, дробь), количество значений и, наконец, само значение или адрес. Хитрость: если значение помещается в 4 байта, оно лежит прямо в теге; если нет — там адрес, по которому значение записано в другом месте файла. Так каталог остаётся компактным, а длинные данные не раздувают его.

Именно «теговость» делает TIFF почти бессмертным. Программа читает теги, которые знает, и спокойно пропускает незнакомые. Поэтому файл из 1990-х открывается сегодня, а новые возможности (новый тип сжатия, географические координаты, цветовой профиль) добавляются просто как новые теги — старый софт их не понимает, но и не ломается.

Заголовок
8 байт: II/MM + 42 + адрес IFD
Магическое число
42 (0x2A)
Один тег
12 байт
Тегов в спецификации
70+ стандартных
Данные пикселей
полосы (strips) или тайлы (tiles)
Несколько страниц
цепочка IFD
Глубина цвета
до 16 бит (и 32 бит float)
Порог BigTIFF
4 ГБ (32-битные адреса)

Полосы и тайлы: как уложены пиксели

Сами пиксели TIFF хранит не одним сплошным куском, а разбитыми на части. Так удобнее: программа может загрузить нужный фрагмент огромного изображения, не читая весь файл, а каждый кусок сжимается независимо. Есть два способа разбивки.

  • Полосы (strips). Картинка режется горизонтальными лентами — по несколько строк пикселей в каждой. Это базовый, самый распространённый способ; такой TIFF умеет открыть любая программа.
  • Тайлы (tiles). Картинка режется на прямоугольные плитки одинакового размера, как мозаика. Это эффективнее для очень больших изображений — карт, спутниковых снимков, сканов в сотни мегапикселей: чтобы показать кусочек, достаточно прочитать несколько плиток.

Адреса и длины этих кусков — тоже теги (для полос свои, для тайлов свои). По ним программа точно знает, в каком месте файла лежит каждая лента или плитка и сколько байт занимает.

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

Многостраничность — это цепочка IFD

Теперь самое интересное — как в один .tif влезают десятки страниц. Секрет уже спрятан в анатомии: помните те 4 байта в конце каждого IFD со ссылкой на следующий каталог? Это и есть механизм многостраничности.

Каждая страница — это отдельный IFD со своими тегами и своими пикселями. Первая страница ссылается на вторую, вторая — на третью, и так далее. Последний IFD вместо адреса содержит нули — это сигнал «дальше ничего нет». Получается односвязный список, как вагоны поезда, сцепленные друг с другом.

Важная деталь: страницы независимы. Одна может быть цветным сканом фотографии в LZW, следующая — чёрно-белым листом текста в компактном CCITT-сжатии, у каждой своё разрешение и размер. Именно поэтому сканеры и факсы так любят TIFF: целый многостраничный договор уезжает одним файлом, а внутри каждый лист оптимально упакован.

1

Читаем заголовок

Берём первые 8 байт: определяем порядок байтов, проверяем число 42 и узнаём адрес первого IFD.

2

Открываем первый IFD

Читаем счётчик тегов, разбираем теги: размер, цвет, сжатие, адреса полос или тайлов. Это страница 1.

3

Собираем пиксели

По адресам из тегов достаём полосы или тайлы, при необходимости распаковываем — страница готова к показу.

4

Переходим по ссылке

В конце IFD берём адрес следующего каталога. Не ноль — повторяем шаги 2–3 для следующей страницы; ноль — файл закончился.

Зачем это знать

Многостраничный TIFF — фактически готовый документ. Самый естественный способ им поделиться — собрать страницы в один PDF: порядок и независимость листов сохранятся, а открыть его сможет кто угодно. Сделать это можно в конвертере TIFF в PDF.

Сжатие LZW простыми словами

Внутри полос и тайлов пиксели обычно сжаты. Самый знаменитый метод в TIFF — LZW (Lempel–Ziv–Welch), тот же алгоритм, что когда-то применялся в GIF. Главное про него: он сжимает без потерь. Распакованный файл побайтово совпадает с оригиналом — ни один пиксель не страдает, в отличие от JPEG.

Работает LZW как умный словарь. Представьте, что вы переписываете текст и заметили, что слово «изображение» встречается сто раз. Вместо того чтобы писать его целиком, вы один раз заводите сокращение — скажем, «#7» — и дальше пишете только его. LZW делает то же самое с последовательностями байтов: находит повторяющиеся цепочки, заносит их в словарь и заменяет короткими кодами. Чем больше в данных повторов, тем сильнее сжатие.

Красота в том, что словарь не нужно хранить в файле. И упаковщик, и распаковщик строят его на лету по одним и тем же правилам, читая данные по порядку. Поэтому при открытии словарь восстанавливается сам собой, и картинка собирается точь-в-точь как была.

LZW не выбрасывает данные — он находит в них повторы и заменяет их сокращениями. Поэтому файл легче, а качество не меняется ни на пиксель.

Есть тонкость, о которой полезно знать. На ровных областях (логотипы, схемы, текст, чёрно-белые сканы) повторов много — LZW работает отлично. А на шумных фотографиях соседние пиксели почти всегда чуть разные, повторов мало, и выигрыш скромнее. Хуже того, на 16-битных изображениях «в лоб» LZW иногда даже раздувает файл. Спасает предиктор (predictor) — приём, при котором вместо самих значений пикселей записывается разница с соседом. У плавных градиентов соседи близки, разницы получаются маленькими и однообразными, и тут уже и LZW, и ZIP сжимают заметно плотнее.

Другие способы сжатия и когда что брать

LZW — не единственный вариант. TIFF задумывался как «контейнер», и тип сжатия в нём — просто значение одного из тегов. Вот основные режимы и для чего каждый хорош.

МетодПотериСильная сторонаКогда брать
Без сжатияНетМаксимальная совместимость, мгновенное чтениеПромежуточные файлы, древний софт
LZWНетБыстро, поддерживается почти вездеГрафика, текст, универсальный выбор
ZIP (Deflate)НетСжимает плотнее, особенно с предикторомФотографии, 16-битные файлы
PackBitsНетПростейший, очень быстрыйПростая графика, обмен между программами
CCITT G3/G4НетКрошечный размер для ч/б документовСканы текста, факсы (1 бит)
JPEG-в-TIFFЕстьСамый малый весРедко: когда вес важнее точности

Пара ориентиров без формул. CCITT G4 — чемпион по сжатию чёрно-белого текста: многостраничный скан договора в нём весит копейки, поэтому его и ставят сканеры. ZIP с предиктором — лучший дефолт для фотографий и глубокого цвета. LZW — когда нужна максимальная совместимость со старыми программами. А JPEG-в-TIFF существует, но идёт вразрез с самой идеей формата: если уже жертвовать качеством, проще сохранить отдельный JPG из TIFF.

Слои, прозрачность и альфа-канал

TIFF умеет хранить больше, чем просто цветные каналы. Здесь часто всё путают, поэтому разложим по полочкам — это два разных механизма.

Прозрачность (альфа-канал). Кроме каналов цвета (RGB или CMYK), TIFF добавляет «дополнительные сэмплы» — теги ExtraSamples. Один из них и есть альфа: для каждого пикселя он задаёт степень прозрачности. Бывает двух видов. Неассоциированный альфа хранит цвет и прозрачность раздельно — это привычная маска. Ассоциированный (предумноженный) — цвет заранее перемножен на прозрачность; так быстрее накладывать слои друг на друга, но это нужно учитывать при конвертации, иначе по краям появится тёмная или светлая кайма.

Слои Photoshop. А вот полноценные слои (как в PSD) TIFF хранит хитрее. Само изображение всегда лежит сведённым — это видят все программы. А отдельные слои Photoshop прячет в приватный тег ImageSourceData. Открыть такой файл в Photoshop — слои на месте; открыть в любом другом просмотрщике — увидите только финальную картинку.

Не доверяйте слоям в TIFF

Слои в TIFF понимает по сути только Photoshop, и тег ImageSourceData ощутимо раздувает файл. Если нужны живые слои — храните рабочий файл в PSD. TIFF со слоями стоит воспринимать как страховку «на всякий случай», а не как универсальный формат для обмена слоями.

Многослойная топографическая карта с линиями высот — аналогия слоёв и геопривязки в GeoTIFF
Слой за слоем, координата за координатой: эту логику GeoTIFF переносит прямо в теги файла. Фото: Pexels

BigTIFF и GeoTIFF: гиганты и спецверсии

У классического TIFF есть жёсткий потолок. Все адреса внутри файла — 32-битные, а это значит, что файл не может быть больше 4 гигабайт: дальше адресам просто не хватает разрядов, чтобы указать на нужный байт. Для фотографии это бесконечно много, но для спутникового снимка целой страны или микроскопии в сверхвысоком разрешении — впритык.

BigTIFF снимает ограничение. По сути это тот же TIFF, но с 64-битными адресами; и магическое число в заголовке меняется с 42 на 43 — по нему программа сразу понимает, что перед ней «большая» версия. Теоретический предел вырастает до астрономических величин (миллионы петабайт), так что про 4 ГБ можно забыть. Снаружи всё то же — те же теги, та же логика IFD, — просто адреса шире.

GeoTIFF решает другую задачу — не размер, а смысл. Обычная картинка не знает, какому месту на Земле соответствует её пиксель. GeoTIFF добавляет несколько специальных тегов с географической привязкой: масштаб пикселя на местности (ModelPixelScale), опорные точки (ModelTiepoint) и описание системы координат (GeoKeyDirectory). Благодаря «теговой» природе формата это просто новые теги — старые программы их игнорируют и всё равно показывают картинку, а ГИС-софт читает и точно сажает снимок на карту. GeoTIFF — стандарт де-факто для спутниковых снимков, карт высот и аэрофотосъёмки, и его часто сочетают с BigTIFF, потому что такие данные легко перешагивают 4 ГБ.

Что из этого следует на практике

Знание внутренностей — это не теория ради теории. Вот как оно помогает в обычных задачах.

  • Понимаете, почему TIFF тяжёлый. Сжатие без потерь не выбрасывает данные, а лишь ищет повторы. Поэтому фото в TIFF в разы больше JPG — и это нормально для мастер-файла.
  • Выбираете сжатие осознанно. Текст и сканы — CCITT G4, фотографии — ZIP с предиктором, нужна максимальная совместимость — LZW. Это прямо влияет на размер файла.
  • Не теряете страницы при конвертации. Зная, что многостраничность — это цепочка IFD, вы не удивитесь, что хороший конвертер сохраняет все листы. Для документа выбирайте TIFF в PDF, для одной картинки — TIFF в JPG.
  • Аккуратны со слоями и альфой. Слои живут только в Photoshop, а предумноженную альфу нужно обрабатывать правильно, иначе получите кайму по краям.

Соберите многостраничный TIFF в удобный PDF

Цепочку страниц из .tif удобнее всего превратить в один PDF — порядок листов сохранится, а открыть файл сможет кто угодно и где угодно. Бесплатно, прямо в браузере, без установки и регистрации.

Конвертировать TIFF в PDF

Нужна не сборка документа, а лёгкая копия одной картинки для веба или пересылки? Тогда подойдёт TIFF в JPG. А весь список преобразований всегда есть на странице всех форматов.

IFD (Image File Directory, каталог изображения) — это оглавление одной картинки внутри TIFF. Это список тегов, которые описывают ширину, высоту, цвет, тип сжатия и адреса самих пикселей. Файл начинается с 8-байтового заголовка, который указывает на первый IFD; каждый IFD заканчивается ссылкой на следующий. Эта цепочка и делает TIFF многостраничным.
Многостраничность в TIFF — это цепочка IFD. Каждая страница описывается собственным каталогом IFD со своими пикселями, а в конце каждого IFD стоит адрес следующего. Программа читает первую страницу, переходит по ссылке ко второй и так далее, пока ссылка не станет нулевой. Поэтому один файл .tif может хранить десятки отсканированных листов.
LZW сжимает без потерь. Это словарный алгоритм: он находит повторяющиеся последовательности байтов, заносит их в словарь и заменяет короткими кодами. При распаковке словарь восстанавливается, и изображение получается побайтово идентичным оригиналу. Ни один пиксель не теряется — в отличие от JPEG.
Оба метода сжимают без потерь, но по-разному. LZW старше, быстрее и совместим почти со всем софтом. ZIP (Deflate) обычно сжимает плотнее, особенно фотографии и совместно с предиктором, но чуть медленнее и реже встречается в старых программах. Для фотографий чаще выбирают ZIP, для максимальной совместимости — LZW.
Прозрачность — да: TIFF поддерживает альфа-канал через дополнительный сэмпл (ExtraSamples), как ассоциированный (предумноженный), так и неассоциированный. Слои Photoshop тоже можно сохранить, но они лежат в приватном теге ImageSourceData и видны только в Photoshop. Другие программы покажут лишь сведённое изображение, поэтому слои в TIFF — это страховка для самого Photoshop, а не универсальный формат слоёв.