# RGB565

RGB565 is color format, or a way of representing color with just 2 bytes (unlike traditional 24 bit RGB formats that use 3 bytes, one for each component), that is 16 bits (giving a total of 65536 distinct colors), by using 5 bits (highest) for red, 6 bits for green (to which human eye is most sensitive) and 5 bits for blue; it can also be seen as a color palette. It is similar to RGB332 -- it's basically a mid way between RGB332 and full 24bit RGB against which it saves one byte per pixel, but compared to RGB332 byte sex comes to play here. Practically speaking you will rarely need anything more than this, 65 thousand colors are absolutely sufficient for everything.

Yet another similar format to this one is RGB555 which sacrifices one useful bit for gaining the nice property of having the same size of each component. The one "wasted" bit may also be utilized, e.g. for marking transparency. Variants of RGB565 can also be obtained by swapping the order of components, e.g. BGR565 etc.

It would also be possible (but more complex) to use a different color model than RGB, for example HSV or HSL. In this case 6 bits should probably be allocated for the value (lightness) component, as human sight is more sensitive to this color component. However this would somehow have to address the issue of some colors (such as black) having multiple possible representations.

Here is a C code for the basic conversions to/from RGB565:

```
unsigned int rgbTo565(unsigned char red, unsigned char green,
  unsigned char blue)
{
  return (((unsigned int) (red / 8)) << 11) |
    (((unsigned int) (green / 4)) << 5) | (blue / 8);
}

void rgbFrom565(unsigned int colorIndex, unsigned char *red,
  unsigned char *green, unsigned char *blue)
{
  unsigned char value = colorIndex >> 11;
  *red = value != 31 ? value * 8 : 255;
  
  value = (colorIndex >> 5) & 0x3f;
  *green = value != 63 ? value * 4 : 255;
  
  value = colorIndex & 0x1f;
  *blue = value != 31 ? value * 8 : 255;
}
```

And also maybe a more practical variant:

```
uint16_t rgbTo565(uint32_t c)
{
  return ((c >> 8) & 0xf800) | ((c >> 5) & 0x07e0) | ((c >> 3) & 0x001f);
}

uint32_t rgbFrom565(uint16_t c565)
{
  uint32_t c =
    ((c565 & 0xf800) << 8) | ((c565 & 0x7e0) << 5) | ((c565 & 0x001f) << 3);
  return c | ((c >> 5) & 0x070307);
}
```

There exist nice tricks you can do with colors represented this way, like quickly divide all three R, G and B components by a power of two just by doing one bit shift and logical AND to zero the highest bits of the components, or approximating addition of colors with logical OR and so on -- for details see the article on RGB332.