我正在处理一个处理(以及其他)图像的库。为了与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
答案 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_t
或uint8_t
的数组或结构来处理。