I'm decoding a .BMP file, and I'm at a point where I need to handle 16-bit colors. The entire codebase uses 32-bit colors (R, G, B, A), so I need to convert the color to a 24-bit RGB value (one byte for each color).
Each component of the color is 5-bit as per the specification (1 bit is wasted). My code is as follows:
ushort color = BitConverter.ToUInt16(data, 54 + i);
byte blue = (byte)((color | 0b0_00000_00000_11111) / 31f * 255);
byte green = (byte)(((color | 0b0_00000_11111_00000) >> 5) / 31f * 255);
byte red = (byte)(((color | 0b0_11111_00000_00000) >> 10) / 31f * 255);
However, this doesn't seem particularly efficient. I tried doing color << (8 - 5), which makes the process much faster and avoids floating-point conversions, but it isn't accurate - a value of 31 (11111) converts to 248. Is there a way to achieve this with some other bit-manipulation hack, or am I forced to convert each number to a float just to change the color space?