Два слова про libtiff

Все-таки вот загадочная вещь этот ваш libtiff.

TIFF-файлы, как мы знаем, бывают tiled, бывают striped, а бывают одним куском (это, конечно, один страйп и никак иначе). Когда оно одним куском - стандартно собранная libtiff умеет эмулировать страйпы вменяемого размера (для тех, кто читает полосками), но речь не об этом.

Понятно что striped - это частный случай tiled, просто тайлы имеют ширину со все изображение. Но не наоборот.

И вот допустим некто (то есть я) хочет читать картинку банальным TIFFReadScanline(), но склеить ласты, если изображение tiled. Точнее, такое tiled, которое нельзя прочитать через TIFFReadScanline. Ну и хочется, конечно, заранее склеить ласты отказаться читать такое, какое читать через этот интерфейс нельзя.

OK, вот есть TIFFNumberOfTiles(TIFF*). Казалось бы, если она вернет что-то больше единицы, то вот ОНО. Но нет, для striped - оно тоже возвращает некое количество (считая каждый страйп - тайлом). Этот признак не подходит.

Есть TIFFNumberOfStrips(TIFF*), она для tiled TIFFs возвращает 1. Ну тоже ничего себе такое число. То есть  в принципе то (судя по всему, я не пробовал) (кажется) можно читать tiled TIFF как striped, только страйп будет единственным. Как следствие, если вы не просто читаете данные, а что-то с ними делаете (ну там LAB->RGB или 32bit FP->8bit RGB), вам понадобится временный буфер, размером со все исходное изображение (а для 32bit FP - это вчетверо больше результата) - в который вы будете читать этот единственный страйп. Для приложения, которое может читать одновременно несколько десятков БОЛЬШИХ TIFF-файлов - ну немного неприемлемо иметь 4x по памяти.

Складывается впечатление (но это в доке если и написано, то НЕДОСТАТОЧНО КРУПНЫМИ БУКВАМИ), что единственный правильный и универсальный интерфейс - это TIFFReadTile(). Вроде бы (ну исходя из возвращаемого количества тайлов для файлов записанных страйпами и/или одним куском), для не-тайловых TIFFs оно подразумевает тайлы вменяемого размера, ну а для тайловых - ну извините, как записали, так мы и вынуждены читать (а тайлы бывают и совсем маленькие, типа 80x80, на каждый такой пускать fp2int conversion тоже не хочется).

UPD: все не так:

  • TIFFisTiled()
  • и если да - то читай по тайлам, а если нет - то по строкам или страйпам.
  • То есть для произвольных TIFF-ов надо писать оба варианта кода, и тайловый и нет.
  • Убилбынах.
  • Потому что если уж TIFFTileSize() вернула что-то разумное (исходя из идеи, что страйп - это тоже тайл),то почему не дать поработать с этим как с тайлом?

Add new comment