[comp.sources.x] v03i029: program to display gif images on color servers, Part01/01

mikew@wyse.wyse.com (Mike Wexler) (02/22/89)

Submitted-by: bradley@cis.upenn.edu (John Bradley)
Posting-number: Volume 3, Issue 29
Archive-name: xgif/part01

[I made to changes to this program.  Adding a break after a default:
statement in a switch statement.  This kept Sun's compiler from
complaining.  And removing #include <strings.h> which was unnecessary
since <X11/Xos.h> is already included. -mcw]

#! /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 Imakefile Makefile patchlevel.h xgif.c
#   xgif.h xgif.man xgifload.c
# Wrapped by mikew@wyse on Tue Feb 21 11:08:39 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'\" \(817 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xxgif is a program that displays GIF images on an 8-plane X11 display.  The
Ximages can be freely rescaled.
X
XA collection of GIF images is available via anonymous ftp to 
X"dsl.cis.upenn.edu" [128.91.2.12].
X
XJohn Bradley  -  bradley@cis.upenn.edu
X
XRevision History:
X
XPATCH 1  -  Somewhat more intellegent color use.  Basically, it only trys
Xto allocate the colors that the GIF picture actually USES, rather than one 
Xcolor for each entry in the GIF colormap.  Ran into a bunch of pictures that
Xonly used 16 colors out of a 256-entry colormap...
X
XAlso added [-display] option, in keeping with the New Improved Standard
XCommand Line Options for X11.
X
XPATCH 2  -  (2/13/89) Minor problem with dying on unexpected X events.  
XDifferent window managers send different events.  Solution:  simply IGNORE 
Xunexpected X events.
X
END_OF_FILE
if test 817 -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'\" \(310 characters\)
sed "s/^X//" >'AUTHOR' <<'END_OF_FILE'
XWritten by John Bradley (bradley@cis.upenn.edu), one of the fine folks at 
Xthe University of Pennsylvania.
X
XDo whatever you want with this program, though it *would* be nice if my name
Xremained on it somewhere...  Other than that, it may be freely modified,
Xdistributed, and used to fill up disk space.
X
X--jhb
END_OF_FILE
if test 310 -ne `wc -c <'AUTHOR'`; then
    echo shar: \"'AUTHOR'\" unpacked with wrong size!
fi
# end of 'AUTHOR'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(119 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
XLOCAL_LIBRARIES = $(XLIB)
X
XOBJS = \
X	xgif.o \
X	xgifload.o
X
XSRCS = \
X	xgif.c \
X	xgifload.c
X
XComplexProgramTarget(xgif)
X
END_OF_FILE
if test 119 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(7275 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
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 = /global
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	xgif.o \
X	xgifload.o
X
XSRCS = \
X	xgif.c \
X	xgifload.c
X
X PROGRAM = xgif
X
Xall:: xgif
X
Xxgif: $(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:: xgif
X	$(INSTALL) -c $(INSTALLFLAGS) xgif $(BINDIR)
X
Xinstall.man:: xgif.man
X	$(INSTALL) -c $(INSTMANFLAGS) xgif.man $(MANDIR)/xgif.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
Xxgif.o: xgif.h /usr/include/stdio.h /usr/include/math.h /usr/include/ctype.h
Xxgif.o: /global/include/X11/Xos.h /usr/include/sys/types.h
Xxgif.o: /usr/include/sys/sysmacros.h /usr/include/strings.h
Xxgif.o: /usr/include/sys/file.h /usr/include/sys/fcntl.h
Xxgif.o: /usr/include/sys/time.h /usr/include/sys/time.h
Xxgif.o: /global/include/X11/Xlib.h /global/include/X11/X.h
Xxgif.o: /global/include/X11/Xutil.h
Xxgifload.o: xgif.h /usr/include/stdio.h /usr/include/math.h
Xxgifload.o: /usr/include/ctype.h /global/include/X11/Xos.h
Xxgifload.o: /usr/include/sys/types.h /usr/include/sys/sysmacros.h
Xxgifload.o: /usr/include/strings.h /usr/include/sys/file.h
Xxgifload.o: /usr/include/sys/fcntl.h /usr/include/sys/time.h
Xxgifload.o: /usr/include/sys/time.h /global/include/X11/Xlib.h
Xxgifload.o: /global/include/X11/X.h /global/include/X11/Xutil.h
END_OF_FILE
if test 7275 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
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 2
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 'xgif.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xgif.c'\"
else
echo shar: Extracting \"'xgif.c'\" \(8705 characters\)
sed "s/^X//" >'xgif.c' <<'END_OF_FILE'
X/*
X * xgif.c - displays GIF pictures on an X11 display
X *
X *  Author:    John Bradley, University of Pennsylvania
X *                (bradley@cis.upenn.edu)
X */
X
X#define MAIN
X#include "xgif.h"
X
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    LoadGIF(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,"xgif","xgif",None,
X                            argv,argc,&hints);
X
X    if (!mainW) FatalError("Can't open main window");
X
X}
X
X
END_OF_FILE
if test 8705 -ne `wc -c <'xgif.c'`; then
    echo shar: \"'xgif.c'\" unpacked with wrong size!
fi
# end of 'xgif.c'
fi
if test -f 'xgif.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xgif.h'\"
else
echo shar: Extracting \"'xgif.h'\" \(1025 characters\)
sed "s/^X//" >'xgif.h' <<'END_OF_FILE'
X/*
X *  xgif.h  -  header file for xgif, 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#ifndef MAIN
X#define WHERE extern
X#else
X#define WHERE
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_FILE
if test 1025 -ne `wc -c <'xgif.h'`; then
    echo shar: \"'xgif.h'\" unpacked with wrong size!
fi
# end of 'xgif.h'
fi
if test -f 'xgif.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xgif.man'\"
else
echo shar: Extracting \"'xgif.man'\" \(4487 characters\)
sed "s/^X//" >'xgif.man' <<'END_OF_FILE'
X.TH xgif 1X
X.SH NAME
Xxgif \- displays GIF (*) pictures on X11 displays
X.SH SYNTAX
X\fBxgif\fP [\fIdisplay\fP] [ [-g] \fIgeometry\fP] [-e \fIexpansion\fP]
X[-s \fIstrip\fP] [-ns] [\fIfilename\fP]
X.SH DESCRIPTION
X\fBxgif\fP is an X11 program that displays GIF 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
Xcolors.  The theory runs like this:  if you have 256 unique colors in your
XGIF 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 GIF colormap.  This will
Xhave the desired effect of making some of the (previously different) colors
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 colors as possible.  The theory
Xworks like this:  if you have 256 unique colors in your GIF file, you will
Xprobably be able to allocate all but a few of them.  Rather than stripping off
Xbits, decreasing the color 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
XOne DEFINITE drawback of the '-ns' option is that it's only really useful
Xon the FIRST picture you try to display.  If you try to display two pictures
Xsimultaneously, the first picture will (presumably) use up most (if not ALL)
Xof the colortable, leaving NO colors for the second picture.  Therefore, the
Xsecond (and succeeding pictures) will probably not look very good.  When you
Xuse the 'auto-strip' feature, you will be able to get considerably more 
Xpictures on the screen simultaneously.  Probably.  Varies wildly, based on 
Xthe actual pictures being displayed.
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.  This program 
Xignores 'local colormaps' in GIF files (see the GIF spec for details).  
XIt also only displays the first image in GIF files that have multiple 
Ximages in them.
X.PP
XThe number of pictures you can display simultaneously varies wildly.  It 
Xdepends on how many colors are in the GIF files, and how many of them are
Xshared by other GIF files.  Suffice it to say that you can ALWAYS display a
Xpicture, though the colors may or may not be right.  If the program was
Xunable to get all the desired colors, it will mention that fact.
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
XJohn Bradley  -  bradley@cis.upenn.edu
X.PP
XBased (heavily) on gif2ras.c, by Patrick J. Naughton (naughton@wind.sun.com),
Xa program that converts GIF pictures to Sun Rasterfiles.
X.PP
X(*) GIF is a no doubt a trademark of CompuServe, so watch it!
END_OF_FILE
if test 4487 -ne `wc -c <'xgif.man'`; then
    echo shar: \"'xgif.man'\" unpacked with wrong size!
fi
# end of 'xgif.man'
fi
if test -f 'xgifload.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xgifload.c'\"
else
echo shar: Extracting \"'xgifload.c'\" \(15199 characters\)
sed "s/^X//" >'xgifload.c' <<'END_OF_FILE'
X/*
X * xgifload.c  -  based strongly on...
X *
X * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
X *
X * Copyright (c) 1988, 1989 by Patrick J. Naughton
X *
X * Author: Patrick J. Naughton
X * naughton@wind.sun.com
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind.  The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof.  In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X */
X
X#include "xgif.h"
X
Xtypedef int boolean;
X
X#define NEXTBYTE (*ptr++)
X#define IMAGESEP 0x2c
X#define INTERLACEMASK 0x40
X#define COLORMAPMASK 0x80
X
XFILE *fp;
X
Xint BitOffset = 0,		/* Bit Offset of next code */
X    XC = 0, YC = 0,		/* Output X and Y coords of current pixel */
X    Pass = 0,			/* Used by output routine if interlaced pic */
X    OutCount = 0,		/* Decompressor output 'stack count' */
X    RWidth, RHeight,		/* screen dimensions */
X    Width, Height,		/* image dimensions */
X    LeftOfs, TopOfs,		/* image offset */
X    BitsPerPixel,		/* Bits per pixel, read from GIF header */
X    BytesPerScanline,		/* bytes per scanline in output raster */
X    ColorMapSize,		/* number of colors */
X    Background,			/* background color */
X    CodeSize,			/* Code size, read from GIF header */
X    InitCodeSize,		/* Starting code size, used during Clear */
X    Code,			/* Value returned by ReadCode */
X    MaxCode,			/* limiting value for current code size */
X    ClearCode,			/* GIF clear code */
X    EOFCode,			/* GIF end-of-information code */
X    CurCode, OldCode, InCode,	/* Decompressor variables */
X    FirstFree,			/* First free code, generated per GIF spec */
X    FreeCode,			/* Decompressor, next free slot in hash table */
X    FinChar,			/* Decompressor variable */
X    BitMask,			/* AND mask for data size */
X    ReadMask;			/* Code AND mask for current code size */
X
Xboolean Interlace, HasColormap;
Xboolean Verbose = False;
X
Xbyte *Image;			/* The result array */
Xbyte *RawGIF;			/* The heap array to hold it, raw */
Xbyte *Raster;			/* The raster data stream, unblocked */
X
X    /* The hash table used by the decompressor */
Xint Prefix[4096];
Xint Suffix[4096];
X
X    /* An output array used by the decompressor */
Xint OutCode[1025];
X
X    /* The color map, read from the GIF header */
Xbyte Red[256], Green[256], Blue[256], used[256];
Xint  numused;
X
Xchar *id = "GIF87a";
X
X
X
X/*****************************/
XLoadGIF(fname)
X  char *fname;
X/*****************************/
X{
X    int            filesize;
X    register byte  ch, ch1;
X    register byte *ptr, *ptr1;
X    register 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    /* find the size of the file */
X    fseek(fp, 0L, 2);
X    filesize = ftell(fp);
X    fseek(fp, 0L, 0);
X
X    if (!(ptr = RawGIF = (byte *) malloc(filesize)))
X	FatalError("not enough memory to read gif file");
X
X    if (!(Raster = (byte *) malloc(filesize)))
X	FatalError("not enough memory to read gif file");
X
X    if (fread(ptr, filesize, 1, fp) != 1)
X	FatalError("GIF data read failed");
X
X    if (strncmp(ptr, id, 6))
X	FatalError("not a GIF file");
X
X    ptr += 6;
X
X/* Get variables from the GIF screen descriptor */
X
X    ch = NEXTBYTE;
X    RWidth = ch + 0x100 * NEXTBYTE;	/* screen dimensions... not used. */
X    ch = NEXTBYTE;
X    RHeight = ch + 0x100 * NEXTBYTE;
X
X    if (Verbose)
X	fprintf(stderr, "screen dims: %dx%d.\n", RWidth, RHeight);
X
X    ch = NEXTBYTE;
X    HasColormap = ((ch & COLORMAPMASK) ? True : False);
X
X    BitsPerPixel = (ch & 7) + 1;
X    numcols = ColorMapSize = 1 << BitsPerPixel;
X    BitMask = ColorMapSize - 1;
X
X    Background = NEXTBYTE;		/* background color... not used. */
X
X    if (NEXTBYTE)		/* supposed to be NULL */
X	FatalError("corrupt GIF file (bad screen descriptor)");
X
X
X/* Read in global colormap. */
X
X    if (HasColormap) {
X	if (Verbose)
X	    fprintf(stderr, "%s is %dx%d, %d bits per pixel, (%d colors).\n",
X		fname, Width,Height,BitsPerPixel, ColorMapSize);
X	for (i = 0; i < ColorMapSize; i++) {
X	    Red[i] = NEXTBYTE;
X	    Green[i] = NEXTBYTE;
X	    Blue[i] = NEXTBYTE;
X            used[i] = 0;
X	    }
X        numused = 0;
X
X        }
X
X    else {  /* no colormap in GIF file */
X        fprintf(stderr,"%s:  warning!  no colortable in this file.  Winging it.\n",cmd);
X        if (!numcols) numcols=256;
X        for (i=0; i<numcols; i++) cols[i] = (unsigned long) i;
X        }
X
X/* Check for image seperator */
X
X    if (NEXTBYTE != IMAGESEP)
X	FatalError("corrupt GIF file (no image separator)");
X
X/* Now read in values from the image descriptor */
X
X    ch = NEXTBYTE;
X    LeftOfs = ch + 0x100 * NEXTBYTE;
X    ch = NEXTBYTE;
X    TopOfs = ch + 0x100 * NEXTBYTE;
X    ch = NEXTBYTE;
X    Width = ch + 0x100 * NEXTBYTE;
X    ch = NEXTBYTE;
X    Height = ch + 0x100 * NEXTBYTE;
X    Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
X
X    if (Verbose)
X	fprintf(stderr, "Reading a %d by %d %sinterlaced image...",
X		Width, Height, (Interlace) ? "" : "non-");
X
X    else 
X        fprintf(stderr, "%s:  %s is %dx%d, %d colors  ",
X	   cmd, fname, Width,Height,ColorMapSize);
X    
X
X/* Note that I ignore the possible existence of a local color map.
X * I'm told there aren't many files around that use them, and the spec
X * says it's defined for future use.  This could lead to an error
X * reading some files. 
X */
X
X/* Start reading the raster data. First we get the intial code size
X * and compute decompressor constant values, based on this code size.
X */
X
X    CodeSize = NEXTBYTE;
X    ClearCode = (1 << CodeSize);
X    EOFCode = ClearCode + 1;
X    FreeCode = FirstFree = ClearCode + 2;
X
X/* The GIF spec has it that the code size is the code size used to
X * compute the above values is the code size given in the file, but the
X * code size used in compression/decompression is the code size given in
X * the file plus one. (thus the ++).
X */
X
X    CodeSize++;
X    InitCodeSize = CodeSize;
X    MaxCode = (1 << CodeSize);
X    ReadMask = MaxCode - 1;
X
X/* Read the raster data.  Here we just transpose it from the GIF array
X * to the Raster array, turning it from a series of blocks into one long
X * data stream, which makes life much easier for ReadCode().
X */
X
X    ptr1 = Raster;
X    do {
X	ch = ch1 = NEXTBYTE;
X	while (ch--) *ptr1++ = NEXTBYTE;
X	if ((Raster - ptr1) > filesize)
X	    FatalError("corrupt GIF file (unblock)");
X    } while(ch1);
X
X    free(RawGIF);		/* We're done with the raw data now... */
X
X    if (Verbose) {
X	fprintf(stderr, "done.\n");
X	fprintf(stderr, "Decompressing...");
X    }
X
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
X/* Decompress the file, continuing until you see the GIF EOF code.
X * One obvious enhancement is to add checking for corrupt files here.
X */
X
X    Code = ReadCode();
X    while (Code != EOFCode) {
X
X/* Clear code sets everything back to its initial value, then reads the
X * immediately subsequent code as uncompressed data.
X */
X
X	if (Code == ClearCode) {
X	    CodeSize = InitCodeSize;
X	    MaxCode = (1 << CodeSize);
X	    ReadMask = MaxCode - 1;
X	    FreeCode = FirstFree;
X	    CurCode = OldCode = Code = ReadCode();
X	    FinChar = CurCode & BitMask;
X	    AddToPixel(FinChar);
X	}
X	else {
X
X/* If not a clear code, then must be data: save same as CurCode and InCode */
X
X	    CurCode = InCode = Code;
X
X/* If greater or equal to FreeCode, not in the hash table yet;
X * repeat the last character decoded
X */
X
X	    if (CurCode >= FreeCode) {
X		CurCode = OldCode;
X		OutCode[OutCount++] = FinChar;
X	    }
X
X/* Unless this code is raw data, pursue the chain pointed to by CurCode
X * through the hash table to its end; each code in the chain puts its
X * associated output code on the output queue.
X */
X
X	    while (CurCode > BitMask) {
X		if (OutCount > 1024) {
X		    fprintf(stderr,"\nCorrupt GIF file (OutCount)!\n");
X                    _exit(-1);  /* calling 'exit(-1)' dumps core, so I don't */
X                    }
X		OutCode[OutCount++] = Suffix[CurCode];
X		CurCode = Prefix[CurCode];
X	    }
X
X/* The last code in the chain is treated as raw data. */
X
X	    FinChar = CurCode & BitMask;
X	    OutCode[OutCount++] = FinChar;
X
X/* Now we put the data out to the Output routine.
X * It's been stacked LIFO, so deal with it that way...
X */
X
X	    for (i = OutCount - 1; i >= 0; i--)
X		AddToPixel(OutCode[i]);
X	    OutCount = 0;
X
X/* Build the hash table on-the-fly. No table is stored in the file. */
X
X	    Prefix[FreeCode] = OldCode;
X	    Suffix[FreeCode] = FinChar;
X	    OldCode = InCode;
X
X/* Point to the next slot in the table.  If we exceed the current
X * MaxCode value, increment the code size unless it's already 12.  If it
X * is, do nothing: the next code decompressed better be CLEAR
X */
X
X	    FreeCode++;
X	    if (FreeCode >= MaxCode) {
X		if (CodeSize < 12) {
X		    CodeSize++;
X		    MaxCode *= 2;
X		    ReadMask = (1 << CodeSize) - 1;
X		}
X	    }
X	}
X	Code = ReadCode();
X    }
X
X    free(Raster);
X
X    if (Verbose)
X	fprintf(stderr, "done.\n");
X    else
X        fprintf(stderr,"(of which %d are used)\n",numused);
X
X    if (fp != stdin)
X	fclose(fp);
X
X    ColorDicking(fname);
X}
X
X
X/* Fetch the next code from the raster data stream.  The codes can be
X * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
X * maintain our location in the Raster array as a BIT Offset.  We compute
X * the byte Offset into the raster array by dividing this by 8, pick up
X * three bytes, compute the bit Offset into our 24-bit chunk, shift to
X * bring the desired code to the bottom, then mask it off and return it. 
X */
XReadCode()
X{
Xint RawCode, ByteOffset;
X
X    ByteOffset = BitOffset / 8;
X    RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
X    if (CodeSize >= 8)
X	RawCode += (0x10000 * Raster[ByteOffset + 2]);
X    RawCode >>= (BitOffset % 8);
X    BitOffset += CodeSize;
X    return(RawCode & ReadMask);
X}
X
X
XAddToPixel(Index)
Xbyte Index;
X{
X    if (YC<Height)
X        *(Image + YC * BytesPerScanline + XC) = Index;
X
X    if (!used[Index]) { used[Index]=1;  numused++; }
X
X/* Update the X-coordinate, and if it overflows, update the Y-coordinate */
X
X    if (++XC == Width) {
X
X/* If a non-interlaced picture, just increment YC to the next scan line. 
X * If it's interlaced, deal with the interlace as described in the GIF
X * spec.  Put the decoded scan line out to the screen if we haven't gone
X * past the bottom of it
X */
X
X	XC = 0;
X	if (!Interlace) YC++;
X	else {
X	    switch (Pass) {
X		case 0:
X		    YC += 8;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 4;
X		    }
X		break;
X		case 1:
X		    YC += 8;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 2;
X		    }
X		break;
X		case 2:
X		    YC += 4;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 1;
X		    }
X		break;
X		case 3:
X		    YC += 2;
X		break;
X		default:
X		break;
X	    }
X	}
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    /* no need to allocate any colors if no colormap in GIF file */
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                    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}
END_OF_FILE
if test 15199 -ne `wc -c <'xgifload.c'`; then
    echo shar: \"'xgifload.c'\" unpacked with wrong size!
fi
# end of 'xgifload.c'
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