thunk / The Panel / Color in Sixteen Bits

Color in Sixteen Bits

A pixel shows one color. To a machine, then, a color has to be a number, because bits are all a machine can store. This lesson is about the number.

Start with the light itself. A screen makes color by mixing three tiny lights inside each pixel: one red, one green, one blue. Each of the three is a channel. Turn all three up full and you get white. Turn them all off and you get black. Red at full with the others off is pure red; red and green together make yellow. Every color the panel can show is a recipe: how bright is red, how bright is green, how bright is blue.

So a color is three brightness numbers, and the question is how many bits to spend on them. Spend too many and every picture gets heavy; spend too few and smooth color turns blotchy. This panel's answer, a very common one for small displays, is sixteen bits for the whole color, one u16 per pixel. M2 promised you a 16-bit color format called RGB565. This is it.

Five, six, five

RGB565 spends its sixteen bits like this: 5 for red, 6 for green, 5 for blue. 5 + 6 + 5 = 16. Inside the u16, red takes the top five bits:

bit:  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
       R  R  R  R  R  G  G  G  G  G  G  B  B  B  B  B

      RRRRRGGG GGGBBBBB

Why does green get the extra bit? Because your eyes do. Human eyes are more sensitive to differences in green than to differences in red or blue; two nearby shades of green look distinct where the same-sized step in red would be invisible. The spare bit goes where you can see it.

Each channel's value is an intensity: 0 means that light is off, and the biggest value the field can hold (31 for red and blue, 63 for green) means fully on.

Three colors worth memorizing

Set all five red bits and nothing else, and you get pure red. The same move on each field:

Sixteen bits give 2 to the 16th, 65,536 possible values, so RGB565 can name 65,536 different colors, and a whole color travels in just two bytes.

Two bytes should sound familiar. In M3 you decoded a trace that carried 0x2C and then 0xF8. Split 0xF800 into bytes the way M2 taught, shift and mask, and its high byte is 0xF8. The second byte of that mystery transaction was the first half of a pure red pixel, already in flight toward the panel. What the 0x2C in front of it was, lesson four will tell you.

Where do 76,800 of these u16 values live while they are being the picture? Lesson three answers that.

Key terms

Checks

Answer these to prove the lesson landed. Graded right here; nothing is sent anywhere.

How many bits does one RGB565 color take in total?

Which channel gets six bits, and why?

Which RGB565 value is pure red?