Update
This commit is contained in:
parent
e89960bcfb
commit
5cb3296fc9
11 changed files with 63 additions and 22 deletions
57
rgb332.md
57
rgb332.md
|
@ -1,8 +1,8 @@
|
|||
# RGB332
|
||||
|
||||
RGB332 is a general 256 color [palette](palette.md) that encodes one color with 1 byte (i.e. 8 bits): 3 bits for red, 3 bits for green and 2 bits for blue (human eye is least sensitive to blue). RGB332 is an implicit palette -- it doesn't have to be stored in memory because the color index itself determines the color and vice versa. Compared to the classic 24 bit RGB (which assigns 8 bits to each of the RGB components), RGB332 is very "[KISS](kiss.md)/[suckless](suckless.md)" and often [good enough](good_enough.md) (especially with [dithering](dithering.md)) as it saves memory, avoids headaches with [endianness](byte_sex.md) and represents each color with just a single number (as opposed to 3), so it is often used in simple and limited computers such as [embedded](embedded.md). It is also in the [public domain](public_domain.md), unlike some other palettes, so it's additionally a legally safe choice. RGB332 also has a "sister palette" called [RGB565](rgb565.md) which uses two bytes instead of one and so offers many more colors.
|
||||
RGB332 is a general 256 color [palette](palette.md) that encodes one color with 1 [byte](byte.md) (i.e. 8 [bits](bit.md)): 3 bits (highest) for red, 3 bits for green and 2 bits (lowest) for blue (as human eye is least sensitive to blue). RGB332 is an implicit palette -- it doesn't have to be stored in memory because the color index itself determines the color and vice versa. Compared to the classic 24 bit RGB (which assigns 8 bits to each of the RGB components), RGB332 is very "[KISS](kiss.md)/[suckless](suckless.md)" and often [good enough](good_enough.md) (especially with [dithering](dithering.md)) as it saves memory, avoids headaches with [endianness](byte_sex.md) and represents each color with just a single number (as opposed to 3), so it is often used in simple and limited computers such as [embedded](embedded.md). It is also in the [public domain](public_domain.md), unlike some other palettes, so it's additionally a legally safe choice. RGB332 also has a "sister palette" called [RGB565](rgb565.md) which uses two bytes instead of one and so offers many more colors.
|
||||
|
||||
A disadvantage of plain 332 palette is the linearity of each component's intensity, i.e. lack of [gamma correction](gamma_correction.md), so there are too many almost indistinguishable bright colors while too few darker ones { TODO: does a gamma corrected 332 exist? make it? ~drummyfish }. Another disadvantage is the non-alignment of the blue component with red and green components, i.e. while R/G components have 8 levels of intensity and so step from 0 to 255 by 36.4, the B component only has 4 levels and steps by exactly 85, which makes it impossible to create exact shades of grey (which has to have all R, G and B components equal).
|
||||
A disadvantage of plain 332 palette lies in the linearity of each component's intensity, i.e. lack of [gamma correction](gamma_correction.md), so there are too many almost indistinguishable bright colors while too few darker ones { TODO: does a gamma corrected 332 exist? make it? ~drummyfish }. Another disadvantage is the non-alignment of the blue component with red and green components, i.e. while R/G components have 8 levels of intensity and so step from 0 to 255 by 36.4, the B component only has 4 levels and steps by exactly 85, which makes it impossible to create exact shades of grey (which of course have to have all R, G and B components equal).
|
||||
|
||||
The RGB values of the 332 palette are following:
|
||||
|
||||
|
@ -41,15 +41,52 @@ The RGB values of the 332 palette are following:
|
|||
#ffda00 #ffda55 #ffdaaa #ffdaff #ffff00 #ffff55 #ffffaa #ffffff
|
||||
```
|
||||
|
||||
With RGB332 addition/subtraction of colors can be [approximated](approximation.md) in a very fast way using the [OR](or.md)/[AND](and.md) operation -- however this only works sometimes (check visually). For example if you need to quickly brighten/darken all pixels in a 332 image, you can just OR/AND each pixel with these values:
|
||||
## Operations
|
||||
|
||||
Here are [C](c.md) functions for converting RGB332 to RGB24 and back:
|
||||
|
||||
```
|
||||
brighten by 3: | 0x6d (011 011 01)
|
||||
brighten by 2: | 0x49 (010 010 01)
|
||||
brighten by 1: | 0x24 (001 001 00)
|
||||
darken by 1: & 0xdb (110 110 11)
|
||||
darken by 2: & 0xb6 (101 101 10)
|
||||
darken by 3: & 0x92 (100 100 10)
|
||||
unsigned char rgbTo332(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
return ((red / 32) << 5) | ((green / 32) << 2) | (blue / 64);
|
||||
}
|
||||
|
||||
void rgbFrom332(unsigned char colorIndex, unsigned char *red, unsigned char *green, unsigned char *blue)
|
||||
{
|
||||
unsigned char value = (colorIndex >> 5) & 0x07;
|
||||
*red = value != 7 ? value * 36 : 255;
|
||||
|
||||
value = (colorIndex >> 2) & 0x07;
|
||||
*green = value != 7 ? value * 36 : 255;
|
||||
|
||||
value = colorIndex & 0x03;
|
||||
*blue = (value != 3) ? value * 72 : 255;
|
||||
}
|
||||
```
|
||||
|
||||
TODO: conversion to/from RGB24
|
||||
Addition/subtraction of two RGB332 colors can be performed by simply adding/subtracting the two color values as long as no over/underflow occurs in either component -- by adding the values we basically perform a parallel addition/subtraction of all three components with only one operation. Unfortunately checking for when exactly such overflow occurs is not easy to do quickly { Or is it? ~drummyfish }, but to rule out e.g. an overflow with addition we may for example check whether the highest bit of each component in both colors to be added is 0 (i.e. `if (((color1 & 0x92) | (color2 & 0x92)) == 0) newColor = color1 + color2;`). { Code untested. ~drummyfish }
|
||||
|
||||
Addition/subtraction of colors can also be [approximated](approximation.md) in a very fast way using the [OR](or.md)/[AND](and.md) operation instead of arithmetic addition/subtraction -- however this only works sometimes (check visually). For example if you need to quickly brighten/darken all pixels in a 332 image, you can just OR/AND each pixel with these values:
|
||||
|
||||
```
|
||||
brighten by more: doesn't really work anymore
|
||||
brighten by 3: | 0x6d (011 011 01)
|
||||
brighten by 2: | 0x49 (010 010 01)
|
||||
brighten by 1: | 0x24 (001 001 00)
|
||||
darken by 1: & 0xdb (110 110 11)
|
||||
darken by 2: & 0xb6 (101 101 10)
|
||||
darken by 3: & 0x92 (100 100 10)
|
||||
darken by more: doesn't really work anymore
|
||||
```
|
||||
|
||||
{ TODO: Would it be possible to accurately add two 332 colors by adding all components in parallel using bitwise operators somehow? I briefly tried but the result seemed too complex to be worth it though. ~drummyfish }
|
||||
|
||||
Inverting a 332 color is done simply by inverting all bits in the color value.
|
||||
|
||||
TODO: blending?
|
||||
|
||||
## See Also
|
||||
|
||||
- [RGB565](rgb565.md)
|
||||
- [palette](palette.md)
|
||||
- [grayscale](grayscale.md)
|
Loading…
Add table
Add a link
Reference in a new issue