RGBV(6)                                                   RGBV(6)

     NAME
          rgbv - colour map

     DESCRIPTION
          To solve problems of consistency and portability among
          Inferno applications, Inferno uses a fixed colour map,
          called rgbv, on 8-bit-per-pixel displays.  Although this
          avoids problems caused by multiplexing colour maps between
          applications, it requires that the colour map chosen be
          suitable for most purposes and usable for all.  Other sys-
          tems that use fixed colour maps tend to sample the colour
          cube uniformly, which has advantages-mapping from a (red,
          green, blue) triple to the colour 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 colour cube
          uniformly gives a colour 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 colour cube into subregions of size
          6x6x6 (as in Netscape Navigator) or 8x8x4 (as in Plan 9),
          picking 1 colour in each, Inferno's rgbv colour map uses a
          4x4x4 subdivision, with 4 shades in each subcube.  The idea
          is to reduce the colour resolution by dicing the colour 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 colour (3 subcubes with 4 samples plus
          black) and a reasonable selection of colours covering the
          rest of the colour cube.  The advantage is better represen-
          tation of continuous tones.

          The following function computes the 256 3-byte entries in
          the colour 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[255-i-(j&15)];
                           den = r;

     Page 1                       Plan 9             (printed 3/28/24)

     RGBV(6)                                                   RGBV(6)

                           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) coor-
          dinates 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 colour map is indexed is
          designed to distribute the grey shades uniformly throughout
          the map-the i 'th grey shade, 0_<i_<15 has index 255-i×17,
          with white going to 0 and black to 255.  We do this so that
          when a call to draw converts a 1, 2 or 4 bit-per-pixel pic-
          ture to 8 bits per pixel (which it does by replicating the
          pixels' bits), the converted pixel values are the appropri-
          ate grey shades.

          The rgbv 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
          colour 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
          colour cube with colours whose differences are almost imper-
          ceptible.  Either reason suggests concentrating the avail-
          able intensities at the low end of the range.

     SEE ALSO
          draw-intro(2), draw-image(2).

     Page 2                       Plan 9             (printed 3/28/24)