v09i050: xloadimage, Part03/09
saber.com!jimf at saber.com
saber.com!jimf at saber.com
Fri Sep 28 11:55:37 AEST 1990
Submitted-by: saber.com!jimf at 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 at 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+ at 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 at 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 at 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 at 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 at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list