[comp.sources.misc] v09i024: PBMPLUS part 8 of 19: pgm.shar1 of 1

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (11/27/89)

Posting-number: Volume 9, Issue 24
Submitted-by: jef@helios.ee.lbl.gov (Jef Poskanzer)
Archive-name: pbmplus/part08

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	pgm/Makefile
#	pgm/Imakefile
#	pgm/pgm.5
#	pgm/libpgm.3
#	pgm/libpgm1.c
#	pgm/libpgm2.c
#	pgm/pgm.h
#	pgm/libpgm.h
#	pgm/fstopgm.c
#	pgm/fstopgm.1
#	pgm/hipstopgm.c
#	pgm/hipstopgm.1
#	pgm/pgmenhance.c
#	pgm/pgmenhance.1
# This archive created: Wed Nov 22 22:55:28 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/Makefile'" '(3023 characters)'
if test -f 'pgm/Makefile'
then
	echo shar: will not over-write existing file "'pgm/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/Makefile'
X# Makefile for pgm tools.
X#
X# Copyright (C) 1989 by Jef Poskanzer.
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation.  This software is provided "as is" without express or
X# implied warranty.
X
X# Default values, usually overridden by top-level Makefile.
X# CC =		cc
XCC =		gcc -fcombine-regs
X# CFLAGS =	
X# CFLAGS =	-g
XCFLAGS =	-O
X# CFLAGS =	-g -O
XLDFLAGS =	-s
X# LDFLAGS =	
XINSTALLBINARIES =	/usr/new/pbm
XINSTALLMANUALS1 =	/usr/man/mann
XINSTALLMANUALS3 =	/usr/man/mann
XINSTALLMANUALS5 =	/usr/man/mann
X
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h ../pbmplus.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XSHELL =		/bin/sh
XINCLUDE =	$(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPGM =	libpgm.a
X
XBINARIES =	fitstopgm fstopgm hipstopgm pgmenhance pgmhist pgmnorm \
X		pgmtopbm pgmtofits pgmtops psidtopgm rawtopgm tifftopgm
X
XMANUALS1 =	fitstopgm.1 fstopgm.1 hipstopgm.1 pgmenhance.1 pgmhist.1 \
X		pgmnorm.1 pgmtofits.1 pgmtopbm.1 pgmtops.1 psidtopgm.1 \
X		rawtopgm.1 tifftopgm.1
XMANUALS3 =	libpgm.3
XMANUALS5 =	pgm.5
X
Xall:		binaries
Xinstall:	installbinaries installmanuals
X# install:	installbinaries
X
Xbinaries:	$(BINARIES)
X
Xinstallbinaries:	binaries
X	cp $(BINARIES) $(INSTALLBINARIES)
X
Xinstallmanuals:
X	cp $(MANUALS1) $(INSTALLMANUALS1)
X	cp $(MANUALS3) $(INSTALLMANUALS3)
X	cp $(MANUALS5) $(INSTALLMANUALS5)
X
X# Rule for plain programs.
X$(BINARIES):	pgm.h $(DEFPBM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPGM):	libpgm1.o libpgm2.o
X	-rm $(LIBPGM)
X	ar rc $(LIBPGM) libpgm1.o libpgm2.o
X	-ranlib $(LIBPGM)
X
Xlibpgm1.o:	pgm.h $(DEFPBM) libpgm.h libpgm1.c
X	$(CC) $(ALLCFLAGS) -c libpgm1.c
Xlibpgm2.o:	pgm.h $(DEFPBM) libpgm.h libpgm2.c $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpgm2.c
X
X# Other dependencies.
Xfitstopgm:	fitstopgm.c
Xfstopgm:	fstopgm.c
Xhipstopgm:	hipstopgm.c
Xpgmenhance:	pgmenhance.c
Xpgmhist:	pgmhist.c
Xpgmnorm:	pgmnorm.c
Xpgmtofits:	pgmtofits.c
Xpgmtopbm:	pgmtopbm.c dithers.h $(DEFPBM)
Xpgmtops:	pgmtops.c
Xpsidtopgm:	psidtopgm.c
Xrawtopgm:	rawtopgm.c
Xtifftopgm:	tifftopgm.c tiff.h
X
Xclean:
X	-rm -f *.o *.a *.cat core $(BINARIES)
X
X
X# Imakefile stuff.  Ignore if you're not an X11 type.
X
X            TOP = ../../../../../../usr/src/new/X11
X
X             RM = rm -f
X             MV = mv
X        UTILSRC = $(TOP)/util
X       IMAKESRC = $(UTILSRC)/imake
X       IRULESRC = $(UTILSRC)/imake.includes
X          IMAKE = $(IMAKESRC)/imake
X  IMAKE_DEFINES =
X      IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
X			-s Makefile $(IMAKE_DEFINES)
XMakefile: Imakefile
X	-@if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP)
X
XMakefiles:
SHAR_EOF
if test 3023 -ne "`wc -c < 'pgm/Makefile'`"
then
	echo shar: error transmitting "'pgm/Makefile'" '(should have been 3023 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/Imakefile'" '(1538 characters)'
if test -f 'pgm/Imakefile'
then
	echo shar: will not over-write existing file "'pgm/Imakefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/Imakefile'
X# Imakefile for pgm tools.
X#
X# Copyright (C) 1989 by Jef Poskanzer.
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation.  This software is provided "as is" without express or
X# implied warranty.
X
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h ../pbmplus.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XINCLUDE =	$(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPGM =	libpgm.a
X
XBINARIES =	fitstopgm fstopgm hipstopgm pgmenhance pgmhist pgmnorm \
X		pgmtofits pgmtopbm pgmtops psidtopgm rawtopgm tifftopgm
X
XMANUALS1 =	fitstopgm.1 fstopgm.1 hipstopgm.1 pgmenhance.1 pgmhist.1 \
X		pgmnorm.1 pgmtofits.1 pgmtopbm.1 pgmtops.1 psidtopgm.1 \
X		rawtopgm.1 tifftopgm.1
XMANUALS3 =	libpgm.3
XMANUALS5 =	pgm.5
X
Xall:		$(BINARIES)
X
Xinstall::	all
X	cp $(BINARIES) $(BINDIR)
X
Xinstall.man::
X	cp $(MANUALS1) $(MANUALS3) $(MANUALS5) $(MANDIR)
X
X# Rule for plain programs.
X$(BINARIES):	pgm.h $(DEFPBM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPGM):	libpgm1.o libpgm2.o
X	-rm $(LIBPGM)
X	ar rc $(LIBPGM) libpgm1.o libpgm2.o
X	-ranlib $(LIBPGM)
X
Xlibpgm1.o:	pgm.h $(DEFPBM) libpgm.h libpgm1.c
X	$(CC) $(ALLCFLAGS) -c libpgm1.c
Xlibpgm2.o:	pgm.h $(DEFPBM) libpgm.h libpgm2.c $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpgm2.c
SHAR_EOF
if test 1538 -ne "`wc -c < 'pgm/Imakefile'`"
then
	echo shar: error transmitting "'pgm/Imakefile'" '(should have been 1538 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgm.5'" '(2949 characters)'
if test -f 'pgm/pgm.5'
then
	echo shar: will not over-write existing file "'pgm/pgm.5'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgm.5'
X.TH pgm 5 "01 August 1989"
X.SH NAME
Xpgm - portable graymap file format
X.SH DESCRIPTION
XThe portable graymap format is a lowest common denominator grayscale
Xfile format.
XThe definition is as follows:
X.IP - 2
XA "magic number" for identifying the file type.
XA pgm file's magic number is the two characters "P2".
X.IP - 2
XWhitespace (blanks, TABs, CRs, LFs).
X.IP - 2
XA width, formatted as ASCII characters in decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XA height, again in ASCII decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XThe maximum gray value, again in ASCII decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XWidth * height gray values, each in ASCII decimal, between 0 and the specified
Xmaximum value, separated by whitespace, starting at the top-left
Xcorner of the graymap, proceding in normal English reading order.
XA value of 0 means black, and the maximum value means white.
X.IP - 2
XCharacters from a "#" to the next end-of-line are ignored (comments).
X.IP - 2
XNo line should be longer than 70 characters.
X.PP
XHere is an example of a small graymap in this format:
X.PP
X.nf
XP2
X# feep.pgm
X24 7
X15
X0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
X0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
X0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
X0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
X0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
X0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
X0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
X.fi
X.PP
XPrograms that read this format should be as lenient as possible,
Xaccepting anything that looks remotely like a graymap.
X.PP
XThere is also a variant on the format, available
Xby setting the RAWBITS option at compile time.  This variant is
Xdifferent in the following ways:
X.IP - 2
XThe "magic number" is "P5" instead of "P2".
X.IP - 2
XThe gray values are stored as plain bytes, instead of ASCII decimal.
X.IP - 2
XNo whitespace is allowed in the grays section.
X.IP - 2
XThe files are smaller and many times faster to read and write.
X.PP
XNote that this raw format can only be used for maxvals less than
Xor equal to 255.
XIf you use the PGM library and try to write a file with a larger maxval,
Xit will automatically fall back on the slower but more general ASCII
Xformat.
X.SH "SEE ALSO"
Xfitstopgm(1), fstopgm(1), hipstopgm(1), psidtopgm(1), rawtopgm(1), tifftopgm(1),
Xpgmenhance(1), pgmhist(1), pgmnorm(1),
Xpgmtofits(1), pgmtopbm(1), pgmtops(1),
Xpnm(5), pbm(5), ppm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 2949 -ne "`wc -c < 'pgm/pgm.5'`"
then
	echo shar: error transmitting "'pgm/pgm.5'" '(should have been 2949 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm.3'" '(2764 characters)'
if test -f 'pgm/libpgm.3'
then
	echo shar: will not over-write existing file "'pgm/libpgm.3'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm.3'
X.de Ss
X.    sp
X.    ft CW
X.    nf
X..
X.de Se
X.    fi
X.    ft P
X.    sp
X..
X.TH pgm 3
X.SH NAME
Xpgm - functions to support portable graymap programs
X.SH SYNOPSIS
X.Ss
X#include <pgm.h>
Xcc ... libpgm.a libpbm.a
X.Se
X.SH DESCRIPTION
X.SS TYPES AND CONSTANTS
X.Ss
Xtypedef unsigned char gray;
X#define PGM_MAXMAXVAL 255
Xextern gray pgm_pbmmaxval;
X.Se
XEach
X.IR gray
Xshould contain only the values between
X.IR 0
Xand
X.IR PGM_MAXMAXVAL .
X.IR pgm_pbmmaxval
Xis the maxval used when a PGM program reads a PBM file.
XNormally it is 1; however, for some programs, a larger value gives better
Xresults.
X.SS PGM MEMORY MANAGEMENT
X.Ss
Xgray **pgm_allocarray(int cols, int rows)
X.Se
XAllocate an array of grays.
X.Ss
Xgray *pgm_allocrow( int cols )
X.Se
XAllocate a row of the given number of grays.
X.Ss
Xvoid pgm_freearray( grayrow, rows )
X.Se
XFree the array allocated with
X.IR pgm_allocarray()
Xcontaining the given number
Xof rows.
X.Ss
Xpbm_freerow( grayrow )
X.Se
XFree a row of grays.
X.SS READING PBM FILES
X.Ss
Xvoid
Xpgm_readpgminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xgray *maxvalP;
X.Se
XRead the header from a pgm file, filling in the rows, cols, maxval and format
Xvariables.
X.Ss
Xvoid
Xpgm_readpgmrow( file, grayrow, cols, maxval, format )
XFILE *file;
Xgray *grayrow;
Xgray maxval;
Xint cols, format;
X.Se
XRead a row of grays into the grayrow array.
XFormat and cols were filled in by
X.IR pgm_readpgminit() .
X.Ss
Xgray **
Xpgm_readpgm( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xgray *maxvalP;
X.Se
XRead an entire graymap file into memory, returning the allocated array and
Xfilling in the rows, cols and maxval variables.
XThis function combines
X.IR pgm_readpgminit() ,
X.IR pgm_allocarray()
Xand
X.IR pgm_readpgmrow() .
X.SS WRITING PGM FILES
X.Ss
Xvoid
Xpgm_writepgminit( file, cols, rows, maxval )
XFILE *file;
Xint cols, rows;
Xgray maxval;
X.Se
XWrite the header for a portable graymap file.
X.Ss
Xvoid
Xpgm_writepgmrow( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X.Se
XWrite a row from a portable graymap.
X.Ss
Xvoid
Xpgm_writepgm( file, bits, cols, rows, maxval )
XFILE *file;
Xgray **bits;
Xint cols, rows;
Xgray maxval;
X.Se
XWrite the header and all data for a portable graymap.
XThis function combines
X.IR pgm_writepgminit()
Xand
X.IR pgm_writepgmrow() .
X.SH "SEE ALSO"
Xpgm(3), ppm(3)
X.SH AUTHOR
XManual by Tony Hansen.
X
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 2764 -ne "`wc -c < 'pgm/libpgm.3'`"
then
	echo shar: error transmitting "'pgm/libpgm.3'" '(should have been 2764 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm1.c'" '(2976 characters)'
if test -f 'pgm/libpgm1.c'
then
	echo shar: will not over-write existing file "'pgm/libpgm1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm1.c'
X/* libpgm1.c - pgm utility library part 1
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#include "libpgm.h"
X#include "pbm.h"
X#include "libpbm.h"
X
Xvoid
Xpgm_readpgminitrest( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xgray *maxvalP;
X    {
X    /* Read size. */
X    *colsP = pbm_getint( file );
X    *rowsP = pbm_getint( file );
X
X    /* Read maxval. */
X    *maxvalP = pbm_getint( file );
X    if ( *maxvalP > PGM_MAXMAXVAL )
X	pm_error(
X	    "maxval too large - %d > %d\n", *maxvalP, PGM_MAXMAXVAL, 0,0,0 );
X    }
X
Xstatic bit *bitrow;
X
Xgray pgm_pbmmaxval = 1;
X
Xvoid
Xpgm_readpgminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xgray *maxvalP;
X    {
X    /* Check magic number. */
X    *formatP = pbm_readmagicnumber( file );
X    switch ( *formatP )
X	{
X        case PGM_FORMAT:
X        case RPGM_FORMAT:
X	pgm_readpgminitrest( file, colsP, rowsP, maxvalP );
X	break;
X
X        case PBM_FORMAT:
X        case RPBM_FORMAT:
X	pbm_readpbminitrest( file, colsP, rowsP );
X	*maxvalP = pgm_pbmmaxval;
X	bitrow = pbm_allocrow( *colsP );
X	break;
X
X	default:
X	pm_error( "bad magic number - not a pgm or pbm file", 0,0,0,0,0 );
X	}
X    }
X
Xvoid
Xpgm_readpgmrow( file, grayrow, cols, maxval, format )
XFILE *file;
Xgray *grayrow;
Xint cols, format;
Xgray maxval;
X    {
X    register int col;
X    register gray *gP;
X    register bit *bP;
X
X    switch ( format )
X	{
X	case PGM_FORMAT:
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    *gP = pbm_getint( file );
X#ifdef DEBUG
X	    if ( *gP > maxval )
X		pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    }
X	break;
X	
X	case RPGM_FORMAT:
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    *gP = pbm_getrawbyte( file );
X#ifdef DEBUG
X	    if ( *gP > maxval )
X		pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    }
X	break;
X	
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbmrow( file, bitrow, cols, format );
X	for ( col = 0, gP = grayrow, bP = bitrow; col < cols; col++, gP++, bP++ )
X	    *gP = ( *bP == PBM_WHITE ) ? maxval : 0;
X	break;
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xgray **
Xpgm_readpgm( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xgray *maxvalP;
X    {
X    gray **grays;
X    int row;
X    int format;
X
X    pgm_readpgminit( file, colsP, rowsP, maxvalP, &format );
X
X    grays = pgm_allocarray( *colsP, *rowsP );
X
X    for ( row = 0; row < *rowsP; row++ )
X	pgm_readpgmrow( file, grays[row], *colsP, *maxvalP, format );
X
X    return grays;
X    }
SHAR_EOF
if test 2976 -ne "`wc -c < 'pgm/libpgm1.c'`"
then
	echo shar: error transmitting "'pgm/libpgm1.c'" '(should have been 2976 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm2.c'" '(3031 characters)'
if test -f 'pgm/libpgm2.c'
then
	echo shar: will not over-write existing file "'pgm/libpgm2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm2.c'
X/* libpgm2.c - pgm utility library part 2
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#include "libpgm.h"
X
Xvoid
Xpgm_writepgminit( file, cols, rows, maxval )
XFILE *file;
Xint cols, rows;
Xgray maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, RPGM_MAGIC2,
X	    cols, rows, maxval );
X    else
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
X	    cols, rows, maxval );
X#else /*PBMPLUS_RAWBITS*/
X    fprintf(
X	file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
X	cols, rows, maxval );
X#endif /*PBMPLUS_RAWBITS*/
X    }
X
Xstatic int
Xputus( n, file )
Xunsigned short n;
XFILE *file;
X    {
X    if ( n >= 10 )
X	if ( putus( n / 10, file ) == EOF )
X	    return EOF;
X    return putc( n % 10 + '0', file );
X    }
X
X#ifdef PBMPLUS_RAWBITS
Xstatic void
Xpgm_writepgmrowraw( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X    register int col;
X    register gray *gP;
X
X    for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	{
X#ifdef DEBUG
X	if ( *gP > maxval )
X	    pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putc( *gP, file ) == EOF )
X	    pm_perror( 0 );
X	}
X    }
X#endif /*PBMPLUS_RAWBITS*/
X
Xstatic void
Xpgm_writepgmrowplain( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X    register int col, charcount;
X    register gray *gP;
X
X    charcount = 0;
X    for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	{
X	if ( charcount >= 70 )
X	    {
X	    if ( putc( '\n', file ) == EOF )
X		pm_perror( 0 );
X	    charcount = 0;
X	    }
X#ifdef DEBUG
X	if ( *gP > maxval )
X	    pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putus( (unsigned long) *gP, file ) == EOF )
X	    pm_perror( 0 );
X	if ( putc( ' ', file ) == EOF )
X	    pm_perror( 0 );
X	charcount += 4;
X	}
X    if ( putc( '\n', file ) == EOF )
X	pm_perror( 0 );
X    }
X
Xvoid
Xpgm_writepgmrow( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	pgm_writepgmrowraw( file, grayrow, cols, maxval );
X    else
X	pgm_writepgmrowplain( file, grayrow, cols, maxval );
X#else /*PBMPLUS_RAWBITS*/
X    pgm_writepgmrowplain( file, grayrow, cols, maxval );
X#endif /*PBMPLUS_RAWBITS*/
X    }
X
Xvoid
Xpgm_writepgm( file, grays, cols, rows, maxval )
XFILE *file;
Xgray **grays;
Xint cols, rows;
Xgray maxval;
X    {
X    int row;
X
X    pgm_writepgminit( file, cols, rows, maxval );
X
X    for ( row = 0; row < rows; row++ )
X	pgm_writepgmrow( file, grays[row], cols, maxval );
X    }
SHAR_EOF
if test 3031 -ne "`wc -c < 'pgm/libpgm2.c'`"
then
	echo shar: error transmitting "'pgm/libpgm2.c'" '(should have been 3031 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgm.h'" '(1323 characters)'
if test -f 'pgm/pgm.h'
then
	echo shar: will not over-write existing file "'pgm/pgm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgm.h'
X/* pgm.h - header file for libpgm portable graymap library
X*/
X
X#ifndef _PGM_H_
X#define _PGM_H_
X
X#include "pbm.h"
X
X#ifdef PGM_BIGGRAYS
Xtypedef unsigned short gray;
X#define PGM_MAXMAXVAL 65535
X#else /*PGM_BIGGRAYS*/
Xtypedef unsigned char gray;
X#define PGM_MAXMAXVAL 255
X#endif /*PGM_BIGGRAYS*/
X
X/* Declarations of routines. */
X
X#define pgm_allocarray( cols, rows ) ((gray **) pm_allocarray( cols, rows, sizeof(gray) ))
X#define pgm_allocrow( cols ) ((gray *) pm_allocrow( cols, sizeof(gray) ))
X#define pgm_freearray( grayrow, rows ) pm_freearray( grayrow, rows )
X#define pgm_freerow( grayrow ) pm_freerow( grayrow )
X
Xgray **pgm_readpgm( /* FILE *file, int *colsP, int *rowsP, gray *maxvalP */ );
Xvoid pgm_readpgminit( /* FILE *file, int *colsP, int *rowsP, gray *maxvalP, int *formatP */ );
Xvoid pgm_readpgmrow( /* FILE *file, gray *grayrow, int cols, gray maxval, int format */ );
X
Xvoid pgm_writepgm( /* FILE *file, gray **grays, int cols, int rows, gray maxval */ );
Xvoid pgm_writepgminit( /* FILE *file, int cols, int rows, gray maxval */ );
Xvoid pgm_writepgmrow( /* FILE *file, gray *grayrow, int cols, gray maxval */ );
X
Xextern gray pgm_pbmmaxval;
X/* This is the maxval used when a PGM program reads a PBM file.  Normally
X** it is 1; however, for some programs, a larger value gives better results
X*/
X
X#endif /*_PGM_H_*/
SHAR_EOF
if test 1323 -ne "`wc -c < 'pgm/pgm.h'`"
then
	echo shar: error transmitting "'pgm/pgm.h'" '(should have been 1323 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm.h'" '(484 characters)'
if test -f 'pgm/libpgm.h'
then
	echo shar: will not over-write existing file "'pgm/libpgm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm.h'
X/* libpgm.h - internal header file for libpgm portable graymap library
X*/
X
X#ifndef _LIBPGM_H_
X#define _LIBPGM_H_
X
X/* Magic constants. */
X
X#define PGM_MAGIC1 'P'
X#define PGM_MAGIC2 '2'
X#define RPGM_MAGIC2 '5'
X#define PGM_FORMAT (PGM_MAGIC1 * 256 + PGM_MAGIC2)
X#define RPGM_FORMAT (PGM_MAGIC1 * 256 + RPGM_MAGIC2)
X
X
X/* And here are some routines internal to the pgm library. */
X
Xvoid pgm_readpgminitrest( /* FILE *file, int *colsP, int *rowsP, int *maxvalP */ );
X
X#endif /*_LIBPGM_H_*/
SHAR_EOF
if test 484 -ne "`wc -c < 'pgm/libpgm.h'`"
then
	echo shar: error transmitting "'pgm/libpgm.h'" '(should have been 484 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/fstopgm.c'" '(3441 characters)'
if test -f 'pgm/fstopgm.c'
then
	echo shar: will not over-write existing file "'pgm/fstopgm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/fstopgm.c'
X/* fstopgm.c - read a Usenix FaceSaver file and produce a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray **grays, *gP;
X    int argn, row;
X    register int col;
X    int maxval;
X    int rows = 0, cols = 0, depth = 0, xrows = 0, xcols = 0, xdepth = 0;
X#define STRSIZE 1000
X    char buf[STRSIZE], firstname[STRSIZE], lastname[STRSIZE], email[STRSIZE];
X    int gethexit();
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn < argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( "[fsfile]" );
X
X    /* Read the FaceSaver header. */
X    for ( ; ; )
X	{
X	if ( fgets( buf, STRSIZE, ifd ) == (char *) 0 )
X	    pm_error( "error reading header", 0,0,0,0,0 );
X
X	/* Blank line ends header. */
X	if ( strlen( buf ) == 1 )
X	    break;
X
X	if ( sscanf( buf, "FirstName: %s\n", firstname ) == 1 )
X	    ;
X	else if ( sscanf( buf, "LastName: %s\n", lastname ) == 1 )
X	    ;
X	else if ( sscanf( buf, "E-mail: %s\n", email ) == 1 )
X	    ;
X	else if ( sscanf( buf, "PicData: %d %d %d\n",
X			  &cols, &rows, &depth ) == 3 )
X	    {
X	    if ( depth != 8 )
X		pm_error(
X		    "can't handle 'PicData' depth other than 8", 0,0,0,0,0 );
X	    }
X	else if ( sscanf( buf, "Image: %d %d %d\n",
X			  &xcols, &xrows, &xdepth ) == 3 )
X	    {
X	    if ( xdepth != 8 )
X		pm_error(
X		    "can't handle 'Image' depth other than 8", 0,0,0,0,0 );
X	    }
X	}
X    if ( cols <= 0 || rows <= 0 )
X	pm_error( "invalid header", 0,0,0,0,0 );
X    maxval = ( 1 << depth ) - 1;
X    if ( maxval > PGM_MAXMAXVAL )
X	pm_error(
X	    "depth is too large - try recompiling with a larger gray type",
X	    0,0,0,0,0 );
X    if ( xcols != 0 && xrows != 0 && ( xcols != cols || xrows != rows ) )
X	{
X	float rowratio, colratio;
X
X	rowratio = (float) xrows / (float) rows;
X	colratio = (float) xcols / (float) cols;
X	fprintf(
X	    stderr,
X	    "(Warning: non-square pixels; to fix do a 'ppmscale -%cscale %g | ppmtopgm'.)\n",
X	    rowratio > colratio ? 'y' : 'x',
X	    rowratio > colratio ? rowratio / colratio : colratio / rowratio );
X	}
X
X    /* Now read the hex bits. */
X    grays = pgm_allocarray( cols, rows );
X    for ( row = rows - 1; row >= 0; row--)
X	{
X	for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
X	    {
X	    *gP = gethexit( ifd ) << 4;
X	    *gP += gethexit( ifd );
X	    }
X	}
X    pm_close( ifd );
X
X    /* And write out the graymap. */
X    pgm_writepgm( stdout, grays, cols, rows, (gray) maxval );
X
X    exit( 0 );
X    }
X
Xint
Xgethexit( ifd )
XFILE *ifd;
X    {
X    register int i;
X    register char c;
X
X    for ( ; ; )
X	{
X	i = getc( ifd );
X	if ( i == EOF )
X	    pm_error( "premature EOF", 0,0,0,0,0 );
X	c = (char) i;
X	if ( c >= '0' && c <= '9' )
X	    return c - '0';
X	else if ( c >= 'A' && c <= 'F' )
X	    return c - 'A' + 10;
X	else if ( c >= 'a' && c <= 'f' )
X	    return c - 'a' + 10;
X	/* Else ignore - whitespace. */
X	}
X    }
SHAR_EOF
if test 3441 -ne "`wc -c < 'pgm/fstopgm.c'`"
then
	echo shar: error transmitting "'pgm/fstopgm.c'" '(should have been 3441 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/fstopgm.1'" '(667 characters)'
if test -f 'pgm/fstopgm.1'
then
	echo shar: will not over-write existing file "'pgm/fstopgm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/fstopgm.1'
X.TH fstopgm 1 "06 April 89"
X.SH NAME
Xfstopgm - convert a Usenix FaceSaver file into a portable graymap
X.SH SYNOPSIS
Xfstopgm [fsfile]
X.SH DESCRIPTION
XReads a Usenix FaceSaver file as input.
XProduces a portable graymap as output.
X.SH "SEE ALSO"
Xpgm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 667 -ne "`wc -c < 'pgm/fstopgm.1'`"
then
	echo shar: error transmitting "'pgm/fstopgm.1'" '(should have been 667 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/hipstopgm.c'" '(4363 characters)'
if test -f 'pgm/hipstopgm.c'
then
	echo shar: will not over-write existing file "'pgm/hipstopgm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/hipstopgm.c'
X/* hipstopgm.c - read a HIPS file and produce a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
Xstruct HIPS_Header {
X    char *orig_name;	/* An indication of the originator of this sequence. */
X    char *seq_name;	/* The sequence name. */
X    int num_frame;	/* The number of frames in this sequence. */
X    char *orig_date;	/* The date the sequence was originated. */
X    int rows;		/* The number of rows in each image, the height. */
X    int cols;		/* The number of columns in each image, the width. */
X    int bits_per_pixel;	/* The number of significant bits per pixel. */
X    int bit_packing;	/* Nonzero if the bits were packed such as to
X			   eliminate any unused bits resulting from a
X			   bits_per_pixel value which was not an even
X			   multiple of eight. */
X    int pixel_format;	/* An indication of the format of each pixel.
X    char *seq_history;	/* A description of the sequence of transformations
X			   leading up to the current image. */
X    char *seq_desc;	/* A free form description of the contents of the
X			   sequence. */
X    };
X#define HIPS_PFBYTE 0
X#define HIPS_PFSHORT 1
X#define HIPS_PFINT 2
X#define HIPS_PFFLOAT 3
X#define HIPS_PFCOMPLEX 4
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray *grayrow, *gP;
X    int argn, row;
X    register int col;
X    int maxval;
X    int rows, cols;
X    struct HIPS_Header h;
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn < argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( "[hipsfile]" );
X
X    read_hips_header( ifd, &h );
X
X    cols = h.cols;
X    rows = h.rows * h.num_frame;
X
X    switch ( h.pixel_format )
X	{
X	case HIPS_PFBYTE:
X	if ( h.bits_per_pixel != 8 )
X	    pm_error(
X		"can't handle unusual bits_per_pixel %d", h.bits_per_pixel,
X		0,0,0,0 );
X	if ( h.bit_packing != 0 )
X	    pm_error( "can't handle bit_packing", 0,0,0,0,0 );
X	maxval = 255;
X	break;
X
X	default:
X	pm_error( "unknown pixel format %d", h.pixel_format, 0,0,0,0 );
X	}
X    if ( maxval > PGM_MAXMAXVAL )
X	pm_error( "bits_per_pixel is too large - try recompiling with a larger gray type" );
X
X    pgm_writepgminit( stdout, cols, rows, (gray) maxval );
X    grayrow = pgm_allocrow( cols );
X    for ( row = 0; row < rows; row++)
X	{
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    int ich;
X
X	    switch ( h.pixel_format )
X		{
X		case HIPS_PFBYTE:
X		ich = getc( ifd );
X		if ( ich == EOF )
X		    pm_error( "premature EOF", 0,0,0,0,0 );
X		*gP = (gray) ich;
X		break;
X
X		default:
X		pm_error( "can't happen", 0,0,0,0,0 );
X		}
X	    }
X	pgm_writepgmrow( stdout, grayrow, cols, (gray) maxval );
X	}
X    pm_close( ifd );
X
X    exit( 0 );
X    }
X
Xread_hips_header( fd, hP )
XFILE *fd;
Xstruct HIPS_Header *hP;
X    {
X    char buf[5000];
X
X    /* Read and toss orig_name. */
X    read_line( fd, buf, 5000 );
X
X    /* Read and toss seq_name. */
X    read_line( fd, buf, 5000 );
X
X    /* Read num_frame. */
X    read_line( fd, buf, 5000 );
X    hP->num_frame = atoi( buf );
X
X    /* Read and toss orig_date. */
X    read_line( fd, buf, 5000 );
X
X    /* Read rows. */
X    read_line( fd, buf, 5000 );
X    hP->rows = atoi( buf );
X
X    /* Read cols. */
X    read_line( fd, buf, 5000 );
X    hP->cols = atoi( buf );
X
X    /* Read bits_per_pixel. */
X    read_line( fd, buf, 5000 );
X    hP->bits_per_pixel = atoi( buf );
X
X    /* Read bit_packing. */
X    read_line( fd, buf, 5000 );
X    hP->bit_packing = atoi( buf );
X
X    /* Read pixel_format. */
X    read_line( fd, buf, 5000 );
X    hP->pixel_format = atoi( buf );
X
X    /* Now read and toss lines until we get one with just a period. */
X    do
X	{
X	read_line( fd, buf, 5000 );
X	}
X    while ( strcmp( buf, ".\n" ) != 0 );
X    }
X
Xread_line( fd, buf, size )
XFILE *fd;
Xchar *buf;
Xint size;
X    {
X    if ( fgets( buf, size, fd ) == NULL )
X	pm_error( "error reading header", 0,0,0,0,0 );
X    }
SHAR_EOF
if test 4363 -ne "`wc -c < 'pgm/hipstopgm.c'`"
then
	echo shar: error transmitting "'pgm/hipstopgm.c'" '(should have been 4363 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/hipstopgm.1'" '(853 characters)'
if test -f 'pgm/hipstopgm.1'
then
	echo shar: will not over-write existing file "'pgm/hipstopgm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/hipstopgm.1'
X.TH hipstopgm 1 "24 August 89"
X.SH NAME
Xhipstopgm - convert a HIPS file into a portable graymap
X.SH SYNOPSIS
Xhipstopgm [hipsfile]
X.SH DESCRIPTION
XReads a HIPS file as input.
XProduces a portable graymap as output.
X.PP
XIf the HIPS file contains more than one frame in sequence, hipstopgm
Xwill concatenate all the frames vertically.
X.PP
XHIPS is a format developed at the Human Information Processing
XLaboratory, NYU.
X.SH "SEE ALSO"
Xpgm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 853 -ne "`wc -c < 'pgm/hipstopgm.1'`"
then
	echo shar: error transmitting "'pgm/hipstopgm.1'" '(should have been 853 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmenhance.c'" '(2974 characters)'
if test -f 'pgm/pgmenhance.c'
then
	echo shar: will not over-write existing file "'pgm/pgmenhance.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmenhance.c'
X/* pgmenhance.c - edge-enhance a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray **grays, *newgrayrow, *ngP;
X    int argn, n, rows, cols, row, col;
X    float phi, omphi;
X    gray maxval, sum;
X    long newval;
X    char *usage = "[-N] [pgmfile]  ( 1 <= N <= 9, default = 9 )";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    n = 9;
X
X    if ( argn < argc )
X	{
X	if ( argv[argn][0] == '-' )
X	    {
X	    if ( sscanf( &(argv[argn][1]), "%d", &n ) != 1 )
X		pm_usage( usage );
X	    if ( n < 1 || n > 9 )
X		pm_usage( usage );
X	    argn++;
X	    }
X	}
X
X    if ( argn != argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    pgm_pbmmaxval = 255;	/* use a larger value for better (?) results */
X    grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
X
X    pgm_writepgminit( stdout, cols, rows, maxval );
X    newgrayrow = pgm_allocrow( cols );
X
X    /* The edge enhancing technique is taken from Philip R. Thompson's "xim"
X    ** program, which in turn took it from section 6 of "Digital Halftones by
X    ** Dot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
X    ** October 1987, which in turn got it from two 1976 papers by J. F. Jarvis
X    ** et. al.
X    */
X    phi = n / 10.0;
X    omphi = 1.0 - phi;
X
X    /* Row 0. */
X    for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
X	*ngP = grays[0][col];
X    pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X
X    /* Other rows. */
X    for ( row = 1; row < rows - 1; row++ )
X	{
X	ngP = newgrayrow;
X	*ngP = grays[row][0];
X	ngP++;
X	for ( col = 1; col < cols - 1; col++, ngP++ )
X	    {
X	    /* Compute the sum of the neighborhood. */
X	    sum =
X		grays[row-1][col-1] + grays[row-1][col] + grays[row-1][col+1] +
X		grays[row  ][col-1] + grays[row  ][col] + grays[row  ][col+1] +
X		grays[row+1][col-1] + grays[row+1][col] + grays[row+1][col+1];
X	    /* Now figure new value. */
X	    newval =
X		(long) ( ( grays[row][col] - phi * sum / 9 ) / omphi + 0.5 );
X	    if ( newval < 0 )
X		newgrayrow[col] = 0;
X	    else if ( newval > maxval )
X		newgrayrow[col] = maxval;
X	    else
X		newgrayrow[col] = newval;
X	    }
X	newgrayrow[cols - 1] = grays[row][cols - 1];
X	pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X	}
X
X    /* Last row. */
X    for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
X	*ngP = grays[rows - 1][col];
X    pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X
X    pm_close( ifd );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 2974 -ne "`wc -c < 'pgm/pgmenhance.c'`"
then
	echo shar: error transmitting "'pgm/pgmenhance.c'" '(should have been 2974 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmenhance.1'" '(1114 characters)'
if test -f 'pgm/pgmenhance.1'
then
	echo shar: will not over-write existing file "'pgm/pgmenhance.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmenhance.1'
X.TH pgmenhance 1 "13 January 1989"
X.SH NAME
Xpgmenhance - edge-enhance a portable graymap
X.SH SYNOPSIS
Xpgmenhance [-N] [pgmfile]
X.SH DESCRIPTION
XReads a portable graymap as input.
XEnhances the edges, and writes a portable graymap as output.
XThe optional -N argument should be a digit from 1 to 9.
X1 is the lowest level of enhancement, 9 is the highest,
XThe default is 9.
X.PP
XThe edge enhancing technique is taken from Philip R. Thompson's "xim"
Xprogram, which in turn took it from section 6 of "Digital Halftones by
XDot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
XOctober 1987, which in turn got it from two 1976 papers by J. F. Jarvis
Xet. al.
X.SH "SEE ALSO"
Xpgm(5), pbm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 1114 -ne "`wc -c < 'pgm/pgmenhance.1'`"
then
	echo shar: error transmitting "'pgm/pgmenhance.1'" '(should have been 1114 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0