读取16位DPX像素数据

时间:2016-10-20 21:34:46

标签: c++ pixels 16-bit

我正在尝试从16位dpx文件中读取像素数据,该文件是前一个git repo的扩展名(因为它只支持10位)。

这是dpx format summary

我正在利用此headercpp处理标题信息并获取该类数据。

请注意,变量_pixelOffset,_width,_height和_channels基于dpx的标头信息。 pPixels是一个float *数组:

#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 个答案:

答案 0 :(得分: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;

    ...