argv@island.uu.net (Dan Heller) (11/14/89)
Submitted-by: madd@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@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@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@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@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@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@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