jimf@saber.com (09/28/90)
Submitted-by: saber.com!jimf@saber.com Posting-number: Volume 9, Issue 50 Archive-name: xloadimage/part03 #! /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 3 (of 9)." # Contents: mrmcpyrght.h bright.c clip.c cmuwmraster.c compress.c # dither.c faces.c fbm.c fill.c g3.c imagetypes.c options.c # Wrapped by jimf@armory on Tue Sep 25 19:37:40 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'mrmcpyrght.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mrmcpyrght.h'\" else echo shar: Extracting \"'mrmcpyrght.h'\" \(1079 characters\) sed "s/^X//" >'mrmcpyrght.h' <<'END_OF_FILE' X#ifndef _MRM_COPYRIGHT_ X X/**** X Copyright 1990 Mark Majhor X X Permission to use, copy, modify, distribute, and sell this X software and its documentation for any purpose is hereby granted X without fee, provided that the above copyright notice appear in X all copies and that both that copyright notice and this X permission notice appear in supporting documentation. The X author makes no representations about the suitability of this X software for any purpose. It is provided "as is" without express X or implied warranty. X X THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, X INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, X IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT X OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM X LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, X NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X****/ X Xstatic char *MRMCopyright = "Copyright 1990 Mark Majhor"; X#define _MRM_COPYRIGHT_ X#endif END_OF_FILE if test 1079 -ne `wc -c <'mrmcpyrght.h'`; then echo shar: \"'mrmcpyrght.h'\" unpacked with wrong size! fi # end of 'mrmcpyrght.h' fi if test -f 'bright.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'bright.c'\" else echo shar: Extracting \"'bright.c'\" \(1733 characters\) sed "s/^X//" >'bright.c' <<'END_OF_FILE' 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 unsigned 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} X Xvoid gammacorrect(image, disp_gam, verbose) X Image *image; X float disp_gam; X unsigned int verbose; X{ int a; X int gammamap[256]; X X if (! RGBP(image)) /* we're AT&T */ X return; X X if (verbose) { X printf(" Adjusting colormap for display gamma of %4.2f...", disp_gam); X fflush(stdout); X } X X make_gamma(disp_gam,gammamap); X X for (a= 0; a < image->rgb.used; a++) { X *(image->rgb.red + a)= gammamap[(*(image->rgb.red + a))>>8]<<8; X *(image->rgb.green + a)= gammamap[(*(image->rgb.green + a))>>8]<<8; X *(image->rgb.blue + a)= gammamap[(*(image->rgb.blue + a))>>8]<<8; X } X X if (verbose) X printf("done\n"); X} END_OF_FILE if test 1733 -ne `wc -c <'bright.c'`; then echo shar: \"'bright.c'\" unpacked with wrong size! fi # end of 'bright.c' fi if test -f 'clip.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'clip.c'\" else echo shar: Extracting \"'clip.c'\" \(2780 characters\) sed "s/^X//" >'clip.c' <<'END_OF_FILE' 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 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_FILE if test 2780 -ne `wc -c <'clip.c'`; then echo shar: \"'clip.c'\" unpacked with wrong size! fi # end of 'clip.c' fi if test -f 'cmuwmraster.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cmuwmraster.c'\" else echo shar: Extracting \"'cmuwmraster.c'\" \(2722 characters\) sed "s/^X//" >'cmuwmraster.c' <<'END_OF_FILE' X/* X * X * handle CMU Window Manager (ITC) raster image type X * X * dan lovinger (dl2n+@andrew.cmu.edu) 07.11.90 X * X * the format is essentially a byte-reversed sun raster w/o encoding 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 "cmuwmraster.h" X Xint babble(name, headerp) Xchar *name; Xstruct cmuwm_header *headerp; X{ X printf("%s is a %dx%d %d plane CMU WM raster\n", X name, X memToVal(headerp->width, sizeof(long)), X memToVal(headerp->height, sizeof(long)), X memToVal(headerp->depth, sizeof(short))); X} X Xint cmuwmIdent(fullname, name) Xchar *fullname, *name; X{ X ZFILE *zf; X struct cmuwm_header header; X int r; X X if (!(zf = zopen(fullname))) X { X perror("cmuwmIdent"); X return(0); X } X X switch (zread(zf, &header, sizeof(struct cmuwm_header))) X { X case -1: X perror("cmuwmIdent"); X r =0; X break; X X case sizeof(struct cmuwm_header): X if (memToVal(header.magic, sizeof(long)) != CMUWM_MAGIC) X { 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 X zclose(zf); X X return r; X} X XImage* cmuwmLoad(fullname, name, verbose) Xchar *fullname, *name; Xunsigned int verbose; X{ X ZFILE *zf; X struct cmuwm_header header; X Image *image; X int depth, height, width, row, col, linelen, r; X byte *lineptr; X X if (!(zf= zopen(fullname))) X { X perror("cmuwmLoad"); X return(NULL); X } X X switch (zread(zf, &header, sizeof(struct cmuwm_header))) X { X case -1: X perror("cmuwmLoad"); X zclose(zf); X exit(1); X X case sizeof(struct cmuwm_header): X if (memToVal(header.magic, sizeof(long)) != CMUWM_MAGIC) X { X zclose(zf); X return(NULL); X } X if (verbose) babble(name, &header); X break; X X default: X zclose(zf); X return(NULL); X } X X if (memToVal(header.depth, sizeof(short)) != 1) X { X fprintf(stderr,"CMU WM raster %s is of depth %d, must be 1", X name, X depth); X return(NULL); X } X X image = newBitImage(width = memToVal(header.width, sizeof(long)), X height = memToVal(header.height, sizeof(long))); X X linelen = (width / 8) + (width % 8 ? 1 : 0); X lineptr = image->data; X X for (row = 0; row < height; row++) X { X r = zread(zf, lineptr, linelen); X X if (r == -1) X { X perror("cmuwmLoad"); X exit(1); X } X X if (r != linelen) X { X printf("cmuwmLoad: short raster\n"); X exit(1); X } X X for (r = 0; r < linelen; r++) X { X lineptr[r] ^= 0xff; X } X X lineptr += linelen; X } X X zclose(zf); X X image->title = dupString(name); X X return image; X} X X X X X END_OF_FILE if test 2722 -ne `wc -c <'cmuwmraster.c'`; then echo shar: \"'cmuwmraster.c'\" unpacked with wrong size! fi # end of 'cmuwmraster.c' fi if test -f 'compress.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'compress.c'\" else echo shar: Extracting \"'compress.c'\" \(2391 characters\) sed "s/^X//" >'compress.c' <<'END_OF_FILE' X/* compress.c: X * X * compress a colormap by removing unused RGB colors X * X * jim frost 10.05.89 X * X * Copyright 1989, 1990 Jim Frost. See included file "copyright.h" for X * complete 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, *pixptr2; X unsigned int a, x, y; X Pixel color, newpixlen; 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 X/* Okay, we've compressed the colors, let's do the image */ X for (y=0,x=1;rgb.used>x;y++) x=x*2; X newpixlen = (y / 8) + (y % 8 ? 1 : 0); X if (newpixlen < image->pixlen) X { X if (verbose) X printf(" Compressing image...");fflush(stdout); X pixptr = image->data; pixptr2 = image->data; X for (y= 0; y < image->height; y++) X for (x= 0; x < image->width; x++) { X valToMem(memToVal(pixptr2,image->pixlen), pixptr, newpixlen); X pixptr2 += image->pixlen; X pixptr += newpixlen; X } X image->pixlen = newpixlen; X if (verbose) X printf("done\n"); X } X X} END_OF_FILE if test 2391 -ne `wc -c <'compress.c'`; then echo shar: \"'compress.c'\" unpacked with wrong size! fi # end of 'compress.c' fi if test -f 'dither.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dither.c'\" else echo shar: Extracting \"'dither.c'\" \(6159 characters\) sed "s/^X//" >'dither.c' <<'END_OF_FILE' X/* dither.c X * X * completely reworked dithering module for xloadimage X * uses error-diffusion dithering (floyd-steinberg) instead X * of simple 4x4 ordered-dither that was previously used X * X * the previous version of this code was written by steve losen X * (scl@virginia.edu) X * X * jim frost 07.10.89 X * Steve Losen 11.17.89 X * kirk johnson 06.04.90 X * X * Copyright 1990 Kirk L. Johnson (see the included file X * "kljcpyrght.h" for complete copyright information) X * X * Copyright 1989, 1990 Jim Frost and Steve Losen. See included file X * "copyright.h" for complete copyright information. X */ X X#include "copyright.h" X#include "kljcpyrght.h" X#include "image.h" X X#define RedPercent 0.299 X#define GrnPercent 0.587 /* color -> grey conversion parameters */ X#define BluPercent 0.114 X X#define MaxIntensity 65536 /* maximum possible Intensity */ X X#define MaxGrey 32768 /* limits on the grey levels used */ X#define Threshold 16384 /* in the dithering process */ X#define MinGrey 0 X Xstatic unsigned int tone_scale_adjust(); Xstatic void LeftToRight(); Xstatic void RightToLeft(); X X X/* X * simple floyd-steinberg dither with serpentine raster processing X */ X XImage *dither(cimage, verbose) X Image *cimage; X unsigned int verbose; X{ X Image *image; /* destination image */ X unsigned int *grey; /* grey map for source image */ X double tmp; /* work space */ X unsigned int spl; /* source pixel length in bytes */ X unsigned int dll; /* destination line length in bytes */ X unsigned char *src; /* source data */ X unsigned char *dst; /* destination data */ X int *curr; /* current line buffer */ X int *next; /* next line buffer */ X int *swap; /* for swapping line buffers */ X Pixel color; /* pixel color */ X unsigned int level; /* grey level */ X unsigned int i, j; /* loop counters */ X X /* X * check the source image X */ X goodImage(cimage, "dither"); X if (! RGBP(cimage)) X return(NULL); X X /* X * allocate destination image X */ X if (verbose) X { X printf(" Dithering image..."); X fflush(stdout); X } X image = newBitImage(cimage->width, cimage->height); X if (cimage->title) X { X image->title = (char *)lmalloc(strlen(cimage->title) + 12); X sprintf(image->title, "%s (dithered)", cimage->title); X } X X /* X * if the number of entries in the colormap isn't too large, compute X * the grey level for each entry and store it in grey[]. else the X * grey levels will be computed on the fly. X */ X if (cimage->depth <= 16) X { X grey = (unsigned int *)lmalloc(sizeof(unsigned int) * cimage->rgb.used); X for (i=0; i<cimage->rgb.used; i++) X { X tmp = (cimage->rgb.red[i] * RedPercent); X tmp += (cimage->rgb.green[i] * GrnPercent); X tmp += (cimage->rgb.blue[i] * BluPercent); X X grey[i] = (tmp / MaxIntensity) * MaxGrey; X } X X for (i=0; i<cimage->rgb.used; i++) X grey[i] = tone_scale_adjust(grey[i]); X } X else X { X grey = NULL; X } X X /* X * dither setup X */ X spl = cimage->pixlen; X dll = (image->width / 8) + (image->width % 8 ? 1 : 0); X src = cimage->data; X dst = image->data; X X curr = (int *)lmalloc(sizeof(int) * (cimage->width + 2)); X next = (int *)lmalloc(sizeof(int) * (cimage->width + 2)); X curr += 1; X next += 1; X for (j=0; j<cimage->width; j++) X { X curr[j] = 0; X next[j] = 0; X } X X /* X * primary dither loop X */ X for (i=0; i<cimage->height; i++) X { X /* copy the row into the current line */ X for (j=0; j<cimage->width; j++) X { X color = memToVal(src, spl); X src += spl; X X if (grey == NULL) X { X tmp = (cimage->rgb.red[color] * RedPercent); X tmp += (cimage->rgb.green[color] * GrnPercent); X tmp += (cimage->rgb.blue[color] * BluPercent); X X level = tone_scale_adjust((tmp / MaxIntensity) * MaxGrey); X } X else X { X level = grey[color]; X } X X curr[j] += level; X } X X /* dither the current line */ X if (i & 0x01) X RightToLeft(curr, next, cimage->width); X else X LeftToRight(curr, next, cimage->width); X X /* copy the dithered line to the destination image */ X for (j=0; j<cimage->width; j++) X if (curr[j] < Threshold) X dst[j / 8] |= 1 << (7 - (j & 7)); X dst += dll; X X /* circulate the line buffers */ X swap = curr; X curr = next; X next = swap; X for (j=0; j<cimage->width; j++) X next[j] = 0; X } X X /* X * clean up X */ X lfree(grey); X lfree(curr-1); X lfree(next-1); X if (verbose) X printf("done\n"); X X return(image); X} X X X/* X * a _very_ simple tone scale adjustment routine. provides a piecewise X * linear mapping according to the following: X * X * input: output: X * 0 (MinGrey) 0 (MinGrey) X * Threshold Threshold/2 X * MaxGrey MaxGrey X * X * this should help things look a bit better on most displays. X */ Xstatic unsigned int tone_scale_adjust(val) X unsigned int val; X{ X unsigned int rslt; X X if (val < Threshold) X rslt = val / 2; X else X rslt = (((val - Threshold) * (MaxGrey-(Threshold/2))) / X (MaxGrey-Threshold)) + (Threshold/2); X X return rslt; X} X X X/* X * dither a line from left to right X */ Xstatic void LeftToRight(curr, next, width) X int *curr; X int *next; X int width; X{ X int idx; X int error; X int output; X X for (idx=0; idx<width; idx++) X { X output = (curr[idx] > Threshold) ? MaxGrey : MinGrey; X error = curr[idx] - output; X curr[idx] = output; X next[idx-1] += error * 3 / 16; X next[idx] += error * 5 / 16; X next[idx+1] += error * 1 / 16; X curr[idx+1] += error * 7 / 16; X } X} X X X/* X * dither a line from right to left X */ Xstatic void RightToLeft(curr, next, width) X int *curr; X int *next; X int width; X{ X int idx; X int error; X int output; X X for (idx=(width-1); idx>=0; idx--) X { X output = (curr[idx] > Threshold) ? MaxGrey : MinGrey; X error = curr[idx] - output; X curr[idx] = output; X next[idx+1] += error * 3 / 16; X next[idx] += error * 5 / 16; X next[idx-1] += error * 1 / 16; X curr[idx-1] += error * 7 / 16; X } X} END_OF_FILE if test 6159 -ne `wc -c <'dither.c'`; then echo shar: \"'dither.c'\" unpacked with wrong size! fi # end of 'dither.c' fi if test -f 'faces.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'faces.c'\" else echo shar: Extracting \"'faces.c'\" \(3903 characters\) sed "s/^X//" >'faces.c' <<'END_OF_FILE' 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 "image.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(fullname, name, 1)) { X freeImage(image); X return(1); X } X return(0); X} END_OF_FILE if test 3903 -ne `wc -c <'faces.c'`; then echo shar: \"'faces.c'\" unpacked with wrong size! fi # end of 'faces.c' fi if test -f 'fbm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fbm.c'\" else echo shar: Extracting \"'fbm.c'\" \(6960 characters\) sed "s/^X//" >'fbm.c' <<'END_OF_FILE' X/* X * fbm.c: X * X * adapted from code by Michael Mauldin, (mlm) at Carnegie-Mellon X * University, (fbm tools) and Kirk L. Johnson, (tuna@athena.mit.edu), X * (gif.c). X * X * fbmin.c X * Mark Majhor X * August 1990 X * X * routines for reading FBM files X * X * Copyright 1990 Mark Majhor (see the included file X * "mrmcpyrght.h" for complete copyright information) X */ X# include <stdio.h> X# include <math.h> X# include <ctype.h> X# include "image.h" X# include "fbm.h" X X/**** X ** X ** local variables X ** X ****/ X Xstatic BYTE file_open = 0; /* status flags */ Xstatic BYTE image_open = 0; X Xstatic ZFILE *ins; /* input stream */ Xstatic FBMFILEHDR phdr; /* header structure */ X X/**** X ** X ** global variables X ** X ****/ X Xstatic int fbmin_img_width; /* image width */ Xstatic int fbmin_img_height; /* image height */ Xstatic int fbmin_img_depth; /* image depth */ Xstatic int fbmin_img_bits; /* color bits */ Xstatic int fbmin_img_rowlen; /* length of one row of data */ Xstatic int fbmin_img_plnlen; /* length of one plane of data */ Xstatic int fbmin_img_clrlen; /* length of the colormap */ Xstatic int fbmin_img_aspect; /* image aspect ratio */ Xstatic int fbmin_img_physbits; /* physical bits per pixel */ Xstatic char *fbmin_img_title; /* name of image */ Xstatic char *fbmin_img_credit; /* credit for image */ X X/* X * open FBM image in the input stream; returns FBMIN_SUCCESS if X * successful. (might also return various FBMIN_ERR codes.) X */ Xstatic int fbmin_open_image(s) XZFILE *s; X{ X char *hp; /* header pointer */ X int c; X X /* make sure there isn't already a file open */ X if (file_open) X return(FBMIN_ERR_FAO); X X /* remember that we've got this file open */ X file_open = 1; X ins = s; X X /* read in the fbm file header */ X hp = (char *) &phdr; X if (zread(ins, hp, sizeof(phdr)) != sizeof(phdr)) X return FBMIN_ERR_EOF; X X if (strncmp(FBM_MAGIC, phdr.magic, sizeof(FBM_MAGIC)) != 0) X return FBMIN_ERR_BAD_SIG; X X /* Now extract relevant features of FBM file header */ X fbmin_img_width = atoi(phdr.cols); X fbmin_img_height = atoi(phdr.rows); X fbmin_img_depth = atoi(phdr.planes); X fbmin_img_bits = atoi(phdr.bits); X fbmin_img_rowlen = atoi(phdr.rowlen); X fbmin_img_plnlen = atoi(phdr.plnlen); X fbmin_img_clrlen = atoi(phdr.clrlen); X fbmin_img_aspect = atoi(phdr.aspect); X fbmin_img_physbits = atoi(phdr.physbits); X fbmin_img_title = phdr.title; X fbmin_img_credit = phdr.credits; X X if (fbmin_image_test() != FBMIN_SUCCESS) X return FBMIN_ERR_BAD_SD; X X return FBMIN_SUCCESS; X} X X/* X * close an open FBM file X */ X Xstatic int fbmin_close_file() X{ X /* make sure there's a file open */ X if (!file_open) X return FBMIN_ERR_NFO; X X /* mark file (and image) as closed */ X file_open = 0; X image_open = 0; X X /* done! */ X return FBMIN_SUCCESS; X} X Xstatic fbmin_image_test() X{ X if (fbmin_img_width < 1 || fbmin_img_width > 32767) { X fprintf (stderr, "Invalid width (%d) on input\n", fbmin_img_width); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_height < 1 || fbmin_img_height > 32767) { X fprintf (stderr, "Invalid height (%d) on input\n", fbmin_img_height); X return (0); X } X X if (fbmin_img_depth != 1 && fbmin_img_depth != 3) { X fprintf (stderr, "Invalid number of planes (%d) on input %s\n", X fbmin_img_depth, "(must be 1 or 3)"); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_bits < 1 || fbmin_img_bits > 8) { X fprintf (stderr, "Invalid number of bits (%d) on input %s\n", X fbmin_img_bits, "(must be [1..8])"); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_physbits != 1 && fbmin_img_physbits != 8) { X fprintf (stderr, "Invalid number of physbits (%d) on input %s\n", X fbmin_img_physbits, "(must be 1 or 8)"); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_rowlen < 1 || fbmin_img_rowlen > 32767) { X fprintf (stderr, "Invalid row length (%d) on input\n", X fbmin_img_rowlen); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_depth > 1 && fbmin_img_plnlen < 1) { X fprintf (stderr, "Invalid plane length (%d) on input\n", X fbmin_img_plnlen); X return FBMIN_ERR_BAD_SD; X } X X if (fbmin_img_aspect < 0.01 || fbmin_img_aspect > 100.0) { X fprintf (stderr, "Invalid aspect ratio %lg on input\n", X fbmin_img_aspect); X return FBMIN_ERR_BAD_SD; X } X return FBMIN_SUCCESS; X} X X/* X * semi-graceful fatal error mechanism X */ X Xstatic fbmin_fatal(msg) X char *msg; X{ X printf("Error reading FBM file: %s\n", msg); X exit(0); X} X X/* X * these are the routines added for interfacing to xloadimage X */ X X/* X * tell someone what the image we're loading is. this could be a little more X * descriptive but I don't care X */ X Xstatic void tellAboutImage(name) X char *name; X{ X printf("%s is a %dx%d FBM image with %d colors\n", name, X fbmin_img_width, fbmin_img_height, fbmin_img_clrlen / 3); X} X XImage *fbmLoad(fullname, name, verbose) X char *fullname, *name; X unsigned int verbose; X{ X ZFILE *zf; X Image *image; X register int x, y, c, j, k, mask, bit, ubyte, rowlen, plnlen; X int totalBytes, hdrbits; X unsigned char *pixptr, *scan, *cm; X extern int Scrn; X unsigned char *r, *g, *b; X X if (! (zf= zopen(fullname))) X return(NULL); X if (fbmin_open_image(zf) != FBMIN_SUCCESS) { /* read image header */ X fbmin_close_file(); X zclose(zf); X return(NULL); X } X if (verbose) X tellAboutImage(name); X X image = newRGBImage(fbmin_img_width, fbmin_img_height, fbmin_img_bits); X X /* if image has a local colormap, override global colormap X */ X if (fbmin_img_clrlen > 0) { X cm = (unsigned char *) lmalloc(fbmin_img_clrlen); X X if (zread(ins, cm, fbmin_img_clrlen) != fbmin_img_clrlen) { X fprintf (stderr, "can't read colormap (%d bytes)\n", fbmin_img_clrlen); X return(NULL); X } X /* X * fbm color map is organized as X * buf[3][16] X */ X y = fbmin_img_clrlen / 3; X r = &cm[0], g = &cm[y], b = &cm[2 * y]; X for (x = 0; x < y; x++, r++, g++, b++) { X image->rgb.red[x] = *r << 8; X image->rgb.green[x] = *g << 8; X image->rgb.blue[x] = *b << 8; X } X image->rgb.used = y; X X } else X cm = NULL; X X rowlen = fbmin_img_rowlen; X plnlen = fbmin_img_plnlen; X X for (k = 0; k < fbmin_img_depth; k++) { X pixptr = &(image->data[k * plnlen]); X X for (j = 0; j < fbmin_img_height; j++, pixptr += rowlen) { X if (zread(ins, pixptr, rowlen) != rowlen) { X printf("%s: Short read within image data\n", fullname); X exit(1); X } X } X } X X if (cm != NULL) X lfree(cm); X X fbmin_close_file(); X zclose(zf); X image->title= dupString(name); X return(image); X} X Xunsigned int fbmIdent(fullname, name) Xchar *fullname, *name; X{ X ZFILE *zf; X unsigned int ret; X X if (! (zf= zopen(fullname))) X return(0); X if (fbmin_open_image(zf) == FBMIN_SUCCESS) { X tellAboutImage(name); X ret = 1; X } else X ret = 0; X fbmin_close_file(); X zclose(zf); X return(ret); X} END_OF_FILE if test 6960 -ne `wc -c <'fbm.c'`; then echo shar: \"'fbm.c'\" unpacked with wrong size! fi # end of 'fbm.c' fi if test -f 'fill.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fill.c'\" else echo shar: Extracting \"'fill.c'\" \(1500 characters\) sed "s/^X//" >'fill.c' <<'END_OF_FILE' 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_FILE if test 1500 -ne `wc -c <'fill.c'`; then echo shar: \"'fill.c'\" unpacked with wrong size! fi # end of 'fill.c' fi if test -f 'g3.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'g3.c'\" else echo shar: Extracting \"'g3.c'\" \(7159 characters\) sed "s/^X//" >'g3.c' <<'END_OF_FILE' X/** g3.c - read a Group 3 FAX file and product a bitmap X ** X ** Adapted from Paul Haeberli's <paul@manray.sgi.com> G3 to Portable Bitmap X ** code. X ** X ** modified by jimf on 09.18.90 to fail on any load error. this was done X ** to cut down on the false positives caused by a lack of any read ID X ** string. the old errors are currently ifdef'ed out -- if you want 'em X ** define ALLOW_G3_ERRORS. X **/ X X/* Edit History X X07/03/90 2 nazgul Added recovery for premature EOF X*/ X X#include "image.h" X#include "g3.h" X X/**** X ** X ** Local defines X ** X ****/ X X#define BITS_TO_BYTES(bits) (bits/8)+((bits-((bits/8)*8)?1:0)) X#define TABSIZE(tab) (sizeof(tab)/sizeof(struct tableentry)) X X/**** X ** X ** Local variables X ** X ****/ X Xint g3_eof = 0; Xint g3_eols; Xint g3_rawzeros; Xint maxlinelen; Xint rows, cols; X X/**** X ** X ** Local tables X ** X ****/ X Xtableentry *whash[HASHSIZE]; Xtableentry *bhash[HASHSIZE]; X Xint g3_addtohash(hash, te, n, a, b) X tableentry *hash[]; X tableentry *te; X int n, a, b; X{ X unsigned int pos; X X while (n--) { X pos = ((te->length+a)*(te->code+b))%HASHSIZE; X if (hash[pos] != 0) { X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Hash collision during initialization.\n"); X exit(1); X#else X return(-1); X#endif X } X hash[pos] = te; X te++; X } X} X Xtableentry *g3_hashfind(hash, length, code, a, b) X tableentry *hash[]; X int length, code; X int a, b; X{ X unsigned int pos; X tableentry *te; X X pos = ((length+a)*(code+b))%HASHSIZE; X if (pos >= HASHSIZE) { X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Bad hash position, length %d code %d pos %d.\n", X length, code, pos); X exit(2); X#else X return(NULL); X#endif X } X te = hash[pos]; X return ((te && te->length == length && te->code == code) ? te : 0); X} X Xint g3_getfaxrow(fd, bitrow) X ZFILE *fd; X byte *bitrow; X{ X int col; X int curlen, curcode, nextbit; X int count, color; X tableentry *te; X X /* First make the whole row white... */ X bzero((char *) bitrow, maxlinelen); /* was memset -- jimf 09.11.90 */ X X col = 0; X g3_rawzeros = 0; X curlen = 0; X curcode = 0; X color = 1; X count = 0; X while (!g3_eof) { X if (col >= MAXCOLS) { X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Input row %d is too long, skipping to EOL.\n", rows); X g3_skiptoeol(fd); X return (col); X#else X return(-1); X#endif X } X do { X if (g3_eof) return 0; X if (g3_rawzeros >= 11) { X nextbit = g3_rawgetbit(fd); X if (nextbit) { X if ( col == 0 ) X /* 6 consecutive EOLs mean end of document */ X g3_eof = (++g3_eols >= 5); X else X g3_eols = 0; X X return (col); X } X } X else X nextbit = g3_rawgetbit(fd); X X curcode = (curcode<<1) + nextbit; X curlen++; X } while (curcode <= 0); X X /* No codewords are greater than 13 bytes */ X if (curlen > 13) { X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Bad code word at row %d, col %d (len %d code 0x%2.2x), skipping to EOL.\n", rows, col, curlen, curcode ); X g3_skiptoeol(fd); X return (col); X#else X return(-1); X#endif X } X if (color) { X /* White codewords are at least 4 bits long */ X if (curlen < 4) X continue; X te = g3_hashfind(whash, curlen, curcode, WHASHA, WHASHB); X } X else { X /* Black codewords are at least 2 bits long */ X if (curlen < 2) X continue; X te = g3_hashfind(bhash, curlen, curcode, BHASHA, BHASHB); X } X if (!te) X continue; X switch (te->tabid) { X case TWTABLE: X case TBTABLE: X count += te->count; X if (col+count > MAXCOLS) X count = MAXCOLS-col; X if (count > 0) { X if (color) { X col += count; X count = 0; X } X else X g3_bitson(bitrow, col, count); X } X curcode = 0; X curlen = 0; X color = !color; X break; X case MWTABLE: X case MBTABLE: X count += te->count; X curcode = 0; X curlen = 0; X break; X case EXTABLE: X count += te->count; X curcode = 0; X curlen = 0; X break; X default: X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Bad table id from table entry.\n"); X exit(3); X#else X return(-1); X#endif X } X } X return (0); X} X Xint g3_skiptoeol(fd) X ZFILE *fd; X{ X while (g3_rawzeros<11 && !g3_eof) X (void) g3_rawgetbit(fd); X while(!g3_rawgetbit(fd) && !g3_eof); X return(0); X} X Xint g3_rawgetbit(fd) X ZFILE *fd; X{ X int b; X static int shdata; X static int curbit = 8; X X if (curbit >= 8) { X shdata = zgetc(fd); X if (shdata == EOF) { X#ifdef ALLOW_G3_ERRORS X fprintf(stderr, "G3: Premature EOF at line %d.\n", rows); X g3_eols = 5; X g3_eof = 1; X return 0; X#else X return(-1); X#endif X } X curbit = 0; X } X if (shdata & bmask[curbit]) { X g3_rawzeros = 0; X b = 1; X } X else { X g3_rawzeros++; X b = 0; X } X curbit++; X return b; X} X Xint g3_bitson(b, c, n) X bit *b; X int c, n; X{ X int i, col; X bit *bP; X X bP = b; X col = c; X bP+=(c/8); X i = (c - ((c/8)*8)); X while(col <= (c+n)) { X for(;col <= (c+n) && i < 8; i++) { X *bP |= bmask[i]; X col++; X } X i = 0; X bP++; X } X return(0); X} X X/* All G3 images begin with a G3 EOL codeword which is eleven binary 0's X * followed by one binary 1. There could be up to 15 0' so that the image X * starts on a char boundary. X */ Xint g3_ident(fd) X ZFILE *fd; X{ X X int ret = 0; X X for (g3_rawzeros = 0; !g3_rawgetbit(fd) && !g3_eof;); X if(g3_rawzeros >=11 || g3_rawzeros <= 15) X ret = 1; X X return(ret); X X} X XImage *g3Load(fullname, name, verbose) X char *fullname, *name; X unsigned int verbose; X{ X X ZFILE *fd; X Image *image; X int i, col; X byte *currline; X X if ((fd = zopen(fullname)) == NULL) X return(NULL); X X if (!g3_ident(fd)) X return(NULL); X X /* Initialize and load the hash tables */ X for ( i = 0; i < HASHSIZE; ++i ) X whash[i] = bhash[i] = (tableentry *) 0; X g3_addtohash(whash, twtable, TABSIZE(twtable), WHASHA, WHASHB); X g3_addtohash(whash, mwtable, TABSIZE(mwtable), WHASHA, WHASHB); X g3_addtohash(whash, extable, TABSIZE(extable), WHASHA, WHASHB); X g3_addtohash(bhash, tbtable, TABSIZE(tbtable), BHASHA, BHASHB); X g3_addtohash(bhash, mbtable, TABSIZE(mbtable), BHASHA, BHASHB); X g3_addtohash(bhash, extable, TABSIZE(extable), BHASHA, BHASHB); X X g3_eols = 0; X X /* Calulate the number of bytes needed for maximum number of columns X * (bits), create a temprary storage area for it. X */ X maxlinelen = BITS_TO_BYTES(MAXCOLS); X X image = newBitImage(MAXCOLS, MAXROWS); X X currline = image->data; X cols = 0; X for (rows = 0; rows < MAXROWS; ++rows) { X col = g3_getfaxrow(fd, currline); X#ifndef ALLOW_G3_ERRORS X if (col < 0) { X freeImage(image); X zclose(fd); X return(NULL); X } X#endif X if (g3_eof) X break; X if (col > cols) X cols = col; X currline += BITS_TO_BYTES(cols); X } X X zclose(fd); X image->title= dupString(name); X image->width = cols; X image->height = rows; X if (!image->width || !image->height) { /* sanity check */ X freeImage(image); X return(NULL); X } X X if(verbose) X printf(" %s is a %dx%d G3 FAX image.\n", image->width, image->height); X return(image); X} X X/* originally this used only g3_ident to determine if it was a G3 image, but X * it was always getting false positives so now it loads the whole image in X * to see if it's reasonable. X */ Xint g3Ident(fullname, name) X char *fullname, *name; X{ X Image *image; X X if (image= g3Load(fullname, name)) { X freeImage(image); X return(1); X } X return(0); X} END_OF_FILE if test 7159 -ne `wc -c <'g3.c'`; then echo shar: \"'g3.c'\" unpacked with wrong size! fi # end of 'g3.c' fi if test -f 'imagetypes.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'imagetypes.c'\" else echo shar: Extracting \"'imagetypes.c'\" \(1900 characters\) sed "s/^X//" >'imagetypes.c' <<'END_OF_FILE' 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 zreset(NULL); X return(image); X } X printf("%s: unknown or unsupported image type\n", fullname); X zreset(NULL); 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 zreset(NULL); X return; X } X zreset(NULL); 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_FILE if test 1900 -ne `wc -c <'imagetypes.c'`; then echo shar: \"'imagetypes.c'\" unpacked with wrong size! fi # end of 'imagetypes.c' fi if test -f 'options.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'options.c'\" else echo shar: Extracting \"'options.c'\" \(634 characters\) sed "s/^X//" >'options.c' <<'END_OF_FILE' 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_FILE if test 634 -ne `wc -c <'options.c'`; then echo shar: \"'options.c'\" unpacked with wrong size! fi # end of 'options.c' fi echo shar: End of archive 3 \(of 9\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.