Я пытаюсь прочитать 16-битный файл TIFF в оттенках серого (BitsPerSample = 16) с помощью небольшой программы на C для преобразования в массив чисел с плавающей запятой для дальнейшего анализа. Данные пикселей, согласно информации заголовка, находятся в одной полосе размером 2048x2048 пикселей. Кодировка с прямым порядком байтов.
С этой информацией заголовка я ожидал, что смогу прочитать один блок размером 2048x2048x2 байта и интерпретировать его как 2-байтовые целые числа 2048x2048. Фактически я получаю изображение разделить на четыре квадранта размером 1024x1024 пикселя каждое, два нижних из которых содержат только нули. Каждый из двух верхних квадрантов выглядит так, как я ожидал, будет выглядеть вся картина: альтернативный текст http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457.png
Если я читаю тот же файл в GIMP или Imagemagick, оба говорят мне, что им нужно уменьшить до 8 бит (что мне не помогает - мне нужен полный диапазон), но пиксели появляются в нужных местах: альтернативный текст http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457_gimp.png
Это наводит на мысль, что мое представление о том, как данные расположены в одной полосе, неверно. С другой стороны, файл должен быть правильно отформатирован с точки зрения информации заголовка, иначе GIMP не поймет это правильно. Где я ошибаюсь?
Вывод tiffdump:
15_inRT_0p457.tiff:
Магия: 0x4949 Версия: 0x2a
Каталог 0: смещение 8 (0x8) следующий 0 (0)
Ширина изображения (256) ДЛИННЫЙ (4) 1 <2048>
Длина изображения (257) ДЛИННЫЙ (4) 1 <2048>
BitsPerSample (258) КОРОТКИЙ (3) 1 <16>
Компрессия (259) КОРОТКИЕ (3) 1 <1>
Фотометрический (262) КОРОТКИЕ (3) 1 <1>
Полосы смещения (273) ДЛИННЫЕ (4) 1 <4096>
Ориентация (274) КОРОТКИЕ (3) 1 <1>
RowsPerStrip (278) ДЛИННЫЙ (4) 1 <2048>
StripByteCounts (279) ДЛИННЫЙ (4) 1 <8388608>
XResolution (282) RATIONAL (5) 1 <126,582>
Y Разрешение (283) РАЦИОНАЛЬНОЕ (5) 1 <126,582>
Разрешение Ед. (296) КОРОТКИЕ (3) 1 <3>
34710 (0x8796) ДЛИННЫЙ (4) 1 <0>
(Тег 34710 - это информация о камере; чтобы убедиться, что это не имеет никакого значения, я обнуил весь диапазон от конца каталога файла изображения до начала данных в 0x1000, и на самом деле это не имеет значения. любая разница.)





Вы понимаете, что если StripOffsets - это массив, это смещение к массиву смещений, верно? Возможно, вы неправильно выполняете это разыменование.
Какая у вас платформа? Что ты пытаешься сделать? Если вы хотите работать в .NET в Windows, моя компания продает набор инструментов для обработки изображений, который включает в себя кодек TIFF, который работает практически со всем, что вы можете на него набросить, и будет возвращать изображения 16 бит на пиксель. У нас также есть много инструментов, которые изначально работают с изображениями 16bpp.
Я нашел проблему - она была в моей программе на C ...
Я выделил память для массива long и использовал fread () для чтения данных:
#define PPR 2048;
#define BPP 2;
long *pix;
pix=malloc(PPR*PPR*sizeof(long));
fread(pix,BPP,PPR*PPR,in);
Но поскольку данные поступают в виде 2-байтовых блоков (BPP = 2), но sizeof (long) = 4, fread () плотно упаковывает данные внутри выделенной памяти, а не упаковывает их в пакеты большого размера. Таким образом, я получаю две строки, упакованные вместе в одну, а вторую половину изображения пустую.
Я изменил его, чтобы перебрать количество пикселей и каждый раз читать два байта и вместо этого сохранять их в выделенной памяти:
for (m=0;m<PPR*PPR;m++) {
b1=fgetc(in);
b2=fgetc(in);
*(pix+m)=256*b1+b2;
}
Спасибо плинтусу. StripOffsets указывает на 0x1000, который является началом данных - это ровно 2048x2048x2 байта от конца файла. Я использую Linux, и все наши пакеты для анализа данных написаны на C, поэтому, боюсь, я вряд ли стану вашим клиентом.