Чтение 16-битного TIFF в оттенках серого

Я пытаюсь прочитать 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, и на самом деле это не имеет значения. любая разница.)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
2 908
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы понимаете, что если StripOffsets - это массив, это смещение к массиву смещений, верно? Возможно, вы неправильно выполняете это разыменование.

Какая у вас платформа? Что ты пытаешься сделать? Если вы хотите работать в .NET в Windows, моя компания продает набор инструментов для обработки изображений, который включает в себя кодек TIFF, который работает практически со всем, что вы можете на него набросить, и будет возвращать изображения 16 бит на пиксель. У нас также есть много инструментов, которые изначально работают с изображениями 16bpp.

Спасибо плинтусу. StripOffsets указывает на 0x1000, который является началом данных - это ровно 2048x2048x2 байта от конца файла. Я использую Linux, и все наши пакеты для анализа данных написаны на C, поэтому, боюсь, я вряд ли стану вашим клиентом.

user53343 09.01.2009 20:47
Ответ принят как подходящий

Я нашел проблему - она ​​была в моей программе на 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;
}

Другие вопросы по теме