简体   繁体   中英

Swap first and last 5 bits in a 16-bit number

I have some C/C++ code where I have a 16-bit number ( uint16_t ), and I need to swap the first 5 bits with the last 5 bits, keeping their left-to-right order within each block of 5 bits. The middle 6 bits need to remain intact. I am not great at bitwise maths/operations so help would be appreciated!

Conceptually speaking, the switching of positions would look like:

ABCDEFGHIJKLMNOP becomes LMNOPFGHIJKABCDE

or more literally...

10101000000001010 becomes 0101000000010101 .

Any help would be much appreciated!

First, you should check if whatever library you use doesn't have a RGB-BGR swap for R5G6B5 pixels already.

Here is a literal translation of what you wrote in your question. It is probably too slow for real-time video:

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;
}

Instead of breaking the input into 3 separate R, G and B components you can work on R and B in parallel by shifting to the higher bits

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

Another alternative to use multiplication to swap R and B

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

It's basically this technique which is useful for extracting bits or moving bits around

You can check the compiled result on Godbolt to see the multiplication method produces shorter output, but it's only useful if you have a fast multiplier

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM