Структура и формат файла Photoshop. Часть 4: Layer and Mask Information Section

2012-02-16 papirosnik Photoshop

Эта статья обещает быть самой объёмной и информативной из всего цикла, так как содержит наиболее важную информацию о псд файле, а секция, которая здесь будет описана, имеет самый большой как абсолютный размер (в байтах), так и относительный (в логических блоках информации). Четвёртый блок (не путать с 4-м энергоблоком АЭС из Сталкера) содержит в себе огромное число информации, которая зачастую чередуется таким образом, что даже авторы оригинального документа (далее просто официальный документ) не могут вразумительно её описать. В этом документе есть информация, которая не только ничего не объясняет, а наоборот, запутывает и является ошибочной. Ну об этом по порядку.

Традиционно и этот блок начинается из 4-х байтового поля длины. И единственное, что обладает хоть каким-то постоянством в структуре псд — это неизменное поле длины в начале каждой секции. По-крайней мере эта традиция продержалась аж до 4-й секции. Забегая вперёд, скажу, что в последней, 5-й, секции, она будет нарушена. И если предыдущие три секции были относительно лёгкими, то здесь, готовьтесь —  начинается вся эта катавасия, о которой я говорил ещё в 1-й статье.

Сразу после 4-х байтов длины начинается блок: Layer info. Тут снова читаем четыре байта длины. Но теперь эта длина относится только к Layer Info.  И (Внимание!) может быть нулевой. Причём это поле может быть нулевым не только, если в Psd совсем нет слоёв, а также и в том случае, если этот документ создан в режиме 16- или 32-bit на канал. Об этом экзотическом случае — в конце статьи.

А пока же предположим, что у нас самая обычная псд-шка и всё идёт по тому сценарию, который описан в официальном документе. Сразу после поля длины Layer Info (и если эта длина не нулевая) расположено 2-х байтовое поле, которое означает количество слоёв. Причём это количество включает в себя и маркер начала группы (это отдельный невидимый слой), и маркер конца группы (это тоже отдельный слой). Предположим в вашей psd содержится 10 слоёв, которые собраны в две разные группы. Тогда из этого 2-х байтового поля вы получите число 14 (10 физических слоёв +2 на каждую группу). А ещё количество слоёв может быть отрицательным. Если такое случается, то берите его абсолютное значение, но где-то установите флажок, что первый встретившийся канал в данных есть альфа-маска для составной картинки (которая хранится в 5-й секции псд и будет описана в следующей статье).

Сразу же за полем с количеством слоёв следуют записи по каждому слою.
Приведу здесь структуру каждой записи, а пояснения — ниже.
Таблица 4.1 Информация о слое.

Длина Описание
4 * 4 Прямоугольник, содержащий размеры слоя: Определён как Верх, Лево, НИз, Право.
2 Количество каналов в слое
6 * 

число каналов

Информация о каждом канале. : 6 айт на канал, состоящие из: 

2 байта для ID канала: 0 = красный, 1 = зелёный, и т.д.;

-1 = маска прозрачности; -2 = пользовательская маска, -3 реальная пользовательская маска (когда представлены обе: и пользовательская, и векторная маски)

4 байта длины данных для соответствующего канала (В **PSB** это поле содержит 8 байт). Имеено в этих данных будет содержаться само изображение канала (см. ниже)

4 Сигнатура для блендинга: ‘8BIM’
4 Признак режима блендинга (нзначения оставляю без перевода, прим. автора):
‘norm’ = normal, ‘dark’ = darken, ‘lite’ = lighten, ‘hue ‘ = hue, ‘sat ‘ = saturation, ‘colr’ = color, ‘lum ‘ = luminosity, ‘mul ‘ = multiply, ‘scrn’ = screen, ‘diss’ = dissolve, ‘over’ = overlay, ‘hLit’ = hard light, ‘sLit’ = soft light, ‘diff’ = difference, ‘smud’ = exclusion, ‘div ‘ = color dodge, ‘idiv’ = color burn, ‘lbrn’ = linear burn, ‘lddg’ = linear dodge, ‘vLit’ = vivid light, ‘lLit’ = linear light, ‘pLit’ = pin light, ‘hMix’ = hard mix, ‘pass’ = pass through, ‘dkCl’ = darker color, ‘lgCl’ = lighter color, ‘fsub’ = subtract, ‘fdiv’ = divide
1 Прозрачность. 0 = прозрачный … 255 = непрозрачный
1 Отсечение: 0 = базовое, 1 = не базовое
1 Флаги: 

bit 0 = прозрачность заблокирована (замочком в фотошопе, прим. автора)
bit 1 = видимость (если установлен в 1 — то слой невидим, прим. автора);
bit 2 = устарел;
bit 3 = 1 для фотошопа 5.0 и выше,говорит о том, что бит 4 содержит полезную информацию;
bit 4 = пиксельные данные не относятся к отображению в документе

1 Наполнитель (ноль)
4 Длина дополнительных данных ( = общая длина следующих пяти полей; вот в этом месте вообще мало кому понятная дезинформация написана, прим. автора).
Перем. Данные маски слоя: Может быть 40 байт, 24 или 4 байта (если нет маски слоя). (пояснения ниже, прим. автора)
Перем. Границы блендинга слоя. (пояснения см. ниже, прим. автора.)
Перем. Имя слоя: Pascal-строка, расширенная так, чтобы её длина делилась на 4.

Уже веселее, не правда ли?
Уже можно кое-что прочитать, но надо прояснить, что хранится в последних трёх полях переменной длины и что там дезинформирующего в поле с длиной дополнительных данных. Начнём с Данных для маски слоя.
Эти данные структурированы так (перевод чуть ли не дословный, чтобы ничего не исказить и  не повторять, прим. автора (то бишь меня) даны в скобках и каждый раз обозначены):

Таблица 4.2 Данные маски слоя

Длина Описание
4 Размер данных: 36, 20, or 0. Если ноль, нижеследующие данные не представлены
4 * 4 Прямоугольник, обрамляющий маску: Верх, Лево, НИз, Право
1 Цвет по-умолчанию. 0 или 255
1 Флаги. 

бит 0 = позиция относится к слою
бит 1 = маска слоя запрещена (зачёркнута в фотошопе, прим. автора)
бит 2 = инвертировать маску слоя при блендинге

2 Выравнивание. Это поле существует, только если длина = 20.
1 Реальные флаги. Значение трактуется так же, как и Флаги выше.
1 Фон реальной пользовательской маски. 0 or 255.
Значение трактуется так же, как и Флаги выше (вообще бред, прим. автора)
4 * 4 Прямоугольник, ограничивающий реальную маску: Верх, Лево, Низ, Право.

Теперь разберём что хранится во втором поле переменной длины.

Таблица 4.3 Границы блендинга слоя

Длина Описание
4 Длина данных о границах блендинга лоя слоя
4 Составной серый для начальной границы блендинга. Содержит 2 значения чёрного с последующими 2 значениями беклого. Представлен, но не имеет смысла для  Lab & Grayscale.
4 Составной серый для конечной  границы блендинга
4 Начальная граница для 1-го канала
4 Конечная граница для 1-го канала
4 Начальная граница для 2-го канала
4 Конечная граница для 2-го канала
4 Начальная граница для N-го канала
4 Конечная граница для N-го канала

Ну что тут можно сказать. Если вы не пишите программу, имеющей своей целью повторить (или переплюнуть) фотошоп, читайте данные из таблицы 4.2 (на будущее), но игнорируйте их, потому что применить их  пока не на чём. Но если будете читать эти данные, знайте, что повторяющихся 8-байтных блоков может быть на 1 больше, чем количество слоёв, так как первый блок будет использоваться для альфа-маски составной картинки (именно об этом шла речь выше, там, где мы читали количество слоёв).

После того, как будут прочитаны данные, структура которых описана в 2-х последних таблицах, вернёмся к нашей основной: Информация о слое. Здесь остаётся третье (последнее) поле: Имя слоя. Сперва читаем байт длины строки. Затем указанное число байт самой строки. А потом надо выравняться как-то так, чтобы длина поля (или блока) была кратной 4-м. Иначе мы не попадём на правильное начало описания для след. блока. Я что-то не совсем понял, что там должно быть кратным 4-м, то ли длина строки, то ли граница блока, но такой код для выравнивания работает:
int a = (nameLen + 1) % 4;
if (a > 0) { for (int i = 4-a; i > 0; —i) ++index; }

Тут я что-то слегка намудрил… вижу, что этот код можно написать элегантнее (без условия и цикла), но не вижу как. Поэтому, раз  работает, то пусть себе и работает, тем более что это совсем не критичный участок кода.
Итак, начитавшись информации о текущем слое, казалось бы, можно переходить к следующему. Но после блока основной информации, может быть ещё блок с дополнительной. О её наличии говорит ненулевое поле «Длина дополнительных данных»  в таблице 4.1.
Итак, если размер дополнительных данных для слоя не равен нулю, то сразу за выровненным на 4 именем слоя идут блоки дополнительных данных. Эти блоки можно игнорировать, а можно и  разобрать каждый. Не вдаваяcь в подробности, привожу код (С#), читающий каждый блок:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ExtraInfo
{
      const uint _signature = 0x4D494238;		// 8BIM
      public ExtraInfo(byte[] buf, ref int index)
      {
          uint sig = BitConverter.ToUInt32(buf, index);
          if (sig != _signature)
          {
              return;
          }
          index += 4; 
 
          ID = new string(Encoding.Default.GetChars(buf, index, 4));
          index += 4;<code> </code>
 
          Size = Utils.Swap4b(BitConverter.ToUInt32(buf, index));
          index += 4;
 
          _data = new byte[Size];
          Buffer.BlockCopy(buf, index, _data, 0, Size);
          index += (int)Size;
 
          index += (index & 1); // rounding up to a multiple of 2
      }
 
      public string ID { get; internal set; }
      public uint Size { get; internal set; }
 
      private byte[] _data = null;
      public ReadOnlyCollection<byte> Data
      {
           get { return Array.AsReadOnly<byte>(_data); }
      }
}

В дополнительной иформации хранятcя блоки, описывающие данные разного рода. Не все они понадобятся. Лично я использовал блок с ID ==  ‘luni’ (юникодное имя слоя) и блок ID==’lsct’ (разделитель групп).

Прочитав дополнительную информацию о слое, переходим к чтению основной информации для следующего слоя, затем читаем его дополнительную (если есть) и так повторяем для каждого слоя. В результате, прочитав информацию по каждому слою, мы выйдем к тому месту, где хранится изображения слоёв. Если вернуться к самому началу, то последовательность наших действий будет выглядеть так:
1. Читаем длину секции, если она нулевая, то на этом и всё
2. Если же длина ненулевая, то читаем Layer Info
2.1 Читаем длину Layer Info
2.2 Читаем кол-во слоёв
2.3 Читаем Информацию по очередному слою (включая маски и границы блендинга)
2.4 Читаем дополнительную информацию по очередному слою
2.5 Повторяем два предыдущих пункта для каждого слоя
3. Читаем изображение для каждого слоя (порядок слоёв тот же)

Как выполнить пункт три — расскажу в след. статье, это отдельная обширная тема, тем более она понадобиться для чтения и  5-й секции Psd. А пока мы получили необходимый минимум, чтобы читать информацию о структуре псд. Мы уже умеем открывать псд-шку, извлекать из неё кое-какие данные, но пока ещё не получили ни одного пиксела изображения. На этом этапе, если Вам нужны только данные о слоях и не нужны изображения, уже можно остановиться. Следующий блок данных содержит только пиксельные данные для каждого канала в слое, а последняя, пятая, секция в псд — пиксельные данные для всей картинки в целом.

В завершение надо сказать о том экзотическом случае, когда псд не имеет информации о слоях (в 16- и 32-бит-на- канал документах) . Длина 4-й секции равна нулю. Где же в таком случае брать информацию о слоях? Ответ отправляет нас к предыдущей статье. Блоки, которые мы получаем из третьей секции псд, могут иметь (в числе прочих) имена Lr16 или Lr32 (для 16-битных и 32-битных псд соответственно). В поле Data этих блоков целиком и последовательно хранится информация о слоях, которую мы описываем в этой статье, а также само изображение слоёв, которое мы будем получать в след. статье этого цикла.

PS. Когда я говорою  о 16-ти или 32-х битных псд, речь идёт не о 16-битных или 32-битных цветах. Речь идёт о количестве бит на канал. Т.е. реально в 16-ти битной псд полный цвет будет состоять из 64-х бит (в 32-х битных псд цвет составляет 128 бит). Это довольно-таки экзотические режимы на современном этапе развития компьютерной техники. Обычная нормальная псд (с 32-битным цветом) содержит 8бит на канал, и она же в целом соответствует той структуре, которая описана в официальном документе. Такая нормальная псд в моей терминологии называется 8-ми битной (не путать с 8-ми битными с индексированными цветами, которые мной не рассматриваются вообще).

PS2. Не могу не напомнить, что все числа хранятся в BigEndian формате.

psd,

6 комментариев to “Структура и формат файла Photoshop. Часть 4: Layer and Mask Information Section”


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Powered by WordPress. Designed by elogi.