c-显示10位RGB的整数类型



我很难找到任何关于如何在C中实现显示器的10位RGB输出的开发人员文档,如果可能的话,主要用于Linux上的Xorg/Wayland并与Windows兼容。

目前,我正在开发的应用程序(darktable(正在使用uint8_t来输出RGB值。10位uint的类型是什么?有什么方法可以从代码中检查GPU/编解码器的10位支持吗?

我在谷歌上搜索了一点,以澄清10位RGB的含义。

维基百科上的颜色深度–深颜色(30/36/48位(我发现:

一些早期的系统在一个32位字中放置了三个10位通道,其中2位未使用(或用作4级alpha通道(。

我觉得这是最合理的。

据此,红色有10位,绿色有10位;蓝色有10位。+2位未使用(或保留给Alpha(。

这留下了两个问题:

  1. 它存储的是RGBa、BGRa还是aRGB?(我相信我过去见过所有这些变化。(

  2. 要存储的组合值是Little Endian还是Big Endian?

当我在实际工作中遇到这种情况时,我基于一个假设进行了实现,呈现了一些测试模式,检查它是否像预期的那样,如果没有交换resp。部分。没有什么,我感到骄傲,但是,IMHO,我用最少的努力得到了预期的结果。

因此,假设我有一个存储为RGB三元组的颜色,其分量值在[0,1]范围内,下面的函数将其转换为aRGB:

uint32_t makeRGB30(float r, float g, float b)
{
const uint32_t mask = (1u << 10u) - 1u;
/* convert float -> uint */
uint32_t rU = r * mask, gU = g * mask, bU = b * mask;
/* combine and return color components */
return ((rU & mask) << 20) | ((gU & mask) << 10) | (bU & mask);
}

这导致具有以下位布局的值:

aaRRRRRR.RRRRGGGG.GGGGGGBB.BBBBBBBB

演示的小样本:

#include <stdint.h>
#include <stdio.h>
uint32_t makeRGB30(float r, float g, float b)
{
const uint32_t mask = (1u << 10u) - 1u;
/* convert float -> uint */
uint32_t rU = r * mask, gU = g * mask, bU = b * mask;
/* combine and return color components */
return ((rU & mask) << 20) | ((gU & mask) << 10) | (bU & mask);
}
int main(void)
{
/* samples */
const float colors[][3] = {
{ 0.0f, 0.0f, 0.0f }, /* black */
{ 1.0f, 0.0f, 0.0f }, /* red */
{ 0.0f, 1.0f, 0.0f }, /* green */
{ 0.0f, 0.0f, 1.0f }, /* blue */
{ 1.0f, 1.0f, 0.0f }, /* yellow */
{ 1.0f, 0.0f, 1.0f }, /* magenta */
{ 0.0f, 1.0f, 1.0f }, /* cyan */
{ 1.0f, 1.0f, 1.0f } /* white */
};
const size_t n = sizeof colors / sizeof *colors;
for (size_t i = 0; i < n; ++i) {
float *color = colors[i];
uint32_t rgb = makeRGB30(color[0], color[1], color[2]);
printf("(%f, %f, %f): %08xn", color[0], color[1], color[2], rgb);
}
/* done */
return 0;
}

输出:

(0.000000, 0.000000, 0.000000): 00000000
(1.000000, 0.000000, 0.000000): 3ff00000
(0.000000, 1.000000, 0.000000): 000ffc00
(0.000000, 0.000000, 1.000000): 000003ff
(1.000000, 1.000000, 0.000000): 3ffffc00
(1.000000, 0.000000, 1.000000): 3ff003ff
(0.000000, 1.000000, 1.000000): 000fffff
(1.000000, 1.000000, 1.000000): 3fffffff

视频直播演示

颜色通道的确切排列方式取决于API。它很可能是平面的(即每个通道一个单声道图像(,它可以被打包(即将几个通道打包成一个数据字(,它可能被交织(对每个通道使用不同的表示(。

然而,有一点是肯定的:对于任何不完全适合"本地"类型的通道格式,都必须进行一些比特处理才能访问它

要了解该字段的巨大性,只需查看Vulkan API第一个版本指定的图像格式:https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s03.html–该文件还描述了每种格式的位是如何准确排列的。

最新更新