v05i028: xloadimage, Part02/02

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


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



#! /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 2 (of 2)."
# Contents:  reduce.c root.c send.c sunraster.c sunraster.h value.c
#   window.c xbitmap.c xloadimage.c xloadimage.h xloadimage.man zio.c
#   zoom.c
# Wrapped by madd at world on Thu Nov  9 09:41:22 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f reduce.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"reduce.c\"
else
echo shar: Extracting \"reduce.c\" \(5661 characters\)
sed "s/^X//" >reduce.c <<'END_OF_reduce.c'
X/* reduce.c:
X *
X * reduce an image's colormap usage to a set number of colors.
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 "image.h"
X
X#define DIST(A, B) ((A) < (B) ? (B) - (A) : (A) - (B))
X
X/* find the distance between two colors.  we loose some accuracy here because
X * a triple squared short may not fit in a long.  we use a table lookup
X * to help speed this up; it's an O(exp(n,2)) algorithm.
X */
X
Xstatic unsigned int  squareInit= 0;
Xstatic unsigned long squareTable[32768];
X
Xstatic void initSquareTable()
X{ unsigned long a;
X
X  for (a= 0; a < 32768; a++)
X    squareTable[a]= a * a;
X  squareInit= 1;
X}
X
Xstatic unsigned long colorDistance(rgb, a, b)
X     RGBMap *rgb;
X     Pixel   a, b;
X{
X  return(squareTable[DIST(*(rgb->red + a), *(rgb->red + b)) >> 1] +
X	 squareTable[DIST(*(rgb->green + a), *(rgb->green + b)) >> 1] +
X	 squareTable[DIST(*(rgb->blue + a), *(rgb->blue + b)) >> 1]);
X}
X
XPixel bestColor(rgb, color, rdist)
X     RGBMap        *rgb;
X     Pixel          color;
X     unsigned long *rdist;
X{ Pixel         qcolor, bcolor;
X  unsigned long qdist, bdist;
X
X  bdist= 0xffffffff;
X  for (qcolor= color + 1; qcolor < rgb->used; qcolor++)
X    if ((qdist= colorDistance(rgb, color, qcolor)) && (qdist < bdist)) {
X      bdist= qdist;
X      bcolor= qcolor;
X    }
X  *rdist= bdist;
X  return(bcolor);
X}
X
Xvoid reduceRGBMap(rgb, n, verbose)
X     RGBMap *rgb;
X     int     verbose;
X{ unsigned int   numcolors;
X  Pixel          a, b;
X  Pixel          lowextreme, highextreme; /* intensity extremes */
X  unsigned long  lowintensity, highintensity, myintensity;
X  Pixel          bcolor1; /* closest colors */
X  Pixel          bcolor2;
X  unsigned long  bdist;
X  Pixel         *best;    /* array holding best match for each color */
X  unsigned long *dists;   /* array holding distances of best matches */
X  Pixel         *same;    /* array holding identical pixel lists */
X  Intensity      newred, newgreen, newblue;
X
X  if (!squareInit)     /* only do multiplies once */
X    initSquareTable();
X
X  if (verbose) {
X    printf("  Reducing colormap to %d colors...", n);
X    fflush(stdout);
X  }
X
X  best= (Pixel *)lmalloc(sizeof(Pixel) * rgb->used);
X  same= (Pixel *)lmalloc(sizeof(Pixel) * rgb->used);
X  dists= (unsigned long *)lmalloc(sizeof(unsigned long) * rgb->used);
X
X  /* find out how many unique colors we have by subtracting identical ones
X   * and build table of identicals.  find extreme intensities while we're
X   * at it.
X   */
X
X  lowextreme= highextreme= rgb->used - 1;
X  lowintensity= highintensity= *(rgb->red + lowextreme) +
X     *(rgb->green + lowextreme) + *(rgb->blue + lowextreme);
X  for (a= 0; a < rgb->used; a++)
X    *(same + a)= a;
X  for (numcolors= rgb->used, a= 0; a < rgb->used - 1; a++) {
X    if (*(same + a) == a) {
X      myintensity= *(rgb->red + a) + *(rgb->green + a) + *(rgb->blue + a);
X      if (myintensity < lowintensity) {
X	lowintensity= myintensity;
X	lowextreme= a;
X      }
X      if (myintensity > highintensity) {
X	highintensity= myintensity;
X	highextreme= a;
X      }
X      for (b= a + 1; b < rgb->used; b++) {
X	if ((*(rgb->red + a) == *(rgb->red + b)) &&
X	    (*(rgb->green + a) == *(rgb->green + b)) &&
X	    (*(rgb->blue + a) == *(rgb->blue + b))) {
X	  numcolors--;
X	  *(same + b)= a;
X	}
X      }
X    }
X  }
X
X  for (a= 0; a < rgb->used - 1; a++) /* build table of "bests" */
X    *(best + a)= bestColor(rgb, a, dists + a);
X
X  /* find the two closest colors in the colormap and average them, thus
X   * reducing the size of the colormap by one.  continue until we fit.
X   * this is simplistic but effective.
X   */
X
X  while (numcolors-- > n) {
X    bdist= 0xffffffff; /* a really big number */
X    for (a= 0; a < rgb->used - 1; a++)
X      if ((*(same + a) == a) && (*(dists + a) < bdist)) {
X	bdist= *(dists + a);
X	bcolor1= a;
X      }
X
X    bcolor2= *(same + *(best + bcolor1));
X
X    /* calculate new rgb values.  we average the colors unless one of them
X     * is an extreme.
X     */
X
X    if ((bcolor1 == lowextreme) || (bcolor1 == highextreme)) {
X      newred= *(rgb->red + bcolor1);
X      newgreen= *(rgb->green + bcolor1);
X      newblue= *(rgb->blue + bcolor1);
X    }
X    else if ((bcolor2 == lowextreme) || (bcolor2 == highextreme)) {
X      newred= *(rgb->red + bcolor2);
X      newgreen= *(rgb->green + bcolor2);
X      newblue= *(rgb->blue + bcolor2);
X    }
X    else {
X      newred= ((unsigned int)(*(rgb->red + bcolor1)) +
X	       (unsigned int)(*(rgb->red + bcolor2))) >> 1;
X      newgreen= ((unsigned int)(*(rgb->green + bcolor1)) +
X		 (unsigned int)(*(rgb->green + bcolor2))) >> 1;
X      newblue= ((unsigned int)(*(rgb->blue + bcolor1)) +
X		(unsigned int)(*(rgb->blue + bcolor2))) >> 1;
X    }
X
X    for (a= 0; a < rgb->used; a++)
X      if ((*(same + a) == bcolor1) || (*(same + a) == bcolor2)) {
X	*(same + a)= bcolor1;
X        *(rgb->red + a)= newred;
X        *(rgb->green + a)= newgreen;
X        *(rgb->blue + a)= newblue;
X      }
X	
X    for (a= 0; a < rgb->used - 1; a++)
X      if ((*(best + a) == bcolor1) || (*(same + a) == bcolor1) ||
X	  (*(same + *(best + a)) == bcolor1))
X	*(best + a)= bestColor(rgb, a, dists + a);
X  }
X
X  lfree(best);
X  lfree(dists);
X  lfree(same);
X
X  if (verbose)
X    printf("done\n");
X}
X
Xvoid reduce(image, n, verbose)
X     Image        *image;
X     unsigned int  n, verbose;
X{ char buf[BUFSIZ];
X
X  goodImage(image);
X  if (! RGBP(image)) /* we're AT&T */
X    return;
X  compress(image, verbose);
X  reduceRGBMap(&(image->rgb), n, verbose);
X  compress(image, verbose);
X  sprintf(buf, "%s (%d colors)", image->title, image->rgb.used);
X  lfree(image->title);
X  image->title= dupString(buf);
X}
END_OF_reduce.c
if test 5661 -ne `wc -c <reduce.c`; then
    echo shar: \"reduce.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f root.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"root.c\"
else
echo shar: Extracting \"root.c\" \(912 characters\)
sed "s/^X//" >root.c <<'END_OF_root.c'
X/* root.c:
X *
X * this loads an image onto the root window
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
Xvoid imageOnRoot(disp, scrn, image, install, verbose)
X     Display      *disp;
X     int           scrn;
X     Image        *image;
X     unsigned int  install;
X     unsigned int  verbose;
X{ Pixmap   pixmap;
X  Colormap xcmap;
X
X  if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn), image,
X		     &pixmap, &xcmap, verbose))
X    exit(1);
X  XSetWindowBackgroundPixmap(disp, RootWindow(disp, scrn), pixmap);
X  XSetWindowColormap(disp, RootWindow(disp, scrn), xcmap);
X  if (install)
X    XInstallColormap(disp, scrn, xcmap);
X  XClearWindow(disp, RootWindow(disp, scrn));
X  XFreeColormap(disp, xcmap);
X  XFreePixmap(disp, pixmap);
X  XSetCloseDownMode(disp, RetainPermanent);
X}
END_OF_root.c
if test 912 -ne `wc -c <root.c`; then
    echo shar: \"root.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f send.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"send.c\"
else
echo shar: Extracting \"send.c\" \(4340 characters\)
sed "s/^X//" >send.c <<'END_OF_send.c'
X/* send.c:
X *
X * send an Image to an X pixmap
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 "xloadimage.h"
X
Xunsigned int sendImageToX(disp, scrn, visual, image, pixmap, cmap, verbose)
X     Display      *disp;
X     int           scrn;
X     Visual       *visual;
X     Image        *image;
X     Pixmap       *pixmap;
X     Colormap     *cmap;
X     unsigned int  verbose;
X{ Pixel        *index;
X  unsigned int  a, newmap, x, y;
X  byte         *pixptr;
X  XColor        xcolor;
X  XGCValues     gcv;
X  GC            gc;
X  XImage       *ximage;
X
X  goodImage(image, "sendImageToX");
X
X  switch(visual->class) {
X  case PseudoColor:
X  case GrayScale:
X  case StaticColor:
X  case StaticGray:
X    break;
X  default:
X    printf("sendImageToX: unsupported display visual\n");
X    exit(1);
X  }
X
X  index= (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
X  xcolor.flags= DoRed | DoGreen | DoBlue;
X
X  /* get the colormap to use
X   */
X
X  if (visual == DefaultVisual(disp, scrn)) {
X    *cmap= DefaultColormap(disp, scrn);
X    newmap= 0;
X  }
X  else {
X    if ((visual->class == PseudoColor) || (visual->class == GrayScale))
X      *cmap= XCreateColormap(disp, scrn, AllocNone);
X    else
X      *cmap= XCreateColormap(disp, scrn, AllocAll);
X    newmap= 1;
X  }
X
X  /* here's where we have fun; we try to build a reasonable colormap from
X   * whatever X will give us.  ugh.  blech.  gag.  puke.  barf.
X   */
X
X  if ((visual->class == PseudoColor) || (visual->class == GrayScale)) {
X    for (a= 0; a < image->rgb.used; a++) {
X      if (! XAllocColorCells(disp, *cmap, False, NULL, 0, index + a, 1))
X	if (newmap)
X	  break;
X	else {
X	  *cmap= XCopyColormapAndFree(disp, *cmap);
X	  newmap= 1;
X	  a--;
X	}
X    }
X    if (a < image->rgb.used)     /* can't get enough colors, so reduce */
X      reduce(image, a, verbose); /* the colormap to fit what we have */
X    for (a= 0; a < image->rgb.used; a++) {
X      xcolor.pixel= *(index + a);
X      xcolor.red= *(image->rgb.red + a);
X      xcolor.green= *(image->rgb.green + a);
X      xcolor.blue= *(image->rgb.blue + a);
X      XStoreColor(disp, *cmap, &xcolor);
X    }
X  }
X  else if ((visual->class == StaticColor) || (visual->class == StaticGray)) {
X    for (a= 0; a < image->rgb.used; a++) {
X      xcolor.red= *(image->rgb.red + a);
X      xcolor.green= *(image->rgb.green + a);
X      xcolor.blue= *(image->rgb.blue + a);
X      if (! XAllocColor(disp, *cmap, &xcolor)) {
X	printf("sendImageToX: XAllocColor failed on StaticGrey visual\n");
X	return(0);
X      }
X      *(index + a)= xcolor.pixel;
X    }
X  }
X
X  *pixmap= XCreatePixmap(disp, RootWindow(disp, scrn), image->width,
X			 image->height, DefaultDepth(disp, scrn));
X
X  /* blast the image across
X   */
X
X  switch (image->type) {
X  case IBITMAP:
X    gcv.function= GXcopy;
X    gcv.foreground= *(index + 1);
X    gcv.background= *index;
X    gc= XCreateGC(disp, *pixmap, GCFunction | GCForeground | GCBackground,
X		  &gcv);
X    ximage= XCreateImage(disp, visual, image->depth, XYBitmap, 0, image->data,
X			 image->width, image->height, 8, 0);
X    ximage->bitmap_bit_order= MSBFirst;
X    ximage->byte_order= MSBFirst;
X    XPutImage(disp, *pixmap, gc, ximage, 0, 0, 0, 0,
X	      image->width, image->height);
X    XFreeGC(disp, gc);
X    break;
X
X  case IRGB:
X
X    /* modify pixel values to fit the colormap
X     */
X
X    if (verbose) {
X      printf("  Modifying image to conform to X colormap...");
X      fflush(stdout);
X    }
X    pixptr= image->data;
X    for (y= 0; y < image->height; y++)
X      for (x= 0; x < image->width; x++) {
X	valToMem(*(index + memToVal(pixptr, image->pixlen)),
X		 pixptr, image->pixlen);
X	pixptr += image->pixlen;
X      }
X    if (verbose)
X      printf("done\n");
X
X    gcv.function= GXcopy;
X    gc= XCreateGC(disp, *pixmap, GCFunction, &gcv);
X    ximage= XCreateImage(disp, visual, image->depth, ZPixmap, 0, image->data,
X			 image->width, image->height, 8, 0);
X    ximage->byte_order= MSBFirst; /* trust me, i know what i'm talking about */
X
X    XPutImage(disp, *pixmap, gc, ximage, 0, 0,
X	      0, 0, image->width, image->height);
X    ximage->data= NULL;
X    XDestroyImage(ximage); /* waste not want not */
X    XFreeGC(disp, gc);
X    break;
X
X  default:
X    printf("sendImageToX: bad image type\n");
X    return(0);
X  }
X  lfree(index);
X  return(1);
X}
END_OF_send.c
if test 4340 -ne `wc -c <send.c`; then
    echo shar: \"send.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sunraster.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sunraster.c\"
else
echo shar: Extracting \"sunraster.c\" \(4799 characters\)
sed "s/^X//" >sunraster.c <<'END_OF_sunraster.c'
X/* sunraster.c:
X *
X * sun rasterfile image type
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 "xloadimage.h"
X#include "sunraster.h"
X
Xstatic void babble(name, header)
X     char           *name;
X     struct rheader *header;
X{
X  printf("%s is a", name);
X  switch (memToVal(header->type, 4)) {
X  case ROLD:
X    printf("n old-style");
X    break;
X  case RSTANDARD:
X    printf(" standard");
X    break;
X  case RRLENCODED:
X    printf(" run-length encoded");
X    break;
X  default:
X    printf(" unknown-type");
X  }
X  printf(" %dx%d ", memToVal(header->width, 4), memToVal(header->height, 4));
X  if (memToVal(header->depth, 4) > 1)
X    printf("%d plane color", memToVal(header->depth, 4));
X  else
X    printf("monochrome");
X  printf(" Sun rasterfile\n");
X}
X
Xint sunRasterIdent(fullname, name)
X     char *fullname, *name;
X{ ZFILE          *zf;
X  struct rheader  header;
X  int             r;
X
X  if (! (zf= zopen(fullname))) {
X    perror("sunRasterIdent");
X    return(0);
X  }
X  switch (zread(zf, &header, sizeof(struct rheader))) {
X  case -1:
X    perror("sunRasterIdent");
X    r= 0;
X    break;
X
X  case sizeof(struct rheader):
X    if (memToVal(header.magic, 4) != RMAGICNUMBER) {
X      r= 0;
X      break;
X    }
X    babble(name, &header);
X    r= 1;
X    break;
X
X  default:
X    r= 0;
X    break;
X  }
X  zclose(zf);
X  return(r);
X}
X
X/* read either rl-encoded or normal image data
X */
X
Xstatic void sunread(zf, buf, len, enc)
X     ZFILE        *zf;
X     byte         *buf;
X     unsigned int  len;
X     unsigned int  enc;  /* true if encoded file */
X{ static byte repchar, remaining= 0;
X
X  /* rl-encoded read
X   */
X
X  if (enc) {
X    while (len--)
X      if (remaining) {
X	remaining--;
X	*(buf++)= repchar;
X      }
X      else {
X	if (zread(zf, &repchar, 1) != 1) {
X	  printf("sunRasterLoad: Bad read on image data\n");
X	  exit(1);
X	}
X	if (repchar == RESC) {
X	  if (zread(zf, &remaining, 1) != 1) {
X	    printf("sunRasterLoad: Bad read on image data\n");
X	    exit(1);
X	  }
X	  if (remaining == 0)
X	    *(buf++)= RESC;
X	  else {
X	    if (zread(zf, &repchar, 1) != 1) {
X	      printf("sunRasterLoad: Bad read on image data\n");
X	      exit(1);
X	    }
X	    *(buf++)= repchar;
X	  }
X	}
X	else
X	  *(buf++)= repchar;
X      }
X  }
X
X  /* normal read
X   */
X
X  else {
X    if (zread(zf, buf, len) < len) {
X      printf("sunRasterLoad: Bad read on image data\n");
X      exit(1);
X    }
X  }
X}
X
XImage *sunRasterLoad(fullname, name, verbose)
X     char         *fullname, *name;
X     unsigned int  verbose;
X{ ZFILE          *zf;
X  struct rheader  header;
X  unsigned int    mapsize;
X  byte           *map;
X  byte           *mapred, *mapgreen, *mapblue;
X  unsigned int    depth;
X  unsigned int    linelen;   /* length of raster line in bytes */
X  unsigned int    fill;      /* # of fill bytes per raster line */
X  unsigned int    enc;
X  byte            fillchar;
X  Image          *image;
X  byte           *lineptr;
X  unsigned int    y;
X
X  if (! (zf= zopen(fullname))) {
X    perror("sunRasterLoad");
X    return(NULL);
X  }
X  switch (zread(zf, &header, sizeof(struct rheader))) {
X  case -1:
X    perror("sunRasterLoad");
X    zclose(zf);
X    exit(1);
X
X  case sizeof(struct rheader):
X    if (memToVal(header.magic, 4) != RMAGICNUMBER) {
X      zclose(zf);
X      return(NULL);
X    }
X    if (verbose)
X      babble(name, &header);
X    break;
X
X  default:
X    zclose(zf);
X    return(NULL);
X  }
X
X  /* get an image to put the data in
X   */
X
X  depth= memToVal(header.depth, 4);
X  if (depth == 1)
X    image= newBitImage(memToVal(header.width, 4),
X		       memToVal(header.height, 4));
X  else
X    image= newRGBImage(memToVal(header.width, 4),
X		       memToVal(header.height, 4),
X		       memToVal(header.depth, 4));
X
X  /* set up the colormap
X   */
X
X  if (depth == 1)
X    linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
X  else
X    linelen= image->width * image->pixlen;
X  fill= (linelen % 2 ? 1 : 0);
X  if (mapsize= memToVal(header.maplen, 4)) {
X    map= lmalloc(mapsize);
X    if (zread(zf, map, mapsize) < mapsize) {
X      printf("sunRasterLoad: Bad read on colormap\n");
X      exit(1);
X    }
X    mapsize /= 3;
X    mapred= map;
X    mapgreen= mapred + mapsize;
X    mapblue= mapgreen + mapsize;
X    for (y= 0; y < mapsize; y++) {
X      *(image->rgb.red + y)= (*(mapred++) << 8);
X      *(image->rgb.green + y)= (*(mapgreen++) << 8);
X      *(image->rgb.blue + y)= (*(mapblue++) << 8);
X    }
X    lfree(map);
X    image->rgb.used= mapsize;
X  }
X
X  enc= (memToVal(header.type, 4) == RRLENCODED);
X  lineptr= image->data;
X  for (y= 0; y < image->height; y++) {
X    sunread(zf, lineptr, linelen, enc);
X    lineptr += linelen;
X    if (fill)
X      sunread(zf, &fillchar, fill, enc);
X  }
X  zclose(zf);
X  image->title= dupString(name);
X  return(image);
X}
END_OF_sunraster.c
if test 4799 -ne `wc -c <sunraster.c`; then
    echo shar: \"sunraster.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sunraster.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sunraster.h\"
else
echo shar: Extracting \"sunraster.h\" \(1643 characters\)
sed "s/^X//" >sunraster.h <<'END_OF_sunraster.h'
X/* sunraster.h
X *
X * this describes the header for Sun rasterfiles.  if you have SunOS, a
X * better description is in /usr/include/rasterfile.h.  this is used
X * instead to improve portability and to avoid distribution problems.
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X
Xstruct rheader {
X  unsigned char magic[4];   /* magic number */
X  unsigned char width[4];   /* width of image in pixels */
X  unsigned char height[4];  /* height of image in pixels */
X  unsigned char depth[4];   /* depth of each pixel */
X  unsigned char length[4];  /* length of the image in bytes */
X  unsigned char type[4];    /* format of file */
X  unsigned char maptype[4]; /* type of colormap */
X  unsigned char maplen[4];  /* length of colormap in bytes */
X};
X
X/* following the header is the colormap (unless maplen is zero) then
X * the image.  each row of the image is rounded to 2 bytes.
X */
X
X#define RMAGICNUMBER 0x59a66a95 /* magic number of this file type */
X
X/* these are the possible file formats
X */
X
X#define ROLD       0 /* old format, see /usr/include/rasterfile.h */
X#define RSTANDARD  1 /* standard format */
X#define RRLENCODED 2 /* run length encoding to compress the image */
X
X/* these are the possible colormap types.  if it's in RGB format,
X * the map is made up of three byte arrays (red, green, then blue)
X * that are each 1/3 of the colormap length.
X */
X
X#define RNOMAP  0 /* no colormap follows the header */
X#define RRGBMAP 1 /* rgb colormap */
X#define RRAWMAP 2 /* raw colormap; good luck */
X
X#define RESC 128 /* run-length encoding escape character */
X
END_OF_sunraster.h
if test 1643 -ne `wc -c <sunraster.h`; then
    echo shar: \"sunraster.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f value.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"value.c\"
else
echo shar: Extracting \"value.c\" \(715 characters\)
sed "s/^X//" >value.c <<'END_OF_value.c'
X/* value.c:
X *
X * routines for converting byte values to long values.  these are pretty
X * portable although they are not necessarily the fastest things in the
X * world.
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
Xunsigned long memToVal(p, len)
X     byte *p;
X     int   len;
X{ unsigned int  a;
X  unsigned long i;
X
X  i= 0;
X  for (a= 0; a < len; a++)
X    i= (i << 8) + *(p++);
X  return(i);
X}
X
Xvoid valToMem(val, p, len)
X     unsigned long  val;
X     byte          *p;
X     unsigned int   len;
X{ int a;
X
X  for (a= len - 1; a >= 0; a--) {
X    *(p + a)= val & 0xff;
X    val >>= 8;
X  }
X}
END_OF_value.c
if test 715 -ne `wc -c <value.c`; then
    echo shar: \"value.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f window.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"window.c\"
else
echo shar: Extracting \"window.c\" \(6632 characters\)
sed "s/^X//" >window.c <<'END_OF_window.c'
X/* window.c:
X *
X * display an image in a window
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 <X11/cursorfont.h>
X
Xstatic void setCursor(disp, window, iw, ih, ww, wh, cursor)
X     Display      *disp;
X     Window        window;
X     unsigned int  iw, ih;
X     unsigned int  ww, wh;
X     Cursor       *cursor;
X{ XSetWindowAttributes swa;
X
X  if ((ww == iw) && (wh == ih))
X    swa.cursor= XCreateFontCursor(disp, XC_icon);
X  else if ((ww < iw) && (wh == ih))
X    swa.cursor= XCreateFontCursor(disp, XC_sb_h_double_arrow);
X  else if ((ww == iw) && (wh < ih))
X    swa.cursor= XCreateFontCursor(disp, XC_sb_v_double_arrow);
X  else
X    swa.cursor= XCreateFontCursor(disp, XC_fleur);
X  XChangeWindowAttributes(disp, window, CWCursor, &swa);
X  XFreeCursor(disp, *cursor);
X  *cursor= swa.cursor;
X}
X
Xvoid imageInWindow(disp, scrn, image, winx, winy, winwidth, winheight, install,
X		   verbose)
X     Display      *disp;
X     int           scrn;
X     Image        *image;
X     unsigned int  winx, winy, winwidth, winheight;
X     unsigned int  install;
X     unsigned int  verbose;
X{ Pixmap               pixmap;
X  Colormap             xcmap;
X  XSetWindowAttributes swa;
X  XSizeHints           sh;
X  XGCValues            gcv;
X  GC                   gc;
X  Window               window;
X  int                  pixx, pixy;
X  int                  lastx, lasty, mousex, mousey;
X  union {
X    XEvent              event;
X    XAnyEvent           any;
X    XButtonEvent        button;
X    XKeyEvent           key;
X    XConfigureEvent     configure;
X    XExposeEvent        expose;
X    XMotionEvent        motion;
X    XResizeRequestEvent resize;
X  } event;
X
X  /* figure out the window size.  unless specifically requested to do so,
X   * we will not exceed 90% of display real estate.
X   */
X
X  lastx= (winwidth || winheight);
X  if (!winwidth) {
X    winwidth= image->width;
X    if (winwidth > DisplayWidth(disp, scrn) * 0.9)
X      winwidth= DisplayWidth(disp, scrn) * 0.9;
X  }
X  if (!winheight) {
X    winheight= image->height;
X    if (winheight > DisplayHeight(disp, scrn) * 0.9)
X      winheight= DisplayHeight(disp, scrn) * 0.9;
X  }
X
X  if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn),
X		     image, &pixmap, &xcmap, verbose))
X    exit(1);
X  swa.backing_store= NotUseful;
X  swa.bit_gravity= NorthWestGravity;
X  swa.cursor= XCreateFontCursor(disp, XC_watch);
X  swa.colormap= xcmap;
X  swa.event_mask= ButtonPressMask | Button1MotionMask | KeyPressMask |
X    ExposureMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask;
X  swa.save_under= False;
X  window= XCreateWindow(disp, RootWindow(disp, scrn), 0, 0,
X			image->width, image->height, 0,
X			DefaultDepth(disp, scrn),
X			InputOutput, CopyFromParent,
X			CWBackingStore | CWBitGravity | CWCursor |
X			CWColormap | CWEventMask | CWSaveUnder, &swa);
X  XStoreName(disp, window, image->title);
X  XSetIconName(disp, window, image->title);
X
X  sh.width= winwidth;
X  sh.height= winheight;
X  sh.min_width= 1;
X  sh.min_height= 1;
X  sh.max_width= image->width;
X  sh.max_height= image->height;
X  sh.width_inc= 1;
X  sh.height_inc= 1;
X  sh.flags= PMinSize | PMaxSize | PResizeInc;
X  if (lastx)
X    sh.flags |= USSize;
X  else
X    sh.flags |= PSize;
X  if (winx || winy) {
X    sh.x= winx;
X    sh.y= winy;
X    sh.flags |= USPosition;
X  }
X  XSetNormalHints(disp, window, &sh);
X
X  gcv.function= GXcopy;
X  gc= XCreateGC(disp, window, GCFunction, &gcv);
X  XMapWindow(disp, window);
X  pixx= pixy= 0;
X  lastx= lasty= -1;
X  setCursor(disp, window, image->width, image->height,
X	    winwidth, winheight, &(swa.cursor));
X
X  for (;;) {
X    XNextEvent(disp, &event);
X    switch (event.any.type) {
X    case ButtonPress:
X      if (event.button.button == 1) {
X	lastx= event.button.x;
X	lasty= event.button.y;
X	break;
X      }
X#ifdef NUKE_ME
X      XDestroyWindow(disp, window);
X      XFreeCursor(disp, swa.cursor);
X      XFreePixmap(disp, pixmap);
X      XFreeColormap(disp, xcmap);
X      return;
X#else
X      break;
X#endif
X
X    case KeyPress: {
X      char buf[128];
X      KeySym ks;
X      XComposeStatus status;
X
X      XLookupString(&event.key,buf,128,&ks,&status);
X      if (buf[0]=='q' || buf[0]=='Q') {
X        XDestroyWindow(disp, window);
X        XFreeCursor(disp, swa.cursor);
X        XFreePixmap(disp, pixmap);
X        XFreeColormap(disp, xcmap);
X        return;
X      }
X    }
X      break;
X
X    case MotionNotify:
X      mousex= event.button.x;
X      mousey= event.button.y;
X      while (XCheckTypedEvent(disp, MotionNotify, &event) == True) {
X	mousex= event.button.x;
X	mousey= event.button.y;
X      }
X      pixx += lastx - mousex;
X      pixy += lasty - mousey;
X      lastx= mousex;
X      lasty= mousey;
X      if (pixx < 0)
X	pixx= 0;
X      if (pixy < 0)
X	pixy= 0;
X      if (pixx + winwidth > image->width)
X	pixx= image->width - winwidth;
X      if (pixy + winheight > image->height)
X	pixy= image->height - winheight;
X      XCopyArea(disp, pixmap, window, gc,
X		pixx, pixy, winwidth, winheight, 0, 0);
X      break;
X
X    case ConfigureNotify:
X
X      /* if we got resized too big, fix it.  it's a stupid window manager.
X       */
X
X      if ((event.configure.width > image->width) ||
X	  (event.configure.height > image->height)) {
X	if (event.configure.width > image->width)
X	  winwidth= image->width;
X	else
X	  winwidth= event.configure.width;
X	if (event.configure.height > image->height)
X	  winheight= image->height;
X	else
X	  winheight= event.configure.height;
X	XResizeWindow(disp, window, winwidth, winheight);
X      }
X      else {
X	winwidth= event.configure.width;
X	winheight= event.configure.height;
X      }
X
X      /* configure the cursor to indicate which directions we can drag
X       */
X
X      if (pixx + winwidth > image->width)
X	pixx= image->width - winwidth;
X      if (pixy + winheight > image->height)
X	pixy= image->height - winheight;
X      setCursor(disp, window, image->width, image->height,
X		winwidth, winheight, &(swa.cursor));
X
X      /* repaint 
X       */
X
X      XCopyArea(disp, pixmap, window, gc,
X		pixx, pixy, winwidth, winheight, 0, 0);
X      break;
X
X    case DestroyNotify:
X      XFreeCursor(disp, swa.cursor);
X      XFreePixmap(disp, pixmap);
X      XFreeColormap(disp, xcmap);
X      return;
X
X    case Expose:
X      XCopyArea(disp, pixmap, window, gc,
X		pixx + event.expose.x, pixy + event.expose.y,
X		event.expose.width, event.expose.height,
X		event.expose.x, event.expose.y);
X      break;
X
X    case EnterNotify:
X      if (install)
X	XInstallColormap(disp, xcmap);
X      break;
X
X    case LeaveNotify:
X      if (install)
X	XUninstallColormap(disp, xcmap);
X    }
X  }
X}
END_OF_window.c
if test 6632 -ne `wc -c <window.c`; then
    echo shar: \"window.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xbitmap.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xbitmap.c\"
else
echo shar: Extracting \"xbitmap.c\" \(5281 characters\)
sed "s/^X//" >xbitmap.c <<'END_OF_xbitmap.c'
X/* xbitmap.c:
X *
X * at one time this was XRdBitF.c.  it bears very little resemblence to it
X * now.  that was ugly code.  this is cleaner, faster, and more reliable
X * in most cases.
X *
X * jim frost 10.06.89
X *
X * Copyright, 1987, Massachusetts Institute of Technology
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "mit.cpyrght"
X#include "copyright.h"
X#include "xloadimage.h"
X#include <ctype.h>
X
Xchar *rindex();
X
X#define MAX_SIZE 255
X
Xstatic short        HexTable[256];  /* conversion value */
Xstatic unsigned int Initialized= 0; /* easier to fill in at run time */
X
X#define b0000 0 /* things make more sense if you see them by bit */
X#define b0001 1
X#define b0010 2
X#define b0011 3
X#define b0100 4
X#define b0101 5
X#define b0110 6
X#define b0111 7
X#define b1000 8
X#define b1001 9
X#define b1010 10
X#define b1011 11
X#define b1100 12
X#define b1101 13
X#define b1110 14
X#define b1111 15
X
X#define HEXSTART -1
X#define HEXDELIM -2
X#define HEXBAD   -3
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']= b0000;
X  HexTable['1']= b1000;
X  HexTable['2']= b0100;
X  HexTable['3']= b1100;
X  HexTable['4']= b0010;
X  HexTable['5']= b1010;
X  HexTable['6']= b0110;
X  HexTable['7']= b1110;
X  HexTable['8']= b0001;
X  HexTable['9']= b1001;
X  HexTable['A']= b0101; HexTable['a']= HexTable['A'];
X  HexTable['B']= b1101; HexTable['b']= HexTable['B'];
X  HexTable['C']= b0011; HexTable['c']= HexTable['C'];
X  HexTable['D']= b1011; HexTable['d']= HexTable['D'];
X  HexTable['E']= b0111; HexTable['e']= HexTable['E'];
X  HexTable['F']= b1111; HexTable['f']= HexTable['F'];
X  HexTable['x']= HEXSTART;
X  HexTable['\r']= HEXDELIM;
X  HexTable['\n']= HEXDELIM;
X  HexTable['\t']= HEXDELIM;
X  HexTable[' ']= HEXDELIM;
X  HexTable[',']= HEXDELIM;
X  HexTable['}']= HEXDELIM;
X
X  Initialized = 1;
X}
X
X/* read a hex value and return its value
X */
X
Xstatic int nextInt(zf)
X     ZFILE *zf;
X{ int c;
X  int value= 0;
X  int shift= 0;
X    
X  for (;;) {
X    c= zgetc(zf);
X    if (c == EOF)
X      return(-1);
X    else {
X      c= HexTable[c & 0xff];
X      switch(c) {
X      case HEXSTART:
X	shift= 0; /* reset shift counter */
X	break;
X      case HEXDELIM:
X	if (shift)
X	  return(value);
X	break;
X      case HEXBAD:
X	return(-1);
X      default:
X	value += (c << shift);
X	shift += 4;
X      }
X    }
X  }
X}
X
Xstatic void badFile(name)
X     char *name;
X{
X  printf("%s: bad X bitmap file\n", name);
X  exit(1);
X}
X
XImage *xbitmapLoad(fullname, name, verbose)
X     char         *fullname, *name;
X     unsigned int  verbose;
X{ ZFILE        *zf;
X  Image        *image;
X  char          line[MAX_SIZE];
X  char          name_and_type[MAX_SIZE];
X  char         *type;
X  int           value;
X  int           v10p;
X  unsigned int  linelen, dlinelen;
X  unsigned int  x, y;
X  unsigned int  w, h;
X  byte         *dataptr;
X
X  if (!Initialized)
X    initHexTable();
X
X  if (! (zf= zopen(fullname)))
X    return(NULL);
X
X  /* get width/height values */
X
X  while (zgets(line, MAX_SIZE, zf)) {
X    if (strlen(line) == MAX_SIZE-1) {
X      fclose(zf);
X      return(NULL);
X    }
X
X    /* width/height/hot_x/hot_y scanning
X     */
X
X    if (sscanf(line,"#define %s %d", name_and_type, &value) == 2) {
X      if (!(type = rindex(name_and_type, '_')))
X	type = name_and_type;
X      else
X	type++;
X
X      if (!strcmp("width", type))
X	w= (unsigned int)value;
X      if (!strcmp("height", type))
X	h= (unsigned int)value;
X    }
X
X    /* if start of data, determine if it's X10 or X11 data and break
X     */
X
X    if (sscanf(line, "static short %s = {", name_and_type) == 1) {
X      v10p = 1;
X      break;
X    }
X    if ((sscanf(line,"static unsigned char %s = {", name_and_type) == 1) ||
X	(sscanf(line, "static char %s = {", name_and_type) == 1)) {
X      v10p = 0;
X      break;
X    }
X  }
X
X  if (!w || !h)
X    return(NULL);
X  image= newBitImage(w, h);
X
X  /* get title of bitmap if any
X   */
X
X  if ((type = rindex(name_and_type, '_')) && !strcmp("bits[]", type + 1)) {
X    *type= '\0';
X    image->title= dupString(name_and_type);
X  }
X    
X  /* read bitmap data
X   */
X
X  linelen= (w / 8) + (w % 8 ? 1 : 0); /* internal line length */
X  if (v10p) {
X    dlinelen= (w / 8) + (w % 16 ? 2 : 0);
X    dataptr= image->data;
X    for (y= 0; y < h; y++) {
X      for (x= 0; x < dlinelen; x++) {
X	if ((value= nextInt(zf)) < 0) {
X	  freeImage(image);
X	  return(NULL);
X	}
X	*(dataptr++)= value >> 8;
X	if (++x < linelen)
X	  *(dataptr++)= value & 0xff;
X      }
X    }
X  }
X  else {
X    dataptr= image->data;
X    for (y= 0; y < h; y++)
X      for (x= 0; x < linelen; x++) {
X	if ((value= nextInt(zf)) < 0)
X	  badFile(name);
X	*(dataptr++)= value;
X      }
X  }
X
X  if (verbose) {
X    printf("%s is a %dx%d X", name, image->width, image->height);
X    if (v10p)
X      printf("10");
X    else
X      printf("11");
X    if (image->title)
X      printf(" bitmap file titled '%s'", image->title);
X    printf("\n");
X  }
X  return(image);
X}
X
X/* this is the easiest way to do this.  it's not likely we'll have mondo
X * x bitmaps anyway given their size
X */
X
Xint xbitmapIdent(fullname, name)
X     char         *fullname, *name;
X{ Image *image;
X
X  if (image= xbitmapLoad(fullname, name, 1)) {
X    freeImage(image);
X    return(1);
X  }
X  return(0);
X}
END_OF_xbitmap.c
if test 5281 -ne `wc -c <xbitmap.c`; then
    echo shar: \"xbitmap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xloadimage.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xloadimage.c\"
else
echo shar: Extracting \"xloadimage.c\" \(8052 characters\)
sed "s/^X//" >xloadimage.c <<'END_OF_xloadimage.c'
X/* loadimage.c:
X *
X * generic image loader for X11
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 "xloadimage.h"
X
X/* options array and definitions
X */
X
Xchar *Options[] = {
X  "onroot", /* global options */
X  "border",
X  "display",
X  "geometry",
X  "help",
X  "identify",
X  "list",
X  "install",
X  "path",
X  "quiet",
X  "supported",
X  "verbose",
X  "view",
X
X  "at", /* image options */
X  "background",
X  "brighten",
X  "center",
X  "clip",
X  "colors",
X  "dither",
X  "foreground",
X  "name",
X  "xzoom",
X  "yzoom",
X  "zoom",
X  NULL
X};
X
X#define ONROOT    0
X#define BORDER    1
X#define DISPLAY   2
X#define GEOMETRY  3
X#define HELP      4
X#define IDENTIFY  5
X#define LIST      6
X#define INSTALL   7
X#define PATH      8
X#define QUIET     9
X#define SUPPORTED 10
X#define VERBOSE   11
X#define VIEW      12
X
X#define AT         13
X#define BACKGROUND 14
X#define BRIGHT     15
X#define CENTER     16
X#define CLIP       17
X#define COLORS     18
X#define DITHER     19
X#define FOREGROUND 20
X#define NAME       21
X#define XZOOM      22
X#define YZOOM      23
X#define ZOOM       24
X
X/* the real thing
X */
X
Xmain(argc, argv)
X     int argc;
X     char *argv[];
X{ unsigned int  onroot= 1;
X  char         *border;
X  char         *dname;
X  unsigned int  identify;
X  unsigned int  install;
X  unsigned int  verbose;
X  Image        *dispimage;      /* image that will be sent to the display */
X  Image        *newimage;       /* new image we're loading */
X  Display      *disp;           /* display we're sending to */
X  int           scrn;           /* screen we're sending to */
X  XColor        xcolor;         /* color for border option */
X  ImageOptions  images[MAXIMAGES]; /* list of image w/ options to load */
X  unsigned int  imagecount;     /* number of images in ImageName array */
X  unsigned int  a;
X  unsigned int  winx, winy;     /* location of window */
X  unsigned int  winwidth, winheight; /* geometry of window */
X
X  if (argc < 2)
X    usage(argv[0]);
X
X  /* defaults and other initial settings.  some of these depend on what
X   * our name was when invoked.
X   */
X
X  loadPathsAndExts();
X  onroot= 0;
X  verbose= 1;
X  if (!strcmp(tail(argv[0]), "xview")) {
X    onroot= 0;
X    verbose= 1;
X  }
X  else if (!strcmp(tail(argv[0]), "xsetbg")) {
X    onroot= 1;
X    verbose= 0;
X  }
X  border= NULL;
X  dname= NULL;
X  identify= 0;
X  install= 0;
X  winx= winy= winwidth= winheight= 0;
X
X  imagecount= 0;
X  for (a= 1; a < argc; a++) {
X    switch (optionNumber(argv[a], Options)) {
X    case OPT_BADOPT:
X      printf("%s: Bad option\n", argv[a]);
X      usage(argv[0]);
X      /* NOTREACHED */
X
X    case OPT_NOTOPT:
X      if (imagecount == MAXIMAGES)
X	printf("%s: Too many images (ignoring)\n", argv[++a]);
X      else
X	images[imagecount++].name= argv[a];
X      break;
X
X    case OPT_SHORTOPT:
X      printf("%s: Not enough characters to identify option\n", argv[a]);
X      usage(argv[0]);
X      /* NOTREACHED */
X
X    /* process options global to everything
X     */
X
X    case ONROOT:
X      onroot= 1;
X      break;
X
X    case BORDER:
X      border= argv[++a];
X      break;
X
X    case DISPLAY:
X      dname= argv[++a];
X      break;
X
X    case GEOMETRY:
X      XParseGeometry(argv[++a], &winx, &winy, &winwidth, &winheight);
X      break;
X
X    case HELP:
X      usage(argv[0]);
X      exit(0);
X
X    case IDENTIFY:
X      identify= 1;
X      break;
X
X    case LIST:
X      listImages();
X      exit(0);
X
X    case INSTALL:
X      install= 1;
X      break;
X
X    case PATH:
X      showPath();
X      break;
X
X    case QUIET:
X      verbose= 0;
X      break;
X
X    case SUPPORTED:
X      supportedImageTypes();
X      break;
X
X    case VERBOSE:
X      verbose= 1;
X      break;
X
X    case VIEW:
X      onroot= 0;
X
X    /* process options local to an image
X     */
X
X    case AT:
X      if (sscanf(argv[++a], "%d,%d",
X		 &images[imagecount].atx, &images[imagecount].aty) != 2) {
X	printf("Bad argument to -at\n");
X	usage(argv[0]);
X	/* NOTREACHED */
X      }
X      break;
X
X    case BACKGROUND:
X      images[imagecount].bg= argv[++a];
X      break;
X
X    case BRIGHT:
X      images[imagecount].bright= atoi(argv[++a]);
X      break;
X
X    case CENTER:
X      images[imagecount].center= 1;
X      break;
X
X    case CLIP:
X      if (sscanf(argv[++a], "%d,%d,%d,%d",
X		 &images[imagecount].clipx, &images[imagecount].clipy,
X		 &images[imagecount].clipw, &images[imagecount].cliph) != 4) {
X	printf("Bad argument to -clip\n");
X	usage(argv[0]);
X	/* NOTREACHED */
X      }
X      break;
X
X    case COLORS:
X      images[imagecount].colors= atoi(argv[++a]);
X      if (images[imagecount].colors < 2) {
X	printf("Argument to -colors is too low (ignored)\n");
X	images[imagecount].colors= 0;
X      }
X      else if (images[imagecount].colors > 65536) {
X	printf("Argument to -colors is too high (ignored)\n");
X	images[imagecount].colors= 0;
X      }
X      break;
X
X    case DITHER:
X      images[imagecount].dither= 1;
X      break;
X
X    case FOREGROUND:
X      images[imagecount].fg= argv[++a];
X      break;
X
X    case NAME:
X      if (imagecount == MAXIMAGES)
X	printf("%s: Too many images (ignoring)\n", argv[++a]);
X      else
X	images[imagecount++].name= argv[++a];
X      break;
X
X    case XZOOM:
X      images[imagecount].xzoom= atoi(argv[++a]);
X      break;
X
X    case YZOOM:
X      images[imagecount].yzoom= atoi(argv[++a]);
X      break;
X
X    case ZOOM:
X      images[imagecount].xzoom= images[imagecount].yzoom= atoi(argv[++a]);
X      break;
X
X    default:
X
X      /* this should not happen!
X       */
X
X      printf("%s: Internal error parsing arguments\n", argv[0]);
X      exit(1);
X    }
X  }
X
X  if (!imagecount) /* NO-OP from here on */
X    exit(0);
X
X  if (identify) {                    /* identify the named image(s) */
X    for (a= 0; a < imagecount; a++)
X      identifyImage(images[a].name);
X    exit(0);
X  }
X
X  /* start talking to the display
X   */
X
X  if (! (disp= XOpenDisplay(dname))) {
X    printf("%s: Cannot open display\n", XDisplayName(dname));
X    exit(1);
X  }
X  scrn= DefaultScreen(disp);
X  XSetIOErrorHandler(ioErrorHandler);
X
X  dispimage= NULL;
X  if (onroot && (winwidth || winheight || images[0].center ||
X      images[a].atx || images[a].aty)) {
X    if (!winwidth)
X	winwidth= DisplayWidth(disp, scrn);
X    if (!winheight)
X      winheight= DisplayHeight(disp, scrn);
X    if (DefaultDepth(disp, scrn) == 1)
X      dispimage= newBitImage(winwidth, winheight);
X    else {
X      dispimage= newRGBImage(winwidth, winheight, DefaultDepth(disp, scrn));
X      dispimage->rgb.used= 1;
X    }
X    *(dispimage->rgb.red)= 65535;   /* default border value is white */
X    *(dispimage->rgb.green)= 65535;
X    *(dispimage->rgb.blue)= 65535;
X    if (border) {
X      XParseColor(disp, DefaultColormap(disp, scrn), border, &xcolor);
X      *dispimage->rgb.red= xcolor.red;
X      *dispimage->rgb.green= xcolor.green;
X      *dispimage->rgb.blue= xcolor.blue;
X    }
X    fill(dispimage, 0, 0, winwidth, winheight, 0, verbose);
X  }
X
X  /* load in each named image
X   */
X
X  for (a= 0; a < imagecount; a++) {
X    if (! (newimage= loadImage(images[a].name, verbose)))
X      continue;
X    if ((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1))
X      images[a].dither= 1;
X    newimage= processImage(disp, scrn, newimage, &images[a], verbose);
X    if (!images[a].clipw && !images[a].cliph) {
X      images[a].clipw= newimage->width;
X      images[a].cliph= newimage->height;
X    }
X    if (images[a].center) {
X      images[a].atx= (dispimage->width - images[a].clipw) / 2;
X      images[a].aty= (dispimage->height - images[a].cliph) / 2;
X    }
X    if (dispimage) {
X      if (! dispimage->title)
X	dispimage->title= dupString(newimage->title);
X      merge(dispimage, newimage, images[a].atx, images[a].aty, verbose);
X      freeImage(newimage);
X    }
X    else
X      dispimage= newimage;
X  }
X
X  if (! dispimage) {
X    printf("No images to display\n");
X    exit(1);
X  }
X
X  if (onroot)
X    imageOnRoot(disp, scrn, dispimage, install, verbose);
X  else
X    imageInWindow(disp, scrn, dispimage, winx, winy, winwidth, winheight,
X		  install, verbose);
X  XCloseDisplay(disp);
X}
END_OF_xloadimage.c
if test 8052 -ne `wc -c <xloadimage.c`; then
    echo shar: \"xloadimage.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xloadimage.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xloadimage.h\"
else
echo shar: Extracting \"xloadimage.h\" \(1509 characters\)
sed "s/^X//" >xloadimage.h <<'END_OF_xloadimage.h'
X/* xloadimage.h:
X *
X * jim frost 06.21.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#include <X11/X.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X
X#include "image.h"
X#include "options.h"
X
X/* image name and option structure used when processing arguments
X */
X
Xtypedef struct {
X  char         *name;         /* name of image */
X  int           atx, aty;     /* location to load image at */
X  unsigned int  bright;       /* brightness multiplier */
X  unsigned int  center;       /* true if image is to be centered */
X  unsigned int  clipx, clipy; /* area of image to be used */
X  unsigned int  clipw, cliph;
X  unsigned int  dither;       /* true if image is to be dithered */
X  unsigned int  colors;       /* max # of colors to use for this image */
X  char         *fg, *bg;      /* foreground/background colors if mono image */
X  unsigned int  xzoom, yzoom; /* zoom percentages */
X} ImageOptions;
X
X#ifndef MAXIMAGES
X#define MAXIMAGES BUFSIZ /* max # of images we'll try to load at once */
X#endif
X
X/* function declarations
X */
X
XZFILE *zopen(); /* io.c */
Xint    zread();
Xint    zgetc();
Xchar  *zgets();
Xvoid   zclose();
X
Xchar *tail(); /* misc.c */
Xvoid usage();
Xvoid goodImage();
XImage *processImage();
Xint ioErrorHandler();
X
Xint findImage(); /* path.c */
Xvoid listImages();
Xvoid loadPathsAndExts();
Xvoid showPath();
X
Xunsigned int sendImageToX(); /* send.c */
X
XVisual *getBestVisual(); /* visual.c */
END_OF_xloadimage.h
if test 1509 -ne `wc -c <xloadimage.h`; then
    echo shar: \"xloadimage.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xloadimage.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xloadimage.man\"
else
echo shar: Extracting \"xloadimage.man\" \(9205 characters\)
sed "s/^X//" >xloadimage.man <<'END_OF_xloadimage.man'
X.TH XLOADIMAGE 1 "7 October 1989"
X.SH NAME
Xxloadimage, xsetbg, xview \- load images into an X11 window or onto
Xthe root window
X.SH SYNOPSIS
X\fIxloadimage\fR [global_options] {[image_options] image ...}
X.SH DESCRIPTION
X\fIXloadimage\fR displays images in an X11 window or loads them onto
Xthe root window.  See the \fIIMAGE TYPES\fR section below for
Xsupported image types.  Compressed images will automatically be
Xuncompressed.
X.PP
XIf the destination display cannot support the number of colors in the
Ximage, the image will be dithered (monochrome destination) or have its
Xcolormap reduced (color destination) as appropriate.  This can also be
Xdone forcibly with the \fI-dither\fR and \fI-colors\fR options.
X.PP
XIf more than one image is to be loaded, they will be merged into a
Xsingle image.  The \fI-at\fR and \fI-center\fR options control where
Xsubsequent images will be loaded onto the initial image.  Any
Xcombination of color image depths and/or monochrome images may be
Xloaded at one time.
X.PP
XA variety of image manipulations can be specified, including
Xbrightening, clipping, dithering, depth-reduction, and zooming.  Most
Xof these manipulations have simple implementations; speed was opted
Xfor above accuracy.
X.PP
XIf you are viewing a large image in a window, the initial window will
Xbe at most 90% of the size of the display.  You may move the image
Xaround in the window by dragging with the first mouse button.  The
Xcursor will indicate which directions you may drag, if any.  You may
Xexit the window by typing 'q' or 'Q' when the keyboard focus is on the
Xwindow.
X.PP
X\fIXsetbg\fR is equivalent to \fIxloadimage -onroot -quiet\fR and
X\fIxview\fR is equivalent to \fIxloadimage -view -verbose\fR.
X.SH GLOBAL OPTIONS
XThe following options affect the global operation of \fIxloadimage\fR.
XThey may be specified anywhere on the command line.
X.TP 8
X-border \fIcolor\fR
XThis sets the background portion of the window which is not covered by
Xany images to be \fIcolor\fR.
X.TP
X-colors \fIn\fR
XSpecify the maximum number of colors to use in the image.  This is a
Xway to forcibly reduce the depth of an image.
X.TP
X-display \fIdisplay_name\fR
XX11 display name to send the image(s) to.
X.TP
X-geometry \fIWxH[{+-X}{+-}Y]\fR
XThis sets the size of the window onto which the images are loaded to a
Xdifferent value than the size of the image.  When viewing an image in
Xa window, this can be used to reduce the size of the destination
Xwindow.  When loading an image onto the root window, this option
Xcontrols the size of the pixmap which will be loaded onto the root.
XIf the size is smaller than that of the display, the image will be
Xreplicated.
X.TP
X-install
XForcibly install the image's colormap when the window is focused.
XThis violates ICCCM standards and only exists to allow operation with
Xnaive window managers.  Use this option only if your window manager
Xdoes not install colormaps properly.
X.TP
X-list
XList the images which are along the image path.
X.TP
X-help
XDisplays a short summary of xloadimage command line syntax.
X.TP
X-onroot
XLoad image(s) onto the root window instead of viewing in a window.
XThis is the opposite of \fI-view\fR.  \fIXSetbg\fR has this option set
Xby default.
X.TP
X-path
XDisplays the image path and image suffixes which will be used when
Xlooking for images.  These are loaded from ~/.xloadimagerc and
Xoptionally from a systemwide file (normally /usr/lib/xloadimagerc).
X.TP
X-quiet
XForces \fIxloadimage\fR and \fIxview\fR to be quiet.  This is the
Xdefault for \fIxsetbg\fR, but the others like to whistle. 
X.TP
X-supported
XList the supported image types. 
X.TP
X-verbose
XCauses \fIxloadimage\fR to be talkative, telling you what kind of
Ximage it's playing with and any special processing that it has to do. 
XThis is the default for \fIxview\fR and \fIxloadimage\fR. 
X.TP
X-view
XView image(s) in a window.  This is the opposite of \fI-onroot\fR and
Xthe default for \fIxsetbg\fR. 
X.SH IMAGE OPTIONS
XThe following options may preceed each image.  These options are
Xlocal to the image they preceed. 
X.TP
X-background \fIcolor\fR
XUse \fIcolor\fR as the background color instead of the default
X(usually white but this depends on the image type) if you are
Xtransferring a monochrome image to a color display. 
X.TP
X-brighten \fIpercentage\fR
XSpecify a percentage multiplier for a color image's colormap.  A value
Xof more than 100 will brighten an image, one of less than 100 will
Xdarken it. 
X.TP
X-center
XCenter the image on the first image loaded.  If this is an option to
Xthe first image, and the \fI-onroot\fR option is specified, the image
Xwill be centered on the display background. 
X.TP
X-at \fIX\fR,\fIY\fR
XIndicates coordinates to load the image at on the first image.  If
Xthis is an option to the first image, and the \fI-onroot\fR option is
Xspecified, the image will be loaded at the given location on the
Xdisplay background. 
X.TP
X-clip \fIX\fR,\fIY\fR,\fIW\fR,\fIH\fR
XClip the image before loading it.  \fIX\fR and \fIY\fR define the
Xupper-left corner of the clip area, and \fIW\fR and \fIH\fR define the
Xextents of the area.  A zero value for \fIW\fR or \fIH\fR will be
Xinterpreted as the remainder of the image. 
X.TP
X-dither
XForce halftone dithering of a color image when displaying on a color
Xdisplay.  This happens by default when viewing color images on a
Xmonochrome display.  This option is ignored on monochrome images. 
X.TP
X-foreground \fIcolor\fR
XUse \fIcolor\fR as the foreground color instead of black if you are
Xtransferring a monochrome image to a color display.  This can also be
Xused to invert the foreground and background colors of a monochrome
Ximage. 
X.TP
X-name \fIimage_name\fR
XForce the next argument to be treated as an image name.  This is
Xuseful if the name of the image is \fI-dither\fR, for instance. 
X.TP
X-xzoom \fIpercentage\fR
XZoom the X axis of an image by \fIpercentage\fR.  A number greater
Xthan 100 will expand the image, one smaller will compress it.  A zero
Xvalue will be ignored. 
X.TP
X-yzoom \fIpercentage\fR
XZoom the Y axis of an image by \fIpercentage\fR.  See \fI-xzoom\fR for
Xmore information. 
X.TP
X-zoom \fIpercentage\fR
XZoom both the X and Y axes by \fIpercentage\fR.  See \fI-xzoom\fR for
Xmore information. 
X.SH EXAMPLES
XTo load the rasterfile "my.image" onto the background and replicate
Xit to fill the entire background:
X.sp
X.ti +5
Xxloadimage my.image
X.PP
XTo load a monochrome image "my.image" onto the background, using red
Xas the foreground color, replicate the image, and overlay
X"another.image" onto it at coordinate (10,10):
X.sp
X.ti +5
Xxloadimage -foreground red my.image -at 10,10 another.image
X.PP
XTo center the rectangular region from 10 to 110 along the X axis and
Xfrom 10 to the height of the image along the Y axis:
X.sp
X.ti +5
Xxloadimage -center -clip 10,10,100,0 my.image
X.SH PATHS AND EXTENSIONS
XThe file ~/.xloadimagerc (and optionally a system-wide file which is
Xsystem-specific) defines the path and default extensions that
X.I xloadimage
Xwill use when looking for images.  The file can have two statements:
X"path=" and "extension=" (the equals signs must follow the word with
Xno spaces between).  Everything following the "path=" keyword
Xwill be prepended to the supplied image name if the supplied name does
Xnot specify an existing file.  The paths will be searched in the order
Xthey are specified.  Everything following the "extension=" keyword
Xwill be appended to the supplied image name if the supplied name does
Xnot specify and existing file.  As with paths, these extensions will
Xbe searched in the order they are given.  Comments are any portion of
Xa line following a hash-mark (#).  The following is a sample
X~/.xloadimagerc file:
X.PP
X.nf
X  # paths to look for images in
X  path= /usr/local/images
X        /home/usr1/guest/madd/images
X        /usr/include/X11/bitmaps
X
X  # default extensions for images; .Z is automatic; scanned in order
X  extension= .csun .msun .sun .face .xbm .bm
X.fi
X.SH IMAGE TYPES
X.PP
X\fIXloadimage\fR currently supports the following image types:
X.nf
X  Faces Project images
X  Portable Bitmap (PBM) images
X  Sun monochrome rasterfiles
X  Sun color RGB rasterfiles
X  X10 bitmap files
X  X11 bitmap files
X.fi
X.PP
XBoth normal and compact PBM images are supported.  Both standard and
Xrun-length encoded Sun rasterfiles are supported.
X.SH AUTHOR
X.nf
XJim Frost
XSoftware Tool & Die
Xmadd at std.com
X.fi
X.SH BUGS
XLoading images onto the root with PseudoColor or GrayScale displays
Xcan cause colormap problems (and may interfere with window manager
Xoperation) if there are not enough colors in the default colormap to
Xallocate all of the colors read/write.  This can happen on images
Xwhich have too many unique colors or if images are loaded onto the
Xroot in succession.  Since there is currently no X standard for
Xchanging the root colormap, this problem may or may not be corrected
Xin the future.
X.PP
XSince \fIxloadimage\fR does not want a window larger than the image to
Xbe displayed, it resizes the window to fit the image if the window
Xmanager resizes the window to a size which is too large.  This could
Xcause a conflict if the window manager responds to the resize request
Xby resizing the window to the larger size.  This should be rare given
Xthe state of current window managers and has never been observed.
END_OF_xloadimage.man
if test 9205 -ne `wc -c <xloadimage.man`; then
    echo shar: \"xloadimage.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f zio.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"zio.c\"
else
echo shar: Extracting \"zio.c\" \(1380 characters\)
sed "s/^X//" >zio.c <<'END_OF_zio.c'
X/* zio.c:
X *
X * this properly opens and reads from an image file, compressed or otherwise.
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 "image.h"
X
XZFILE *zopen(name)
X     char *name;
X{ ZFILE *zf;
X  char   buf[BUFSIZ];
X
X  zf= (ZFILE *)lmalloc(sizeof(ZFILE));
X  if ((strlen(name) > 2) && !strcmp(".Z", name + (strlen(name) - 2))) {
X    zf->type= ZPIPE;
X    sprintf(buf, "uncompress -c %s", name);
X    if (! (zf->stream= popen(buf, "r"))) {
X      lfree(zf);
X      return(NULL);
X    }
X    return(zf);
X  }
X  zf->type= ZSTANDARD;
X  if (! (zf->stream= fopen(name, "r"))) {
X    lfree(zf);
X    return(NULL);
X  }
X  return(zf);
X}
X
Xint zread(zf, buf, len)
X     ZFILE        *zf;
X     byte         *buf;
X     unsigned int  len;
X{ int r;
X
X  if ((r= fread(buf, len, 1, zf->stream)) != 1)
X    return(r);
X  return(len);
X}
X
Xint zgetc(zf)
X     ZFILE *zf;
X{
X  return(fgetc(zf->stream));
X}
X
Xchar *zgets(buf, size, zf)
X     char         *buf;
X     unsigned int  size;
X     ZFILE        *zf;
X{
X  return(fgets(buf, size, zf->stream));
X}
X
Xvoid zclose(zf)
X     ZFILE *zf;
X{
X  switch(zf->type) {
X  case ZSTANDARD:
X    fclose(zf->stream);
X    break;
X  case ZPIPE:
X    pclose(zf->stream);
X    break;
X  default:
X    printf("zclose: bad ZFILE structure\n");
X    exit(1);
X  }
X  lfree(zf);
X}
END_OF_zio.c
if test 1380 -ne `wc -c <zio.c`; then
    echo shar: \"zio.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f zoom.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"zoom.c\"
else
echo shar: Extracting \"zoom.c\" \(4142 characters\)
sed "s/^X//" >zoom.c <<'END_OF_zoom.c'
X/* zoom.c:
X *
X * zoom an image
X *
X * jim frost 10.11.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 unsigned int *buildIndex(width, zoom, rwidth)
X     unsigned int  width;
X     unsigned int  zoom;
X     unsigned int *rwidth;
X{ float         fzoom;
X  unsigned int *index;
X  unsigned int  a;
X
X  if (!zoom) {
X    fzoom= 100.0;
X    *rwidth= width;
X  }
X  else {
X    fzoom= (float)zoom / 100.0;
X    *rwidth= fzoom * width;
X  }
X  index= (unsigned int *)lmalloc(sizeof(unsigned int) * *rwidth);
X  for (a= 0; a < *rwidth; a++)
X    if (zoom)
X      *(index + a)= (float)a / fzoom;
X    else
X      *(index + a)= a;
X  return(index);
X}
X
XImage *zoom(oimage, xzoom, yzoom, verbose)
X     Image        *oimage;
X     unsigned int  xzoom, yzoom;
X{ char          buf[BUFSIZ];
X  Image        *image;
X  unsigned int *xindex, *yindex;
X  unsigned int  xwidth, ywidth;
X  unsigned int  x, y, xsrc, ysrc;
X  unsigned int  pixlen;
X  unsigned int  srclinelen;
X  byte         *srcline, *srcptr;
X  byte         *destptr;
X  byte          srcmask, destmask, bit;
X  Pixel         value;
X
X  goodImage(oimage, "zoom");
X
X  if (!xzoom && !yzoom) /* stupid user */
X    return(NULL);
X
X  if (verbose) {
X    if (!xzoom) {
X      printf("  Zooming image Y axis by %d%%...", yzoom);
X      sprintf(buf, "%s (Y zoom %d%%)", oimage->title, yzoom);
X    }
X    else if (!yzoom) {
X      printf("  Zooming image X axis by %d%%...", xzoom);
X      sprintf(buf, "%s (X zoom %d%%)", oimage->title, xzoom);
X    }
X    else if (xzoom == yzoom) {
X      printf("  Zooming image by %d%%...", xzoom);
X      sprintf(buf, "%s (%d%% zoom)", oimage->title, xzoom);
X    }
X    else {
X      printf("  Zooming image X axis by %d%% and Y axix by %d%%...",
X	     xzoom, yzoom);
X      sprintf(buf, "%s (X zoom %d%% Y zoom %d%%)", oimage->title,
X	      xzoom, yzoom);
X    }
X    fflush(stdout);
X  }
X
X  xindex= buildIndex(oimage->width, xzoom, &xwidth);
X  yindex= buildIndex(oimage->height, yzoom, &ywidth);
X
X  switch (oimage->type) {
X  case IBITMAP:
X    image= newBitImage(xwidth, ywidth);
X    for (x= 0; x < oimage->rgb.used; x++) {
X      *(image->rgb.red + x)= *(oimage->rgb.red + x);
X      *(image->rgb.green + x)= *(oimage->rgb.green + x);
X      *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
X    }
X    image->rgb.used= oimage->rgb.used;
X    destptr= image->data;
X    srcline= oimage->data;
X    srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
X    for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
X      while (ysrc != *(yindex + y)) {
X	ysrc++;
X	srcline += srclinelen;
X      }
X      srcptr= srcline;
X      srcmask= 0x80;
X      destmask= 0x80;
X      bit= srcmask & *srcptr;
X      for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) {
X	if (xsrc != *(xindex + x)) {
X	  do {
X	    xsrc++;
X	    if (!(srcmask >>= 1)) {
X	      srcmask= 0x80;
X	      srcptr++;
X	    }
X	  } while (xsrc != *(xindex + x));
X	  bit= srcmask & *srcptr;
X	}
X	if (bit)
X	  *destptr |= destmask;
X	if (!(destmask >>= 1)) {
X	  destmask= 0x80;
X	  destptr++;
X	}
X      }
X    }
X    break;
X
X  case IRGB:
X    image= newRGBImage(xwidth, ywidth, oimage->depth);
X    for (x= 0; x < oimage->rgb.used; x++) {
X      *(image->rgb.red + x)= *(oimage->rgb.red + x);
X      *(image->rgb.green + x)= *(oimage->rgb.green + x);
X      *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
X    }
X    image->rgb.used= oimage->rgb.used;
X    pixlen= oimage->pixlen;
X    destptr= image->data;
X    srcline= oimage->data;
X    srclinelen= oimage->width * pixlen;
X    for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
X      while (ysrc != *(yindex + y)) {
X	ysrc++;
X	srcline += srclinelen;
X      }
X
X      srcptr= srcline;
X      value= memToVal(srcptr, pixlen);
X      for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) {
X	if (xsrc != *(xindex + x)) {
X	  do {
X	    xsrc++;
X	    srcptr += image->pixlen;
X	  } while (xsrc != *(xindex + x));
X	  value= memToVal(srcptr, pixlen);
X	}
X	valToMem(value, destptr++, pixlen);
X      }
X    }
X    break;
X  }
X
X  image->title= dupString(buf);
X  lfree(xindex);
X  lfree(yindex);
X  if (verbose)
X    printf("done\n");
X  return(image);
X}
END_OF_zoom.c
if test 4142 -ne `wc -c <zoom.c`; then
    echo shar: \"zoom.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    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



More information about the Comp.sources.x mailing list