C++ 在缓冲区/数组中使用颜色结构
我正在开发一个处理(以及其他)图像的库。为了与OGL的互操作性,我需要(至少)写入BGRA缓冲区(字节顺序->B优先)C++ 在缓冲区/数组中使用颜色结构,c++,arrays,struct,endianness,C++,Arrays,Struct,Endianness,我正在开发一个处理(以及其他)图像的库。为了与OGL的互操作性,我需要(至少)写入BGRA缓冲区(字节顺序->B优先) 为此,我正在设计一个ColorARGB类,它应该表示一种颜色。我想到了两种方法:第一种方法将颜色值存储为uint32\t,并提供字节缓冲区的转换方法;第二种方法将组件存储为字节,应该能够直接使用。代码: struct ColorARGB { uint32_t clrValue; ColorARGB(uint32_t clrValue):clrValue(clrV
为此,我正在设计一个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
}
第二个版本应该允许std::vector
,而第一个版本会有问题,即在big-endian机器上,缓冲区是ARGB而不是BGRA。我也可以重新解释_cast
,而ColorARGB
由于结尾的原因无法解释
颜色argb2有什么问题吗?我是否会遇到可能的对齐问题,特别是在处理字节缓冲区(uint8\u t*
)时?我可以简单地将比较实现为reinterpret\u cast(&lhs)==reinterpret\u cast(&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
理论上你可能会遇到对齐问题,但在实践中,我从未见过这种情况发生 还有第三个选项您没有列举,那就是通过使用联合来实现这两个。大致如下:
typedef union ARGBPixel {
uint32_t colorValue;
uint8_t components[4]; // <- Or an existing struct with separate a,r,g,b
} ARGBPixel;
typedef联合ARGBPixel{
uint32_t颜色值;
uint8_t components[4];//理论上,您可能会遇到对齐问题,但在实践中,我从未见过这种情况发生
还有第三个选项您没有列举,那就是通过使用联合来实现这两个目的。大致如下:
typedef union ARGBPixel {
uint32_t colorValue;
uint8_t components[4]; // <- Or an existing struct with separate a,r,g,b
} ARGBPixel;
typedef联合ARGBPixel{
uint32_t颜色值;
uint8_t components[4];//有趣的是,几天前我为一个SO答案编写了一个代码示例。它使用了一个简单的“颜色”键入以演示一个点。您可以。它使用一个并集为您提供选项1和一点选项2。您还应该知道,除非您将uint32\u t
的地址从BGRA(uint8\t)传递到
,您将拥有UB。也就是说,如果您打算传入一个uint8\u t
数组并将其别名为uint32\u t
,您将违反严格的别名规则。这真的违反了严格的别名规则吗?因为我认为它只引用“函数的指针参数”。在这里,我只有一个参数。除了使用字符类型的左值或它自己的类型之外,任何对变量的访问都是官方未定义的行为。您可以使用uint8\u t*
访问uint32\u t
(假设它是无符号字符的别名),但您无法通过uint32\u t*
访问最初的uint\u t8
数组。因此,对于我的情况,什么是一个好的解决方案呢?根据这一点,甚至重新解释为ColorARGB2
的转换将是UB。有趣的是,几天前我为So答案编写了一个代码示例。它使用了一个简单的“颜色”键入以演示一个点。您可以。它使用一个并集为您提供选项1和一点选项2。您还应该知道,除非您将uint32\u t
的地址从BGRA(uint8\t)传递到
,您将拥有UB。也就是说,如果您打算传入一个uint8\u t
数组并将其别名为uint32\u t
,您将违反严格的别名规则。这真的违反了严格的别名规则吗?因为我认为它只引用“函数的指针参数”。在这里,我只有一个参数。除了使用字符类型的左值或它自己的类型之外,任何对变量的访问都是官方未定义的行为。您可以使用uint8\u t*
访问uint32\u t
(假设它是无符号字符的别名),但您无法通过uint32\u t*
访问最初的uint\u t8
数组。因此,对我的情况来说,什么是一个好的解决方案呢?根据这一点,即使重新解释为ColorARGB2
也将是UB.AFAIK,您不应该阅读您尚未编写的工会成员的内容。我正在考虑这个问题,但我觉得这只会增加另一个失败点。好吧,你不应该读你没有写信给的工会会员的书。我在想这个,但我觉得这只会增加另一个失败点。