[comp.sources.x] v09i081: XV -- successor to XGIF, Part01/01

bradley@grip.cis.upenn.edu (John Bradley) (10/11/90)

Submitted-by: bradley@grip.cis.upenn.edu (John Bradley)
Posting-number: Volume 9, Issue 81
Archive-name: xv/part01


--------------------(cut here)-------------------
#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./docs`
then
  mkdir ./docs
  echo "mkdir ./docs"
fi
if `test ! -s ./docs/xv.blurb`
then
echo "writting ./docs/xv.blurb"
cat > ./docs/xv.blurb << '\BARFOO\'
XV is a direct successor to XGIF.  

New features include:
  * more graphic formats supported (GIF, PBM/PGM/PPM, and X11 bitmap)

  * works on most X displays (1-, 4-, 6-, 8-, and 24-bit displays are
    supported)

  * arbitrary scaling, cropping, rotation (in 90-degree steps)

  * can write files in all formats listed above

  * arbitrary gamma correction curve for brightness/contrast control
    and interesting effects

  * cool-whizo user interface

  * better color allocation code, including the ability to install its own
    colormap if necessary

  * more robust error handling

  * and more bug fixes than we'd care to discuss...


Full Description:
-----------------
XV is a program that displays image files in GIF, PBM/PGM/PPM, and X11 Bitmap
formats.  It is a direct sequel to XGIF, and fixes most (if not all) of the
shortcomings of that program.  XV runs on nearly ALL X displays, 1-bit,
4-bit, 6-bit, 8-bit, and 24-bit, color, grayscale, and black/white.  

XV displays one image at a time in an output window.  You can arbitrarily
stretch or compress the window, and the picture will be rescaled to fit.  
You can rotate the picture in 90-degree steps.  You can repeatedly 'crop'
a picture (define a rectangular 'region-of-interest' and 'throw away' the
rest).  You can magnify any portion of the picture by any amount, up to the 
maximum size of your screen.  

XV allows you click on the picture to determine pixel RGB values and x,y 
coordinates.  You can perform arbitrary 'gamma correction' on the picture
both in RGB space and HSV space.  You can specify the maximum number of colors
that XV should use, for some interesting visual effects.  You can have
the program produce a stippled version of the picture using black and white,
or any other pair of colors.  

XV can write images in a variety of formats, with many of the modifications 
you may have made to the picture saved as well.  You can use XV to do format 
conversion.  XV will also automatically uncompress compress-ed files, as well 
as read files from stdin.


John Bradley                    University of Pennsylvania  -  GRASP Lab
     bradley@cis.upenn.edu

     October 9, 1990
\BARFOO\
else
  echo "will not over write ./docs/xv.blurb"
fi
if `test ! -d ./bitmaps`
then
  mkdir ./bitmaps
  echo "mkdir ./bitmaps"
fi
if `test ! -s ./bitmaps/down`
then
echo "writting ./bitmaps/down"
cat > ./bitmaps/down << '\BARFOO\'
#define down_width 16
#define down_height 16
static char down_bits[] = {
   0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0xf1, 0x87, 0x11, 0x84, 0x11, 0x84,
   0x11, 0x84, 0x1f, 0xbc, 0x05, 0x90, 0x09, 0x88, 0x11, 0x84, 0x21, 0x82,
   0x41, 0x81, 0x81, 0x80, 0x01, 0x80, 0xff, 0xff};
\BARFOO\
else
  echo "will not over write ./bitmaps/down"
fi
if `test ! -s ./bitmaps/down1`
then
echo "writting ./bitmaps/down1"
cat > ./bitmaps/down1 << '\BARFOO\'
#define down1_width 16
#define down1_height 16
static char down1_bits[] = {
   0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0xf1, 0x87, 0xf1, 0x87, 0xf1, 0x87,
   0xf1, 0x87, 0xff, 0xbf, 0xfd, 0x9f, 0xf9, 0x8f, 0xf1, 0x87, 0xe1, 0x83,
   0xc1, 0x81, 0x81, 0x80, 0x01, 0x80, 0xff, 0xff};
\BARFOO\
else
  echo "will not over write ./bitmaps/down1"
fi
if `test ! -s ./bitmaps/grasp`
then
echo "writting ./bitmaps/grasp"
cat > ./bitmaps/grasp << '\BARFOO\'
#define grasp_width 64
#define grasp_height 64
static char grasp_bits[] = {
   0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
   0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x05, 0x00, 0x00,
   0x00, 0x00, 0xfc, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
   0xff, 0xff, 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
   0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf0, 0xff, 0xff,
   0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
   0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0xff,
   0xff, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
   0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0x07,
   0x54, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x07,
   0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x00,
   0x00, 0x00, 0xfe, 0x1f, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xf8, 0x3f,
   0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0xff, 0xff, 0x1f, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xf8, 0x01, 0x03, 0x8f, 0x3f,
   0xff, 0xff, 0xfc, 0xf9, 0x83, 0x83, 0x9f, 0x7f, 0xff, 0x7f, 0xfe, 0xfb,
   0x87, 0xc7, 0xbf, 0x7f, 0xff, 0x3f, 0x8e, 0x3b, 0xc7, 0xc7, 0xb9, 0x73,
   0x00, 0x00, 0x0e, 0x38, 0xc7, 0xce, 0x83, 0x73, 0x00, 0x00, 0xee, 0xbb,
   0xc7, 0x8e, 0x8f, 0x7b, 0x00, 0x00, 0xee, 0xfb, 0xe3, 0x0f, 0x9f, 0x3f,
   0x00, 0x00, 0x8e, 0xfb, 0xe1, 0x1f, 0xb8, 0x1f, 0x00, 0x00, 0x9e, 0xbb,
   0xe3, 0xde, 0xb9, 0x03, 0x00, 0x00, 0xfc, 0xbb, 0x73, 0xdc, 0xbf, 0x03,
   0x00, 0x00, 0xfc, 0x39, 0x77, 0xb8, 0x9f, 0x03, 0x00, 0x00, 0xf0, 0x38,
   0x77, 0x38, 0x8f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x10, 0x20,
   0x00, 0x40, 0x00, 0x00, 0xff, 0x7f, 0x10, 0xec, 0xee, 0xec, 0xee, 0x0a,
   0xff, 0xff, 0x10, 0xaa, 0x2a, 0x4a, 0x2a, 0x0a, 0xff, 0xff, 0xf1, 0xfe,
   0x2e, 0xde, 0x2e, 0x0e, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08,
   0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0x0f, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0xff, 0xff, 0x7f, 0x00,
   0x00, 0x00, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfe, 0x1f,
   0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x03,
   0x00, 0xc0, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0x54, 0xff, 0xff, 0x03,
   0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
   0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0xff,
   0xff, 0xff, 0x1f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
   0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x80, 0xff, 0xff,
   0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00,
   0x00, 0x00, 0xf8, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
   0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x17, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/grasp"
fi
if `test ! -s ./bitmaps/penn`
then
echo "writting ./bitmaps/penn"
cat > ./bitmaps/penn << '\BARFOO\'
#define penn_width 64
#define penn_height 64
static char penn_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
   0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x18, 0x00, 0x00,
   0x00, 0x00, 0x18, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00,
   0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00, 0x00, 0xd8, 0xab, 0xff,
   0xff, 0xd5, 0x1b, 0x00, 0x00, 0x58, 0x7d, 0xfd, 0xbf, 0xbe, 0x1a, 0x00,
   0x00, 0xd8, 0x93, 0x1f, 0xf7, 0xc9, 0x1b, 0x00, 0x00, 0x58, 0x01, 0x0d,
   0xb2, 0x80, 0x1a, 0x00, 0x00, 0xd8, 0x11, 0xef, 0xee, 0x88, 0x1b, 0x00,
   0x00, 0x58, 0x01, 0x15, 0xad, 0x80, 0x1a, 0x00, 0x00, 0xd8, 0x11, 0x67,
   0xe2, 0x88, 0x1b, 0x00, 0x00, 0x58, 0x01, 0xf5, 0xb1, 0x80, 0x1a, 0x00,
   0x00, 0xd8, 0x39, 0xff, 0xff, 0x9c, 0x1b, 0x00, 0x00, 0x58, 0xff, 0xfd,
   0xbf, 0xff, 0x1a, 0x00, 0x00, 0xd8, 0xaa, 0xfe, 0x7f, 0x55, 0x1b, 0x00,
   0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00, 0x00, 0xd8, 0xff, 0xff,
   0xff, 0xff, 0x1b, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00,
   0x00, 0x58, 0x00, 0x80, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x58, 0x00, 0xc0,
   0x03, 0x00, 0x1a, 0x00, 0x00, 0x58, 0x00, 0xe0, 0x07, 0x00, 0x1a, 0x00,
   0x00, 0x58, 0x00, 0xf0, 0x0f, 0x00, 0x1a, 0x00, 0x00, 0x58, 0x00, 0xf8,
   0x1f, 0x00, 0x1a, 0x00, 0x00, 0x58, 0x00, 0x7c, 0x3e, 0x00, 0x1a, 0x00,
   0x00, 0x58, 0x00, 0x1e, 0x78, 0x00, 0x1a, 0x00, 0x00, 0x98, 0x00, 0x1f,
   0xf8, 0x00, 0x19, 0x00, 0x00, 0xb8, 0x80, 0x0f, 0xf0, 0x01, 0x1d, 0x00,
   0x00, 0xb0, 0xc0, 0x0f, 0xf0, 0x03, 0x0d, 0x00, 0x00, 0xb0, 0xe0, 0x1f,
   0xf8, 0x07, 0x0d, 0x00, 0x00, 0xb0, 0xf0, 0x1f, 0xf8, 0x0f, 0x0d, 0x00,
   0x00, 0x30, 0x79, 0x7e, 0x7e, 0x9e, 0x0c, 0x00, 0x00, 0x60, 0x1d, 0xf8,
   0x1f, 0xb8, 0x06, 0x00, 0x00, 0x60, 0x1f, 0xf8, 0x1f, 0xf8, 0x06, 0x00,
   0x00, 0x60, 0x0e, 0xf0, 0x0f, 0x70, 0x06, 0x00, 0x00, 0xc0, 0x0e, 0xf0,
   0x0f, 0x70, 0x03, 0x00, 0x00, 0xc0, 0x1c, 0x78, 0x1e, 0x38, 0x03, 0x00,
   0x00, 0x80, 0x1d, 0x38, 0x1c, 0xb8, 0x01, 0x00, 0x00, 0x80, 0x79, 0x1e,
   0x78, 0x9e, 0x01, 0x00, 0x00, 0x00, 0xfb, 0x0f, 0xf0, 0xdf, 0x00, 0x00,
   0x00, 0x00, 0xf3, 0x07, 0xe0, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x03,
   0xc0, 0x67, 0x00, 0x00, 0x00, 0x00, 0xec, 0x01, 0x80, 0x37, 0x00, 0x00,
   0x00, 0x00, 0xcc, 0x00, 0x00, 0x33, 0x00, 0x00, 0x3c, 0x00, 0x98, 0x00,
   0x00, 0x19, 0x00, 0x3c, 0x6e, 0x78, 0x30, 0x01, 0x80, 0x0c, 0x1e, 0x76,
   0xda, 0x87, 0x60, 0x06, 0x60, 0x06, 0xe1, 0x5b, 0xfa, 0x88, 0xc1, 0x08,
   0x10, 0x83, 0x19, 0x5f, 0x1a, 0x46, 0x81, 0x33, 0xcc, 0x81, 0x72, 0x59,
   0xda, 0x70, 0x01, 0xc7, 0xe3, 0x80, 0x0e, 0x59, 0x96, 0xbf, 0x01, 0x1c,
   0x38, 0x80, 0xfd, 0x69, 0x60, 0x8a, 0x07, 0x78, 0x1e, 0xe0, 0x59, 0x06,
   0xc0, 0xcb, 0x1d, 0xe0, 0x07, 0xb8, 0xd3, 0x03, 0xc0, 0x69, 0xf0, 0x80,
   0x01, 0x0f, 0x96, 0x03, 0x00, 0x08, 0x09, 0x1f, 0xf8, 0x60, 0x10, 0x00,
   0x00, 0x90, 0x5d, 0xe0, 0x07, 0xf6, 0x08, 0x00, 0x00, 0x60, 0x48, 0x0b,
   0xd0, 0x16, 0x06, 0x00, 0x00, 0x80, 0x25, 0xe3, 0xdc, 0x87, 0x01, 0x00,
   0x00, 0x00, 0x8e, 0xe4, 0x94, 0x70, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01,
   0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/penn"
fi
if `test ! -s ./bitmaps/scrlgray`
then
echo "writting ./bitmaps/scrlgray"
cat > ./bitmaps/scrlgray << '\BARFOO\'
#define scrlgray_width 8
#define scrlgray_height 8
static char scrlgray_bits[] = {
   0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44};
\BARFOO\
else
  echo "will not over write ./bitmaps/scrlgray"
fi
if `test ! -s ./bitmaps/up`
then
echo "writting ./bitmaps/up"
cat > ./bitmaps/up << '\BARFOO\'
#define up_width 16
#define up_height 16
static char up_bits[] = {
   0xff, 0xff, 0x01, 0x80, 0x81, 0x80, 0x41, 0x81, 0x21, 0x82, 0x11, 0x84,
   0x09, 0x88, 0x05, 0x90, 0x1f, 0xbc, 0x11, 0x84, 0x11, 0x84, 0x11, 0x84,
   0xf1, 0x87, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff};
\BARFOO\
else
  echo "will not over write ./bitmaps/up"
fi
if `test ! -s ./bitmaps/up1`
then
echo "writting ./bitmaps/up1"
cat > ./bitmaps/up1 << '\BARFOO\'
#define up1_width 16
#define up1_height 16
static char up1_bits[] = {
   0xff, 0xff, 0x01, 0x80, 0x81, 0x80, 0xc1, 0x81, 0xe1, 0x83, 0xf1, 0x87,
   0xf9, 0x8f, 0xfd, 0x9f, 0xff, 0xbf, 0xf1, 0x87, 0xf1, 0x87, 0xf1, 0x87,
   0xf1, 0x87, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff};
\BARFOO\
else
  echo "will not over write ./bitmaps/up1"
fi
if `test ! -s ./bitmaps/gray50`
then
echo "writting ./bitmaps/gray50"
cat > ./bitmaps/gray50 << '\BARFOO\'
#define gray50_width 8
#define gray50_height 8
static char gray50_bits[] = {
   0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc};
\BARFOO\
else
  echo "will not over write ./bitmaps/gray50"
fi
if `test ! -s ./bitmaps/gray25`
then
echo "writting ./bitmaps/gray25"
cat > ./bitmaps/gray25 << '\BARFOO\'
#define gray25_width 8
#define gray25_height 8
static char gray25_bits[] = {
   0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22};
\BARFOO\
else
  echo "will not over write ./bitmaps/gray25"
fi
if `test ! -s ./bitmaps/i_chr`
then
echo "writting ./bitmaps/i_chr"
cat > ./bitmaps/i_chr << '\BARFOO\'
#define i_chr_width 20
#define i_chr_height 13
static char i_chr_bits[] = {
   0xe0, 0x7f, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00,
   0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0xe0, 0x7f, 0x00,
   0x00, 0x09, 0x00, 0xf0, 0xff, 0x00, 0x50, 0xd5, 0x00, 0xb0, 0xaa, 0x00,
   0xf0, 0xff, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_chr"
fi
if `test ! -s ./bitmaps/i_blk`
then
echo "writting ./bitmaps/i_blk"
cat > ./bitmaps/i_blk << '\BARFOO\'
#define i_blk_width 20
#define i_blk_height 13
static char i_blk_bits[] = {
   0x40, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x0c, 0x02, 0x00, 0x03, 0xcc, 0x01,
   0x0d, 0x3a, 0x06, 0xb1, 0x19, 0x06, 0x41, 0xe8, 0x05, 0x41, 0x88, 0x04,
   0x41, 0x88, 0x04, 0x41, 0x88, 0x04, 0x43, 0x9c, 0x06, 0x4c, 0xb2, 0x01,
   0xf0, 0xc1, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_blk"
fi
if `test ! -s ./bitmaps/i_fifo`
then
echo "writting ./bitmaps/i_fifo"
cat > ./bitmaps/i_fifo << '\BARFOO\'
#define i_fifo_width 20
#define i_fifo_height 13
static char i_fifo_bits[] = {
   0x80, 0x0f, 0xf0, 0x80, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xf0,
   0xff, 0xff, 0xff, 0xf0, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xf0,
   0xff, 0xff, 0xff, 0x00, 0x07, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0,
   0xff, 0xff, 0xff};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_fifo"
fi
if `test ! -s ./bitmaps/i_dir`
then
echo "writting ./bitmaps/i_dir"
cat > ./bitmaps/i_dir << '\BARFOO\'
#define i_dir_width 20
#define i_dir_height 13
static char i_dir_bits[] = {
   0xf0, 0x01, 0x00, 0x08, 0x02, 0x00, 0xfe, 0xff, 0x07, 0x02, 0x00, 0x04,
   0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04,
   0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04,
   0xfe, 0xff, 0x07};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_dir"
fi
if `test ! -s ./bitmaps/i_lnk`
then
echo "writting ./bitmaps/i_lnk"
cat > ./bitmaps/i_lnk << '\BARFOO\'
#define i_lnk_width 20
#define i_lnk_height 13
static char i_lnk_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0xff, 0x07,
   0xe0, 0xff, 0x07, 0x30, 0xc0, 0x01, 0x30, 0x40, 0x00, 0xe0, 0x0f, 0x00,
   0xc0, 0x1f, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0xfe, 0x1f, 0x00,
   0xfe, 0x0f, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_lnk"
fi
if `test ! -s ./bitmaps/i_sock`
then
echo "writting ./bitmaps/i_sock"
cat > ./bitmaps/i_sock << '\BARFOO\'
#define i_sock_width 20
#define i_sock_height 13
static char i_sock_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x84, 0xf0, 0x0f,
   0x8c, 0x10, 0x00, 0x9f, 0x5a, 0x05, 0xbf, 0xb5, 0x0a, 0x9f, 0xff, 0x0f,
   0x8c, 0xff, 0x0f, 0x84, 0xff, 0x0f, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_sock"
fi
if `test ! -s ./bitmaps/rb_off`
then
echo "writting ./bitmaps/rb_off"
cat > ./bitmaps/rb_off << '\BARFOO\'
#define rb_off_width 15
#define rb_off_height 15
static char rb_off_bits[] = {
   0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40,
   0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20,
   0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03};
\BARFOO\
else
  echo "will not over write ./bitmaps/rb_off"
fi
if `test ! -s ./bitmaps/i_reg`
then
echo "writting ./bitmaps/i_reg"
cat > ./bitmaps/i_reg << '\BARFOO\'
#define i_reg_width 20
#define i_reg_height 13
static char i_reg_bits[] = {
   0xc0, 0x7f, 0x00, 0xa0, 0x40, 0x00, 0x90, 0x40, 0x00, 0xf0, 0x40, 0x00,
   0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00,
   0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00, 0x10, 0x40, 0x00,
   0xf0, 0x7f, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/i_reg"
fi
if `test ! -s ./bitmaps/fc_left`
then
echo "writting ./bitmaps/fc_left"
cat > ./bitmaps/fc_left << '\BARFOO\'
#define fc_left_width 16
#define fc_left_height 16
static char fc_left_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x04, 0x70, 0x82, 0x8c, 0xe2,
   0x22, 0x9c, 0x2d, 0x90, 0x2d, 0x80, 0x21, 0x90, 0x22, 0x9c, 0x1c, 0xe3,
   0x70, 0x82, 0x80, 0x02, 0x00, 0x07, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_left"
fi
if `test ! -s ./bitmaps/rb_on`
then
echo "writting ./bitmaps/rb_on"
cat > ./bitmaps/rb_on << '\BARFOO\'
#define rb_on_width 15
#define rb_on_height 15
static char rb_on_bits[] = {
   0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0xc2, 0x21, 0xf2, 0x27, 0xf1, 0x47,
   0xf9, 0x4f, 0xf9, 0x4f, 0xf9, 0x4f, 0xf1, 0x47, 0xf2, 0x27, 0xc2, 0x21,
   0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03};
\BARFOO\
else
  echo "will not over write ./bitmaps/rb_on"
fi
if `test ! -s ./bitmaps/rb_on1`
then
echo "writting ./bitmaps/rb_on1"
cat > ./bitmaps/rb_on1 << '\BARFOO\'
#define rb_on1_width 15
#define rb_on1_height 15
static char rb_on1_bits[] = {
   0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0xc6, 0x31, 0xf6, 0x37, 0xf3, 0x67,
   0xfb, 0x6f, 0xfb, 0x6f, 0xfb, 0x6f, 0xf3, 0x67, 0xf6, 0x37, 0xc6, 0x31,
   0x1c, 0x1c, 0xf8, 0x0f, 0xe0, 0x03};
\BARFOO\
else
  echo "will not over write ./bitmaps/rb_on1"
fi
if `test ! -s ./bitmaps/rb_off1`
then
echo "writting ./bitmaps/rb_off1"
cat > ./bitmaps/rb_off1 << '\BARFOO\'
#define rb_off1_width 15
#define rb_off1_height 15
static char rb_off1_bits[] = {
   0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x06, 0x30, 0x06, 0x30, 0x03, 0x60,
   0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x06, 0x30, 0x06, 0x30,
   0x1c, 0x1c, 0xf8, 0x0f, 0xe0, 0x03};
\BARFOO\
else
  echo "will not over write ./bitmaps/rb_off1"
fi
if `test ! -s ./bitmaps/grasp.old`
then
echo "writting ./bitmaps/grasp.old"
cat > ./bitmaps/grasp.old << '\BARFOO\'
#define grasp_width 64
#define grasp_height 64
static char grasp_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
   0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x00,
   0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0xe0, 0xff,
   0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x1f, 0x00,
   0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xff,
   0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
   0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07,
   0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x0f,
   0x00, 0xf8, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x3f,
   0xff, 0xff, 0x7f, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xff, 0xff, 0x1f, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0xf8, 0x01, 0x03, 0x8f, 0x3f,
   0xff, 0x7f, 0xfc, 0xf9, 0x83, 0x83, 0x9f, 0x7f, 0xff, 0x3f, 0xfe, 0xfb,
   0x87, 0xc7, 0xbf, 0x7f, 0xff, 0x3f, 0x8e, 0x3b, 0xc7, 0xc7, 0xb9, 0x73,
   0x00, 0x00, 0x0e, 0x38, 0xc7, 0xce, 0x83, 0x73, 0x00, 0x00, 0xee, 0xbb,
   0xc7, 0x8e, 0x8f, 0x7b, 0x00, 0x00, 0xee, 0xfb, 0xe3, 0x0f, 0x9f, 0x3f,
   0x00, 0x00, 0x8e, 0xfb, 0xe1, 0x1f, 0xb8, 0x1f, 0x00, 0x00, 0x9e, 0xbb,
   0xe3, 0xde, 0xb9, 0x03, 0x00, 0x00, 0xfc, 0xbb, 0x73, 0xdc, 0xbf, 0x03,
   0x00, 0x00, 0xfc, 0x39, 0x77, 0xb8, 0x9f, 0x03, 0x00, 0x00, 0xf0, 0x38,
   0x77, 0x38, 0x8f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x10, 0x20,
   0x00, 0x40, 0x00, 0x00, 0xff, 0x3f, 0x10, 0xec, 0xee, 0xec, 0xee, 0x0a,
   0xff, 0x7f, 0x10, 0xaa, 0x2a, 0x4a, 0x2a, 0x0a, 0xff, 0xff, 0xf0, 0xfe,
   0x2e, 0xde, 0x2e, 0x0e, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
   0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0x07, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xff, 0xff, 0x7f, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x01,
   0x00, 0xf0, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x1f,
   0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x07, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
   0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
   0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xfc, 0xff,
   0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
   0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf8,
   0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x01, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/grasp.old"
fi
if `test ! -s ./bitmaps/fc_right`
then
echo "writting ./bitmaps/fc_right"
cat > ./bitmaps/fc_right << '\BARFOO\'
#define fc_right_width 16
#define fc_right_height 16
static char fc_right_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x20, 0x03, 0x41, 0x0e, 0x47, 0x30,
   0x39, 0x44, 0x09, 0xb4, 0x01, 0xb4, 0x09, 0x84, 0x39, 0x44, 0xc7, 0x38,
   0x41, 0x0e, 0x40, 0x01, 0xe0, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_right"
fi
if `test ! -s ./bitmaps/fc_mid`
then
echo "writting ./bitmaps/fc_mid"
cat > ./bitmaps/fc_mid << '\BARFOO\'
#define fc_mid_width 16
#define fc_mid_height 16
static char fc_mid_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0x40, 0x04, 0x20, 0x08,
   0xe0, 0x0e, 0xe0, 0x0e, 0x20, 0x08, 0xa0, 0x0b, 0xe0, 0x0f, 0xa0, 0x0b,
   0x40, 0x04, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_mid"
fi
if `test ! -s ./bitmaps/fc_leftm`
then
echo "writting ./bitmaps/fc_leftm"
cat > ./bitmaps/fc_leftm << '\BARFOO\'
#define fc_leftm_width 16
#define fc_leftm_height 16
static char fc_leftm_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0xf0, 0x83, 0xfc, 0xe3,
   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfc, 0xe3,
   0xf0, 0x83, 0x80, 0x03, 0x00, 0x07, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_leftm"
fi
if `test ! -s ./bitmaps/fc_midm`
then
echo "writting ./bitmaps/fc_midm"
cat > ./bitmaps/fc_midm << '\BARFOO\'
#define fc_midm_width 16
#define fc_midm_height 16
static char fc_midm_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f,
   0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f, 0xe0, 0x0f,
   0xc0, 0x07, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_midm"
fi
if `test ! -s ./bitmaps/fc_rightm`
then
echo "writting ./bitmaps/fc_rightm"
cat > ./bitmaps/fc_rightm << '\BARFOO\'
#define fc_rightm_width 16
#define fc_rightm_height 16
static char fc_rightm_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xe0, 0x03, 0xc1, 0x0f, 0xc7, 0x3f,
   0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xc7, 0x3f,
   0xc1, 0x0f, 0xc0, 0x01, 0xe0, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_rightm"
fi
if `test ! -s ./bitmaps/fc_left1`
then
echo "writting ./bitmaps/fc_left1"
cat > ./bitmaps/fc_left1 << '\BARFOO\'
#define fc_left1_width 16
#define fc_left1_height 16
static char fc_left1_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x02, 0xe0, 0x14, 0x10, 0x1f,
   0xd8, 0x14, 0xd8, 0x14, 0x08, 0x10, 0x08, 0x14, 0xd0, 0x14, 0x70, 0x1e,
   0x60, 0x13, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_left1"
fi
if `test ! -s ./bitmaps/fc_right1`
then
echo "writting ./bitmaps/fc_right1"
cat > ./bitmaps/fc_right1 << '\BARFOO\'
#define fc_right1_width 16
#define fc_right1_height 16
static char fc_right1_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x03, 0x28, 0x07, 0xf8, 0x08,
   0x28, 0x1b, 0x28, 0x1b, 0x08, 0x10, 0x28, 0x10, 0x28, 0x0b, 0x38, 0x0e,
   0xc8, 0x06, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_right1"
fi
if `test ! -s ./bitmaps/fc_right1m`
then
echo "writting ./bitmaps/fc_right1m"
cat > ./bitmaps/fc_right1m << '\BARFOO\'
#define fc_right1m_width 16
#define fc_right1m_height 16
static char fc_right1m_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0x03, 0xe8, 0x07, 0xf8, 0x0f,
   0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x0f, 0xf8, 0x0f,
   0xc8, 0x07, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_right1m"
fi
if `test ! -s ./bitmaps/fc_left1m`
then
echo "writting ./bitmaps/fc_left1m"
cat > ./bitmaps/fc_left1m << '\BARFOO\'
#define fc_left1m_width 16
#define fc_left1m_height 16
static char fc_left1m_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xe0, 0x17, 0xf0, 0x1f,
   0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x1f,
   0xe0, 0x13, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00};
\BARFOO\
else
  echo "will not over write ./bitmaps/fc_left1m"
fi
if `test ! -s ./README`
then
echo "writting ./README"
cat > ./README << '\BARFOO\'
Installation
------------
Check the Makefile for the configuration option(s).  'make'.  Enjoy.


Caveats
-------

XV has been developed on a Sun4/280 running SunOS 4.0, using both the normal
'cc' and gcc-1.37 compilers.  There shouldn't be anything grotesque enough
in the code to break any other compilers.  

The viewing environment has mainly been an IBM RT with an 8-bit color display.
The window managers of choice have been TWM (recently) and UWM (in the past).

It has been compiled and tested on the following systems:  Sun 4 running SunOS 
4.0, VAXstation 3500 running Ultrix 3.0, MicroVax II running Ultrix 2.0, 
DecStation 3100 running UWS 2.0, IBM RISC System/6000 running AIX 3.0.

It has displayed on the following systems:  IBM RT (8-bit color), Sun 3 
(1-bit B/W), Sun 3 (8-bit grayscale), Sun 4 (1-bit B/W), MicroVax II (8-bit
color), MicroVax II (4-bit grayscale), a variety of HPs (4-bit color, 6-bit 
color, 8-bit color, and 24-bit color), and Visual, NCD, Tektronix, and
HDS X terminals (1-bit B/W abd 8-bit color).

Provided you don't have some odd-ball 5-bit StaticColor display, it should
work for you.

One note:  on some machines, the function 'vsprintf' (a VARARGS sprintf())
doesn't exist.  You won't be able to compile on these machines.  They are
wrong.


Bizarrities
-----------

There are problems with using XV under 'dxwm', DEC's window manager.  You'll
have to specify '-dxwm' to enable a couple of kludges, and even then XV is
unable to MOVE its window AT ALL.  (This was with dxwm controlling my X11R4
IBM RT display.  Your mileage (dxwm controlling a DEC server, ferinstance)
may vary.

XV would appear to exercise a pair of bugs in TWM, the version from the X11R4 
tape.  Perhaps they've been fixed by now.

Colormap Installation:  under twm, if you have multiple XVs running, and each
has their own colormap, sometimes the colormap doesn't get properly installed 
if you move the mouse directly from one XV to the other, quickly, so that it 
doesn't see the mouse go into the root window, or any other window.  If you 
move the mouse outside the window and move it back in, it SHOULD install the
colormap correctly.

Colormap Installation: Note, if an alternate colormap is installed, it will
ONLY be installed when the mouse is inside the IMAGE window.  It will not be
installed when the mouse is in any other XV windows.  This is because I can't
guarantee that the other windows will still have contrasting
foreground/background colors when the alternate colormap is installed.  It is
assumed that if you put the mouse in a window, you will want to use that
window, so you'd better be able to READ that window...

There's a bug in my version of TWM that creeps up if you have titlebars 
turned off.  Essentially, XV tells the window manager to make the window a
certain size.  TWM (wrongly) adds enough room at the top to put its title bar 
there, but doesn't draw it, since titlebars are turned off.  XV gets back a
ConfigureNotify event on the window with the new size, which is large by 20-odd
pixels in height.  There's no way to detect this behavior that I know of.
Workaround:  wait for a fixed version of TWM, until then, run (at least XV) 
with titlebars on.



Modifying XV
------------

ADDING A NEW FILE FORMAT TO XV

This category is split up into two sections, reading a new file format, and 
writing a new file format, because it's perfectly conceivable that you'd want 
to do one but not the other.  In some cases, it's even possible that you could
only (realistically, read "easily") do one or the other.  (Example:  you want
to be able to write an Encapsulated PostScript image, but you'd never be able
to read PostScript files without writing a complete postscript interpreter, 
something that's thankfully outside the context of this program.)

Alternately, you might also want to be able to directly display the output of
some Mutant Ray Tracer (or whatever) without going through a conversion
program, yet you'd NEVER want to create more Mutant-Ray-Tracer-format pictures
with xv...

Whatever.  The following instructions are being written as I add PBM/PGM/PPM 
capability to the program, so A) it's likely to be fairly accurate, and B) for
example purposes, I'll be talking about the PBM/PGM/PPM code specifically.

READING A NEW FILE FORMAT

-------
NOTE:  Despite the wide variety of displays and file formats XV deals with,
internally it only manipulates 8-bit colormapped images.  If you're loading
an 8-bit colormapped image, such as a GIF image, no prob.  If you're loading
an 8-or-less-bits format that doesn't have a colormap (such as an 8-bit 
greyscale image, or a 1-bit B/W bitmap) your Load() routine will have to 
generate an appropriate colormap.  And if you're loading up a 24 bit RGB file,
you'll have to compress it down to 8 bits by calling Conf24to8()...
-------

Make a copy of xvpm.c, calling it something appropriate.  I'm adding PBM 
capabilities, so I think xvpbm.c is a fine file name.

Edit the Makefile so that your new module will be compiled.  Add 'xvpbm.o' 
(or whatever)

Edit the new module.

You'll need to #include "xv.h", of course.

The module should have one externally callable function that does the work of
loading up the file.  The function is called with two arguments, a filename
and the number of colors available on this display, like so:

/*******************************************/
int LoadPBM(fname,nc)
    char *fname;   int nc;
/*******************************************/

The file name will be the complete file name (absolute, not relative to any 
directory).  Note:  if xv is reading from <stdin>, don't worry about it.
stdin is automatically copied to a /tmp/xv****** file to make life considerably
simpler (and some times possible at all)

The number of colors argument is going to be (2 << # of bit planes) (or 'ncols'
if specified on the command line).  Either way, this only comes into play if 
you have to do a 24-to-8 bit conversion.  More on that later.

The function returns '0' on success, non-zero on failure.

The function is expected to load up the following global variables:
	byte *pic;	this is a wide*high array of bytes, one byte per pixel,
			starting at the top-left corner, and proceeding in 
			scan-line order.  There is no padding of any sort at 
			the end of a scan line.  The code is expected to 
			malloc() the memory for this image.

	int pWIDE, pHIGH;
			these variables specify the size of the image that
			has been loaded, in pixels.

	byte r[256], g[256], b[256];
			the desired colormap.  As specified above, 'pic' is
			an 8-bits per pixel image.  A given pixel value in pic
			maps to an RGB color through these arrays.  In each
			array, a value of 0 means 'off', and a value of 255
			means 'fully on'.  Note:  the arrays do not have to
			be completely set.  Only RGB entries for pixels that
			actually exist in the 'pic' need to be set.  For 
			example, if the pic is known to be a B/W bitmap with
			pixel values of 0 and 1, you'd only have to set
			{r,g,b}[0] and {r,g,b}[1].

The function should also call 'SetISTR(ISTR_FORMAT, fmt, args)' to set the
"Format:" string in the Info box.  It should call the function as soon as
possible (ie, once it knows the format of the picture, but before it's tried
to load/parse all of the image data...)


Diagnostics:

Non-fatal errors in your Load() routine should be handled by calling
SetISTR(ISTR_WARNING, fmt, args...).  This will print the string in the info
box and in the ctrl box.

Non-fatal errors would be things like 'can't open file'...

Fatal errors should be handled by calling 'FatalError(error_string)'.  
This function prints the string to stderr, and exits the program with an error
code.  The classic fatal error is 'unable to malloc...'.


Handling 24-bit RGB pictures:

If (as in the case of PPM files) you're file format has 24 bits of information
per pixel, you'll have to get it down to 8 bits and a colormap for XV to make
any use of it.  A function 'Conv25to8(pic24, w, h, nc)' is provided, so
don't worry about it.

To use it, you'll have to load your picture into a WIDE*HIGH*3 array of bytes.
(You'll be expected to malloc() this array.)  This array begins at the top left
corner, and proceeds in scan-line order.  The first byte of the array is the
red component of pixel0, followed by the green component of pixel0, followed by
the blue component of pixel0, followed by the red component of pixel1, etc...
There is no padding of any kind.

Once you've got this image built, call 'Conv24to8()' with a pointer to the
24bit image, the width and height of the image, and the number of colors to
'shoot for' in the resulting 8-bit picture.  This is the same parameter that
was passed to your Load() routine, so just pass it along.

If successful, Conv24to8() will return '0'.  It will have generated 'pic', and
filled in values in all the global variables that your Load() routine is
expected to set.  You should now free() the memory associated with the 24-bit
version of your image and leave your Load() function.

Read the source in xvpbm.c for further info on writing the Load() routine.

----------

Once you have a working Load() routine, you'll want to do some other crap...

Edit xv.h and add two function prototypes for any global functions you've
written (presumably just LoadPBM() (in this case)).  You'll need to add a full
function prototype (with parameter types) in the #ifdef __STDC__ section (near
the bottom), and a function reference (just the return type) in the #else /*
non-ANSI */ section at the bottom.



Edit xv.c:


***  Add a filetype #define near the top.  Find the section:

> /* file types that can be read */
> #define UNKNOWN 0
> #define GIF     1
> #define PM      2

And add one more to the list, in this case: "#define PBM 3"

Note: I only added one filetype to this list, despite the fact that
I'm really adding three (or six, really) different file formats to the
program.  This is because all of these file formats are related, and
are handled by the same Load...() function.



*** now tell the openPic() routine about your Load...() routine

find the following (in openPic()):

>    filetype = UNKNOWN;
>    if (strncmp(magicno,"GIF87",5)==0) filetype = GIF;
>    else if (strncmp(magicno,"VIEW",4)==0 ||
>             strncmp(magicno,"WEIV",4)==0) filetype = PM;

Add another 'else' case that will set filetype if it's your format:

>    else if (magicno[0] == 'P' && magicno[1]>='1' &&
>             magicno[1]<='6') filetype = PBM;


And add another case to the switch statement (a few lines further down)

>  switch (filetype) {
>  case GIF: i = LoadGIF(filename);      break;
>  case PM:  i = LoadPM(filename,ncols); break;
>  }

add:

>  case PBM: i = LoadPBM(filename,ncols); break;


That should do it.  Consult the file xvpm.c or xvpbm.c for further information.
Remember: do as I mean, not as I say.

-----------------------------------------------------------------------------




WRITING A NEW FILE FORMAT

-------
NOTE:  Despite the wide variety of displays and file formats XV deals with,
internally it only manipulates 8-bit colormapped images.  As a result, writing
out 24bit RGB images is a horrible waste, and is to be avoided if your file
format can handle colortable images...
-------

If you haven't already done so (if/when you created the Load...() function):
  Make a copy of xvpm.c, calling it something appropriate.  I'm adding PBM 
  capabilities, so I think xvpbm.c is a fine file name.

  Edit the Makefile so that your new module will be compiled.  Add 'xvpbm.o' 
  (or whatever)

  Edit the new module.

  You'll need to #include "xv.h", of course.


The module should have one externally callable function that does the work of
writing the file.  The function is called with a vitual plethora of arguments.
At a minimum, you'll be given a FILE * to an already open-for-writing stream,
a pointer to an 8-bits per pixel image, the width and height of that image, 
pointers to 256-entry red, green, and blue colormaps, the number of colors
actually used in the colormaps, and the 'color style' from the 'Save' dialog 
box.

You may pass more parameters, since you're going to be adding the call to this
function later on.  For example, in my PBM code, I pass one more parameter,
'raw' (whether to save the file as RAW or ASCII) to handle two very similar
formats.  (Rather than haveing WritePBMRaw() and WritePBMAscii()...)

Your function definition should look something like this:

/*******************************************/
int WritePBM(fp,pic,w,h,rmap,gmap,bmap,numcols,colorstyle,raw)
    FILE *fp;
    byte *pic;
    int   w,h;
    byte *rmap, *gmap, *bmap;
    int   numcols, colorstyle, raw;
/*******************************************/

Write the function as you deem appropriate.

Some Notes:
  *  your function should return '0' if successful, non-zero if not
  *  don't close 'fp'
  *  pic is a w*h byte array, starting at top-left, and proceeding in normal
	scan-line order

  *  colorstyle can (currently) take on three values:
	0=FULL COLOR.  This could mean either 24-bit RGB, or an 8-bit colormap
	  or any other color format.  r[pix],g[pix],b[pix] specifies the color
	  of pixel 'pix'.  

	1=GREYSCALE, preferably 8 bits.  Two caveats:  you MUST use the 
	  colormap to determine what grey value to write.  For all you know,
	  pixel value '0' in pic could map to white, '1' could map to black, 
	  and '2' could map to a half-intensity grey.  

	  The other note:  unless the original picture was a greyscale, (which
	  SHOULDN'T be tested for), the colormap is going to have actual 
	  colors in it.  You'll want to map RGB colors into greyscale values
	  using 'the standard formula'  (roughly .33R + .5G +.17B).  The
	  following code shows how to quickly write a raw greyscale image:

	  if (colorstyle == 1) {    /* GreyScale: 8 bits per pixel */
	    byte rgb[256];
	    for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
	    for (i=0, p=pic; i<w*h; i++, p++)
	      putc(rgb[*p],fp);
	  }

	2=B/W STIPPLE:  The stippling algorithm will have already been 
	  preformed by the time your function is called.  'pic' will be an
	  image consisting of the pixel values '1' and '0'.  (pic will STILL
	  be organized the same way (ie, one byte per pixel))

	  1 = WHITE, 0 = BLACK


	* for FULL COLOR or GREYSCALE images, you will be guaranteed that all
	  pixel values in pic are in the range [0 - numcols-1] (inclusive).


That done, edit 'xv.h' and add a pair of function declarations for your new
function.  (one full ANSI-style prototype, and one that just declares the
return type).  (Copy the declarations for 'WritePM()'.)

Edit 'xvdir.c'.  This is the module that controls the 'Save' dialog box.

Add another 'format' type to the 'formatRB' button list:
In the function 'CreateDirW()', find the block that (starts like):

>  formatRB = RBCreate(NULL, dirW, 26, y, "GIF", infofg, infobg);
>  RBCreate(formatRB, dirW, 26, y+18, "PM", infofg, infobg);

copy the last 'RBCreate' call in the list, add '18' to the 'y+**' argument,
and stick in an appropriate format type name.  In this case, I'm adding
two formats (PBM raw and PBM ascii) so I'll add these two lines:

>  RBCreate(formatRB, dirW, 26, y+36, "PBM/PGM/PPM raw", infofg, infobg);
>  RBCreate(formatRB, dirW, 26, y+54, "PBM/PGM/PPM ascii", infofg, infobg);

Depending how many formats you've added, you may have to move the 
'Normal Size' & 'At Current Expansion' buttons down.  Right above the RBCreate
calls that have that string in them is a 'y = y + **' assignment.  Add 18 to
the constant for each 'format' line that you added above.


In the function DoSave(), find the following block:
>  i = RBWhich(formatRB);
>  switch (i) {
>  case 0:  rv = WriteGIF(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB));
>           break;
>  case 1:  rv = WritePM (fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB));
>           break;
>  }

and add cases for your function(s), like so:

>  case 2:  rv = WritePBM(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB),1);
>           break;
>  case 3:  rv = WritePBM(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB),0);
>           break;


\BARFOO\
else
  echo "will not over write ./README"
fi
echo "Finished archive 6 of 8"
exit


dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.