argv@island.uu.net (Dan Heller) (04/07/89)
Submitted-by: Jeff Michaud <michaud@decvax.dec.com> Posting-number: Volume 3, Issue 68 Archive-name: xface/part01 [ I had to modify xface.c to compile on my sun3/60. strchr() was used rather than index(). X11/Xos.h defines strchr for index(), but not the other way around. I didn't find anymore sys-v-isms, so BSD machines shouldn't have too much trouble. I couldn't really test this because I don't have any facesaver images. --argv ] #!/bin/sh # This is a shell archive file. Remove everything above this line # to unbundle. chmod +x "thisfile", then run it: e.g. % thisfile # SHAR archive format. Archive created Thu Apr 6 16:03:12 PDT 1989 # file contains: # AUTHOR # Imakefile # Makefile # README # patchlevel.h # xface.c # xface.h # xface.man # xfaceload.c echo x - AUTHOR sed 's/^X//' > AUTHOR <<'+END+OF+AUTHOR' XAuthor: Jeff Michaud (michaud@decvax.dec.com), DEC X XAdapted from xgif by, X John Bradley (bradley@cis.upenn.edu), University of Pennsylvania. +END+OF+AUTHOR echo '-rw-rw-r-- 1 argv 144 Apr 6 15:45 AUTHOR (as sent)' chmod u=rw,g=rw,o=r AUTHOR ls -l AUTHOR echo x - Imakefile sed 's/^X//' > Imakefile <<'+END+OF+Imakefile' XLOCAL_LIBRARIES = $(XLIB) X XOBJS = \ X xface.o \ X xfaceload.o X XSRCS = \ X xface.c \ X xfaceload.c X XComplexProgramTarget(xface) X +END+OF+Imakefile echo '-rw-rw-r-- 1 argv 124 Apr 6 15:45 Imakefile (as sent)' chmod u=rw,g=rw,o=r Imakefile ls -l Imakefile echo x - Makefile sed 's/^X//' > Makefile <<'+END+OF+Makefile' X# Makefile generated by imake - do not edit! X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $ X# X# The cpp used on this machine replaces all newlines and multiple tabs and X# spaces in a macro expansion with a single space. Imake tries to compensate X# for this, but is not always successful. X# X X########################################################################### X# X Window System Makefile generated from template file Imake.tmpl X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $ X# X# Do not change the body of the imake template file. Server-specific X# parameters may be set in the appropriate .macros file; site-specific X# parameters (but shared by all servers) may be set in site.def. If you X# make any changes, you'll need to rebuild the makefiles using X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in X# the top level directory. X# X# If your C preprocessor doesn't define any unique symbols, you'll need X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing X# "make Makefile", "make Makefiles", or "make World"). X# X# If you absolutely can't get imake to work, you'll need to set the X# variables at the top of each Makefile as well as the dependencies at the X# bottom (makedepend will do this automatically). X# X X########################################################################### X# platform-specific configuration parameters - edit Sun.macros to change X X# platform: $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $ X# operating system: SunOS 3.4 X XBOOTSTRAPCFLAGS = X AS = as X CC = cc X CPP = /lib/cpp X LD = ld X LINT = lint X INSTALL = install X TAGS = ctags X RM = rm -f X MV = mv X LN = ln -s X RANLIB = ranlib XRANLIBINSTFLAGS = -t X AR = ar clq X LS = ls X LINTOPTS = -xz X LINTLIBFLAG = -C X MAKE = make XSTD_CPP_DEFINES = X STD_DEFINES = X X########################################################################### X# site-specific configuration parameters - edit site.def to change X X# site: $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $ X X########################################################################### X# definitions common to all Makefiles - do not edit X X SHELL = /bin/sh X X DESTDIR = /usr X USRLIBDIR = $(DESTDIR)/lib X BINDIR = $(DESTDIR)/bin/X11 X INCDIR = $(DESTDIR)/include X ADMDIR = $(DESTDIR)/usr/adm X LIBDIR = $(USRLIBDIR)/X11 X LINTLIBDIR = $(USRLIBDIR)/lint X FONTDIR = $(LIBDIR)/fonts X XINITDIR = $(LIBDIR)/xinit X XDMDIR = $(LIBDIR)/xdm X UWMDIR = $(LIBDIR)/uwm X AWMDIR = $(LIBDIR)/awm X TWMDIR = $(LIBDIR)/twm X DTDIR = $(LIBDIR)/dt X MANPATH = /usr/man X MANSOURCEPATH = $(MANPATH)/man X MANDIR = $(MANSOURCEPATH)n X LIBMANDIR = $(MANSOURCEPATH)n3 X XAPPLOADDIR = $(LIBDIR)/app-defaults X X INSTBINFLAGS = -m 0755 X INSTUIDFLAGS = -m 4755 X INSTLIBFLAGS = -m 0664 X INSTINCFLAGS = -m 0444 X INSTMANFLAGS = -m 0444 X INSTAPPFLAGS = -m 0444 X INSTKMEMFLAGS = -m 4755 X FCFLAGS = -t X CDEBUGFLAGS = -O X X PATHSEP = / X DEPEND = $(BINDIR)/makedepend X IMAKE = $(BINDIR)/imake X RGB = $(LIBDIR)/rgb X FC = $(BINDIR)/bdftosnf X MKFONTDIR = $(BINDIR)/mkfontdir X MKDIRHIER = $(BINDIR)/mkdirhier.sh X X CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) X LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT X LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES) X X IRULESRC = $(LIBDIR)/imake.includes X X EXTENSIONLIB = $(USRLIBDIR)/libext.a X XLIB = $(USRLIBDIR)/libX11.a X XMULIB = $(USRLIBDIR)/libXmu.a X OLDXLIB = $(USRLIBDIR)/liboldX.a X XTOOLLIB = $(USRLIBDIR)/libXt.a X XAWLIB = $(USRLIBDIR)/libXaw.a X LINTXLIB = $(USRLIBDIR)/lint/llib-lX11.ln X LINTXMU = $(USRLIBDIR)/lint/llib-lXmu.ln X LINTXTOOL = $(USRLIBDIR)/lint/llib-lXt.ln X LINTXAW = $(USRLIBDIR)/lint/llib-lXaw.ln X INCLUDES = -I$(INCDIR) X MACROFILE = Sun.macros X ICONFIGFILES = $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def X IMAKE_DEFINES = X IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \ X -s Makefile $(IMAKE_DEFINES) X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \ X .emacs_* tags TAGS make.log MakeOut X X########################################################################### X# rules: $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $ X X########################################################################### X# start of Imakefile X XLOCAL_LIBRARIES = $(XLIB) X XOBJS = \ X xface.o \ X xfaceload.o X XSRCS = \ X xface.c \ X xfaceload.c X X PROGRAM = xface X Xall:: xface X Xxface: $(OBJS) $(LOCAL_LIBRARIES) X $(RM) $@ X $(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES) X Xrelink:: X $(RM) $(PROGRAM) X $(MAKE) $(MFLAGS) $(PROGRAM) X Xinstall:: xface X $(INSTALL) -c $(INSTALLFLAGS) xface $(BINDIR) X Xinstall.man:: xface.man X $(INSTALL) -c $(INSTMANFLAGS) xface.man $(MANDIR)/xface.n X Xdepend:: $(DEPEND) X Xdepend:: X $(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS) X X$(DEPEND): X @echo "making $@"; \ X cd $(DEPENDSRC); $(MAKE) X Xclean:: X $(RM) $(PROGRAM) X X########################################################################### X# Imake.tmpl common rules for all Makefiles - do not edit X Xemptyrule:: X Xclean:: X $(RM_CMD) \#* X XMakefile:: $(IMAKE) X XMakefile:: Imakefile \ X $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/Imake.rules \ X $(IRULESRC)/site.def \ X $(IRULESRC)/$(MACROFILE) X -@if [ -f Makefile ]; then \ X echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \ X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ X else exit 0; fi X $(IMAKE_CMD) -DTOPDIR=$(TOP) X X$(IMAKE): X @echo "making $@"; \ X cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS) X Xtags:: X $(TAGS) -w *.[ch] X $(TAGS) -xw *.[ch] > TAGS X X########################################################################### X# empty rules for directories that do not have SUBDIRS - do not edit X Xinstall:: X @echo "install done" X Xinstall.man:: X @echo "install.man done" X XMakefiles:: X X########################################################################### X# dependencies generated by makedepend X X# DO NOT DELETE X X#xface.o: xface.h /usr/include/stdio.h /usr/include/math.h /usr/include/ctype.h X#xface.o: /global/include/X11/Xos.h /usr/include/sys/types.h X#xface.o: /usr/include/sys/sysmacros.h /usr/include/strings.h X#xface.o: /usr/include/sys/file.h /usr/include/sys/fcntl.h X#xface.o: /usr/include/sys/time.h /usr/include/sys/time.h X#xface.o: /global/include/X11/Xlib.h /global/include/X11/X.h X#xface.o: /global/include/X11/Xutil.h X#xfaceload.o: xface.h /usr/include/stdio.h /usr/include/math.h X#xfaceload.o: /usr/include/ctype.h /global/include/X11/Xos.h X#xfaceload.o: /usr/include/sys/types.h /usr/include/sys/sysmacros.h X#xfaceload.o: /usr/include/strings.h /usr/include/sys/file.h X#xfaceload.o: /usr/include/sys/fcntl.h /usr/include/sys/time.h X#xfaceload.o: /usr/include/sys/time.h /global/include/X11/Xlib.h X#xfaceload.o: /global/include/X11/X.h /global/include/X11/Xutil.h +END+OF+Makefile echo '-rw-rw-r-- 1 argv 7314 Apr 6 15:47 Makefile (as sent)' chmod u=rw,g=rw,o=r Makefile ls -l Makefile echo x - README sed 's/^X//' > README <<'+END+OF+README' Xxface displays the USENIX FaceSaver Project pictures on an X11 display X(requires at least an 8-plane server, but note that it hasn't been Xtested at on anything greater than 8 planes either). X XThe complete archive of 1,616 faces taken by the FaceSaver project lives Xon uunet.uu.net in the directory faces. X XAuthor: Jeff Michuad - michaud@decvax.dec.com XAdapted from xgif, by John Bradley - bradley@cis.upenn.edu +END+OF+README echo '-rw-rw-r-- 1 argv 413 Apr 6 15:45 README (as sent)' chmod u=rw,g=rw,o=r README ls -l README echo x - patchlevel.h sed 's/^X//' > patchlevel.h <<'+END+OF+patchlevel.h' X#define PATCHLEVEL 3 +END+OF+patchlevel.h echo '-rw-rw-r-- 1 argv 21 Apr 6 15:45 patchlevel.h (as sent)' chmod u=rw,g=rw,o=r patchlevel.h ls -l patchlevel.h echo x - xface.c sed 's/^X//' > xface.c <<'+END+OF+xface.c' X/* X * xface.c - displays FaceSaver UUNET pictures on an X11 display X * X * Author: Jeff Michaud, Digital Equipment Corporation X * (michaud@decvax.dec.com) X * X * Adapted from xgif by: X * John Bradley, University of Pennsylvania X * (bradley@cis.upenn.edu) X */ X X#define MAIN X#include "xface.h" X X/*******************************************/ Xmain(argc, argv) X int argc; X char *argv[]; X/*******************************************/ X{ X int i; X char *display, *geom, *fname; X XEvent event; X X cmd = argv[0]; X display = geom = fname = NULL; X expImage = NULL; X X expand = 1; strip = 0; nostrip = 0; X X /*********************Options*********************/ X X for (i = 1; i < argc; i++) { X char *strind; X X if (!strncmp(argv[i],"-g",2)) { /* geometry */ X i++; X geom = argv[i]; X continue; X } X X if (argv[i][0] == '=') { /* old-style geometry */ X geom = argv[i]; X continue; X } X X if (!strncmp(argv[i],"-d",2)) { /* display */ X i++; X display = argv[i]; X continue; X } X X strind = index(argv[i], ':'); /* old-style display */ X if(strind != NULL) { X display = argv[i]; X continue; X } X X if (!strcmp(argv[i],"-e")) { /* expand */ X i++; X expand=atoi(argv[i]); X continue; X } X X if (!strcmp(argv[i],"-s")) { /* strip */ X i++; X strip=atoi(argv[i]); X continue; X } X X if (!strcmp(argv[i],"-ns")) { /* nostrip */ X nostrip++; X continue; X } X X if (argv[i][0] != '-') { /* the file name */ X fname = argv[i]; X continue; X } X X Syntax(cmd); X } X X if (fname==NULL) fname="-"; X if (expand<1 || expand>MAXEXPAND) Syntax(cmd); X if (strip<0 || strip>7) Syntax(cmd); X X /*****************************************************/ X X /* Open up the display. */ X X if ( (theDisp=XOpenDisplay(display)) == NULL) { X fprintf(stderr, "%s: Can't open display\n",argv[0]); X exit(1); X } X X theScreen = DefaultScreen(theDisp); X theCmap = DefaultColormap(theDisp, theScreen); X rootW = RootWindow(theDisp,theScreen); X theGC = DefaultGC(theDisp,theScreen); X fcol = WhitePixel(theDisp,theScreen); X bcol = BlackPixel(theDisp,theScreen); X theVisual = DefaultVisual(theDisp,theScreen); X X dispcells = DisplayCells(theDisp, theScreen); X if (dispcells<=2) X FatalError("This program requires a color display, pref. 8 bits."); X X X /****************** Open/Read the File *****************/ X LoadFACE(fname); X iWIDE = theImage->width; iHIGH = theImage->height; X X eWIDE = iWIDE * expand; eHIGH = iHIGH * expand; X if (eWIDE > DisplayWidth(theDisp,theScreen)) X eWIDE = DisplayWidth(theDisp,theScreen); X if (eHIGH > DisplayHeight(theDisp,theScreen)) X eHIGH = DisplayHeight(theDisp,theScreen); X X /**************** Create/Open X Resources ***************/ X if ((mfinfo = XLoadQueryFont(theDisp,"variable"))==NULL) X FatalError("couldn't open 'variable' font\n"); X mfont=mfinfo->fid; X XSetFont(theDisp,theGC,mfont); X XSetForeground(theDisp,theGC,fcol); X XSetBackground(theDisp,theGC,bcol); X X CreateMainWindow(cmd,geom,argc,argv); X Resize(eWIDE,eHIGH); X X XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask X | StructureNotifyMask); X XMapWindow(theDisp,mainW); X X /**************** Main loop *****************/ X while (1) { X XNextEvent(theDisp, &event); X HandleEvent(&event); X } X} X X X X/****************/ XHandleEvent(event) X XEvent *event; X/****************/ X{ X switch (event->type) { X case Expose: { X XExposeEvent *exp_event = (XExposeEvent *) event; X X if (exp_event->window==mainW) X DrawWindow(exp_event->x,exp_event->y, X exp_event->width, exp_event->height); X } X break; X X case KeyPress: { X XKeyEvent *key_event = (XKeyEvent *) event; X char buf[128]; X KeySym ks; X XComposeStatus status; X X XLookupString(key_event,buf,128,&ks,&status); X if (buf[0]=='q' || buf[0]=='Q') Quit(); X } X break; X X case ConfigureNotify: { X XConfigureEvent *conf_event = (XConfigureEvent *) event; X X if (conf_event->window == mainW && X (conf_event->width != eWIDE || conf_event->height != eHIGH)) X Resize(conf_event->width, conf_event->height); X } X break; X X X case CirculateNotify: X case MapNotify: X case DestroyNotify: X case GravityNotify: X case ReparentNotify: X case UnmapNotify: break; X X default: /* ignore unexpected events */ X break; X } /* end of switch */ X} X X X/***********************************/ XSyntax() X{ X printf("Usage: %s filename [[-geometry] geom] [[-display] display]\n",cmd); X printf(" [-e 1..%d] [-s 0-7] [-ns]\n",MAXEXPAND); X exit(1); X} X X X/***********************************/ XFatalError (identifier) X char *identifier; X{ X fprintf(stderr, "%s: %s\n",cmd, identifier); X exit(-1); X} X X X/***********************************/ XQuit() X{ X exit(0); X} X X X/***********************************/ XDrawWindow(x,y,w,h) X{ X XPutImage(theDisp,mainW,theGC,expImage,x,y,x,y,w,h); X} X X X/***********************************/ XResize(w,h) Xint w,h; X{ X int ix,iy,ex,ey; X byte *ximag,*ilptr,*ipptr,*elptr,*epptr; X static char *rstr = "Resizing Image. Please wait..."; X X /* warning: this code'll only run machines where int=32-bits */ X X if (w==iWIDE && h==iHIGH) { /* very special case */ X if (expImage != theImage) { X if (expImage) XDestroyImage(expImage); X expImage = theImage; X eWIDE = iWIDE; eHIGH = iHIGH; X } X } X X else { /* have to do some work */ X /* if it's a big image, this'll take a while. mention it */ X if (w*h>(500*500)) { X XDrawImageString(theDisp,mainW,theGC,CENTERX(mfinfo,w/2,rstr), X CENTERY(mfinfo,h/2),rstr, strlen(rstr)); X XFlush(theDisp); X } X X /* first, kill the old expImage, if one exists */ X if (expImage && expImage != theImage) { X free(expImage->data); expImage->data = NULL; X XDestroyImage(expImage); X } X X /* create expImage of the appropriate size */ X X eWIDE = w; eHIGH = h; X ximag = (byte *) malloc(w*h); X expImage = XCreateImage(theDisp,theVisual,8,ZPixmap,0,ximag, X eWIDE,eHIGH,8,eWIDE); X X if (!ximag || !expImage) { X fprintf(stderr,"ERROR: unable to create a %dx%d image\n",w,h); X exit(0); X } X X elptr = epptr = (byte *) expImage->data; X X for (ey=0; ey<eHIGH; ey++, elptr+=eWIDE) { X iy = (iHIGH * ey) / eHIGH; X epptr = elptr; X ilptr = (byte *) theImage->data + (iy * iWIDE); X for (ex=0; ex<eWIDE; ex++,epptr++) { X ix = (iWIDE * ex) / eWIDE; X ipptr = ilptr + ix; X *epptr = *ipptr; X } X } X } X} X X X/***********************************/ XCreateMainWindow(name,geom,argc,argv) X char *name,*geom,**argv; X int argc; X{ X XSetWindowAttributes xswa; X unsigned int xswamask; X XSizeHints hints; X int i,x,y,w,h; X X x=y=w=h=1; X i=XParseGeometry(geom,&x,&y,&w,&h); X if (i&WidthValue) eWIDE = w; X if (i&HeightValue) eHIGH = h; X X if (i&XValue || i&YValue) hints.flags = USPosition; X else hints.flags = PPosition; X X hints.flags |= USSize; X X if (i&XValue && i&XNegative) X x = XDisplayWidth(theDisp,theScreen)-eWIDE-abs(x); X if (i&YValue && i&YNegative) X y = XDisplayHeight(theDisp,theScreen)-eHIGH-abs(y); X X hints.x=x; hints.y=y; X hints.width = eWIDE; hints.height = eHIGH; X hints.max_width = DisplayWidth(theDisp,theScreen); X hints.max_height = DisplayHeight(theDisp,theScreen); X hints.flags |= PMaxSize; X X xswa.background_pixel = bcol; X xswa.border_pixel = fcol; X xswamask = CWBackPixel | CWBorderPixel; X X mainW = XCreateWindow(theDisp,rootW,x,y,eWIDE,eHIGH,2,0,CopyFromParent, X CopyFromParent, xswamask, &xswa); X X XSetStandardProperties(theDisp,mainW,"xface","xface",None, X argv,argc,&hints); X X if (!mainW) FatalError("Can't open main window"); X X} X X +END+OF+xface.c echo '-rw-rw-r-- 1 argv 8848 Apr 6 15:53 xface.c (as sent)' chmod u=rw,g=rw,o=r xface.c ls -l xface.c echo x - xface.h sed 's/^X//' > xface.h <<'+END+OF+xface.h' X/* X * xface.h - header file for xface, but you probably already knew as much X */ X X X#define REVDATE "Rev: 2/13/89" X#define MAXEXPAND 16 X X/* include files */ X#include <stdio.h> X#include <math.h> X#include <ctype.h> X X#include <X11/Xos.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X X X#ifdef vms X#ifndef MAIN X#define WHERE globaldef X#else X#define WHERE globalref X#endif X#else !vms X#ifndef MAIN X#define WHERE extern X#else X#define WHERE X#endif X#endif X Xtypedef unsigned char byte; X X#define CENTERX(f,x,str) ((x)-XTextWidth(f,str,strlen(str))/2) X#define CENTERY(f,y) ((y)-((f->ascent+f->descent)/2)+f->ascent) X X X/* X stuff */ XWHERE Display *theDisp; XWHERE int theScreen, dispcells; XWHERE Colormap theCmap; XWHERE Window rootW, mainW; XWHERE GC theGC; XWHERE unsigned long fcol,bcol; XWHERE Font mfont; XWHERE XFontStruct *mfinfo; XWHERE Visual *theVisual; XWHERE XImage *theImage, *expImage; X X/* global vars */ XWHERE int iWIDE,iHIGH,eWIDE,eHIGH,expand,numcols,strip,nostrip; XWHERE unsigned long cols[256]; XWHERE XColor defs[256]; XWHERE char *cmd; +END+OF+xface.h echo '-rw-rw-r-- 1 argv 1130 Apr 6 15:45 xface.h (as sent)' chmod u=rw,g=rw,o=r xface.h ls -l xface.h echo x - xface.man sed 's/^X//' > xface.man <<'+END+OF+xface.man' X.TH xface 1X X.SH NAME Xxface \- displays FaceSaver pictures on X11 displays X.SH SYNTAX X\fBxface\fP [\fIdisplay\fP] [ [-g] \fIgeometry\fP] [-e \fIexpansion\fP] X[-s 0-7] [-ns] [\fIfilename\fP] X.SH DESCRIPTION X\fBxface\fP is an X11 program that displays FaceSaver pictures on an 8-plane Xdisplay. X.SH OPTIONS XThe '-e' option allows you to expand the picture by an integer amount. For Xexample, viewing a 320x200 picture with an expansion factor of '2' will Xresult in a 640x400 picture, each pixel of which is a 2x2 block. X.PP XYou may also specify an expansion of the picture by specifying the size of Xthe window in the \fIgeometry\fP option. This also allows you specify Xnon-integer expansion factors, and different aspect ratios. Example: if Xyou view a 320x200 picture, but specify a window size of 640x300, the picture Xwill be expanded by a factor of two along the X-axis, but only by a factor of X1.5 along the Y-axis. X.PP XIf you specify both the '-e' option and a window size (via \fIgeometry\fP), Xthe '-e' will be ignored. X.PP XThe '-s' option allows you specify the number of bits to strip off of the Xresolution. The theory runs like this: if you have X256 unique gray levels in your Xface file, you will almost certainly be unable to allocate all of them on an X8-plane display, as a couple colors will already be allocated for the Xwindow manager, and such. Setting this option allows you to strip off the Xlow \fIstrip\fP bits of the R,G,B entries in the colormap. This will Xhave the desired effect of making some of the (previously different) gray levels Xthe SAME, and you will be able to allocate all the colors you need now. X.PP XYou shouldn't ever HAVE to set this option, because if the program is unable Xto allocate the required colors, it will try again after incrementing X\fIstrip\fP. You can, however save some time, or alternately get neat Xvisual effects by setting this option. X.PP XThe '-ns' option turns off the 'auto-strip' feature described above. You Xuse this to FORCE the program to use as many gray levels as possible. XThe theory Xworks like this: if you have 256 unique gray levels in your face file, you will Xprobably be able to allocate all but a few of them. Rather than stripping off Xbits, decreasing the resolution for the whole picture uniformly, the X'nostrip' option makes the program set the few unallocatable colors equal to Xthe 'closest' colors that were allocated. This may cause nasty 'blotches' Xon the picture. Then again, it might not. Only way to tell is to try both Xwith and without the 'auto-strip' 'feature'. X.PP XAlso, it should be noted that if the optional \fIfilename\fP is not supplied, Xthe program will read the picture from stdin. X.SH LIMITATIONS XYou'll require (at least) an 8-plane X11 display. X.PP XNote: This program points out a bug in the X11R2 server for the IBM RT XMegapel display. This bug will occasionally cause the colors in a picture Xto be wrong, but no 'unable to allocate' message will be printed by the Xprogram. (Essentially, the problem is a discrepancy between what the Xserver THINKS the colormap is, and what the colormap in the hardware XACTUALLY is.) X.PP X.SH AUTHOR XJeff Michaud - michaud@decvax.dec.com X.PP XAdapted from xgif, by John Bradley - bradley@cis.upenn.edu, which was Xbased (heavily) on gif2ras.c, by Patrick J. Naughton (naughton@wind.sun.com), Xa program that converts GIF pictures to Sun Rasterfiles. +END+OF+xface.man echo '-rw-rw-r-- 1 argv 3395 Apr 6 15:45 xface.man (as sent)' chmod u=rw,g=rw,o=r xface.man ls -l xface.man echo x - xfaceload.c sed 's/^X//' > xfaceload.c <<'+END+OF+xfaceload.c' X/* X */ X X#include "xface.h" X Xtypedef int boolean; X XFILE *fp; X Xint XC = 0, YC = 0, /* Output X and Y coords of current pixel */ X Width, Height, /* image dimensions */ X BytesPerScanline; /* bytes per scanline in output raster */ X Xboolean HasColormap = True; Xboolean Verbose = False; X Xbyte *Image; /* The result array */ X Xbyte Red[256], Green[256], Blue[256], used[256]; Xint numused = 0; X X X/*****************************/ XLoadFACE(fname) X char *fname; X/*****************************/ X{ X int i; X X if (strcmp(fname,"-")==0) { fp = stdin; fname = "<stdin>"; } X else fp = fopen(fname,"r"); X X if (!fp) FatalError("file not found"); X X init(); X X numcols = 256; X X for( i = 0 ; i < 256 ; ++i ) X used[i] = 0, Red[i] = Green[i] = Blue[i] = cols[i] = i; X X/* Allocate the X Image */ X Image = (byte *) malloc(Width*Height); X if (!Image) FatalError("not enough memory for XImage"); X X theImage = XCreateImage(theDisp,theVisual,8,ZPixmap,0,Image, X Width,Height,8,Width); X if (!theImage) FatalError("unable to create XImage"); X X BytesPerScanline = Width; X X YC = Height - 1; X X fillitup(); X X ColorDicking(fname); X} X XAddToPixel(Index) Xbyte Index; X{ X X if (!used[Index]) { used[Index]=1; numused++; } X X if (YC>=0) X *(Image + YC * BytesPerScanline + XC) = Index; X X/* Update the X-coordinate, and if it overflows, update the Y-coordinate */ X X if (++XC == Width) { X XC = 0; X YC--; X } X} X X X X/*************************/ XColorDicking(fname) Xchar *fname; X{ X /* we've got the picture loaded, we know what colors are needed. get 'em */ X X register int i,j; X static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; X byte lmask, *ptr; X X X if (!HasColormap) return; X X /* Allocate the X colors for this picture */ X X if (nostrip) { /* nostrip was set. try REAL hard to do it */ X for (i=j=0; i<numcols; i++) { X if (used[i]) { X defs[i].red = Red[i]<<8; X defs[i].green = Green[i]<<8; X defs[i].blue = Blue[i]<<8; X defs[i].flags = DoRed | DoGreen | DoBlue; X if (!XAllocColor(theDisp,theCmap,&defs[i])) { X j++; defs[i].pixel = 0xffff; X } X cols[i] = defs[i].pixel; X } X } X X if (j) { /* failed to pull it off */ X XColor ctab[256]; X int dc; X X dc = (dispcells<256) ? dispcells : 256; X X fprintf(stderr,"failed to allocate %d out of %d colors. Trying extra hard.\n",j,numused); X X /* read in the color table */ X for (i=0; i<dc; i++) ctab[i].pixel = i; X XQueryColors(theDisp,theCmap,ctab,dc); X X /* run through the used colors. any used color that has a pixel X value of 0xffff wasn't allocated. for such colors, run through X the entire X colormap and pick the closest color */ X X for (i=0; i<numcols; i++) X if (used[i] && cols[i]==0xffff) { /* an unallocated pixel */ X int d, mdist, close; X unsigned long r,g,b; X X mdist = 100000; close = -1; X r = Red[i]; X g = Green[i]; X b = Blue[i]; X for (j=0; j<dc; j++) { X d = abs(r - (ctab[j].red>>8)) + X abs(g - (ctab[j].green>>8)) + X abs(b - (ctab[j].blue>>8)); X if (d<mdist) { mdist=d; close=j; } X } X if (close<0) FatalError("simply can't do it. Sorry."); X /*bcopy(&defs[close],&defs[i],sizeof(XColor));*/ X memcpy(&defs[close],&defs[i],sizeof(XColor)); X cols[i] = ctab[close].pixel; X } X } /* end 'failed to pull it off' */ X } X X else { /* strip wasn't set, do the best auto-strip */ X j = 0; X while (strip<8) { X lmask = lmasks[strip]; X for (i=0; i<numcols; i++) X if (used[i]) { X defs[i].red = (Red[i] &lmask)<<8; X defs[i].green = (Green[i]&lmask)<<8; X defs[i].blue = (Blue[i] &lmask)<<8; X defs[i].flags = DoRed | DoGreen | DoBlue; X if (!XAllocColor(theDisp,theCmap,&defs[i])) break; X cols[i] = defs[i].pixel; X } X X if (i<numcols) { /* failed */ X strip++; j++; X for (i--; i>=0; i--) X if (used[i]) XFreeColors(theDisp,theCmap,cols+i,1,0L); X } X else break; X } X X if (j && strip<8) X fprintf(stderr,"%s: %s stripped %d bits\n",cmd,fname,strip); X X if (strip==8) { X fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n"); X for (i=0; i<numcols; i++) cols[i]=i; X } X } X X ptr = Image; X for (i=0; i<Height; i++) X for (j=0; j<Width; j++,ptr++) X *ptr = (byte) cols[*ptr]; X} X X X#define BUFSIZE 1024 X#define PIXSIZE 2 X#define MAXBPL 15 /* Max bytes per output line in resultant XBM */ X Xchar line[BUFSIZE]; X Xchar firstname[BUFSIZE]; Xchar lastname [BUFSIZE]; Xchar email [BUFSIZE]; X Xint depth; Xint iwidth, iheight, idepth; X Xint totalpixels; X X/* Scan line Enum junk */ X char *enum_ptr; /* local to enum routines */ Xvoid Xinit_enum(buf) X char *buf; X{ X enum_ptr = buf; X} X X/* Dithering junk */ Xchar **dithtab; X Xint Xnext_enum(out) X char *out; X{ X if( enum_ptr[0] == '\n' || enum_ptr[0] == '\0' ) X return False; X X strncpy(out, enum_ptr, PIXSIZE); X out[PIXSIZE] = '\0'; X enum_ptr += PIXSIZE; X X return True; X} X Xinit() X{ X int nlcounter = 1; X X fgets(line, BUFSIZE, fp); X sscanf(line, "%*s %s", firstname); X X fgets(line, BUFSIZE, fp); X sscanf(line, "%*s %s", lastname); X X fgets(line, BUFSIZE, fp); X sscanf(line, "%*s %s", email); X X fgets(line, BUFSIZE, fp); X sscanf(line, "%*s %d %d %d", &Width, &Height, &depth); X X fgets(line, BUFSIZE, fp); X sscanf(line, "%*s %d %d %d", &iwidth, &iheight, &idepth); X X fgets(line, BUFSIZE, fp); X X totalpixels = Width * Height; X} X Xfillitup() X{ X while( fgets(line, BUFSIZE, fp) != NULL ) { X char pixel[PIXSIZE+1]; X X init_enum(line); X X while( next_enum(pixel) ) { X unsigned int value; X X sscanf(pixel, "%x", &value); X AddToPixel((byte)value); X } X } X} +END+OF+xfaceload.c echo '-rw-rw-r-- 1 argv 6622 Apr 6 15:45 xfaceload.c (as sent)' chmod u=rw,g=rw,o=r xfaceload.c ls -l xfaceload.c exit 0