在缓冲区/数组中使用Color结构

时间:2017-07-31 05:43:46

标签: c++ arrays struct endianness

我正在处理一个处理(以及其他)图像的库。为了与OGL的互操作性,我需要(至少)写入BGRA缓冲区(字节顺序 - > B先) 为此,我正在设计一个应该代表颜色的ColorARGB类。我有两种方法:第一种方法将颜色值存储为uint32_t,并将转换方法提供给字节缓冲区,第二种方法将组件存储为字节,并且应该能够直接使用。在代码中:

struct ColorARGB
{
    uint32_t clrValue;
    ColorARGB(uint32_t clrValue):clrValue(clrValue){}
    ColorARGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
    {
        clrValue = a << 24 | r << 16 | g << 8 | b;
    }
    static ColorARGB fromBGRA(const uint8_t* ptr)
    {
        return fromBGRA(reinterpret_cast<const uint32_t*>(ptr));
    }

    static ColorARGB fromBGRA(const uint32_t* ptr)
    {
        // This is little endian BGRA word format
        return ColorARGB(boost::endian::little_to_native(*ptr));
    }
    // Similar functions for toBGRA
}

或:

struct ColorARGB2{
    uint8_t clrValues[4]; // Or maybe: uint8_t b, g, r, a;
    ColorARGB2(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
    {
        clrValues[0] = b; clrValues[1] = g;
        clrValues[2] = r; clrValues[3] = a;
    }
}

第二个版本应该允许std::vector<ColorARGB2>而第一个版本会出现问题,在大端机器上缓冲区是ARGB而不是BGRA。我也可以reinterpret_cast<ColorARGB2*>,因为ColorARGB无法获得结束原因。

ColorARGB2有什么问题吗?我是否会遇到可能的对齐问题,尤其是在处理字节缓冲区(uint8_t*)时?我可以简单地将比较实现为reinterpret_cast<const uint32_t*>(&lhs) == reinterpret_cast<const uint32_t*>(&rhs),还是由于对齐而失败?

更新(不是真正的答案,但有帮助): 我在boost src代码中找到了以下用法:

#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
    // On x86 (which is little endian), unaligned loads are permitted
#   define RTTR_USE_UNALIGNED_ACCESS 1
#endif

1 个答案:

答案 0 :(得分:0)

理论上你可能遇到对齐问题,但在实践中,我从来没有见过像这样的情况。

还有一个你没有枚举的第三个选项,那就是通过使用union来做到这两个选项。有点像:

typedef union ARGBPixel {
    uint32_t colorValue;
    uint8_t components[4];  // <- Or an existing struct with separate a,r,g,b
} ARGBPixel;

通过上述联合,同一块内存可以作为uint32_tuint8_t的数组或结构来处理。