Ещё в декабре прошлого года я обещал тебе начал рассказывать о формате PSD файлов. Я обещал закончить свой рассказ в январе, но времени не хватило, и я перенёс этот рассказ на февраль. Сейчас я собрался силами и заканчиваю рассмотрение.
Анекдот:
Каждый москаль выбиpает паскаль, хохлы же yси пишyт на си.
В прошлый раз мы остановились на блоке ресурсов. Следующим идёт блок информации о слоях. Он выглядит также, как и предыдущие блоки. Мои знания об этом блоке немного устарели, но я всё же расскажу всё, что знаю.
С начала блока идёт информация о слоях, а затем уже идёт информация о масках. В самом начале стоит значение типа long, в котором хранится длинна всего блока. Далее идёт число типа word, которое показывает количество записей о слоях.
Первой идёт структура, в которой хранится размер слоя:
Для Delphi
TRazmStruct = record
Top, Left, Bottom, Right: Cardinal;
Chenel: Word;
end;
Для С++
struct _PSD_RazmStruct
{
LONG Top;
LONG Left;
LONG Bottom;
LONG Right;
WORD Chenel;
};
Top, Left, Bottom, Right - границы и положение слоя.
Chenel - Количество цветовых каналов для слоя.
Далее идёт информация о длине каналов:
Для Delphi
TChanStruct = record
ChenelID: Word;
LengthOfChennelData: Cardinal;
end;
Для С++
struct _PSD_ChanStruct
{
WORD ChenelID;
LONG LengthOfChennelData;
};
Таких структур несколько. Ты должен прочитать их все. Считывай последовательно эти структуры, пока не наткнёшься на "8BIM". Это и будет конец последовательности структур типа ТChanStruct.
Далее идёт ещё несколько данных:
Имя
Тип в Дельфи
Тип в С++
Ключ режима наложения (см. табл. ниже)
array[0..3] of Byte
BYTE[4]
Прозрачность (0-255 от прозрачного, до непрозрачного)
Char
BYTE
Вырезка
Char
BYTE
Видимость (0-невидимо, 1-видимо)
Char
BYTE
Понятия не имею что, но почти всегда 0
Char
BYTE
Размер вспомогательной инфы
Char
BYTE
Ключи режима наложения
Ключ
Значение
norm
Нормальный
dark
Тёмный
lite
Светлый
hue
Цветовой тон
colr
Цвет
hLit
Жёсткий цвет
sLit
Мягкий цвет
sat
Насыщеный
lum
Яркий
diff
Контраст
mul
Умножение
over
Наложение
scrn
Экран
diss
Наплыв
Далее идёт раздел инфы о масках.
Для Delphi
TMaskStruct = record
Size, Top, Left, Bottom, Right: Cardinal;
Color, Flag: Char;
Fill:Word
end;
Для С++
struct _PSD_MaskStruct
{
LONG Size;
LONG Top;
LONG Left;
LONG Bottom;
LONG Right;
BYTE Color;
BYTE Flag;
WORD Fill;
};
Жаль, но больше ничего хорошего о масках я не смог выяснить. Это явно неполная инфа, но Adobe ни за какие деньги не захотела продавать мне полную спецификацию. Наверно потому что я им предлагал "никакие" деньги (у меня столько нет, сколько требует такая фирма). А если честно, то по моим сведениям , ещё никому не удалось добыть полную спецификацию. Это закрытая инфа.
Теперь мы переходим к последнему блоку данных - непосредственно растровые данные. Самым первым числом типа word в этом блоке стоит флаг. Если он равен 1, то данные сжаты методом RLE. Если данные сжаты, то перед каждой строкой будет число длиной word, в котором хранится длина данных в этой строке.
Растровые данные записываются построчно без дополнительных прибамбасов. Если данные хранятся в нескольких плоскостях, то есть отдельно сохраняется цвета красного, зелёного и синего, то данные так и пишутся - сначала идёт красная составляющая, затем зелёная и в самом конце синяя.
Теперь поговорим о сжатии данных. Для этого используется метод Macintosh ROM Packbit. Этот метод является составной частью TIFF стандарта. Не удивляйся в присутствии тут Macintosh, потому что формат PSD разрабатывался для этой платформы. Только после финансового краха фирмы, были созданы проги для IBM и этот формат с визгом перелетел к нам.
Итак, когда ты читаешь первый байт, то должен проверить в нём старший бит. Если он равен 1, то этот байт ты должен преобразовать до двух, а следующий прочитанный байт выводиться полученное из первого количество раз.
Если старший бит = 0, то счётчику прибавляется 1 и столько раз ты должен теперь вывести следующий прочитанный байт. Для большей ясности, я как и при описании GIF-формата подготовил тебе маленький алгоритм:
СчётчикПрочитанного:=0
Счётчик:=0
ПрочитатьБайт
Если старший бит=1 то
начало
Счётчик:=двоичное дополнение прочитанного байта
Читаем следующий байт
Вывести прочитанное значение столько раз, сколько записано в Счётчике
конец
Если старший бит=0 то
начало
Счётчик:=Прочитанный байт+1
Читаем следующий байт
Вывести прочитанное значение столько раз, сколько записано в Счётчике
конец
Может быть что-то осталось непонятно, поэтому я подготовлю маленький пример для чтения PSD файлов, и возможно ты увидишь его уже в этом номере.