mikew@wyse.wyse.com (Mike Wexler) (01/07/89)
Submitted-by: madd@bu-it.bu.edu (Jim Frost) Posting-number: Volume 2, Issue 79 Archive-name: xbgsun/part01 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: README AUTHOR Makefile common.c common.h patchlevel.h # rasterfile.h xbgsun.c xbgsun.man xviewsun.c xviewsun.man # Wrapped by mikew@wyse on Fri Jan 6 17:50:20 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(734 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThis package contains two programs, xbgsun and xviewsun, which are Xused to manipulate Sun rasterfile images under the X environment. X XXbgsun will load one or more Sun rasterfiles onto the X root window. XIt can optionally perform some kinds of manipulations on the images. X XXviewsun will show a Sun rasterfile in an X window. X XBoth xbgsun and xviewsun can handle monochrome, color, and run-length Xencoded rasterfiles, and can use rasterfiles of different depths than Xthe destination display. If the destination display has fewer colors Xthan the rasterfile, they will attempt to pick the closest available Xcolor. X XSee the enclosed man pages for details on operation. X XJim Frost XAssociative Design Technology Xmadd@bu-it.bu.edu X01.06.88 END_OF_FILE if test 734 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'AUTHOR' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'AUTHOR'\" else echo shar: Extracting \"'AUTHOR'\" \(283 characters\) sed "s/^X//" >'AUTHOR' <<'END_OF_FILE' XDate: Fri, 6 Jan 89 16:53:23 EST XFrom: adt!madd@bu-it.BU.EDU (jim frost) XMessage-Id: <8901062153.AA19775@adt.uucp> XTo: ericw@wyse.com XSubject: new xbgsun and xviewsun X X... XHave fun, X Xjim Xmadd@bu-it.bu.edu X X-- cut here -- X# This is a shell archive. Remove anything before this line, END_OF_FILE if test 283 -ne `wc -c <'AUTHOR'`; then echo shar: \"'AUTHOR'\" unpacked with wrong size! fi # end of 'AUTHOR' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(811 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile for xbgsun & xviewsun X# X# jim frost 12.19.88 X# X# -DPATH should indicate the local image directory if one exists. X# -DSUFFIX indicates a default suffix for images if desired. if X# images are compressed, the suffix should NOT include the .Z since .Z X# is automatically appended if no uncompressed file is found. X# X# Makefile for xviewsun X# XOPTIONS= -DPATH=\"/global/bitmaps\" -DSUFFIX=\".sun\" XCFLAGS= -O $(OPTIONS) -I/global/include XCC= cc XLDFLAGS=-L/global/lib XLIBS= -lX11 X Xall: xviewsun xbgsun X Xxviewsun: common.o xviewsun.o X $(CC) $(LDFLAGS) -o xviewsun $(CFLAGS) xviewsun.o common.o $(LIBS) X Xxbgsun: common.o xbgsun.o X $(CC) $(LDFLAGS) -o xbgsun $(CFLAGS) xbgsun.o common.o $(LIBS) X X.c.o: X $(CC) $(CFLAGS) -c $*.c X Xcommon.o: common.h X X Xclean: X rm -f xviewsun xviewsun.o xbgsun xbgsun.o common.o END_OF_FILE if test 811 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'common.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'common.c'\" else echo shar: Extracting \"'common.c'\" \(16130 characters\) sed "s/^X//" >'common.c' <<'END_OF_FILE' X/* common.c: X * X * routines common to both xbgsun and xviewsun X * X * jim frost 01.06.88 X * X * this is in the public domain X * X * 01.06.88 ability to handle run-length encoding added. X * 12.30.88 original version derived from xbgsun. X */ X X#include <stdio.h> X#include <malloc.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <X11/Xlib.h> X#include "rasterfile.h" X X/* global variables. we could just pass these around but this is simpler X * since there are so many. X */ X XDisplay *disp; /* X display */ Xint width, height, depth; /* dimensions of image */ Xint xorigin, yorigin; /* where to put image */ Xint pwidth, pheight; /* dimensions of pixmap */ Xint cx, cy; /* clip origin */ Xint cwidth, cheight; /* clip dimensions */ Xint verbose; /* talkative mode flag */ Xint docorrupt; /* load corrupt image flag */ Xchar *fgcolor, *bgcolor; /* foreground/background colors */ XPixmap pic; /* destination pixmap */ XXWindowAttributes wa; /* root window attributes */ X X/* local globals X */ X Xstatic unsigned char *data; /* image data area */ Xstatic unsigned long *pixdata; /* pixel data area */ Xstatic unsigned char *red, *blue, *green; /* colormap data areas */ Xstatic int mapsize; /* number of colors in colormap */ Xstatic int bytesperline; /* bytes per image line */ Xstatic int imagebyte, linebyte; X X/* return true if option matches argument for a minimum number of chars X */ X Xint isoption(op, arg, min) Xchar *op, *arg; Xint min; X{ X if ((strlen(arg) < min) && !strncmp(op, arg, strlen(arg))) { X printf("not enough characters specified on option '%s'\n", arg); X exit(1); X } X return(!strncmp(op, arg, strlen(arg))); X} X X/* memToVal and valToMem convert 68000-ordered numbers into whatever the X * local ordering is. if you have bit or byte ordering problems, fix X * them here. this was tested on machines with differing bit and byte X * orders so it should work fine. your mileage may vary. X */ X Xstatic unsigned int memToVal(d, l) Xunsigned char *d; /* char array of number */ Xint l; /* length of array */ X{ int a; X unsigned int i; X X i= 0; X for (a= 0; a < l; a++) X i= (i << 8) + *(d++); X return(i); X} X Xstatic void valToMem(d, l, v) Xunsigned char *d; Xint l; Xunsigned long v; X{ int a; X X for (a= l - 1; a >= 0; a--) { X *(d + a)= v & 0xff; X v >>= 8; X } X} X X/* macro to do 68000 to local integer conversions X */ X X#define localint(d) memToVal(d, 4) X X/* this attempts to find the image. order: X * name X * name.Z X * nameSUFFIX X * nameSUFFIX.Z X * PATH/name X * PATH/name.Z X * PATH/nameSUFFIX X * PATH/nameSUFFIX.Z X */ X Xstatic char *findImage(name) Xchar *name; X{ static char fname[BUFSIZ]; X struct stat sbuf; /* dummy */ X X if (!stat(name, &sbuf)) X return(name); X sprintf(fname, "%s.Z", name); X if (!stat(fname, &sbuf)) X return(fname); X#ifdef SUFFIX X sprintf(fname, "%s%s", name, SUFFIX); X if (!stat(fname, &sbuf)) X return(fname); X sprintf(fname, "%s%s.Z", name, SUFFIX); X if (!stat(fname, &sbuf)) X return(fname); X#endif X#ifdef PATH X if ((*name == '.') || (*name == '/')) X return(name); X sprintf(fname, "%s/%s", PATH, name); X if (!stat(fname, &sbuf)) X return(fname); X sprintf(fname, "%s/%s.Z", PATH, name); X if (!stat(fname, &sbuf)) X return(fname); X#ifdef SUFFIX X sprintf(fname, "%s/%s%s", PATH, name, SUFFIX); X if (!stat(fname, &sbuf)) X return(fname); X sprintf(fname, "%s/%s%s.Z", PATH, name, SUFFIX); X if (!stat(fname, &sbuf)) X return(fname); X#endif X#endif X return(name); X} X X/* this is called if there is a read error getting the image X */ X Xstatic int badRead(fname) Xchar *fname; X{ X if (docorrupt) { X printf("%s: read problem, attempting to use what I have\n", fname); X return(0); X } X printf("%s: error reading image data (possibly short image)\n", fname); X return(-1); X} X X/* read in run length encoded data and decode it X */ X Xstatic int readEncoded(f, buf, size) X FILE *f; X unsigned char *buf; X int size; X{ static int remaining= 0; X static unsigned char repeating; X X while (size--) X if (remaining) { X remaining--; X *(buf++)= repeating; X } X else { X if (fread(&repeating, 1, 1, f) != 1) X return(-1); X if (repeating == RESC) { X if (fread(&repeating, 1, 1, f) != 1) X return(-1); X if (repeating == 0) X *(buf++)= RESC; X else { X remaining= repeating; X if (fread(&repeating, 1, 1, f) != 1) X return(-1); X *(buf++)= repeating; X } X } X else X *(buf++)= repeating; X } X} X X/* this loads the rasterfile into memory X */ X Xint loadImage(name) X char *name; X{ FILE *f; X char *fname, cmd[BUFSIZ]; X struct rheader header; X unsigned char *colormap, byte; X int a, b, len, ilen, maplen, rlencoded; X X /* get rasterfile; we get it from uncompress -c if it ends in .Z, or X * look for a .Z if we don't find an uncompressed one. X */ X X fname= findImage(name); X if ((strlen(fname) > 2) && (!strcmp(fname + strlen(fname) - 2, ".Z"))) { X sprintf(cmd, "uncompress -c %s", fname); X f= popen(cmd, "r"); X } X else X f= fopen(fname, "r"); X X if (f == NULL) { X perror(fname); X return(-1); X } X X if (fread(&header, sizeof(struct rheader), 1, f) != 1) { X printf("%s: error loading rasterfile header.\n", fname); X return(-1); X } X X /* check magic number X */ X X if (localint(header.magic) != RMAGICNUMBER) { X printf("I don't know what '%s' is, but it's not a Sun raster image.\n", X fname); X return(-1); X } X X /* filter out unsupported rasterfiles X */ X X switch(localint(header.type)) { X case RSTANDARD : X rlencoded= 0; X break; X case RRLENCODED : X rlencoded= 1; X break; X default : X printf("%s: unsupported rasterfile type\n", fname); X return(-1); X } X X if ((localint(header.maptype) != RNOMAP) && /* no map, no problem */ X (localint(header.maptype) != RRGBMAP)) { X printf("%s: unsupported colormap type\n", fname); X return(-1); X } X X width= localint(header.width); X height= localint(header.height); X depth= localint(header.depth); X X if (verbose) { X printf("Hmm, %s is a %dx%d %s image", name, width, height, X (depth == 1 ? "monochrome" : "color")); X if (depth > 1) X printf(" with %d planes", depth); X printf(".\n"); X } X X /* read the colormap X */ X X if ((maplen= localint(header.maplen)) > 0) { X if ((colormap= (unsigned char *)malloc(maplen)) == NULL) { X printf("%s: malloc error (cannot load colormap)\n", fname); X exit(1); X } X if (fread(colormap, maplen, 1, f) != 1) { X printf("%s: error reading colormap\n", fname); X return(-1); X } X } X X bytesperline= ((width * depth) / 8); X if ((width) % 16 > 8) /* images are rounded out to 16 bits */ X bytesperline += 2; X else if (width % 16) X bytesperline += 1; X if (depth) { X mapsize= localint(header.maplen) / 3; X red= colormap; X green= colormap + mapsize; X blue= colormap + (mapsize * 2); X } X else { X mapsize= 0; X red= green= blue= NULL; X } X X /* load image data X */ X X if ((data= (unsigned char *)malloc(height * bytesperline)) == NULL) { X printf("%s: malloc error (cannot load image)\n", fname); X exit(1); X } X X for (a= 0; a < height; a++) X if (rlencoded) { X if (readEncoded(f, data + (a * bytesperline), bytesperline) < 0) X return(badRead(fname)); X } X else X if (fread(data + (a * bytesperline), bytesperline, 1, f) != 1) X return(badRead(fname)); X return(0); X} X X/* convert a color name to a pixel value X */ X Xunsigned long nameToPixel(name, pixel) X char *name; X unsigned long *pixel; X{ XColor color; X X if (!XParseColor(disp, wa.colormap, name, &color)) { X printf("Unknown color '%s'", name); X return(-1); X } X if (!XAllocColor(disp, wa.colormap, &color)) { X printf("Cannot allocate color '%s'", name); X return(-1); X } X *pixel= color.pixel; X return(0); X} X X/* find the best color in our colormap X */ X Xstatic void findBestColor(xcolor) XXColor *xcolor; X{ XColor qcolor; X int a; X int bcolor; /* best color */ X long dist; /* our distance from the color */ X long bdist; /* distance for best color yet */ X long qdist; X X bdist= 256 * 256 * 3; X xcolor->red >>= 8; /* shifted so the distance value will fit into */ X xcolor->green >>= 8; /* a long comfortably. why use floats? */ X xcolor->blue >>= 8; X X dist= (xcolor->red * xcolor->red) + (xcolor->green * xcolor->green) + X (xcolor->blue * xcolor->blue); X for (a= 0; a < (1 << wa.depth); a++) { X XQueryColor(disp, wa.colormap, &qcolor); X qcolor.red >>= 8; X qcolor.green >>= 8; X qcolor.blue >>= 8; X qdist= (qcolor.red * qcolor.red) + (qcolor.green * qcolor.green) + X (qcolor.blue * qcolor.blue) - dist; X if (qdist < 0) X qdist= -qdist; X if (qdist < bdist) { X bdist= qdist; X bcolor= a; X } X } X xcolor->pixel= bcolor; X} X X/* translate the image into local colors X */ X Xvoid translateColors() X{ int x, y; X int pixlen; /* length of image pixel in bytes */ X char *haspixval; /* 1 if we've allocated this pixel's color */ X unsigned long *pixval; /* local pixel for image's pixel value */ X unsigned char *pixrow; /* start of image row */ X unsigned char *pixloc; /* current pixel we're playing with */ X unsigned long pixel; /* actual pixel value from image */ X Colormap cmap; /* color map we're using */ X XColor xcolor; X int rval, gval, bval; /* rgb values of image pixel */ X int colors; /* number of colors actually allocated */ X unsigned long *dptr; /* pointer into pixdata */ X int greyscale; /* 1 if colormap is greyscale */ X X /* in the interest of keeping our normal colormap, we only allocate those X * pixel values which are actually used in the image and translate the X * pixel values in the image to those we've allocated. this can be quite X * time consuming, but that's the cost of color! X */ X X pixlen= depth >> 3; X cmap= wa.colormap; X xcolor.flags= DoRed | DoGreen | DoBlue; X if (((haspixval= malloc(1 << depth)) == NULL) || X ((pixval= (unsigned long *)malloc((1 << depth) * sizeof(long))) X == NULL)) { X printf("Malloc failure.\n"); X XCloseDisplay(disp); X exit(1); X } X X /* if we're sending to a different depth of display, we must translate X * the image into pixel values and put it somewhere else. this grabs X * the new area. X */ X X if (wa.depth != depth) X if ((pixdata= dptr= (unsigned long *)malloc(sizeof(long) * width * X height)) == NULL) { X printf("Malloc failure (can't allocate pixel data area).\n"); X exit(1); X } X X greyscale= 1; X colors= 0; X for (x= 0; x < (1 << depth); x++) /* none yet */ X *(haspixval + x)= 0; X X for (y= 0; y < height; y++) { X pixrow= data + (y * bytesperline); X for (x= 0; x < width; x++) { X pixloc= pixrow + (x * pixlen); X pixel= memToVal(pixloc, pixlen); X X if (pixel >= mapsize) { X printf("Something's bogus -- found a pixel with no colormap entry.\n"); X exit(1); X } X X if (! *(haspixval + pixel)) { X rval= memToVal(red + pixel, 1); X gval= memToVal(green + pixel, 1); X bval= memToVal(blue + pixel, 1); X X if (greyscale && ((rval != gval) || (rval != bval))) X greyscale= 0; X X /* if we're color, grab a new colormap entry X */ X X if (wa.depth > 1) { X xcolor.red= rval << 8; /* X colors are 16 bits */ X xcolor.green= gval << 8; X xcolor.blue= bval << 8; X if (!XAllocColor(disp, cmap, &xcolor)) { X cmap= XCopyColormapAndFree(disp, cmap); X if (!XAllocColor(disp, cmap, &xcolor)) X findBestColor(&xcolor); X } X } X X /* if we're mono, figure out if the color is whiter or blacker. most X * servers do this automagically in XAllocColor() but often they X * don't do as good a job. X */ X X else { X xcolor.pixel= ((rval * rval) + (gval * gval) + (bval * bval)); X if (xcolor.pixel < ((255 * 255 * 3) - xcolor.pixel)) X xcolor.pixel= BlackPixel(disp, DefaultScreen(disp)); X else X xcolor.pixel= WhitePixel(disp, DefaultScreen(disp)); X } X X *(haspixval + pixel)= 1; X *(pixval + pixel)= xcolor.pixel; X colors++; X } X if (wa.depth == depth) X valToMem(pixloc, pixlen, *(pixval + pixel)); X else X *(dptr++)= *(pixval + pixel); X } X } X if (verbose) { X if (greyscale) X printf("This is a greyscale image.\n"); X X if (colors < (1 << depth)) X printf("Image only used %d of %d colors in its colormap.\n", colors, X 1 << depth); X else X printf("Image used all of the colors in its colormap.\n"); X X if (wa.depth == 1) X printf("Monochrome destination -- this is going to be ugly.\n"); X else if (wa.depth < depth) X printf("Fewer destination than source planes -- could be \ Xinteresting.\n"); X } X wa.colormap= cmap; X} X X/* send across a monochrome image X */ X Xvoid sendMonoImage() X{ XImage *image; /* XImage for our raster image */ X Pixmap picplane; /* monochrome plane used in transfer */ X XGCValues gcv; X GC gc; X GC planegc; /* gc for picplane */ X X /* set up an XImage structure that points to our bitmap data X */ X X image= XCreateImage(disp, DefaultVisual(disp, DefaultScreen(disp)), 1, X XYPixmap, 0, data, width, height, 16, bytesperline); X X /* since our data will be in MC68000 format, we force the image structure X * to agree with it. neat results if you don't do this. X */ X X image->byte_order= MSBFirst; X image->bitmap_bit_order= MSBFirst; X X /* set up gc that tells server what colors to use X */ X X gcv.function= GXcopy; X gcv.foreground= BlackPixel(disp, DefaultScreen(disp)); X gcv.background= WhitePixel(disp, DefaultScreen(disp)); X if (fgcolor && nameToPixel(fgcolor, &gcv.foreground)) X printf(" requested for foreground, using black.\n"); X if (bgcolor && nameToPixel(bgcolor, &gcv.background)) X printf(" requested for background, using white.\n"); X gc= XCreateGC(disp, pic, GCFunction | GCForeground | GCBackground, &gcv); X X /* send image to pixmap. if we're on a mono screen, we just send it to X * the destination pixmap. otherwise we have to send to a mono pixmap X * and copy that pixmap to the destination pixmap X */ X X if (wa.depth > 1) { X picplane= XCreatePixmap(disp, RootWindow(disp, DefaultScreen(disp)), X pwidth, pheight, 1); X gcv.function= GXcopy; X gcv.foreground= 1; X gcv.background= 0; X planegc= XCreateGC(disp, picplane, GCFunction | GCForeground | X GCBackground, &gcv); X X XPutImage(disp, picplane, planegc, image, cx, cy, xorigin, yorigin, X cwidth, cheight); X XCopyPlane(disp, picplane, pic, gc, xorigin, yorigin, X cwidth, cheight, xorigin, yorigin, 1); X XFreePixmap(disp, picplane); X XFreeGC(disp, planegc); X } X else X XPutImage(disp, pic, gc, image, cx, cy, xorigin, yorigin, X cwidth, cheight); X XFreeGC(disp, gc); X} X X/* send across a color image to a display of the same depth. X */ X Xvoid sendColorImage() X{ XImage *image; X XGCValues gcv; X GC gc; X X image= XCreateImage(disp, DefaultVisual(disp, DefaultScreen(disp)), depth, X ZPixmap, 0, data, width, height, 16, bytesperline); X image->byte_order= MSBFirst; X image->bitmap_bit_order= MSBFirst; X X gcv.function= GXcopy; X gc= XCreateGC(disp, pic, GCFunction, &gcv); X XPutImage(disp, pic, gc, image, cx, cy, xorigin, yorigin, cwidth, cheight); X XFreeGC(disp, gc); X} X X/* send across a color image to whatever X */ X Xvoid sendColorPixels() X{ int x, y; X unsigned long *dptr; X XGCValues gcv; X GC gc; X X if (verbose) X printf("This may take a minute, a pixel at a time is tedious.\n"); X X gcv.function= GXcopy; X gc= XCreateGC(disp, pic, GCFunction, &gcv); X X dptr= pixdata; X for (y= cy; y < cheight; y++) X for (x= cx; x < cwidth; x++) { X XSetForeground(disp, gc, *(dptr++)); X XDrawPoint(disp, pic, gc, x, y); X } X XFreeGC(disp, gc); X} END_OF_FILE if test 16130 -ne `wc -c <'common.c'`; then echo shar: \"'common.c'\" unpacked with wrong size! fi # end of 'common.c' fi if test -f 'common.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'common.h'\" else echo shar: Extracting \"'common.h'\" \(750 characters\) sed "s/^X//" >'common.h' <<'END_OF_FILE' X/* common.h: X * X * externs for common.c routines and variables X */ X X#include <stdio.h> X#include <X11/X.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X Xextern Display *disp; Xextern int width, height, depth; Xextern int bytesperline; Xextern int xorigin, yorigin; Xextern int pwidth, pheight; Xextern int cx, cy; Xextern int cwidth, cheight; Xextern int verbose; Xextern int docorrupt; Xextern char *fgcolor, *bgcolor; Xextern Pixmap pic; Xextern XWindowAttributes wa; X Xint isoption(); Xint loadImage(); Xint nameToPixel(); Xvoid translateColors(); Xvoid sendMonoImage(); Xvoid sendColorImage(); Xvoid sendColorPixels(); END_OF_FILE if test 750 -ne `wc -c <'common.h'`; then echo shar: \"'common.h'\" unpacked with wrong size! fi # end of 'common.h' fi if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(21 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X#define PATCHLEVEL 0 END_OF_FILE if test 21 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi if test -f 'rasterfile.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rasterfile.h'\" else echo shar: Extracting \"'rasterfile.h'\" \(1517 characters\) sed "s/^X//" >'rasterfile.h' <<'END_OF_FILE' X/* rasterfile.h: X * X * this describes the header for Sun rasterfiles. if you have SunOS, a X * better description is in /usr/include/rasterfile.h. this is used X * instead to improve portability and to avoid distribution problems. X */ X Xstruct rheader { X unsigned char magic[4]; /* magic number */ X unsigned char width[4]; /* width of image in pixels */ X unsigned char height[4]; /* height of image in pixels */ X unsigned char depth[4]; /* depth of each pixel */ X unsigned char length[4]; /* length of the image in bytes */ X unsigned char type[4]; /* format of file */ X unsigned char maptype[4]; /* type of colormap */ X unsigned char maplen[4]; /* length of colormap in bytes */ X}; X X/* following the header is the colormap (unless maplen is zero) then X * the image. each row of the image is rounded to 2 bytes. X */ X X#define RMAGICNUMBER 0x59a66a95 /* magic number of this file type */ X X/* these are the possible file formats X */ X X#define ROLD 0 /* old format, see /usr/include/rasterfile.h */ X#define RSTANDARD 1 /* standard format */ X#define RRLENCODED 2 /* run length encoding to compress the image */ X X/* these are the possible colormap types. if it's in RGB format, X * the map is made up of three byte arrays (red, green, then blue) X * that are each 1/3 of the colormap length. X */ X X#define RNOMAP 0 /* no colormap follows the header */ X#define RRGBMAP 1 /* rgb colormap */ X#define RRAWMAP 2 /* raw colormap; good luck */ X X#define RESC 128 /* run-length encoding escape character */ X END_OF_FILE if test 1517 -ne `wc -c <'rasterfile.h'`; then echo shar: \"'rasterfile.h'\" unpacked with wrong size! fi # end of 'rasterfile.h' fi if test -f 'xbgsun.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xbgsun.c'\" else echo shar: Extracting \"'xbgsun.c'\" \(8588 characters\) sed "s/^X//" >'xbgsun.c' <<'END_OF_FILE' X/* xbgsun.c: X * X * Jim Frost, Associative Design Technology X * 9.21.88 X * X * this reads a sun raster image file and sets the root window background X * pixmap to it. X * X * this program is in the public domain. X * X * 12.30.88 broken apart to use function library common with xviewsun. X * 12.21.88 bug fix to stop incorrect "bad option" errors. X * 12.19.88 modified to allow image clipping before loading and to make use X * of a default path and/or suffix. some bug fixes. X * 12.14.88 modified to load multiple rasterimages onto the same background. X * 12.08.88 modified to work with color rasterimages, basically a complete X * rewrite. X * 11.27.88 modified to work on color systems and to always deal with X * XImage's correctly. X * 09.21.88 original version X */ X X#include "common.h" X Xvoid usage(name) X char *name; X{ printf("Usage: %s [global options] [raster options] rasterfile ...\n", X name); X printf("\nGlobal options:\n"); X printf(" -display display_name - Specify X display to use\n"); X printf(" -geometry =XxY - Specify size of destination\n"); X printf(" -verbose | -quiet - Whistle while you work toggles\n"); X printf(" -border color - Specify border color\n"); X printf(" -corrupt - Try to load corrupted image\n"); X printf("\nMore than one rasterfile may be loaded at once, and each may\n"); X printf("be preceeded with its own options from the following list:\n"); X printf(" -at X,Y - Load image at coordinates\n"); X printf(" -center - Center image\n"); X printf(" -clip X,Y,W,H - Clip image before loading\n"); X printf(" -foreground color - Specify foreground for mono image\n"); X printf(" -background color - Specify background for mono image\n"); X exit(1); X} X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ int a, x, y, X tried, /* a load was attempted */ X loaded, /* # of images loaded */ X center, /* center image on pixmap */ X place, /* image has been placed on pixmap */ X clip, X setcmap; /* true if we need to install a colormap */ X char *dname, /* display name */ X *bdcolor; /* border color */ X XGCValues gcv; X GC gc; X X if (argc < 2) X usage(argv[0]); X X tried= loaded= 0; X dname= bdcolor= NULL; X pwidth= pheight= 0; X docorrupt= 0; X verbose= 1; X X for (a= 1; a < argc; a++) X if (*argv[a] != '-') X continue; X X /* parse global options X */ X X else if (isoption("-border", argv[a], 3)) X bdcolor= argv[++a]; X else if (!strcmp("-corrupt", argv[a])) X docorrupt= 1; X else if (isoption("-defaults", argv[a], 3)) { X#ifdef PATH X printf("Default path is '%s'\n", PATH); X#endif X#ifdef SUFFIX X printf("Default suffix is '%s'\n", SUFFIX); X#else X#ifndef PATH X printf("There are no defaults\n"); X#endif X#endif X exit(0); X } X else if (isoption("-display", argv[a], 3)) X dname= argv[++a]; X else if (isoption("-geometry", argv[a], 2)) X XParseGeometry(argv[++a], &xorigin, &yorigin, &pwidth, &pheight); X else if (isoption("-help", argv[a], 2)) X usage(argv[0]); X else if (isoption("-quiet", argv[a], 2)) X verbose= 0; X else if (isoption("-verbose", argv[a], 2)) X verbose= 1; X X /* strip out local options X */ X X else if (isoption("-center", argv[a], 3)) X ; X else if (isoption("-at", argv[a], 2) || X isoption("-clip", argv[a], 3) || X isoption("-foreground", argv[a], 2) || X isoption("-background", argv[a], 3)) X if (++a == argc) { X printf("option '%s' requires an argument\n", argv[a - 1]); X usage(argv[0]); X } X else X a++; X else { X printf("bad argument '%s'\n", argv[a]); X usage(argv[0]); X } X X /* open display and get its configuration X */ X X if ((disp= XOpenDisplay(dname)) == NULL) { X printf("Can't open display.\n"); X exit(1); X } X X XGetWindowAttributes(disp, RootWindow(disp, DefaultScreen(disp)), &wa); X if (wa.colormap == 0) X wa.colormap= DefaultColormap(disp, DefaultScreen(disp)); X X /* if we haven't explicitly set the width/height of our background, X * make it the entire screen X */ X X if (!pwidth && !pheight) { X pwidth= DisplayWidth(disp, DefaultScreen(disp)); X pheight= DisplayHeight(disp, DefaultScreen(disp)); X } X X /* allocate our destination pixmap or window X */ X X pic= XCreatePixmap(disp, RootWindow(disp, DefaultScreen(disp)), X pwidth, pheight, wa.depth); X X /* prepare the border area if the any picture was centered X */ X X if (bdcolor) { X gcv.function= GXcopy; X gcv.foreground= WhitePixel(disp, DefaultScreen(disp)); X if (nameToPixel(bdcolor, &gcv.foreground)) X printf(" requested for border, using white.\n"); X gc= XCreateGC(disp, pic, GCFunction | GCForeground, &gcv); X XFillRectangle(disp, pic, gc, 0, 0, pwidth, pheight); X XFreeGC(disp, gc); X } X X /* loop through arguments again to do loads X */ X X center= place= clip= 0; X fgcolor= bgcolor= NULL; X for (a= 1; a < argc; a++) { X X X /* if name doesn't begin with '-', it's a file to load. X */ X X if (*argv[a] != '-') { X tried= 1; X if (loadImage(argv[a]) < 0) X continue; X loaded++; X X if (center) { X xorigin= (pwidth - width) / 2; X yorigin= (pheight - height) / 2; X } X else if (!place) { X xorigin= 0; X yorigin= 0; X } X X /* do various adjustments to clip area X */ X X if (clip) { X if (cx < 0) { X cwidth += cx; X cx= 0; X } X if (cy < 0) { X cheight += cy; X cy= 0; X } X if (cwidth < 1) X cwidth= width; X if (cheight < 1) X cheight= height; X if (cx + cwidth > width) X cwidth= width - cx; X if (cy + cheight > height) X cheight= height - cy; X } X else { X cx= cy= 0; X cwidth= width; X cheight= height; X } X X if (depth == 1) X sendMonoImage(); X else { X translateColors(); X if (depth == wa.depth) X sendColorImage(); X else X sendColorPixels(); X X if (wa.depth > 1) /* smash in colormap when we're all done */ X setcmap= 1; X } X X /* if the first image isn't centered or placed we replicate it X */ X X if ((loaded == 1) && !center && !place) { X gcv.function= GXcopy; X gc= XCreateGC(disp, pic, GCFunction, &gcv); X for (y= 0; y < pheight; y += cheight) X for (x= 0; x < pwidth; x += cwidth) X XCopyArea(disp, pic, pic, gc, 0, 0, cwidth, cheight, x, y); X XFreeGC(disp, gc); X } X xorigin= yorigin= 0; X center= place= clip= 0; X fgcolor= bgcolor= NULL; X } X X /* not a file, must be an option. X */ X X else if (isoption("-background", argv[a], 3)) X bgcolor= argv[++a]; X X else if (isoption("-at", argv[a], 2)) { X if (center) { X printf("-center and -at functions conflict, ignoring -at\n"); X a++; X continue; X } X if (place) { X printf("only one -at to an image, ignoring additional -at\n"); X a++; X continue; X } X if (sscanf(argv[++a], "%d,%d", &xorigin, &yorigin) != 2) { X printf("bad argument to -at option (ignored)\n"); X continue; X } X place= 1; X } X X else if (isoption("-center", argv[a], 3)) { X if (place) { X printf("-at and -center options conflict, ignoring -center\n"); X continue; X } X if (center) X printf("-center already encountered; you're being redundant\n"); X center= 1; X } X X else if (isoption("-clip", argv[a], 3)) { X if (clip) { X printf("cannot clip an image more than once, ignoring -clip\n"); X continue; X } X if (sscanf(argv[++a], "%d,%d,%d,%d", &cx, &cy, &cwidth, &cheight) != X 4) { X printf("bad argument to -clip option (ignored)\n"); X continue; X } X clip= 1; X } X X else if (isoption("-border", argv[a], 3) || /* skip extra parm if */ X isoption("-display", argv[a], 3) || /* it's a global with */ X isoption("-geometry", argv[a], 2)) /* an argument */ X a++; X X else if (isoption("-foreground", argv[a], 2)) X fgcolor= argv[++a]; X X } X X if (loaded == 0) X if (tried) X exit(1); X else X usage(argv[0]); X X /* set up the colormap if necessary and plug in the image. X */ X X if (setcmap) { X XSetWindowColormap(disp, RootWindow(disp, DefaultScreen(disp)), X wa.colormap); X XInstallColormap(disp, wa.colormap); X } X XSetWindowBackgroundPixmap(disp, RootWindow(disp, DefaultScreen(disp)), pic); X XFreePixmap(disp, pic); X XClearWindow(disp, RootWindow(disp, DefaultScreen(disp))); X XSetCloseDownMode(disp, RetainPermanent); X XCloseDisplay(disp); X X if (verbose && (loaded > 1)) X printf("%d images loaded.\n", loaded); X} END_OF_FILE if test 8588 -ne `wc -c <'xbgsun.c'`; then echo shar: \"'xbgsun.c'\" unpacked with wrong size! fi # end of 'xbgsun.c' fi if test -f 'xbgsun.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xbgsun.man'\" else echo shar: Extracting \"'xbgsun.man'\" \(4201 characters\) sed "s/^X//" >'xbgsun.man' <<'END_OF_FILE' X.TH MAN 1 "6 January 1989" X.SH NAME Xxbgsun \- load Sun rasterfiles onto an X11 root window X.SH SYNOPSIS X.B xbgsun X[global_options] [raster_options] rasterfile ... X.SH DESCRIPTION X.I Xbgsun Xloads one or more Sun rasterfiles onto an X11 root window. If raster Xfile names end in .Z, they will be uncompressed before loading (this Xsaves a lot of disk space). If configured to use them, X.I xbgsun Xwill look for files along a default path and/or with a default suffix Xin addition to .Z. X.PP XUnless the first image loaded onto the window is centered or Xplaced, it will be replicated over the entire window, essentially Xbecoming the background for all subsequent images. X.PP X.I Xbgsun Xwill load color images onto a display of any depth, although they may Xlook strange if it cannot allocate the proper colors. It allocates Xonly those colors which are used in the image that you are Xtransferring. Usually this allows many colormap entries to remain the Xsame as before you load the image, although it slows down operation Xsomewhat. Any combination of image depths may be loaded at one time. X.SH GLOBAL OPTIONS XThe following options affect the global operation of X.I xbgsun: X.TP 8 X-border color XThis sets the background portion of the window which is not covered by Xany images to be X.IR color. X.TP X-corrupt XAttempt to load a rasterfile whose image data area has been corrupted. XThis is really only useful if the image is shorter than expected. X.TP X-defaults XDisplays the default path and suffix which xbgsun will use if it Xcannot find the image with the given name. This options causes Xeverything else to be ignored. X.TP X-display display_name XX11 display name. X.TP X-geometry =XxY XThis sets the size of the window onto which the images are loaded to a Xdifferent value than the size of the display. If the window is Xsmaller than the display, it will be replicated to fill the display. X.TP X-help XDisplays a short summary of xbgsun command line syntax. This option Xcauses everything else to be ignored. X.TP X-quiet XForces X.I xbgsun Xto be quiet while it works. Normally it likes to whistle. X.TP X-verbose XCauses X.I xbgsun Xto be talkative, telling you what kind of image it's playing with and Xany special processing that it has to do. This is the default. X.SH RASTER OPTIONS XThe following options may preceed each rasterfile. These options are Xlocal to the rasterfile they preceed. X.TP X-background color XUse X.IR color Xas the background color instead of white if you are transferring a Xmonochrome image to a color display. X.TP X-center XCenter the image on the window. X.TP X-at X,Y XIndicates where the image should be loaded onto the window. X.TP X-clip X,Y,W,H XClip the image before loading it. X and Y are the coordinates to Xstart clipping at, W is the width to use, and H is the height. If W Xor H are zero or negative, clipping will start at (X,Y) and will Xcontinue to the end of the image. Clipping boundaries are adjusted to Xfit within the image (eg -10,0,100,100 for a 50x50 image will be Xadjusted to 0,0,50,50). This is useful when you would only like a Xportion of an image, such as the girl (guy) in the middle of an image Xbut not all the guys (girls) around her (him). X.TP X-foreground color XUse X.IR color Xas the foreground color instead of black if you are transferring a Xmonochrome image to a color display. X.SH EXAMPLES XTo load the rasterfile "raster.sun" onto the background and replicate Xit to fill the entire background: X.sp X.ti +5 Xxbgsun raster.sun X.PP XTo load a monochrome image "raster.sun" onto the background, using red Xas the foreground color, replicate the image, and overlay X"raster2.sun" onto it at coordinate (10,10): X.sp X.ti +5 Xxbgsun -foreground red raster.sun -at 10,10 raster2.sun X.PP XTo center the rectangular region from 10 to 110 along the X axis and Xfrom 10 to the height of the image along the Y axis: X.sp X.ti +5 Xxbgsun -center -clip 10,10,100,0 raster.sun X.SH AUTHOR X.nf XJim Frost XAssociative Design Technology Xmadd@bu-it.bu.edu X.SH BUGS XXbgsun assumes that the number of colors in a colormap is power(2, Xdepth). This might be bogus on some systems. X.PP XThings can look strange if you transfer an image of depth X.I n Xto a display with a smaller depth (eg color to monochrome). END_OF_FILE if test 4201 -ne `wc -c <'xbgsun.man'`; then echo shar: \"'xbgsun.man'\" unpacked with wrong size! fi # end of 'xbgsun.man' fi if test -f 'xviewsun.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xviewsun.c'\" else echo shar: Extracting \"'xviewsun.c'\" \(4677 characters\) sed "s/^X//" >'xviewsun.c' <<'END_OF_FILE' X/* xbgsun.c: X * X * Jim Frost, Associative Design Technology X * 12.15.88 X * X * this reads a sun raster image file and displays it in a window. it is X * derived from the 12.14.88 version of xbgsun. X * X * 12.30.80 broken apart to use a function library common with xbgsun. X * 12.15.88 original version X */ X X#include <stdio.h> X#include <X11/X.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X Xextern Display *disp; Xextern int width, height, depth; Xextern int bytesperline; Xextern int xorigin, yorigin; Xextern int pwidth, pheight; Xextern int cx, cy; Xextern int cwidth, cheight; Xextern int verbose; Xextern int docorrupt; Xextern char *fgcolor, *bgcolor; Xextern Pixmap pic; Xextern XWindowAttributes wa; X Xvoid usage(name) X char *name; X{ printf("Usage: %s [-display display_name] [-geometry X_geometry] \ X[-foreground color] [-background color] [-corrupt] rasterfile\n", name); X exit(1); X} X Xvoid nuked(disp) XDisplay *disp; X{ X exit(0); X} X X/* this returns the name of the file with no added junk X */ X Xchar *tail(name) Xchar *name; X{ int a; X X if (strlen(name) < 2) X return(name); X for (a= strlen(name); (a > 0) && (name[a - 1] != '/'); a--) X ; X return(&name[a]); X} X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ int a, dummy, X x, y; /* where to put the window */ X char *dname; /* display name */ X XGCValues gcv; X GC gc; X Window window; /* window for image */ X XSetWindowAttributes swa; X XSizeHints sh; X union { X XAnyEvent any; X XExposeEvent expose; X } xevent; X X if (argc < 2) X usage(argv[0]); X X dname= NULL; X verbose= 1; X docorrupt= 0; X xorigin= yorigin= cx= cy= 0; X X /* parse options X */ X X for (a= 1; (a < argc) && (*argv[a] == '-'); a++) X if (isoption("-help", argv[a], 2)) X usage(argv[0]); X else if (!strcmp("-corrupt", argv[a])) X docorrupt= 1; X else if (isoption("-display", argv[a], 2)) X dname= argv[++a]; X else if (isoption("-geometry", argv[a], 2)) X XParseGeometry(argv[++a], &x, &y, &dummy, &dummy); X else if (isoption("-foreground", argv[a], 2)) X fgcolor= argv[++a]; X else if (isoption("-background", argv[a], 2)) X bgcolor= argv[++a]; X if (a != argc - 1) X usage(argv[0]); X X /* try to load the image X */ X X if (loadImage(argv[a]) < 0) X exit(1); X cwidth= pwidth= width; X cheight= pheight= height; X X /* open display and get its configuration X */ X X if ((disp= XOpenDisplay(dname)) == NULL) { X printf("Can't open display.\n"); X exit(1); X } X XSetIOErrorHandler(nuked); X X XGetWindowAttributes(disp, RootWindow(disp, DefaultScreen(disp)), &wa); X if (wa.colormap == 0) X wa.colormap= DefaultColormap(disp, DefaultScreen(disp)); X X /* allocate our destination pixmap or window X */ X X pic= XCreatePixmap(disp, RootWindow(disp, DefaultScreen(disp)), X width, height, wa.depth); X X /* get the image to the server X */ X X if (depth == 1) X sendMonoImage(); X else { X translateColors(); X if (depth == wa.depth) X sendColorImage(); X else X sendColorPixels(); X } X X /* get a window for the image X */ X X swa.event_mask= ButtonPressMask | ExposureMask | EnterWindowMask | X LeaveWindowMask; X window= XCreateWindow(disp, RootWindow(disp, DefaultScreen(disp)), X x, y, width, height, 0, wa.depth, InputOutput, X CopyFromParent, CWEventMask, &swa); X XStoreName(disp, window, tail(argv[a])); X XSetIconName(disp, window, tail(argv[a])); X sh.width= width; X sh.height= height; X sh.flags= USSize; X XSetNormalHints(disp, window, &sh); X X gcv.function= GXcopy; X gc= XCreateGC(disp, window, GCFunction, &gcv); X X XMapWindow(disp, window); X X /* set up the colormap if necessary and set up the window X */ X X if (wa.depth > 1) X XSetWindowColormap(disp, RootWindow(disp, DefaultScreen(disp)), X wa.colormap); X XCopyArea(disp, pic, window, gc, 0, 0, width, height, 0, 0); X X for (;;) { X XNextEvent(disp, &xevent); X switch(xevent.any.type) { X case ButtonPress : X XFreePixmap(disp, pic); X XDestroyWindow(disp, window); X XCloseDisplay(disp); X exit(0); X X case Expose : X XCopyArea(disp, pic, window, gc, xevent.expose.x, xevent.expose.y, X xevent.expose.width, xevent.expose.height, X xevent.expose.x, xevent.expose.y); X break; X X case EnterNotify : X if (wa.depth > 1) X XInstallColormap(disp, wa.colormap); X break; X X case LeaveNotify : X if (wa.depth > 1) X XUninstallColormap(disp, wa.colormap); X break; X } X } X} END_OF_FILE if test 4677 -ne `wc -c <'xviewsun.c'`; then echo shar: \"'xviewsun.c'\" unpacked with wrong size! fi # end of 'xviewsun.c' fi if test -f 'xviewsun.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xviewsun.man'\" else echo shar: Extracting \"'xviewsun.man'\" \(1876 characters\) sed "s/^X//" >'xviewsun.man' <<'END_OF_FILE' X.TH MAN 1 "6 January 1988" X.SH NAME Xxviewsun \- look at a Sun rasterfile in an X11 window X.SH SYNOPSIS X.B xviewsun X[ -display X.IR display_name X] X[ -geometry X.IR X_geometry X] X[ -foreground X.IR color X] X[ -background X.IR color X] X.IR rasterfile X.SH DESCRIPTION X.I Xviewsun Xloads a Sun rasterfile into an X11 window. If the raster file name Xends in .Z, it will be uncompressed before loading (this saves a lot Xof disk space). X.PP X.I Xviewsun Xwill show a color image on a display of any depth, although it may Xlook strange if it cannot allocate the proper colors. It allocates Xonly those colors which are used in the image that you are Xtransferring. Usually this allows many colormap entries to remain the Xsame as before you load the image, although it slows down operation Xsomewhat. X.SH OPTIONS XThe following options are available: X.TP 8 X-display display_name XX11 display name. X.TP X-geometry X_geometry XThis sets the location of the window. Size information is ignored Xsince the size is set by the image to be displayed. X.TP X-foreground color XUse X.IR color Xas the foreground color instead of black if you are transferring a Xmonochrome image to a color display. X.TP X-background color XUse X.IR color Xas the background color instead of white if you are transferring a Xmonochrome image to a color display. X.TP X-corrupt XForce the load of an image file which has been truncated in the image Xdata portion. X.SH AUTHOR X.nf XJim Frost XAssociative Design Technology Xmadd@bu-it.bu.edu X.SH BUGS XXviewsun assumes that the number of colors in a colormap is power(2, Xdepth). This might be bogus on some systems. X.PP XThings can look strange if you transfer an image of depth X.I n Xto a display with a smaller depth (eg color to monochrome). X.PP XThe name X.IR xviewsun Xis close enough to SunView (which is probably a trademark of Sun XMicrosystems) to be confusing. Some might call this a feature. END_OF_FILE if test 1876 -ne `wc -c <'xviewsun.man'`; then echo shar: \"'xviewsun.man'\" unpacked with wrong size! fi # end of 'xviewsun.man' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 Moderator of comp.sources.x