Трудовые будни или еще раз о формате DNG

Не могу молчать, могу только материться, да и то с трудом.

Преамбула:

Даже если вот рассматривать только документированные форматы данных, там спецификации довольно расплывчатые бывают (вот, к примеру мой вопль о JPEG color profiles). Соответственно, в частности в LibRaw, мы работаем только с реальными примерами из реальной жизни, ибо наворотить создатель файла может всякого, всюду соломки не подстелишь, работаем по заявкам. Так вот.

Акт 1, LibRaw "пару месяцев назад"

Все DNG-теги парсятся в общую кучу, то есть вот если есть несколько тегов, скажем, ColorMatrix1, то сработает последний.

Контрпример (зачеркнуто нецензурное): если создать (из более-менее свежего лайтрума) Lossy DNG с 'fast load data', то там будет два JPEG-RAW (в смысле RAW-данные, пожатые JPEG-ом т.е. с потерями). Вместо таблицы линеаризации Adobe использует OpcodeList2 и линеаризует эти JPEG-и полиномом. И для двух JPEG-ов эти полиномы будут разными (сука, ну почему? данные то исходно одни, просто разного разрешения, почему им нужна разная линеаризация).

ОК. Будем делать по науке, для каждой SubIFD свою табличку DNG-тегов (не всех, но тех что реально используем в приложении, ColorMatrix, AnalogBalance, CameraCalibration, уровень черного-белого) и используем потом ту, которая относится к той SubIFD, которую показываем.

Клюв вытащили. Но увяз, оказывается, хвост:

Акт 2. Вчера.

Есть у меня подборка "хитрых примеров" и я их периодически просматриваю (например, свежей версией FRV при подготовке релиза). Хренак, у одного примера - неверный баланс белого, все в пурпур.

Это, да, непростой пример, это Canon sRAW (т.е. исходно YCC) сохраненный лайтрумом (версии 5.7, похоже что это важно, но проверять не буду) в DNG.

Структура файла такая:

  • IFD0 - превьюшка, нежатая, 256px, SubFileType=1 (tiff-превью по сути). Все по рекомендации TIFF-EP, "хранить в начале мелкую превьюшку"
  • IFD1 - собственно RAW-изображение, 3960px. Так как в DNG не бывает YCC, оно (естественно) преобразовано в RGB. При этом баланс белого As Shot поставлен примерно 1-1-1, а реальный баланс спрятан в теге AnalogBalance в IFD0 (а не в IFD1), если его не применить - все будет пурпурное.
  • IFD2 - превьюшка, JPEG, 1024px
  • IFD3 - превьюшка, RAW, fast load data (2048px, JPEG-компрессия)
  • IFD4 - превьюшка, RAW, 256px, JPEG-компрессия, вторая таблица линеаризации (см. пример выше)

Так вот, куча тегов, относящихся к IFD1,3,4 - хранится в IFD0. Что было бы почти правильно (см. ниже), если бы в этой IFD не было бы превьюшки.

Стандарт DNG говорит нам следующее:

  1. DNG is an extension of TIFF 6.0 and is comp atible with the TIFF-EP standard
  2. DNG recommends, but does not require, that the first IFD contain a low-resolution thumbnail, as described in the TIFF-EP specification.

Смотрим теперь в TIFF/EP:

  1. The main image shall be in IFD 0.For the main image, NewSubFileType shall be 0 (main image).
  2. The thumbnail shall be stored in the first IFD, not in IFD 0. That is, IFD 0 shall contain one SubIFDs tag, and the first entry of the SubIFDs tag shall be the thumbnail IFD.

И вот сдается мне, что кто-то в Adobe перепутал IFD0 и FirstIFD (я бы, с такими формулировками, тоже бы перепутал) и сделал все наоборот: в IFD0 положили превьюшку и теги от основного изображения, а в First IFD - основное изображение и немножко тегов, без которых нельзя обойтись: размеры, способ сжатия и подобное.

Ну а жить то с этим как? Нужно ли мне искать недостающие данные только в IFD0, или нужно вообще все теги обсмотреть?

Я проверю, но не сегодня (боюсь раздражиться еще и всю посуду перебить) более новый лайтрум. Судя по количеству жалоб (их нет), все вышеописанное - это фича конкретной довольно старой версии (лайтрума, DNG SDK).

Я это, собственно, вот к чему. Ну ладно, "проприетарные форматы". Ну вот Canon меняет формат Makernotes чуть не с каждой новой камерой (с каждым новым Digic - точно), ну притерпелись, научились. Но вот DNG - документирован в публичных документах, легче от этого стало? Ну только то легче, что можно тыкать вот носом Adobe в нарушение спецификаций, отводить душу. Поддерживать этот зоопарк все едино приходится.

UPD: программируя эту хрень, задумался. А ведь может, в принципе, быть так:

  • IFD0 - есть CameraMatrix и Illuminant
  • IFDn - только Illuminant

И чего, брать Illuminant для данного Sub-Image, а CameraMatrix - общий? Ну это ведь - ну 100% некорректно, но (похоже) авторы стандарта хотят от нас именно этого?