如何用 bit_permute_step 代替手动位操作
How to replace manual bit manipulation by bit_permute_step
如何用 http://programming.sirrida.de/perm_fn.html#bit_permute_step 替换以下手动逻辑?
unsigned int ConvertRGBAToBGRA(unsigned int v) {
unsigned char r = (v)& 0xFF;
unsigned char g = (v >> 8) & 0xFF;
unsigned char b = (v >> 16) & 0xFF;
unsigned char a = (v >> 24) & 0xFF;
return (a << 24) | (r << 16) | (g << 8) | b;
};
有没有更好的方法使用 http://programming.sirrida.de/perm_fn.html#bit_permute_step 来完成上述操作?
是的,即:
return bit_permute_step(v, 0x000000ff, 16);
掩码0x000000ff
所指示的v
位包含r
分量,bit_permute_step
将与对应的位16(距离参数)处进行交换左边,对应于 v
的 b
部分。所以 bit_permute_step(v, 0x000000ff, 16)
会将 r
与 b
交换,从而将 RGBA 转换为 BGRA(同时将 BGRA 转换为 RGBA,因为交换是其自身的逆)。
这也可以通过排列计算器找到:http://programming.sirrida.de/calcperm.php
使用索引 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 24 25 26 27 28 29 30 31
(源索引)并禁用 bit-group 移动。
bit_permute_step
的 32 位整数的 C++ 实现(也可用作 C 代码)可以是:
uint32_t bit_permute_step(uint32_t x, uint32_t m, uint32_t shift) {
uint32_t t;
t = ((x >> shift) ^ x) & m;
x = (x ^ t) ^ (t << shift);
return x;
}
如何用 http://programming.sirrida.de/perm_fn.html#bit_permute_step 替换以下手动逻辑?
unsigned int ConvertRGBAToBGRA(unsigned int v) {
unsigned char r = (v)& 0xFF;
unsigned char g = (v >> 8) & 0xFF;
unsigned char b = (v >> 16) & 0xFF;
unsigned char a = (v >> 24) & 0xFF;
return (a << 24) | (r << 16) | (g << 8) | b;
};
有没有更好的方法使用 http://programming.sirrida.de/perm_fn.html#bit_permute_step 来完成上述操作?
是的,即:
return bit_permute_step(v, 0x000000ff, 16);
掩码0x000000ff
所指示的v
位包含r
分量,bit_permute_step
将与对应的位16(距离参数)处进行交换左边,对应于 v
的 b
部分。所以 bit_permute_step(v, 0x000000ff, 16)
会将 r
与 b
交换,从而将 RGBA 转换为 BGRA(同时将 BGRA 转换为 RGBA,因为交换是其自身的逆)。
这也可以通过排列计算器找到:http://programming.sirrida.de/calcperm.php
使用索引 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 24 25 26 27 28 29 30 31
(源索引)并禁用 bit-group 移动。
bit_permute_step
的 32 位整数的 C++ 实现(也可用作 C 代码)可以是:
uint32_t bit_permute_step(uint32_t x, uint32_t m, uint32_t shift) {
uint32_t t;
t = ((x >> shift) ^ x) & m;
x = (x ^ t) ^ (t << shift);
return x;
}