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.