v05i027: xloadimage, Part01/02

Dan Heller argv at island.uu.net
Tue Nov 14 10:44:01 AEST 1989


Submitted-by: madd at world.std.com (jim frost)
Posting-number: Volume 5, Issue 27
Archive-name: xldimage/part01



This utility will view several types of images under X11, or load
images onto the root window.  The current version supports X11 Bitmap,
Portable Bitmap, Faces Project, and Sun Rasterfile images.  More are
planned.

Jim Frost
    madd at std.com            +1 617-739-WRLD  24hrs {3,12,24}00bps

#! /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 shell archive."
# Contents:  Imakefile Makefile.gcc Makefile.std README bright.c clip.c
#   compress.c copyright.h dither.c faces.c fill.c image.h
#   imagetypes.c imagetypes.h merge.c misc.c mit.cpyrght new.c
#   options.c options.h patchlevel path.c pbm.c pbm.h
# Wrapped by madd at world on Sat Nov 11 23:04:56 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Imakefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Imakefile\"
else
echo shar: Extracting \"Imakefile\" \(626 characters\)
sed "s/^X//" >Imakefile <<'END_OF_Imakefile'
X        DEFINES = -DSYSPATHFILE=\"/usr/lib/X11/xloadimage/xloadimagerc\"
X        DEPLIBS = $(DEPLIBS)
XLOCAL_LIBRARIES = $(XLIB)
X           SRCS = bright.c clip.c compress.c dither.c faces.c fill.c \
X		  imagetypes.c merge.c misc.c new.c options.c path.c \
X		  pbm.c reduce.c root.c send.c sunraster.c value.c \
X		  window.c xbitmap.c xloadimage.c zio.c zoom.c
X           OBJS = bright.o clip.o compress.o dither.o faces.o fill.o \
X		  imagetypes.o merge.o misc.o new.o options.o path.o \
X		  pbm.o reduce.o root.o send.o sunraster.o value.o \
X		  window.o xbitmap.o xloadimage.o zio.o zoom.o
X
XComplexProgramTarget(xloadimage)
END_OF_Imakefile
if test 626 -ne `wc -c <Imakefile`; then
    echo shar: \"Imakefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.gcc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.gcc\"
else
echo shar: Extracting \"Makefile.gcc\" \(613 characters\)
sed "s/^X//" >Makefile.gcc <<'END_OF_Makefile.gcc'
X# Makefile for xloadimage using GNU C compiler
X#
X# Copyright 1989 Jim Frost
X#
X# See file "copyright.h" for complete copyright information.
X
XCC= gcc
XCFLAGS= -O -fstrength-reduce -finline-functions -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X
XLIBS= -lX11
XOBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
X      merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o sen.o \
X      sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
X
Xxloadimage: $(OBJS)
X	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X
Xclean:
X	rm -f *.o *~ xloadimage
X
X.c.o: xloadimage.h
X	$(CC) -c $(CFLAGS) $*.c
END_OF_Makefile.gcc
if test 613 -ne `wc -c <Makefile.gcc`; then
    echo shar: \"Makefile.gcc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.std -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefilee.std\"
else
echo shar: Extracting \"Makefile.std\" \(580 characters\)
sed "s/^X//" >Makefile.std <<'END_OF_Makefile.std'
X# Makefile for xloadimage using standard C compiler
X#
X# Copyright 1989 Jim Frost
X#
X# See file "copyright.h" for complete copyright information.
X
XCC= cc
XCFLAGS= -O -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X
XLIBS= -lX11
XOBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
X      merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o send.o \
X      sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
X
Xxloadimage: $(OBJS)
X	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X
Xclean:
X	rm -f *.o *~ xloadimage
X
X.c.o: xloadimage.h
X	$(CC) -c $(CFLAGS) $*.c
END_OF_Makefile.std
if test 580 -ne `wc -c <Makefile.std`; then
    echo shar: \"Makefile.std\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(3805 characters\)
sed "s/^X//" >README <<'END_OF_README'
XXLOADIMAGE - X11 Image Loading Utility
X
XWHAT IS IT?
X
XThis utility will view several types of images under X11, or load
Ximages onto the root window.  The current version supports X11 Bitmap,
XPortable Bitmap, Faces Project, and Sun Rasterfile images.  More are
Xplanned.
X
XA variety of options are available to modify images prior to viewing.
XThese options include clipping, dithering, depth reduction, zoom
X(either X or Y axis independently or both at once),
Xbrightening/darkening, and image merging.  When applicable, these
Xoptions are done automatically (eg a color image to be displayed on a
Xmonochrome screen will be dithered automatically).
X
XIMPLEMENTATION
X
XMost functions are not particularly fast, and some functions use
Xsimple-minded algorithms deliberately over more advanced ones.  I
Xstressed portability over all and simplicity over performance.  I
Xbelieve the result is a usable, portable tool which should serve the
Xneeds of most users.
X
XThe source code is basically in two parts: image manipulation routines
Xand everything else.  The image manipulation routines should be
Xcompletely independent of X, thus allowing people to use them under
Xother graphical systems.  No guarantees here, but I tried.
X
XPerformance-oriented people will notice that when loading a color
Ximage, the colormap of the image is minimized (and all pixel values in
Xthe image changed), then the colormap is redone (and all pixel values
Xin the image changed again) before sending to X.  This could be
Xreduced to only one remapping of the image but I wanted to keep the
Ximage from X's grubby (greedy?) hands as long as possible, and the
Ximage merging function really wants the image to have a minimized
Xcolormap.
X
XCOMPILING
X
XThere are three ways to compile xloadimage, depending on what
Xenvironment you have.
X
XIf you are compiling under the X11R4 distribution, the apropriate
XImakefile is included and you should compile as with any other client.
XI haven't personally tested this, but if it's broken it'll be easy to
Xfix.
X
XIf you have gcc on your system, compile via "make -f Makefile.gcc".
XGcc should be used if it works because the strength-reduction and
Xinline-functions directives dramatically improve performance of some
Xoperations.
X
XNormal compilations can be done via "make -f Makefile.std".  This
Xinvokes the standard cc using the -O flag.
X
XINSTALLATION
X
XAfter compiling and installing xloadimage, I recommend linking or
Xsymlinking to the executable with the names "xview" and "xsetbg".  The
Xdefault behavior is slightly different when invoked with these
Xcommands (they're also easier to type).
X
XOWNERSHIP
X
XI used the MIT X Consortium copyright with all of these functions,
Xthereby allowing full freedom with the code so long as the copyright
Xnotices remain intact.  Free code can be good code.
X
XSUGGESTIONS AND BUG REPORTS
X
XSuggestions and bug reports should go to:
X
X	Jim Frost
X	madd at std.com
X	..uunet!world!madd
X
XPlease include the version number and sample image data if you are
Xreporting a bug.
X
XFunctions implementing new image types are welcomed; mail them to the
Xsame address and I'll do my best to distribute them.
X
XTHANKS
X
XSpecial thanks to the crew at the Boston University Graphics Lab for
Xtheir assistance and sample images, and to bzs at std.com for his simple
Xdithering algorithm (or what's left of it).
X
XHISTORY
X
XPatch 01 contained a new Makefile.std, Makefile.gcc, and Imakefile.
XIt contained a bug-fix to sendImageToX() which allowed bitmaps to be
Xsent from little-endian machines (eg VAX, 80386) correctly, and a fix
Xto xbitmapLoad() to allow correct loading of X10 bitmap images.  An
Xenhancement to imageInWindow() which allowed exiting from image
Xwindows by typing 'q' was submitted by Chris Tengi
X(tengi at idunno.princeton.edu) and was included.  The previously missing
Xfile 'patchlevel' was included.
END_OF_README
if test 3805 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bright.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bright.c\"
else
echo shar: Extracting \"bright.c\" \(1074 characters\)
sed "s/^X//" >bright.c <<'END_OF_bright.c'
X/* bright.c
X *
X * alter an image's brightness by a given percentage
X *
X * jim frost 10.10.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
Xvoid brighten(image, percent, verbose)
X     Image        *image;
X     int           percent;
X     unsigned int  verbose;
X{ int          a;
X  unsigned int newrgb;
X  float        fperc;
X
X  if (! RGBP(image)) /* we're AT&T */
X    return;
X
X  if (verbose) {
X    printf("  Brightening colormap by %d%%...", percent);
X    fflush(stdout);
X  }
X
X  fperc= (float)percent / 100.0;
X  for (a= 0; a < image->rgb.used; a++) {
X    newrgb= *(image->rgb.red + a) * fperc;
X    if (newrgb > 65535)
X      newrgb= 65535;
X    *(image->rgb.red + a)= newrgb;
X    newrgb= *(image->rgb.green + a) * fperc;
X    if (newrgb > 65535)
X      newrgb= 65535;
X    *(image->rgb.green + a)= newrgb;
X    newrgb= *(image->rgb.blue + a) * fperc;
X    if (newrgb > 65535)
X      newrgb= 65535;
X    *(image->rgb.blue + a)= newrgb;
X  }
X
X  if (verbose)
X    printf("done\n");
X}
END_OF_bright.c
if test 1074 -ne `wc -c <bright.c`; then
    echo shar: \"bright.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f clip.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"clip.c\"
else
echo shar: Extracting \"clip.c\" \(2801 characters\)
sed "s/^X//" >clip.c <<'END_OF_clip.c'
X/* clip.c:
X *
X * return a new image which is a clipped subsection of the old image
X *
X * jim frost 10.04.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
XImage *clip(simage, clipx, clipy, clipw, cliph, verbose)
X     Image        *simage;
X     unsigned int  clipx, clipy, clipw, cliph;
X     unsigned int  verbose;
X{ Image *image;
X  unsigned int  x, y;
X  unsigned int  slinelen, dlinelen;
X  unsigned int  start;
X  byte          startmask, smask, dmask;
X  byte         *sp, *sline, *dp, *dline;
X
X  goodImage(simage, "clip");
X
X  if (verbose) {
X    printf("  Clipping image...");
X    fflush(stdout);
X  }
X
X  /* sane-ify clip area with respect to image
X   */
X
X  if (clipx + clipw > simage->width)
X    clipw -= (simage->width - (clipx + clipw));
X  if (clipy + cliph > simage->height)
X    cliph -= (simage->height - (clipy + cliph));
X
X  switch (simage->type) {
X  case IBITMAP:
X
X    /* this could be sped up; i don't care
X     */
X
X    image= newBitImage(clipw, cliph);
X    for (x= 0; x < simage->rgb.used; x++) {
X      *(image->rgb.red + x)= *(simage->rgb.red + x);
X      *(image->rgb.green + x)= *(simage->rgb.green + x);
X      *(image->rgb.blue + x)= *(simage->rgb.blue + x);
X    }
X    slinelen= (simage->width / 8) + (simage->width % 8 ? 1 : 0);
X    dlinelen= (clipw / 8) + (clipw % 8 ? 1 : 0);
X    start= clipx / 8;
X    startmask= 0x80 >> (clipx % 8);
X    sline= simage->data + (slinelen * clipy);
X    dline= image->data;
X    dp= image->data;
X    for (y= 0; y < cliph; y++) {
X      sp= sline + start;
X      dp= dline;
X      smask= startmask;
X      dmask= 0x80;
X      for (x= 0; x < clipw; x++) {
X	if (*sp & smask)
X	  *dp |= dmask;
X	if (! (smask >>= 1)) {
X	  smask= 0x80;
X	  sp++;
X	}
X	if (! (dmask >>= 1)) {
X	  dmask= 0x80;
X	  dp++;
X	}
X      }
X      sline += slinelen;
X      dline += dlinelen;
X    }
X    break;
X
X  case IRGB:
X    image= newRGBImage(clipw, cliph, simage->depth);
X    for (x= 0; x < simage->rgb.used; x++) {
X      *(image->rgb.red + x)= *(simage->rgb.red + x);
X      *(image->rgb.green + x)= *(simage->rgb.green + x);
X      *(image->rgb.blue + x)= *(simage->rgb.blue + x);
X    }
X    image->rgb.used= simage->rgb.used;
X    slinelen= simage->width * simage->pixlen;
X    start= clipx * simage->pixlen;
X    sline= simage->data + (clipy * slinelen);
X    dp= image->data;
X    for (y= 0; y < cliph; y++) {
X      sp= sline + start;
X      for (x= 0; x < clipw; x++) {
X	valToMem(memToVal(sp, simage->pixlen), dp, simage->pixlen);
X	sp += simage->pixlen;
X	dp += simage->pixlen;
X      }
X      sline += slinelen;
X    }
X    break;
X  default:
X    printf("clip: Unsupported image type\n");
X    exit(1);
X  }
X  image->title= dupString(simage->title);
X  if (verbose)
X    printf("done\n");
X  return(image);
X}
END_OF_clip.c
if test 2801 -ne `wc -c <clip.c`; then
    echo shar: \"clip.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f compress.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"compress.c\"
else
echo shar: Extracting \"compress.c\" \(1815 characters\)
sed "s/^X//" >compress.c <<'END_OF_compress.c'
X/* compress.c:
X *
X * compress a colormap by removing unused RGB colors
X *
X * jim frost 10.05.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
Xvoid compress(image, verbose)
X     Image        *image;
X     unsigned int  verbose;
X{ Pixel        *index;
X  unsigned int *used;  
X  RGBMap        rgb;
X  byte         *pixptr;
X  unsigned int  a, x, y;
X  Pixel         color;
X
X  goodImage(image, "compress");
X  if (! RGBP(image)) /* we're AT&T */
X    return;
X
X  if (verbose) {
X    printf("  Compressing colormap...");
X    fflush(stdout);
X  }
X
X  newRGBMapData(&rgb, image->rgb.size);
X  index= (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
X  used= (unsigned int *)lmalloc(sizeof(unsigned int) * image->rgb.used);
X  for (x= 0; x < image->rgb.used; x++)
X    *(used + x)= 0;
X
X  pixptr= image->data;
X  for (y= 0; y < image->height; y++)
X    for (x= 0; x < image->width; x++) {
X      color= memToVal(pixptr, image->pixlen);
X      if (*(used + color) == 0) {
X	for (a= 0; a < rgb.used; a++)
X	  if ((*(rgb.red + a) == *(image->rgb.red + color)) &&
X	      (*(rgb.green + a) == *(image->rgb.green + color)) &&
X	      (*(rgb.blue + a) == *(image->rgb.blue + color)))
X	    break;
X	*(index + color)= a;
X	*(used + color)= 1;
X	if (a == rgb.used) {
X	  *(rgb.red + a)= *(image->rgb.red + color);
X	  *(rgb.green + a)= *(image->rgb.green + color);
X	  *(rgb.blue + a)= *(image->rgb.blue + color);
X	  rgb.used++;
X	}
X      }
X      valToMem(*(index + color), pixptr, image->pixlen);
X      pixptr += image->pixlen;
X    }
X
X  if (verbose)
X    if (rgb.used < image->rgb.used)
X      printf("%d unique colors of %d\n", rgb.used, image->rgb.used);
X    else
X      printf("no improvement\n");
X
X  freeRGBMapData(&(image->rgb));
X  image->rgb= rgb;
X}
END_OF_compress.c
if test 1815 -ne `wc -c <compress.c`; then
    echo shar: \"compress.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f copyright.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"copyright.h\"
else
echo shar: Extracting \"copyright.h\" \(1084 characters\)
sed "s/^X//" >copyright.h <<'END_OF_copyright.h'
X#ifndef _JIM_COPYRIGHT_
X/*
X * Copyright 1989 Jim Frost
X *
X * Permission to use, copy, modify, distribute, and sell this software
X * and its documentation for any purpose is hereby granted without fee,
X * provided that the above copyright notice appear in all copies and
X * that both that copyright notice and this permission notice appear
X * in supporting documentation.  The author makes no representations
X * about the suitability of this software for any purpose.  It is
X * provided "as is" without express or implied warranty.
X *
X * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
X * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
X * USE OR PERFORMANCE OF THIS SOFTWARE.
X */
X
Xstatic char *Copyright= "Copyright 1989 Jim Frost";
X#define _JIM_COPYRIGHT_
X#endif
END_OF_copyright.h
if test 1084 -ne `wc -c <copyright.h`; then
    echo shar: \"copyright.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dither.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dither.c\"
else
echo shar: Extracting \"dither.c\" \(3914 characters\)
sed "s/^X//" >dither.c <<'END_OF_dither.c'
X/* dither.c:
X *
X * routine for dithering a color image to monochrome based on color
X * intensity.  this is loosely based on an algorithm which barry shein
X * (bzs at std.com) used in his "xf" program.
X *
X * jim frost 07.10.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
X/* 4x4 arrays used for dithering, arranged by nybble
X */
X
X#define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
X#define GRAYSTEP ((unsigned long)(65536 * 3) / GRAYS)
X
Xstatic byte DitherBits[GRAYS][4] = {
X  0xf, 0xf, 0xf, 0xf,
X  0xe, 0xf, 0xf, 0xf,
X  0xe, 0xf, 0xb, 0xf,
X  0xa, 0xf, 0xb, 0xf,
X  0xa, 0xf, 0xa, 0xf,
X  0xa, 0xd, 0xa, 0xf,
X  0xa, 0xd, 0xa, 0x7,
X  0xa, 0x5, 0xa, 0x7,
X  0xa, 0x5, 0xa, 0x5,
X  0x8, 0x5, 0xa, 0x5,
X  0x8, 0x5, 0x2, 0x5,
X  0x0, 0x5, 0x2, 0x5,
X  0x0, 0x5, 0x0, 0x5,
X  0x0, 0x4, 0x0, 0x5,
X  0x0, 0x4, 0x0, 0x1,
X  0x0, 0x0, 0x0, 0x1,
X  0x0, 0x0, 0x0, 0x0
X};
X
X/* simple dithering algorithm, really optimized for the 4x4 array
X */
X
XImage *dither(cimage, verbose)
X     Image        *cimage;
X     unsigned int  verbose;
X{ Image         *image;
X  unsigned char *sp, *dp, *dp2; /* data pointers */
X  unsigned int   dindex;        /* index into dither array */
X  unsigned int   spl;           /* source pixel length in bytes */
X  unsigned int   dll;           /* destination line length in bytes */
X  Pixel          color;         /* pixel color */
X  unsigned int  *index;         /* index into dither array for a given pixel */
X  unsigned int   a, x, y;       /* random counters */
X
X  goodImage(cimage, "dither");
X  if (! RGBP(cimage))
X    return(NULL);
X
X  /* set up
X   */
X
X  if (verbose) {
X    printf("  Dithering image...");
X    fflush(stdout);
X  }
X  image= newBitImage(cimage->width * 4, cimage->height * 4);
X  if (cimage->title) {
X    image->title= (char *)malloc(strlen(cimage->title) + 12);
X    sprintf(image->title, "%s (dithered)", cimage->title);
X  }
X  spl= cimage->pixlen;
X  dll= (image->width / 8) + (image->width % 8 ? 1 : 0);
X
X  /* if the number of possible pixels isn't very large, build an array
X   * which we index by the pixel value to find the dither array index
X   * by color brightness.  we do this in advance so we don't have to do
X   * it for each pixel.  things will break if a pixel value is greater
X   * than (1 << depth), which is bogus anyway.  this calculation is done
X   * on a per-pixel basis if the colormap is too big.
X   */
X
X  if (cimage->depth <= 16) {
X    index= (unsigned int *)malloc(sizeof(unsigned int) * cimage->rgb.used);
X    for (x= 0; x < cimage->rgb.used; x++)
X      *(index + x)=
X	((unsigned long)(*(cimage->rgb.red + x)) +
X	 *(cimage->rgb.green + x) +
X	 *(cimage->rgb.blue + x)) / GRAYSTEP;
X  }
X  else
X    index= NULL;
X
X  /* dither each pixel
X   */
X
X  sp= cimage->data;
X  dp= image->data;
X  for (y= 0; y < cimage->height; y++) {
X    for (x= 0; x < cimage->width; x++) {
X      dp2= dp + (x >> 1);
X      color= memToVal(sp, spl);
X      if (index)
X	dindex= *(index + color);
X      else
X	dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
X		 *(cimage->rgb.green + color) +
X		 *(cimage->rgb.blue + color)) / GRAYSTEP;
X
X      /* loop for the four Y bits in the dither pattern, putting all
X       * four X bits in at once.  if you think this would be hard to
X       * change to be an NxN dithering array, you're right, since we're
X       * banking on the fact that we need only shift the mask based on
X       * whether x is odd or not.  an 8x8 array wouldn't even need that,
X       * but blowing an image up by 64x is probably not a feature.
X       */
X
X      if (x & 1)
X	for (a= 0; a < 4; a++, dp2 += dll)
X	  *dp2 |= DitherBits[dindex][a];
X      else
X	for (a= 0; a < 4; a++, dp2 += dll)
X	  *dp2 |= (DitherBits[dindex][a] << 4);
X      sp += spl;
X    }
X    dp += (dll << 2); /* (dll * 4) but I like shifts */
X  }
X  if (verbose)
X    printf("done\n");
X  return(image);
X}
END_OF_dither.c
if test 3914 -ne `wc -c <dither.c`; then
    echo shar: \"dither.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f faces.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"faces.c\"
else
echo shar: Extracting \"faces.c\" \(3908 characters\)
sed "s/^X//" >faces.c <<'END_OF_faces.c'
X/* faces.c:
X *
X * faces format image loader
X *
X * jim frost 07.06.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "xloadimage.h"
X
Xstatic short        HexTable[256];  /* conversion value */
Xstatic unsigned int Initialized= 0; /* easier to fill in at run time */
X
X#define HEXIGNORE -1
X#define HEXBAD    -2
X
X/* build a hex digit value table with the bits inverted
X */
X
Xstatic void initHexTable()
X{ int a;
X
X  for (a= 0; a < 256; a++)
X    HexTable[a]= HEXBAD;
X
X  HexTable['0']= 0x0;
X  HexTable['1']= 0x1;
X  HexTable['2']= 0x2;
X  HexTable['3']= 0x3;
X  HexTable['4']= 0x4;
X  HexTable['5']= 0x5;
X  HexTable['6']= 0x6;
X  HexTable['7']= 0x7;
X  HexTable['8']= 0x8;
X  HexTable['9']= 0x9;
X  HexTable['A']= 0xa; HexTable['a']= HexTable['A'];
X  HexTable['B']= 0xb; HexTable['b']= HexTable['B'];
X  HexTable['C']= 0xc; HexTable['c']= HexTable['C'];
X  HexTable['D']= 0xd; HexTable['d']= HexTable['D'];
X  HexTable['E']= 0xe; HexTable['e']= HexTable['E'];
X  HexTable['F']= 0xf; HexTable['f']= HexTable['F'];
X  HexTable['\r']= HEXIGNORE;
X  HexTable['\n']= HEXIGNORE;
X  HexTable['\t']= HEXIGNORE;
X  HexTable[' ']= HEXIGNORE;
X
X  Initialized = 1;
X}
X
X/* read a hex value and return its value
X */
X
Xstatic int nextInt(zf, len)
X     ZFILE        *zf;
X     unsigned int  len;
X{ int c;
X  int value= 0;
X  int count;
X
X  len <<= 1;
X  for (count= 0; count < len;) {
X    c= zgetc(zf);
X    if (c == EOF)
X      return(-1);
X    else {
X      c= HexTable[c & 0xff];
X      switch(c) {
X      case HEXIGNORE:
X	break;
X      case HEXBAD:
X	return(-1);
X      default:
X	value= (value << 4) + c;
X	count++;
X      }
X    }
X  }
X  return(value);
X}
X
XImage *facesLoad(fullname, name, verbose)
X     char *fullname, *name;
X{ ZFILE        *zf;
X  Image        *image;
X  char          fname[BUFSIZ];
X  char          lname[BUFSIZ];
X  char          buf[BUFSIZ];
X  unsigned int  w, h, d, iw, ih, id;
X  unsigned int  x, y;
X  int           value;
X  unsigned int  linelen;
X  byte         *lineptr, *dataptr;
X
X  if (!Initialized)
X    initHexTable();
X
X  if (! (zf= zopen(fullname)))
X    return(NULL);
X
X  w= h= d= 0;
X  fname[0]= lname[0]= '\0';
X  while (zgets(buf, BUFSIZ - 1, zf)) {
X    if (! strcmp(buf, "\n"))
X      break;
X    if (!strncmp(buf, "FirstName:", 10))
X      strcpy(fname, buf + 11);
X    else if (!strncmp(buf, "LastName:", 9))
X      strcpy(lname, buf + 10);
X    else if (!strncmp(buf, "Image:", 6)) {
X      if (sscanf(buf + 7, "%d%d%d", &iw, &ih, &id) != 3) {
X	printf("%s: Bad Faces Project image\n", fullname);
X	exit(1);
X      }
X    }
X    else if (!strncmp(buf, "PicData:", 8)) {
X      if (sscanf(buf + 9, "%d%d%d", &w, &h, &d) != 3) {
X	printf("%s: Bad Faces Project image\n", fullname);
X	exit(1);
X      }
X    }
X  }
X  if (!w || !h || !d) {
X    zclose(zf);
X    return(NULL);
X  }
X
X  if (verbose)
X    printf("%s is a  %dx%d %d-bit grayscale Faces Project image\n",
X	   name, w, h, d);
X
X  image= newRGBImage(w, h, d);
X  fname[strlen(fname) - 1]= ' ';
X  strcat(fname, lname);
X  fname[strlen(fname) - 1]= '\0';
X  image->title= dupString(fname);
X
X  /* image is greyscale; build RGB map accordingly
X   */
X
X  for (x= 0; x < image->rgb.size; x++)
X    *(image->rgb.red + x)= *(image->rgb.green + x)= *(image->rgb.blue + x)=
X      (65536 / image->rgb.size) * x;
X  image->rgb.used= image->rgb.size;
X
X  /* read in image data
X   */
X
X  linelen= w * image->pixlen;
X  lineptr= image->data + (h * linelen);
X  for (y= 0; y < h; y++) {
X    lineptr -= linelen;
X    dataptr= lineptr;
X    for (x= 0; x < w; x++) {
X      if ((value= nextInt(zf, image->pixlen)) < 0) {
X	printf("%s: Bad Faces Project image data\n", fullname);
X	exit(1);
X      }
X      *(dataptr++)= value;
X    }
X  }
X  zclose(zf);
X  return(image);
X}
X
Xint facesIdent(fullname, name)
X     char *fullname, *name;
X{ Image *image;
X
X  if (image= facesLoad(name, fullname, 1)) {
X    freeImage(image);
X    return(1);
X  }
X  return(0);
X}
END_OF_faces.c
if test 3908 -ne `wc -c <faces.c`; then
    echo shar: \"faces.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fill.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fill.c\"
else
echo shar: Extracting \"fill.c\" \(1500 characters\)
sed "s/^X//" >fill.c <<'END_OF_fill.c'
X/* fill.c:
X *
X * fill an image area with a particular pixel value
X *
X * jim frost 10.02.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
Xvoid fill(image, fx, fy, fw, fh, pixval)
X     Image        *image;
X     unsigned int  fx, fy, fw, fh;
X     Pixel         pixval;
X{ unsigned int  x, y;
X  unsigned int  linelen, start;
X  byte         *lineptr, *pixptr;
X  byte          startmask, mask;
X
X  goodImage(image);
X  switch(image->type) {
X  case IBITMAP:
X
X    /* this could be made a lot faster
X     */
X
X    linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
X    lineptr= image->data + (linelen * fy);
X    start= (fx / 8) + (fx % 8 ? 1 : 0);
X    startmask= 0x80 >> (fx % 8);
X    for (y= fy; y < fy + fh; y++) {
X      mask= startmask;
X      pixptr= lineptr + start;
X      for (x= fx; x < fw; x++) {
X	if (pixval)
X	  *pixptr |= mask;
X	else
X	  *pixptr &= ~mask;
X	if (mask >>= 1) {
X	  mask= 0x80;
X	  pixptr++;
X	}
X      }
X      lineptr += linelen;
X    }
X    break;
X
X  case IRGB:
X    linelen= image->width * image->pixlen;
X    start= image->pixlen * fx;
X    lineptr= image->data + (linelen * fy);
X    for (y= fy; y < fy + fh; y++) {
X      pixptr= lineptr + start;
X      for (x= fx; x < fw; x++) {
X	valToMem(pixval, pixptr, image->pixlen);
X	pixptr += image->pixlen;
X      }
X      lineptr += linelen;
X    }
X    break;
X  default:
X    printf("fill: Unsupported image type (ignored)\n");
X    return;
X  }
X}
END_OF_fill.c
if test 1500 -ne `wc -c <fill.c`; then
    echo shar: \"fill.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f image.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"image.h\"
else
echo shar: Extracting \"image.h\" \(2063 characters\)
sed "s/^X//" >image.h <<'END_OF_image.h'
X/* image.h:
X *
X * portable image type declarations
X *
X * jim frost 10.02.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include <stdio.h>
X
Xtypedef unsigned long  Pixel;     /* what X thinks a pixel is */
Xtypedef unsigned short Intensity; /* what X thinks an RGB intensity is */
Xtypedef unsigned char  byte;      /* byte type */
X
Xtypedef struct {
X  unsigned int  type;
X  FILE         *stream;
X} ZFILE;
X
X#define ZSTANDARD 0
X#define ZPIPE     1
X
Xtypedef struct rgbmap {
X  unsigned int  size;  /* size of RGB map */
X  unsigned int  used;  /* number of colors used in RGB map */
X  Intensity    *red;   /* color values in X style */
X  Intensity    *green;
X  Intensity    *blue;
X} RGBMap;
X
X/* image structure
X */
X
Xtypedef struct {
X  char         *title;  /* name of image */
X  unsigned int  type;   /* type of image */
X  RGBMap        rgb;    /* RGB map of image if IRGB type */
X  unsigned int  width;  /* width of image in pixels */
X  unsigned int  height; /* height of image in pixels */
X  unsigned int  depth;  /* depth of image in bits if IRGB type */
X  unsigned int  pixlen; /* length of pixel if IRGB type */
X  byte         *data;   /* data rounded to full byte for each row */
X} Image;
X
X#define IBITMAP 0 /* image is a bitmap */
X#define IRGB    1 /* image is RGB */
X
X#define BITMAPP(IMAGE) ((IMAGE)->type == IBITMAP)
X#define RGBP(IMAGE)    ((IMAGE)->type == IRGB)
X
X/* function declarations
X */
X
XImage *clip(); /* clip.c */
X
XImage *dither(); /* dither.c */
X
Xvoid fold(); /* fold.c */
X
XImage *loadImage(); /* imagetypes.c */
Xvoid   identifyImage();
Xvoid   goodImage();
X
XImage *mergeImages(); /* merge.c */
X
Xchar  *dupString(); /* new.c */
XImage *newBitImage();
XImage *newRGBImage();
Xvoid   freeImage();
Xvoid   freeImageData();
Xvoid   newRGBMapData();
Xvoid   freeRGBMapData();
Xbyte  *lcalloc();
Xbyte  *lmalloc();
Xvoid   lfree();
X
Xvoid reduceRGBMap(); /* reduce.c */
Xvoid reduce();
X
Xunsigned long memToVal(); /* value.c */
Xvoid          valToMem();
X
XImage *zoom(); /* zoom.c */
END_OF_image.h
if test 2063 -ne `wc -c <image.h`; then
    echo shar: \"image.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f imagetypes.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"imagetypes.c\"
else
echo shar: Extracting \"imagetypes.c\" \(1812 characters\)
sed "s/^X//" >imagetypes.c <<'END_OF_imagetypes.c'
X/* imagetypes.c:
X *
X * this contains things which reference the global ImageTypes array
X *
X * jim frost 09.27.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X#include "imagetypes.h"
X#include <errno.h>
X
Xextern int errno;
X
X/* load a named image
X */
X
XImage *loadImage(name, verbose)
X     char         *name;
X     unsigned int  verbose;
X{ char   fullname[BUFSIZ];
X  Image *image;
X  int    a;
X
X  if (findImage(name, fullname) < 0) {
X    if (errno == ENOENT)
X      printf("%s: image not found\n", name);
X    else
X      perror(fullname);
X    return(NULL);
X  }
X  for (a= 0; ImageTypes[a].loader; a++)
X    if (image= ImageTypes[a].loader(fullname, name, verbose))
X      return(image);
X  printf("%s: unknown or unsupported image type\n", fullname);
X  return(NULL);
X}
X
X/* identify what kind of image a named image is
X */
X
Xvoid identifyImage(name)
X     char *name;
X{ char fullname[BUFSIZ];
X  int  a;
X
X  if (findImage(name, fullname) < 0) {
X    if (errno == ENOENT)
X      printf("%s: image not found\n", name);
X    else
X      perror(fullname);
X    return;
X  }
X  for (a= 0; ImageTypes[a].identifier; a++)
X    if (ImageTypes[a].identifier(fullname, name))
X      return;
X  printf("%s: unknown or unsupported image type\n", fullname);
X}
X
X/* tell user what image types we support
X */
X
Xvoid supportedImageTypes()
X{ int a;
X
X  printf("Image types supported:\n");
X  for (a= 0; ImageTypes[a].name; a++)
X    printf("  %s\n", ImageTypes[a].name);
X}
X
Xvoid goodImage(image, func)
X     Image *image;
X     char  *func;
X{
X  if (!image) {
X    printf("%s: nil image\n", func);
X    exit(0);
X  }
X  switch (image->type) {
X  case IBITMAP:
X  case IRGB:
X    break;
X  default:
X    printf("%s: bad destination image\n", func);
X    exit(0);
X  }
X}
END_OF_imagetypes.c
if test 1812 -ne `wc -c <imagetypes.c`; then
    echo shar: \"imagetypes.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f imagetypes.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"imagetypes.h\"
else
echo shar: Extracting \"imagetypes.h\" \(881 characters\)
sed "s/^X//" >imagetypes.h <<'END_OF_imagetypes.h'
X/* imagetypes.h:
X *
X * supported image types and the imagetypes array declaration.  when you
X * add a new image type, only the makefile and this header need to be
X * changed.
X *
X * jim frost 10.15.89
X */
X
XImage *facesLoad();
XImage *pbmLoad();
XImage *sunRasterLoad();
XImage *xbitmapLoad();
XImage *xpixmapLoad();
X
Xint facesIdent();
Xint pbmIdent();
Xint sunRasterIdent();
Xint xbitmapIdent();
Xint xpixmapIdent();
X
Xstruct {
X  int    (*identifier)(); /* print out image info if this kind of image */
X  Image *(*loader)();     /* load image if this kind of image */
X  char  *name;            /* name of this image format */
X} ImageTypes[] = {
X  sunRasterIdent, sunRasterLoad, "Sun Rasterfile",
X  pbmIdent,       pbmLoad,       "Portable Bit Map (PBM)",
X  facesIdent,     facesLoad,     "Faces Project",
X  xbitmapIdent,   xbitmapLoad,   "X Bitmap",
X  NULL,           NULL,          NULL
X};
END_OF_imagetypes.h
if test 881 -ne `wc -c <imagetypes.h`; then
    echo shar: \"imagetypes.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f merge.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"merge.c\"
else
echo shar: Extracting \"merge.c\" \(8497 characters\)
sed "s/^X//" >merge.c <<'END_OF_merge.c'
X/* merge.c:
X *
X * this merges two images, folding and reducing colormaps as necessary.
X *
X * jim frost 09.27.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
Xstatic void mergeColors(dest, src, verbose)
X     Image        *dest, *src;
X     unsigned int  verbose;
X{ RGBMap           newcolors;
X  unsigned int     a, b;
X
X  if (dest->rgb.used + src->rgb.used > dest->rgb.size) {
X    newRGBMapData(&newcolors, dest->rgb.used + src->rgb.used);
X    newcolors.used= newcolors.size;
X    for (a= 0, b= 0; a < dest->rgb.used; a++, b++) {
X      *(newcolors.red + b)= *(dest->rgb.red + a);
X      *(newcolors.green + b)= *(dest->rgb.green + a);
X      *(newcolors.blue + b)= *(dest->rgb.blue + a);
X    }
X    for (b= 0; a < src->rgb.used; a++, b++) {
X      *(newcolors.red + b)= *(src->rgb.red + a);
X      *(newcolors.green + b)= *(src->rgb.green + a);
X      *(newcolors.blue + b)= *(src->rgb.blue + a);
X    }
X
X    reduceRGBMap(&newcolors, dest->rgb.size, verbose);
X    dest->rgb.used= dest->rgb.size;
X    
X    for (a= 0; a < dest->rgb.used; a++) {             /* put new colors into */
X      *(dest->rgb.red + a)= *(newcolors.red + a);     /* old colormaps */
X      *(dest->rgb.green + a)= *(newcolors.green + a);
X      *(dest->rgb.blue + a)= *(newcolors.blue + a);
X    }
X    for (a= 0; a < src->rgb.used; a++) {
X      *(src->rgb.red + a)= *(newcolors.red + a + dest->rgb.used);
X      *(src->rgb.green + a)= *(newcolors.green + a + dest->rgb.used);
X      *(src->rgb.blue + a)= *(newcolors.blue + a + dest->rgb.used);
X    }
X    freeRGBMapData(&newcolors);
X  }
X  else
X    for (a= 0; a < src->rgb.used; a++, (dest->rgb.used)++) {
X      *(dest->rgb.red + dest->rgb.used)= *(src->rgb.red + a);
X      *(dest->rgb.green + dest->rgb.used)= *(src->rgb.green + a);
X      *(dest->rgb.blue + dest->rgb.used)= *(src->rgb.blue + a);
X    }
X}
X
Xstatic void bitmapToBitmap(src, dest, atx, aty, clipw, cliph, verbose)
X     Image        *src, *dest;
X     unsigned int  atx, aty, clipw, cliph;
X     unsigned int  verbose;
X{ unsigned int  dithered;
X  unsigned int  destlinelen, srclinelen;
X  unsigned int  deststart;
X  unsigned int  flip;
X  unsigned int  x, y;
X  byte         *destline, *srcline;
X  byte          deststartmask;
X  byte          destmask, srcmask;
X  byte         *destpixel, *srcpixel;
X
X  if (verbose) {
X    printf("  Merging bitmap image onto bitmap image...");
X    fflush(stdout);
X  }
X
X  if (RGBP(src)) { /* dither the RGB image to mono */
X    dithered= 1;
X    src= dither(src, verbose);
X  }
X  else
X    dithered= 0;
X
X  destlinelen= (dest->width / 8) + (dest->width % 8 ? 1 : 0);
X  srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
X  destline= dest->data + (aty * destlinelen);
X  srcline= src->data;
X  deststart= atx / 8;
X  deststartmask= 0x80 >> (atx % 8);
X  flip= ((*dest->rgb.red == *(src->rgb.red + 1)) &&
X	 (*dest->rgb.green == *(src->rgb.green + 1)) &&
X	 (*dest->rgb.blue == *(src->rgb.blue + 1)));
X  for (y= 0; y < cliph; y++) {
X    destpixel= destline + deststart;
X    srcpixel= srcline;
X    destmask= deststartmask;
X    srcmask= 0x80;
X    for (x= 0; x < clipw; x++) {
X      if (flip)
X	if (*srcpixel & srcmask)
X	  *destpixel &= ~destmask;
X	else
X	  *destpixel |= destmask;
X      else
X	if (*srcpixel & srcmask)
X	  *destpixel |= destmask;
X	else
X	  *destpixel &= ~destmask;
X      destmask >>= 1;
X      srcmask >>= 1;
X      if (destmask == 0) {
X	destmask= 0x80;
X	destpixel++;
X      }
X      if (srcmask == 0) {
X	srcmask= 0x80;
X	srcpixel++;
X      }
X    }
X    destline += destlinelen;
X    srcline += srclinelen;
X  }
X  if (dithered)
X    freeImage(src);
X
X  if (verbose)
X    printf("done\n");
X}
X
Xstatic void bitmapToRGB(src, dest, atx, aty, clipw, cliph, verbose)
X     Image        *src, *dest;
X     unsigned int  atx, aty, clipw, cliph;
X     unsigned int  verbose;
X{ unsigned int  bg, fg;
X  unsigned int  destlinelen, srclinelen;
X  unsigned int  deststart;
X  unsigned int  x, y;
X  byte         *destline, *srcline;
X  byte         *destpixel, *srcpixel;
X  byte          srcstartmask, srcmask;
X
X  if (verbose) {
X    printf("  Merging bitmap image onto RGB image...");
X    fflush(stdout);
X  }
X
X  /* get fg and bg colors from dest image
X   */
X  
X  fg= bg= 0;
X  for (x= 0; x < dest->rgb.used; x++)
X    if ((*(dest->rgb.red + x) == *src->rgb.red) &&
X	(*(dest->rgb.green + x) == *src->rgb.green) &&
X	(*(dest->rgb.blue + x) == *src->rgb.blue)) {
X      bg= x;
X      break;
X    }
X  if (x == dest->rgb.used)
X    printf("merge: warning: can't find background color in dest image\n");
X  for (x= 0; x < dest->rgb.used; x++)
X    if ((*(dest->rgb.red + x) == *(src->rgb.red + 1)) &&
X	(*(dest->rgb.green + x) == *(src->rgb.green + 1)) &&
X	(*(dest->rgb.blue + x) == *(src->rgb.blue + 1))) {
X      fg= x;
X      break;
X    }
X  if (x == dest->rgb.used)
X    printf("merge: warning: can't find foreground color in dest image\n");
X  
X  /* merge 'em
X   */
X
X  destlinelen= dest->width * dest->pixlen;
X  srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
X  destline= dest->data + (aty * destlinelen);
X  srcline= src->data;
X  deststart= atx * dest->pixlen;
X
X  for (y= 0; y < cliph; y++) {
X    destpixel= destline + deststart;
X    srcpixel= srcline;
X    srcmask= 0x80;
X    for (x= 0; x < clipw; x++) {
X      valToMem((*srcpixel & srcmask ? fg : bg), destpixel, dest->pixlen);
X      destpixel += dest->pixlen;
X      srcmask >>= 1;
X      if (srcmask == 0) {
X	srcpixel++;
X	srcmask= 0x80;
X      }
X    }
X    destline += destlinelen;
X    srcline += srclinelen;
X  }
X
X  if (verbose)
X    printf("done\n");
X}
X
Xstatic void RGBToRGB(src, dest, atx, aty, clipw, cliph, verbose)
X     Image        *src, *dest;
X     unsigned int  atx, aty, clipw, cliph;
X     unsigned int  verbose;
X{ unsigned int  destlinelen, srclinelen;
X  unsigned int  deststart;
X  unsigned int  x, y;
X  Pixel        *index;
X  byte         *destline, *srcline;
X  byte         *destpixel, *srcpixel;
X
X  if (verbose) {
X    printf("  Merging RGB images...");
X    fflush(stdout);
X  }
X
X  /* build src->dest pixel mapping
X   */
X  
X  index= (Pixel *)lmalloc(sizeof(Pixel) * src->rgb.used);
X  for (x= 0; x < src->rgb.used; x++) {
X    for (y= 0; y < dest->rgb.used; y++)
X      if ((*(dest->rgb.red + y) == *(src->rgb.red + x)) &&
X	  (*(dest->rgb.red + y) == *(src->rgb.red + x)) &&
X	  (*(dest->rgb.red + y) == *(src->rgb.red + x))) {
X	*(index + x)= y;
X	break;
X      }
X    if (y == dest->rgb.used)
X      printf("merge: warning: Can't map source pixel %d to destination\n",
X	     x);
X  }
X
X  destlinelen= dest->width * dest->pixlen;
X  srclinelen= src->width * src->pixlen;
X  deststart= atx * dest->pixlen;
X  destline= dest->data + (aty * destlinelen);
X  srcline= src->data;
X
X  for (y= 0; y < cliph; y++) {
X    destpixel= destline + deststart;
X    srcpixel= srcline;
X    for (x= 0; x < clipw; x++) {
X      valToMem(*(index + memToVal(srcpixel, src->pixlen)),
X	       destpixel, dest->pixlen);
X      destpixel += dest->pixlen;
X      srcpixel += src->pixlen;
X    }
X    destline += destlinelen;
X    srcline += srclinelen;
X  }
X  lfree(index);
X
X  if (verbose)
X    printf("done\n");
X}
X
X/* put src image on dest image (and clip while we're at it).  the bitmap
X * to bitmap merge could be sped up by a factor of four for the general
X * case and eight to thirty-two for specific cases.  i'm for simplicity,
X * though.
X */
X
Xvoid merge(dest, src, atx, aty, verbose)
X     Image        *dest;
X     Image        *src;
X     int           atx, aty;
X     unsigned int  verbose;
X{ unsigned int clipw, cliph;
X
X  goodImage(dest, "merge");
X  goodImage(src, "merge");
X
X  /* adjust clipping of src to fit within dest
X   */
X
X  clipw= src->width;
X  cliph= src->height;
X  if ((atx >= dest->width) || (aty >= dest->height)) /* not on dest, ignore */
X    return;
X  if (atx < 0) {
X    clipw += atx;
X    atx= 0;
X  }
X  if (aty < 0) {
X    cliph += aty;
X    aty= 0;
X  }
X  if (atx + clipw > dest->width)
X    clipw -= (dest->width - (atx + clipw));
X  if (aty + cliph > dest->height)
X    cliph -= (dest->width - (aty + cliph));
X
X  if (BITMAPP(dest) && (BITMAPP(src) || RGBP(src)))
X    bitmapToBitmap(src, dest, atx, aty, clipw, cliph, verbose);
X  else {
X    mergeColors(dest, src, verbose);
X    if (RGBP(dest) && BITMAPP(src))
X      bitmapToRGB(src, dest, atx, aty, clipw, cliph, verbose);
X    else if (RGBP(dest) && RGBP(src))
X      RGBToRGB(src, dest, atx, aty, clipw, cliph, verbose);
X    else {
X      printf("merge: Can't merge these two types of images (sorry)\n");
X      exit(1);
X    }
X  }
X  compress(dest, verbose);
X}
END_OF_merge.c
if test 8497 -ne `wc -c <merge.c`; then
    echo shar: \"merge.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f misc.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"misc.c\"
else
echo shar: Extracting \"misc.c\" \(5020 characters\)
sed "s/^X//" >misc.c <<'END_OF_misc.c'
X/* misc.c:
X *
X * miscellaneous funcs
X *
X * jim frost 10.05.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "xloadimage.h"
X
Xvoid usage(name)
X     char *name;
X{
X  printf("Usage: %s [global options] {[image options] image_name ...}\n",
X	 tail(name));
X  printf("Global options:\n");
X  printf("  -onroot               - load image onto root window\n");
X  printf("  -border colorname     - border image with this color\n");
X  printf("  -display dispname     - destination display\n");
X  printf("  -geometry WxH+X+Y     - destination size and location\n");
X  printf("  -help                 - print this help message\n");
X  printf("  -identify             - identify given images\n");
X  printf("  -list                 - list images in path\n");
X  printf("  -install              - explicitly install colormap\n");
X  printf("  -path                 - show image path for loading\n");
X  printf("  -quiet                - silence is golden\n");
X  printf("  -supported            - show supported image types\n");
X  printf("  -verbose              - whistle while you work\n");
X  printf("  -view                 - view image in a window\n");
X  printf("Image_options:\n");
X  printf("  -at X,Y               - load image at location\n");
X  printf("  -background colorname - background color for bitmap images\n");
X  printf("  -brighten percentage  - specify brightness multiplier\n");
X  printf("  -center               - center image\n");
X  printf("  -colors number        - specify maximum number of RGB colors\n");
X  printf("  -clip X,Y,W,H         - use clipped portion of image\n");
X  printf("  -dither               - dither color image to bitmap image\n");
X  printf("  -foreground colorname - foreground color for bitmap images\n");
X  printf("  -name name            - force next argument to be image name\n");
X  printf("  -xzoom percentage     - zoom the X axis by a percentage\n");
X  printf("  -yzoom percentage     - zoom the Y axis by a percentage\n");
X  printf("  -zoom percentage      - zoom the image by a percentage\n");
X  exit(1);
X}
X
Xchar *tail(path)
X     char *path;
X{ int   s;
X  char *t;
X
X  t= path;
X  for (s= 0; *(path + s) != '\0'; s++)
X    if (*(path + s) == '/')
X      t= path + s + 1;
X  return(t);
X}
X
XImage *processImage(disp, scrn, image, options, verbose)
X     Display      *disp;
X     int           scrn;
X     Image        *image;
X     ImageOptions *options;
X     unsigned int  verbose;
X{ Image        *tmpimage;
X  XColor        xcolor;
X  unsigned int  compressed= 0;
X
X  goodImage(image);
X
X  /* clip the image if requested
X   */
X
X  if ((options->clipx != 0) || (options->clipy != 0) ||
X      (options->clipw != 0) || (options->cliph != 0)) {
X    if (!options->clipw)
X      options->clipw= image->width;
X    if (!options->cliph)
X      options->cliph= image->height;
X    tmpimage= clip(image, options->clipx, options->clipy, options->clipw,
X		   options->cliph, verbose);
X    freeImage(image);
X    image= tmpimage;
X  }
X
X  if (options->xzoom || options->yzoom) { /* zoom image */
X    if (!options->colors && RGBP(image) &&             /* if the image is to */
X	(!options->xzoom && (options->yzoom > 100)) || /* be blown up, */
X	(!options->yzoom && (options->xzoom > 100)) || /* compress before */
X	(options->xzoom + options->yzoom > 200)) {     /* doing it */
X      compress(image, verbose);
X      compressed= 1;
X    }
X    tmpimage= zoom(image, options->xzoom, options->yzoom, verbose);
X    freeImage(image);
X    image= tmpimage;
X  }
X
X  if (options->bright) /* alter image brightness */
X    brighten(image, options->bright, verbose);
X
X  /* forcibly reduce colormap
X   */
X
X  if (options->colors && RGBP(image) && (options->colors < image->rgb.used)) {
X    reduce(image, options->colors, verbose);
X    image->rgb.size= options->colors; /* lie */
X    compressed= 1;
X  }
X
X  if (options->dither && (image->depth > 1)) { /* image is to be dithered */
X    tmpimage= dither(image, verbose);
X    freeImage(image);
X    image= tmpimage;
X    options->clipx *= 4;      /* image was blown up by 4 */
X    options->clipy *= 4;
X    options->clipw *= 4;
X    options->cliph *= 4;
X  }
X  else if (!compressed)       /* make sure colormap is minimized */
X    compress(image, verbose);
X
X  /* set foreground and background colors of mono image
X   */
X
X  xcolor.flags= DoRed | DoGreen | DoBlue;
X  if ((image->depth == 1) && options->fg) {
X    XParseColor(disp, DefaultColormap(disp, scrn), options->fg, &xcolor);
X    *(image->rgb.red + 1)= xcolor.red;
X    *(image->rgb.green + 1)= xcolor.green;
X    *(image->rgb.blue + 1)= xcolor.blue;
X  }
X  if ((image->depth == 1) && options->bg) {
X    XParseColor(disp, DefaultColormap(disp, scrn), options->bg, &xcolor);
X    *image->rgb.red= xcolor.red;
X    *image->rgb.green= xcolor.green;
X    *image->rgb.blue= xcolor.blue;
X  }
X  return(image);
X}
X
X/* this gets called on an I/O error; it really assumes that a KillClient
X * was issued.
X */
X
Xint ioErrorHandler(disp)
X     Display *disp;
X{
X  exit(0);
X}
END_OF_misc.c
if test 5020 -ne `wc -c <misc.c`; then
    echo shar: \"misc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mit.cpyrght -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mit.cpyrght\"
else
echo shar: Extracting \"mit.cpyrght\" \(1292 characters\)
sed "s/^X//" >mit.cpyrght <<'END_OF_mit.cpyrght'
X#ifndef _MIT_COPYRIGHT_
X/*
X * Copyright 1989 Massachusetts Institute of Technology
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of M.I.T. not be used in advertising or
X * publicity pertaining to distribution of the software without specific,
X * written prior permission.  M.I.T. makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X *
X * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
X * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
X * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
X * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X */
X
Xstatic char *MitCopyright=
X  "Copyright 1989 Massachusetts Institute of Technology";
X#define _MIT_COPYRIGHT_
X#endif
END_OF_mit.cpyrght
if test 1292 -ne `wc -c <mit.cpyrght`; then
    echo shar: \"mit.cpyrght\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f new.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"new.c\"
else
echo shar: Extracting \"new.c\" \(2593 characters\)
sed "s/^X//" >new.c <<'END_OF_new.c'
X/* new.c:
X *
X * functions to allocate and deallocate structures and structure data
X *
X * jim frost 09.29.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
Xchar *dupString(s)
X     char *s;
X{ char *d;
X
X  if (!s)
X    return(NULL);
X  d= (char *)lmalloc(strlen(s) + 1);
X  strcpy(d, s);
X  return(d);
X}
X
Xvoid newRGBMapData(rgb, size)
X     RGBMap       *rgb;
X     unsigned int  size;
X{
X  rgb->used= 0;
X  rgb->size= size;
X  rgb->red= (Intensity *)lmalloc(sizeof(Intensity) * size);
X  rgb->green= (Intensity *)lmalloc(sizeof(Intensity) * size);
X  rgb->blue= (Intensity *)lmalloc(sizeof(Intensity) * size);
X}
X
Xvoid freeRGBMapData(rgb)
X     RGBMap *rgb;
X{
X  lfree(rgb->red);
X  lfree(rgb->green);
X  lfree(rgb->blue);
X}
X
XImage *newBitImage(width, height)
X     unsigned int width, height;
X{ Image        *image;
X  unsigned int  linelen;
X
X  image= (Image *)lmalloc(sizeof(Image));
X  image->type= IBITMAP;
X  image->title= NULL;
X  newRGBMapData(&(image->rgb), 2);
X  *(image->rgb.red)= *(image->rgb.green)= *(image->rgb.blue)= 65535;
X  *(image->rgb.red + 1)= *(image->rgb.green + 1)= *(image->rgb.blue + 1)= 0;
X  image->rgb.used= 2;
X  image->width= width;
X  image->height= height;
X  image->depth= 1;
X  linelen= width / 8;
X  if (linelen % 8)
X    linelen++;
X  image->data= (unsigned char *)lcalloc(linelen * height);
X  return(image);
X}
X
XImage *newRGBImage(width, height, depth)
X     unsigned int width, height, depth;
X{ Image        *image;
X  unsigned int  pixlen, numcolors, a;
X
X  pixlen= (depth / 8) + (depth % 8 ? 1 : 0);
X  for (numcolors= 2, a= depth - 1; a; a--)
X    numcolors *= 2;
X  image= (Image *)lmalloc(sizeof(Image));
X  image->type= IRGB;
X  image->title= NULL;
X  newRGBMapData(&(image->rgb), numcolors);
X  image->width= width;
X  image->height= height;
X  image->depth= depth;
X  image->pixlen= pixlen;
X  image->data= (unsigned char *)lmalloc(width * height * pixlen);
X  return(image);
X}
X
Xvoid freeImageData(image)
X     Image *image;
X{
X  if (image->title) {
X    lfree(image->title);
X    image->title= NULL;
X  }
X  freeRGBMapData(&(image->rgb));
X}
X
Xvoid freeImage(image)
X     Image *image;
X{
X  freeImageData(image);
X  lfree(image);
X}
X
Xbyte *lmalloc(size)
X     unsigned int size;
X{ byte *area;
X
X  if (!(area= (byte *)malloc(size))) {
X    perror("malloc");
X    exit(1);
X  }
X  return(area);
X}
X
Xbyte *lcalloc(size)
X     unsigned int size;
X{ byte *area;
X
X  if (!(area= (byte *)calloc(1, size))) {
X    perror("calloc");
X    exit(1);
X  }
X  return(area);
X}
X
Xvoid lfree(area)
X     byte *area;
X{
X  free(area);
X}
END_OF_new.c
if test 2593 -ne `wc -c <new.c`; then
    echo shar: \"new.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f options.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"options.c\"
else
echo shar: Extracting \"options.c\" \(634 characters\)
sed "s/^X//" >options.c <<'END_OF_options.c'
X/* options.c:
X *
X * finds which option in an array an argument matches
X *
X * jim frost 10.03.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "options.h"
X
Xint optionNumber(arg, options)
X     char *arg;
X     char *options[];
X{ int a, b;
X
X  if ((*arg) != '-')
X    return(OPT_NOTOPT);
X  for (a= 0; options[a]; a++) {
X    if (!strncmp(arg + 1, options[a], strlen(arg) - 1)) {
X      for (b= a + 1; options[b]; b++)
X	if (!strncmp(arg + 1, options[b], strlen(arg) - 1))
X	  return(OPT_SHORTOPT);
X      return(a);
X    }
X  }
X  return(OPT_BADOPT);
X}
END_OF_options.c
if test 634 -ne `wc -c <options.c`; then
    echo shar: \"options.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f options.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"options.h\"
else
echo shar: Extracting \"options.h\" \(314 characters\)
sed "s/^X//" >options.h <<'END_OF_options.h'
X/* options.h:
X *
X * optionNumber() definitions
X *
X * jim frost 10.03.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X
X#define OPT_NOTOPT   -1
X#define OPT_BADOPT   -2
X#define OPT_SHORTOPT -3
X
Xint optionNumber(); /* options.c */
END_OF_options.h
if test 314 -ne `wc -c <options.h`; then
    echo shar: \"options.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f patchlevel -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"patchlevel\"
else
echo shar: Extracting \"patchlevel\" \(14 characters\)
sed "s/^X//" >patchlevel <<'END_OF_patchlevel'
XPATCHLEVEL 01
END_OF_patchlevel
if test 14 -ne `wc -c <patchlevel`; then
    echo shar: \"patchlevel\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f path.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"path.c\"
else
echo shar: Extracting \"path.c\" \(4419 characters\)
sed "s/^X//" >path.c <<'END_OF_path.c'
X/* path.c:
X *
X * functions that deal with the image path
X *
X * jim frost 10.03.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "xloadimage.h"
X#include <sys/file.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <pwd.h>
X#include <errno.h>
X
Xextern int errno;
X
Xstatic unsigned int  NumPaths= 0;
Xstatic unsigned int  NumExts= 0;
Xstatic char         *Paths[BUFSIZ];
Xstatic char         *Exts[BUFSIZ];
Xstatic char         *PathToken= "path=";
Xstatic char         *ExtToken= "extension=";
X
X#define VOIDSECTION 0
X#define PATHSECTION 1
X#define EXTSECTION  2
X
Xstatic void readPathsAndExts(name)
X     char *name;
X{ FILE         *f;
X  char          tokenbuf[BUFSIZ];
X  char          buf[BUFSIZ];
X  unsigned int  secnum;
X  unsigned int  linenum;
X  unsigned int  a, b, l;
X  int           c;
X
X  if (! (f= fopen(name, "r")))
X    return;
X
X  secnum= VOIDSECTION;
X  linenum= 0;
X  while (fscanf(f, "%s", tokenbuf) > 0) {
X    linenum++;
X    l= strlen(tokenbuf);
X    for (a= 0, b= 0; a < l; a++, b++) {
X      if (tokenbuf[a] == '\\')
X	tokenbuf[b]= tokenbuf[++a];
X      else if (b != a)
X	tokenbuf[b]= tokenbuf[a];
X      if (tokenbuf[a] == '#') {
X	tokenbuf[b]= '\0';
X	while (((c= fgetc(f)) != '\n') && (c != EOF))
X	  ;
X	break;
X      }
X    }
X
X    if (!strncmp(tokenbuf, PathToken, strlen(PathToken))) {
X      secnum= PATHSECTION;
X      if (sscanf(tokenbuf + strlen(PathToken), "%s", buf) == 0)
X	continue;
X    }
X    else if (!strncmp(tokenbuf, ExtToken, strlen(ExtToken))) {
X      secnum= EXTSECTION;
X      if (sscanf(tokenbuf + strlen(ExtToken), "%s", buf) == 0)
X	continue;
X    }
X    else
X      strcpy(buf, tokenbuf);
X    if (buf[0] == '\0')
X      continue;
X
X    switch (secnum) {
X    case VOIDSECTION:
X      printf("%s: %d: Syntax error\n", name, linenum); /* ala BASIC */
X      fclose(f);
X      return;
X    case PATHSECTION:
X      if (NumPaths < BUFSIZ - 1)
X	Paths[NumPaths++]= dupString(buf);
X      else {
X	printf("%s: %d: Path table overflow\n", name, linenum);
X	fclose(f);
X	return;
X      }
X      break;
X    case EXTSECTION:
X      if (NumExts < BUFSIZ - 1)
X	Exts[NumExts++]= dupString(buf);
X      else {
X	printf("%s: %d: Extension table overflow\n", name, linenum);
X	fclose(f);
X      }
X      break;
X    }
X  }
X}
X
Xvoid loadPathsAndExts()
X{ static int     havepaths= 0;
X  struct passwd *pw;
X  char           buf[BUFSIZ];
X
X  if (havepaths)
X    return;
X  havepaths= 1;
X
X#ifdef SYSPATHFILE
X  readPathsAndExts(SYSPATHFILE);
X#endif
X  if (pw= getpwuid(getuid())) {
X    sprintf(buf, "%s/.xloadimagerc", pw->pw_dir);
X    readPathsAndExts(buf);
X  }
X  else
X    printf("Can't find your password file entry?!?\n");
X}
X
X/* find an image with paths and extensions from defaults files.  returns
X * -1 if access denied or not found, 0 if ok.
X */
X
Xint findImage(name, fullname)
X     char *name, *fullname;
X{ unsigned int   p, e;
X  struct stat    sbuf;
X
X  strcpy(fullname, name);
X  if (! stat(fullname, &sbuf))
X    return(access(fullname, R_OK));
X  strcat(fullname, ".Z");
X  if (! stat(fullname, &sbuf))
X    return(access(fullname, R_OK));
X  for (p= 0; p < NumPaths; p++) {
X    sprintf(fullname, "%s/%s", Paths[p], name);
X    if (! stat(fullname, &sbuf))
X      return(access(fullname, R_OK));
X    strcat(fullname, ".Z");
X    if (! stat(fullname, &sbuf))
X      return(access(fullname, R_OK));
X    for (e= 0; e < NumExts; e++) {
X      sprintf(fullname, "%s/%s%s", Paths[p], name, Exts[e]);
X      if (! stat(fullname, &sbuf))
X	return(access(fullname, R_OK));
X      strcat(fullname, ".Z");
X      if (! stat(fullname, &sbuf))
X	return(access(fullname, R_OK));
X    }
X  }
X  errno= ENOENT; /* file not found */
X  return(-1);
X}
X
X/* list images along our path
X */
X
Xvoid listImages()
X{ unsigned int a;
X  char         buf[BUFSIZ];
X
X  if (!NumPaths) {
X    printf("No image path\n");
X    return;
X  }
X  for (a= 0; a < NumPaths; a++) {
X    printf("%s:\n", Paths[a]);
X    sprintf(buf, "ls %s", Paths[a]);
X    if (system(buf) < 0) {
X      perror("ls");
X      return;
X    }
X  }
X  return;
X}
X
Xvoid showPath()
X{ int a;
X
X  if (!NumPaths && !NumExts) {
X    printf("No image paths or extensions\n");
X    return;
X  }
X  if (NumPaths) {
X    printf("Image path:");
X    for (a= 0; a < NumPaths; a++)
X      printf(" %s", Paths[a]);
X    printf("\n");
X  }
X  if (NumExts) {
X    printf("Image extensions:");
X    for (a= 0; a < NumExts; a++)
X      printf(" %s", Exts[a]);
X    printf("\n");
X  }
X}
END_OF_path.c
if test 4419 -ne `wc -c <path.c`; then
    echo shar: \"path.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pbm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pbm.c\"
else
echo shar: Extracting \"pbm.c\" \(4799 characters\)
sed "s/^X//" >pbm.c <<'END_OF_pbm.c'
X/* pbm.c:
X *
X * portable bit map (pbm) format images
X *
X * jim frost 09.27.89
X */
X
X#include "xloadimage.h"
X
Xstatic int          IntTable[256];
Xstatic unsigned int Initialized= 0;
X
X#define NOTINT  -1
X#define COMMENT -2
X#define SPACE   -3
X#define NEWLINE -4
X
X#define BADREAD    0 /* read error */
X#define NOTPBM     1 /* not a pbm file */
X#define PBMNORMAL  2 /* pbm normal type file */
X#define PBMCOMPACT 3 /* pbm compacty type file */
X
Xstatic void initializeTable()
X{ unsigned int a;
X
X  for (a= 0; a < 256; a++)
X    IntTable[a]= NOTINT;
X  IntTable['#']= COMMENT;
X  IntTable['\n']= NEWLINE;
X  IntTable['\r']= IntTable['\t']= IntTable[' ']= SPACE;
X  IntTable['0']= 0;
X  IntTable['1']= 1;
X  IntTable['2']= 2;
X  IntTable['3']= 3;
X  IntTable['4']= 4;
X  IntTable['5']= 5;
X  IntTable['6']= 6;
X  IntTable['7']= 7;
X  IntTable['8']= 8;
X  IntTable['9']= 9;
X  Initialized= 1;
X}
X
Xstatic int pbmReadChar(zf)
X     ZFILE *zf;
X{ int c;
X
X  if ((c= zgetc(zf)) == EOF) {
X    zclose(zf);
X    return(-1);
X  }
X  if (IntTable[c] == COMMENT)
X    do {
X      if ((c= zgetc(zf)) == EOF)
X	return(-1);
X    } while (IntTable[c] != NEWLINE);
X  return(c);
X}
X
Xstatic int pbmReadInt(zf)
X     ZFILE *zf;
X{ int c, value;
X
X  for (;;) {
X    c= pbmReadChar(zf);
X    if (c < 0)
X      return(-1);
X    if (IntTable[c] >= 0)
X      break;
X  };
X
X  value= IntTable[c];
X  for (;;) {
X    c= pbmReadChar(zf);
X    if (c < 0)
X      return(-1);
X    if (IntTable[c] < 0)
X      return(value);
X    value= (value * 10) + IntTable[c];
X  }
X}
X
Xstatic int isPBM(zf, name, width, height, verbose)
X     ZFILE        *zf;
X     char         *name;
X     int          *width, *height;
X     unsigned int  verbose;
X{ unsigned char buf[4];
X
X  if (! Initialized)
X    initializeTable();
X
X  if (zread(zf, buf, 2) != 2)
X    return(NOTPBM);
X  if (memToVal(buf, 2) == memToVal("P1", 2)) {
X    if (((*width= pbmReadInt(zf)) < 0) || ((*height= pbmReadInt(zf)) < 0))
X      return(NOTPBM);
X    if (verbose)
X      printf("%s is a %dx%d PBM image\n", name, *width, *height);
X    return(PBMNORMAL);
X  }
X  if (memToVal(buf, 2) == 0x2a17) {
X    if (zread(zf, buf, 4) != 4)
X      return(NOTPBM);
X    *width= memToVal(buf, 2);
X    *height= memToVal(buf + 2, 2);
X    if (verbose)
X      printf("%s is a %dx%d Compact PBM image\n", name, *width, *height);
X    return(PBMCOMPACT);
X  }
X  return(NOTPBM);
X}
X
Xint pbmIdent(fullname, name)
X     char *fullname, *name;
X{ ZFILE *zf;
X  int    width, height, ret;
X
X  if (! (zf= zopen(fullname, name)))
X    return(0);
X
X  ret= isPBM(zf, name, &width, &height, 1);
X  zclose(zf);
X  return(ret != NOTPBM);
X}
X
XImage *pbmLoad(fullname, name, verbose)
X     char         *fullname, *name;
X     unsigned int  verbose;
X{ ZFILE        *zf;
X  Image        *image;
X  unsigned int  x, y;
X  int           width, height;
X  unsigned int  linelen;
X  byte          srcmask, destmask;
X  byte         *destptr, *destline;
X  int           src;
X  unsigned int  numbytes, numread;
X
X  if (! (zf= zopen(fullname)))
X    return(NULL);
X
X  switch (isPBM(zf, name, &width, &height, verbose)) {
X  case NOTPBM:
X    zclose(zf);
X    return(NULL);
X    
X  case PBMNORMAL:
X    image= newBitImage(width, height);
X    linelen= (width / 8) + (width % 8 ? 1 : 0);
X    destline= image->data;
X    for (y= 0; y < height; y++) {
X      destptr= destline;
X      destmask= 0x80;
X      for (x= 0; x < width; x++) {
X	do {
X	  if ((src= pbmReadChar(zf)) < 0) {
X	    printf("%s: Short image\n", fullname);
X	    zclose(zf);
X	    exit(1);
X	  }
X	  if (IntTable[src] == NOTINT) {
X	    printf("%s: Bad image data\n", fullname);
X	    zclose(zf);
X	    exit(1);
X	  }
X	} while (IntTable[src] < 0);
X	
X	switch (IntTable[src]) {
X	case 1:
X	  *destptr |= destmask;
X	case 0:
X	  if (! (destmask >>= 1)) {
X	    destmask= 0x80;
X	    destptr++;
X	  }
X	  break;
X	default:
X	  printf("%s: Bad image data\n", fullname);
X	  zclose(zf);
X	  exit(1);
X	}
X      }
X      destline += linelen;
X    }
X    break;
X
X  case PBMCOMPACT:
X    image= newBitImage(width, height);
X    destline= image->data;
X    linelen= (width / 8) + (width % 8 ? 1 : 0);
X    srcmask= 0x80;
X    destmask= 0x80;
X    if ((src= zgetc(zf)) == EOF) {
X      printf("%s: Short image\n", fullname);
X      zclose(zf);
X      exit(1);
X    }
X    numread= 1;
X    numbytes= width * height;
X    numbytes= (numbytes / 8) + (numbytes % 8 ? 1 : 0);
X    for (y= 0; y < height; y++) {
X      destptr= destline;
X      destmask= 0x80;
X      for (x= 0; x < width; x++) {
X	if (src & srcmask)
X	  *destptr |= destmask;
X	if (! (destmask >>= 1)) {
X	  destmask= 0x80;
X	  destptr++;
X	}
X	if (! (srcmask >>= 1)) {
X	  srcmask= 0x80;
X	  if ((numread < numbytes) && ((src= zgetc(zf)) == EOF)) {
X	    printf("%s: Short image\n", fullname);
X	    zclose(zf);
X	    exit(1);
X	  }
X	  numread++;
X	}
X      }
X      destline += linelen;
X    }
X    break;
X  }
X  image->title= dupString(name);
X  return(image);
X}
END_OF_pbm.c
if test 4799 -ne `wc -c <pbm.c`; then
    echo shar: \"pbm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pbm.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pbm.h\"
else
echo shar: Extracting \"pbm.h\" \(146 characters\)
sed "s/^X//" >pbm.h <<'END_OF_pbm.h'
X/* pbm.h:
X *
X * PBM header file
X *
X * jim frost 10.15.89
X */
X
Xtypedef struct {
X  unsigned char width[2];
X  unsigned char height[2];
X} PBMCompact;
END_OF_pbm.h
if test 146 -ne `wc -c <pbm.h`; then
    echo shar: \"pbm.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0



More information about the Comp.sources.x mailing list