| <head> |
| <title>color(7) - Plan 9 from User Space</title> |
| <meta content="text/html; charset=utf-8" http-equiv=Content-Type> |
| </head> |
| <body bgcolor=#ffffff> |
| <table border=0 cellpadding=0 cellspacing=0 width=100%> |
| <tr height=10><td> |
| <tr><td width=20><td> |
| <tr><td width=20><td><b>COLOR(7)</b><td align=right><b>COLOR(7)</b> |
| <tr><td width=20><td colspan=2> |
| <br> |
| <p><font size=+1><b>NAME </b></font><br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td> |
| |
| color – representation of pixels and colors<br> |
| |
| </table> |
| <p><font size=+1><b>DESCRIPTION </b></font><br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td> |
| |
| To address problems of consistency and portability among applications, |
| Plan 9 uses a fixed color map, called <tt><font size=+1>rgbv</font></tt>, on 8-bit-per-pixel |
| displays. Although this avoids problems caused by multiplexing |
| color maps between applications, it requires that the color map |
| chosen be suitable for most purposes and usable for |
| all. Other systems that use fixed color maps tend to sample the |
| color cube uniformly, which has advantages--mapping from a (red, |
| green, blue) triple to the color map and back again is easy--but |
| ignores an important property of the human visual system: eyes |
| are much more sensitive to small changes in intensity than |
| to changes in hue. Sampling the color cube uniformly gives a color |
| map with many different hues, but only a few shades of each. Continuous |
| tone images converted into such maps demonstrate conspicuous artifacts. |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| Rather than dice the color cube into subregions of size 6×6×6 (as |
| in Netscape Navigator) or 8×8×4 (as in previous releases of Plan |
| 9), picking 1 color in each, the <tt><font size=+1>rgbv</font></tt> color map uses a 4×4×4 subdivision, |
| with 4 shades in each subcube. The idea is to reduce the color |
| resolution by dicing the color cube into fewer |
| cells, and to use the extra space to increase the intensity resolution. |
| This results in 16 grey shades (4 grey subcubes with 4 samples |
| in each), 13 shades of each primary and secondary color (3 subcubes |
| with 4 samples plus black) and a reasonable selection of colors |
| covering the rest of the color cube. The advantage is |
| better representation of continuous tones. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| The following function computes the 256 3-byte entries in the |
| color map:<br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td> |
| |
| <tt><font size=+1>void<br> |
| setmaprgbv(uchar cmap[256][3])<br> |
| {<br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td> |
| |
| uchar *c;<br> |
| int r, g, b, v;<br> |
| int num, den;<br> |
| int i, j;<br> |
| for(r=0,i=0; r!=4; r++)<br> |
| for(v=0; v!=4; v++,i+=16)<br> |
| for(g=0,j=v−r; g!=4; g++)<br> |
| for(b=0; b!=4; b++,j++){<br> |
| c = cmap[i+(j&15)];<br> |
| den = r;<br> |
| if(g > den)<br> |
| den = g;<br> |
| if(b > den)<br> |
| den = b;<br> |
| if(den == 0) /* would divide check; pick grey shades */<br> |
| c[0] = c[1] = c[2] = 17*v;<br> |
| else{<br> |
| num = 17*(4*den+v);<br> |
| c[0] = r*num/den;<br> |
| c[1] = g*num/den;<br> |
| c[2] = b*num/den;<br> |
| }<br> |
| }<br> |
| |
| </table> |
| }<br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| </font></tt> |
| |
| </table> |
| There are 4 nested loops to pick the (red,green,blue) coordinates |
| of the subcube, and the value (intensity) within the subcube, |
| indexed by <tt><font size=+1>r</font></tt>, <tt><font size=+1>g</font></tt>, <tt><font size=+1>b</font></tt>, and <tt><font size=+1>v</font></tt>, whence the name <i>rgbv</i>. The peculiar |
| order in which the color map is indexed is designed to distribute |
| the grey shades uniformly through the map--the <i>i</i>’th grey |
| shade, 0<=<i>i</i><=15 has index <i>i</i>x17, with black going to 0 and white to |
| 255. Therefore, when a call to <tt><font size=+1>draw</font></tt> converts a 1, 2 or 4 bit-per-pixel |
| picture to 8 bits per pixel (which it does by replicating the |
| pixels’ bits), the converted pixel values are the appropriate |
| grey shades. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| The <tt><font size=+1>rgbv</font></tt> map is not gamma-corrected, for two reasons. First, photographic |
| film and television are both normally under-corrected, the former |
| by an accident of physics and the latter by NTSC’s design. Second, |
| we require extra color resolution at low intensities because of |
| the non-linear response and adaptation of |
| the human visual system. Properly gamma-corrected displays with |
| adequate low-intensity resolution pack the high-intensity parts |
| of the color cube with colors whose differences are almost imperceptible. |
| Either reason suggests concentrating the available intensities |
| at the low end of the range. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| On ‘true-color’ displays with separate values for the red, green, |
| and blue components of a pixel, the values are chosen so 0 represents |
| no intensity (black) and the maximum value (255 for an 8-bit-per-color |
| display) represents full intensity (e.g., full red). Common display |
| depths are 24 bits per pixel, with 8 bits per |
| color in order red, green, blue, and 16 bits per pixel, with 5 |
| bits of red, 6 bits of green, and 5 bits of blue. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| Colors may also be created with an opacity factor called <tt><font size=+1>alpha</font></tt>, |
| which is scaled so 0 represents fully transparent and 255 represents |
| opaque color. The alpha is <i>premultiplied</i> into the other channels, |
| as described in the paper by Porter and Duff cited in <a href="../man3/draw.html"><i>draw</i>(3)</a>. |
| The function <tt><font size=+1>setalpha</font></tt> (see <a href="../man3/allocimage.html"><i>allocimage</i>(3)</a>) aids the |
| initialization of color values with non-trivial alpha. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| The packing of pixels into bytes and words is odd. For compatibility |
| with VGA frame buffers, the bits within a pixel byte are in big-endian |
| order (leftmost pixel is most significant bits in byte), while |
| bytes within a pixel are packed in little-endian order. Pixels |
| are stored in contiguous bytes. This results in unintuitive |
| pixel formats. For example, for the RGB24 format, the byte ordering |
| is blue, green, red. |
| <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table> |
| |
| To maintain a constant external representation, the <a href="../man3/draw.html"><i>draw</i>(3)</a> interface |
| as well as the various graphics libraries represent colors by |
| 32-bit numbers, as described in <a href="../man3/color.html"><i>color</i>(3)</a>.<br> |
| |
| </table> |
| <p><font size=+1><b>SEE ALSO </b></font><br> |
| |
| <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td> |
| |
| <a href="../man3/color.html"><i>color</i>(3)</a>, <a href="../man3/graphics.html"><i>graphics</i>(3)</a>, <a href="../man3/draw.html"><i>draw</i>(3)</a><br> |
| |
| </table> |
| |
| <td width=20> |
| <tr height=20><td> |
| </table> |
| <!-- TRAILER --> |
| <table border=0 cellpadding=0 cellspacing=0 width=100%> |
| <tr height=15><td width=10><td><td width=10> |
| <tr><td><td> |
| <center> |
| <a href="../../"><img src="../../dist/spaceglenda100.png" alt="Space Glenda" border=1></a> |
| </center> |
| </table> |
| <!-- TRAILER --> |
| </body></html> |