Чтение 16-битных пиксельных данных DPX

Я пытаюсь прочитать данные в пикселях из 16-битного dpx-файла, который является расширением предыдущего git Сделки рЕПО (так как он поддерживает только 10 бит).

Это Сводка формата dpx

Я использую это заголовок а также CPP иметь дело с информацией заголовка и получения такого рода данных.

Обратите внимание, что переменные _pixelOffset, _width, _height и _channels основаны на информации заголовка dpx. pPixels — это массив с плавающей точкой *:

#include <iostream>
#include <fstream>
#include <dpxHeader.h>

//First read the file as binary.
std::ifstream _in(_filePath.asChar(), std::ios_base::binary);

// Seek to the pixel offset to start reading where the pixel data starts.
if (!_in.seekg (_pixelOffset, std::ios_base::beg))
{
std::cerr << "Cannot seek to start of pixel data " << _filePath << " in DPX file.";
return MS::kFailure;
}

// Create char to store data of width length of the image
unsigned char *rawLine = new unsigned char[_width * 4]();

// Iterate over height pixels
for (int y = 0; y < _height; ++y)
{
// Read full pixel data for width.
if (!_in.read ((char *)&rawLine[0], _width * 4))
{
std::cerr << "Cannot read scan line " << y << " " << "from DPX file " << std::endl;
return MS::kFailure;
}

// Iterator over width
for (int x = 0; x < _width; ++x)
{
// We do this to flip the image because it's flipped vertically when read in
int index = ((_height - 1 - y) * _width * _channels) + x * _channels;

unsigned int word = getU32(rawLine + 4 * x, _byteOrder);

pPixels[index] = (((word >> 22) & 0x3ff)/1023.0);
pPixels[index+1] = (((word >> 12) & 0x3ff)/1023.0);
pPixels[index+2] = (((word >> 02) & 0x3ff)/1023.0);
}
}

delete [] rawLine;

В настоящее время это работает для 10-битных файлов, но поскольку я новичок в битовых операциях, я не совсем уверен, как расширить это до 12 и 16-битных. У кого-нибудь есть какие-нибудь подсказки или правильное направление для меня?

1

Решение

Этот формат файла несколько всеобъемлющий, но если вы ориентируетесь только на известное подмножество, его не должно быть слишком сложно расширить.

Из вашего примера кода видно, что вы в настоящее время работаете с тремя компонентами на пиксель и что компоненты заполнены 32-битными словами. В этом режиме как 12-битный, так и 16-битный будут хранить два компонента на слово, согласно предоставленной вами спецификации. Для 12-разрядных старшие 4 бита каждого компонента являются данными заполнения. Вам понадобятся три 32-битных слова, чтобы получить шесть цветовых компонентов для декодирования двух пикселей:

    ...

unsigned int word0 = getU32(rawLine + 6 * x + 0, _byteOrder);
unsigned int word1 = getU32(rawLine + 6 * x + 4, _byteOrder);
unsigned int word2 = getU32(rawLine + 6 * x + 8, _byteOrder);

// First pixel

pPixels[index] = (word0 & 0xffff) / (float)0xffff; // (or 0xfff for 12-bit)
pPixels[index+1] = (word0 >> 16) / (float)0xffff;
pPixels[index+2] = (word1 & 0xffff) / (float)0xffff;

x++;

if(x >= _width) break; // In case of an odd amount of pixels

// Second pixel

pPixels[index+3] = (word1 >> 16) / (float)0xffff;
pPixels[index+4] = (word2 & 0xffff) / (float)0xffff;
pPixels[index+5] = (word2 >> 16) / (float)0xffff;

...
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]