Update
[less_retarded_wiki.git] / rgb332.md
blobb3a066108931657a33411f60f3f7665b40a5ac44
1 # RGB332
3 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 we choose to allocate fewest bits to blue). RGB332 is an implicit palette -- it doesn't have to be stored in memory (though doing so also has justifications) 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.
5 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).
7 The RGB values of the 332 palette are following:
9 ```
10 #000000 #000055 #0000aa #0000ff #002400 #002455 #0024aa #0024ff
11 #004800 #004855 #0048aa #0048ff #006d00 #006d55 #006daa #006dff
12 #009100 #009155 #0091aa #0091ff #00b600 #00b655 #00b6aa #00b6ff
13 #00da00 #00da55 #00daaa #00daff #00ff00 #00ff55 #00ffaa #00ffff
14 #240000 #240055 #2400aa #2400ff #242400 #242455 #2424aa #2424ff
15 #244800 #244855 #2448aa #2448ff #246d00 #246d55 #246daa #246dff
16 #249100 #249155 #2491aa #2491ff #24b600 #24b655 #24b6aa #24b6ff
17 #24da00 #24da55 #24daaa #24daff #24ff00 #24ff55 #24ffaa #24ffff
18 #480000 #480055 #4800aa #4800ff #482400 #482455 #4824aa #4824ff
19 #484800 #484855 #4848aa #4848ff #486d00 #486d55 #486daa #486dff
20 #489100 #489155 #4891aa #4891ff #48b600 #48b655 #48b6aa #48b6ff
21 #48da00 #48da55 #48daaa #48daff #48ff00 #48ff55 #48ffaa #48ffff
22 #6d0000 #6d0055 #6d00aa #6d00ff #6d2400 #6d2455 #6d24aa #6d24ff
23 #6d4800 #6d4855 #6d48aa #6d48ff #6d6d00 #6d6d55 #6d6daa #6d6dff
24 #6d9100 #6d9155 #6d91aa #6d91ff #6db600 #6db655 #6db6aa #6db6ff
25 #6dda00 #6dda55 #6ddaaa #6ddaff #6dff00 #6dff55 #6dffaa #6dffff
26 #910000 #910055 #9100aa #9100ff #912400 #912455 #9124aa #9124ff
27 #914800 #914855 #9148aa #9148ff #916d00 #916d55 #916daa #916dff
28 #919100 #919155 #9191aa #9191ff #91b600 #91b655 #91b6aa #91b6ff
29 #91da00 #91da55 #91daaa #91daff #91ff00 #91ff55 #91ffaa #91ffff
30 #b60000 #b60055 #b600aa #b600ff #b62400 #b62455 #b624aa #b624ff
31 #b64800 #b64855 #b648aa #b648ff #b66d00 #b66d55 #b66daa #b66dff
32 #b69100 #b69155 #b691aa #b691ff #b6b600 #b6b655 #b6b6aa #b6b6ff
33 #b6da00 #b6da55 #b6daaa #b6daff #b6ff00 #b6ff55 #b6ffaa #b6ffff
34 #da0000 #da0055 #da00aa #da00ff #da2400 #da2455 #da24aa #da24ff
35 #da4800 #da4855 #da48aa #da48ff #da6d00 #da6d55 #da6daa #da6dff
36 #da9100 #da9155 #da91aa #da91ff #dab600 #dab655 #dab6aa #dab6ff
37 #dada00 #dada55 #dadaaa #dadaff #daff00 #daff55 #daffaa #daffff
38 #ff0000 #ff0055 #ff00aa #ff00ff #ff2400 #ff2455 #ff24aa #ff24ff
39 #ff4800 #ff4855 #ff48aa #ff48ff #ff6d00 #ff6d55 #ff6daa #ff6dff
40 #ff9100 #ff9155 #ff91aa #ff91ff #ffb600 #ffb655 #ffb6aa #ffb6ff
41 #ffda00 #ffda55 #ffdaaa #ffdaff #ffff00 #ffff55 #ffffaa #ffffff
42 ```
44 ## Operations
46 Here are [C](c.md) functions for converting RGB332 to RGB24 and back:
48 ```
49 unsigned char rgbTo332(unsigned char red, unsigned char green, unsigned char blue)
51   return ((red / 32) << 5) | ((green / 32) << 2) | (blue / 64);
54 void rgbFrom332(unsigned char colorIndex, unsigned char *red, unsigned char *green, unsigned char *blue)
56   unsigned char value = (colorIndex >> 5) & 0x07;
57   *red = value != 7 ? value * 36 : 255;
59   value = (colorIndex >> 2) & 0x07;
60   *green = value != 7 ? value * 36 : 255;
61   
62   value = colorIndex & 0x03;
63   *blue = (value != 3) ? value * 72 : 255;
65 ```
67 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 }
69 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:
71 ```
72 brighten by more:  doesn't really work anymore
73 brighten by 3:     | 0x6d  (011 011 01)
74 brighten by 2:     | 0x49  (010 010 01)
75 brighten by 1:     | 0x24  (001 001 00)
76 darken by 1:       & 0xdb  (110 110 11)
77 darken by 2:       & 0xb6  (101 101 10)
78 darken by 3:       & 0x92  (100 100 10)
79 darken by more:    doesn't really work anymore
80 ```
82 { 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 }
84 Inverting a 332 color is done simply by inverting all bits in the color value.
86 TODO: blending?
88 ## See Also
90 - [RGB565](rgb565.md)
91 - [palette](palette.md)
92 - [grayscale](grayscale.md)