将前5位和后5位交换为16位数字

问题描述

我有一些C / C ++代码,其中有一个16位数字(uint16_t),我需要将前5位与后5位交换,并保持它们的从左到右顺序每块5位。中间的6位需要保持不变。我不擅长按位数学/运算,所以将不胜感激!

从概念上讲,职位转换看起来像:

ABCDEFGHIJKLMnop变为LMnopFGHIJKABCDE

或更确切地说...

10101000000001010变成0101000000010101

任何帮助将不胜感激!

解决方法

首先,您应该检查所使用的任何库是否尚未为R5G6B5像素进行RGB-BGR交换。

这里是您在问题中所写内容的字面翻译。实时视频可能太慢了:

uint16_t rgbswap(uint16_t in) {
    uint16_t r = (in >> 11) & 0b011111;
    uint16_t g = (in >> 5)  & 0b111111;
    uint16_t b = (in >> 0)  & 0b011111;

    return b << 11 | g << 5 | r << 0;
}
,

您无需将输入分为3个单独的R,G和B组件,而是可以通过移至较高位来并行处理R和B

uint16_t rgb2bgr(uint16_t in)
{
    uint16_t r0b = in & 0b1111100000011111;
    uint16_t b0r = ((r0b << 22) | r0b) >> 11;
    return b0r | (in & 0b11111100000);
}

另一种使用乘法来交换R和B的替代方法

uint16_t rgb2bgr_2(uint16_t in)
{
    uint16_t r0b = in & 0b1111100000011111;
    uint16_t b0r = r0b * 0b1000000000000000000000100000 >> 16;
    return b0r | (in & 0b11111100000);
}

基本上是this technique,对于提取位或在周围移动位很有用

您可以检查compiled result on Godbolt来查看乘法方法产生的输出较短,但这仅在具有快速乘法器的情况下有用