Упоролся по TIFF-ам

Расковыряв давеча FP24 в фотошопных TIFF (ImageMagick делает такие же, т.е. похоже что прикол был в DNG SDK, а не в фотошопе/итп), остановиться уже невозможно (заодно я запроектировал generic tiff decoder, который и tiled будет жрать и striped и все почти без дублирования кода, надо же наделать данных для тестирования) и я пошел упарываться дальше.

Вот есть LAB TIFF (CIELAB), у фотошопа они бывают только целочисленные, но нас же такая фигня не остановит?

convert lab-44--30-63.tif -depth 32 -define quantum:format=floating-point -compress LZW lab-44--30-63-fp32.tif

Этот самый lab-44--30-63, это, как понятно из названия, сплошная заливка этим цветом(L:100, a:-30, b:63), записанная из фотошопа. Ну и -fp32

ОТДЕЛЬНО СМЕШНО: пипетка в фотошопе показывает -30 по каналу "a", а в файл фотошоп пишет -29 (во всяком случае, если следовать Adobe Photoshop Technical notes от 22 марта 2002г: unsigned char 227, что после конверсии в signed и есть -29).

Ну и начинаем полученный FP32-файл читать. Фотошоп (2019) такое брать отказывается, посылает, ну читаем libtiff первый триплет

  • Значение №0: 0.435 - ага, ну понятно, шкала 0-1, домножим на 100, будет 43.5 т.е. вполне исходный 44
  • Значение №1: 0.89...  ОЙ?
  • Значение №2: 0.24...  Ну тут тоже понятно, 0.24 * 255 = ~63, тут попадаем.

А что же такое 0.89 (формат с плавучкой, я бы там ожидал что-то в районе -0.11 же?)

Хорошо, смотрим в исходник (8bit integer), там на месте второго байта записано 227 (потому что это SIGNED 8-bit int, т.е. это -29, как уже упомянуто выше).

Дальше пишу гипотезу (очень похожую на настоящую, все сходится): 

  • Тип данных у LAB TIFF: Unsigned int (несмотря на то, что дальше нам стандарт/technical notes предписывают воспринимать a/b как signed)
  • ImageMagick так его и понимает, не парится что это CIELAB в котором тройки unsigned/signed/signed
  • Ну и дальше нормализует 227=>227/255=>0.89
  • (ну и дальше понятно, если мы видим >0.5 то надо взять значение 1 минус прочитанное).

Заметим, что вот точно так же ImageMagick поступает с RGB-данными: в файл пишутся просто value/range значения, прямо из исходного файла, без линеаризации, что приводит к тому, что такие файлы, будучи открытыми в фотошопе, становятся слишком светлыми (гамма применена дважды). Это, по всей видимости, ошибка в фотошопе (потому что цветовые то данные после IM - корректные, там профиль с гаммой скажем 2.2), но от этого не легче.

Возвращаясь после замечания: а ведь плохо же, что вот у CIELAB TIFF в SampleFormat стоит U(nsigned)INT, а на самом деле два сампла из трех - Signed Int. И, да, я согласен с высказанным тут ранее (в комментариях) замечанием, что формат TIFF - помойка. Она, родимая.

P.S. А еще возможны  CMYK/FloatingPoint, но это оставим на следуюший раз, мы пока еще даже CMYK/Integer не читаем.

P.P.S. IrfanView на тему CIELAB/FP не парится и показывает так (все отрицательные становятся сильно положительными):