I'm programming on an 8-bit Z80 embedded system, and encountered a problem. The program needs to render some pixels to the screen. The color is stored as RGB565 format as a 16-bit unsigned integer, but the system color is encoded as BGR565, so I've devised the following code to swap the first and last 5 bits in a uint16_t
.
Note that flash
is uint8_t *
, pointed to the flash memory, and each cell is seen as uint8_t
.
/* read lower 8-bit */
uint16_t color = flash[idx];
/* read higher 8 bits */
color |= ((flash[idx + 1]) << 8);
/*
* This converts RGB565 to BGR565 by swapping the first/last five bits.
* For the last five bits, we extract and bitshift it to the beginning,
* and for the first five bits, we extract and bitstift it to the end.
* Then, we clear the original first and last five bits, and apply the
* bitshifted version on it to swap them.
*/
uint16_t tmp = (color & 0x001F) << 11;
tmp |= (color & 0xF800) >> 11;
color &= 0xFFE0 & 0x07FF; /* at least the compiler can optimize this as 0x07e0 */
color |= tmp;
If I'm programming with a standard compiler, like GCC or Clang, I would be just happy about my solution. But this embedded platform only supports relatively primitive compilers without advanced optimization techniques to remove duplicate computations.
In fact, the best code optimization to this problem is "no code", just make the stored format to be consistent with the system format. But using it as a chance of learning, I'm curious to know if there is a faster way to do the computation above in pure C, especially when we're dealing with a particularly slow machine, like a Z80.
flash
, an array ofuint8_t
? \$\endgroup\$