LBX X Consortium Algorithms

   X Version 11, Release 7.7
     __________________________________________________________

   Table of Contents

   Introduction
   Streaming Compression
   Bitmap Compression
   Pixmap Compression
   Colormap Algorithm
   Extensions

Introduction

   The Low Bandwidth X extension allows for negotiating various
   algorithms used by LBX. This document describes the algorithms
   used in the Consortium implementation of LBX in the X11 Release
   6.4.

Streaming Compression

   LBX negotiates the use of a stream compressor. The consortium
   implementation defines a stream compressor named XC-ZLIB, which
   is based on the Zlib version 1.0 compression library by Gailly
   & Adler.

   The XC-ZLIB compressor is presented with a simple byte stream -
   the X and LBX message boundaries are not apparent. The data is
   broken up into fixed sized blocks. Each block is compressed
   using zlib, then a two byte header is prepended, and then the
   entire packet is transmitted. The header has the following
   information:
     out[0] (length & 0xfff) >> 8 | ((compflag) ? 0x80 : 0);
     out[1] = length & 0xff;

   If the compflag is false, then the contents of the block are
   not compressed.

Bitmap Compression

   LBX also negotiates for bitmap compression. The consortium
   implementation defines a bitmap compressor named XC-FaxG42D,
   which uses the CCITT Group 4 2D compression algorithm.

Pixmap Compression

   LBX allows for the negotiation of pixmap compression. The
   consortium implementation does not define a pixmap compression
   algorithm. (A run-length encoding algorithm was proposed, but
   experimentation proved it was less efficient than allowing the
   stream compressor to compress the image.

Colormap Algorithm

   LBX negotiates for use of a colormap algorithm, used for color
   matching when the proxy allocates pixels in a grabbed colormap.
   The consortium implementation defines an algorithm named
   XC-CMAP. This algorithm consists of three parts, resolving to a
   hardware color, finding the closest existing color, and what
   free cell to allocate.

   The XC-CMAP algorithm resolves a color to a hardware color in
   the following manner:
#define RESCALE(x, nbits) (x >> (16 - nbits)) * 65535 / ((1 << nbits) -
1)
#define GRAY(r, g, b) (30L * r + 59L * g + 11L * b) / 100

sigbits = pVisual->bitsPerRGB;

switch (pVisual->class) {
   case PseudoColor:
   case DirectColor:
   case StaticColor:
   /* rescale to rgb bits */
      *red = RESCALE(*red, sigbits);
      *green = RESCALE(*green, sigbits);
      *blue = RESCALE(*blue, sigbits);
      break;
   case GrayScale:
     /* rescale to gray then rgb bits */
     *blue = *green = *red = RESCALE(GRAY(*red, *green, *blue), sigbits)
;
      break;
   case StaticGray:
     /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
     *blue = *green = *red = RESCALE(RESCALE(GRAY(*red, *green, *blue),
pVisual>numPixelBits), sigbits);
      break;
    case TrueColor:
      /* rescale to [0..limN] then [0..65535] then rgb bits */
      *red = RESCALE(RESCALE(*red, pVisual->numRedBits), sigbits);
      *green = RESCALE(RESCALE(*green, pVisual->numGreenBits), sigbits);
      *blue = RESCALE(RESCALE(*blue, pVisual->numBlueBits), sigbits);
      break;
  }

   The XC-CMAP algorithm matches a color to an existing pixel in
   static visuals by finding the pixel with the lowest color match
   error, computed as follows:
error = errRed * errRed + errGreen * errGreen + errBlue * errBlue

   The XC-CMAP algorithm selects a free pixel to allocate by
   selecting the free pixel with the lowest index from the free
   pixels known to the proxy. For direct visuals, it uses the
   lowest free or matching pixel subfield known to the proxy for
   each color.

Extensions

   LBX allows for extensions to LBX to enable additional
   compression or short-circuiting. The consortium implementation
   does not define any extensions to LBX.
