glenda.party
term% ls -F
term% pwd
$home/manuals/9front/6/color
term% cat index.txt
COLOR(6)                         Games Manual                         COLOR(6)



NAME
       color - representation of pixels and colors

DESCRIPTION
       To  address problems of consistency and portability among applications,
       Plan 9 uses a fixed color map, called  rgbv,  on  8-bit-per-pixel  dis‐
       plays.  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  advan‐
       tages—mapping  from  a  (red,  green, blue) triple to the color map and
       back again is easy—but ignores an important property of the human  vis‐
       ual  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.

       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), pick‐
       ing  1 color in each, the rgbv 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.

       The following function computes the 256 3-byte  entries  in  the  color
       map:

              void
              setmaprgbv(uchar cmap[256][3])
              {
                  uchar *c;
                  int r, g, b, v;
                  int num, den;
                  int i, j;

                  for(r=0,i=0; r!=4; r++)
                    for(v=0; v!=4; v++,i+=16)
                      for(g=0,j=v-r; g!=4; g++)
                        for(b=0; b!=4; b++,j++){
                          c = cmap[i+(j&15)];
                          den = r;
                          if(g > den)
                              den = g;
                          if(b > den)
                              den = b;
                          if(den == 0) /* would divide check; pick grey shades */
                              c[0] = c[1] = c[2] = 17*v;
                          else{
                              num = 17*(4*den+v);
                              c[0] = r*num/den;
                              c[1] = g*num/den;
                              c[2] = b*num/den;
                          }
                        }
              }

       There  are  4  nested loops to pick the (red,green,blue) coordinates of
       the subcube, and the value (intensity) within the subcube,  indexed  by
       r,  g, b, and v, whence the name rgbv.  The peculiar order in which the
       color map is indexed is designed to distribute  the  grey  shades  uni‐
       formly  through  the  map—the i'th grey shade, 0<=i<=15 has index iÃ17,
       with black going to 0 and white to 255.  Therefore, when a call to draw
       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.

       The  rgbv  map  is not gamma-corrected, for two reasons.  First, photo‐
       graphic film and television are both normally under-corrected, the for‐
       mer 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.  Prop‐
       erly gamma-corrected displays with  adequate  low-intensity  resolution
       pack  the high-intensity parts of the color cube with colors whose dif‐
       ferences are almost imperceptible.  Either reason suggests  concentrat‐
       ing the available intensities at the low end of the range.

       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.

       Colors  may  also be created with an opacity factor called alpha, which
       is scaled so 0 represents fully transparent and 255  represents  opaque
       color.   The  alpha  is  premultiplied  into the other channels, as de‐
       scribed in the paper by Porter and Duff cited in draw(2).  The function
       setalpha  (see  allocimage(2))  aids the initialization of color values
       with non-trivial alpha.

       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 exam‐
       ple, for the RGB24 format, the byte ordering is blue, green, red.

       To  maintain  a constant external representation, the draw(3) interface
       as well as the various graphics libraries represent  colors  by  32-bit
       numbers, as described in color(2).

SEE ALSO
       color(2), graphics(2), draw(2)



                                                                      COLOR(6)