Я пытаюсь прочитать данные в пикселях из 16-битного dpx-файла, который является расширением предыдущего git Сделки рЕПО (так как он поддерживает только 10 бит).
Я использую это заголовок а также 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-битных. У кого-нибудь есть какие-нибудь подсказки или правильное направление для меня?
Этот формат файла несколько всеобъемлющий, но если вы ориентируетесь только на известное подмножество, его не должно быть слишком сложно расширить.
Из вашего примера кода видно, что вы в настоящее время работаете с тремя компонентами на пиксель и что компоненты заполнены 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;
...
Других решений пока нет …