[comp.sources.misc] v09i027: PBMPLUS part 11 of 19: ppm.shar1 of 1

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

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

#! /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:
#	ppm/Makefile
#	ppm/Imakefile
#	ppm/ppm.5
#	ppm/libppm.3
#	ppm/libppm1.c
#	ppm/libppm2.c
#	ppm/libppm3.c
#	ppm/libppm4.c
#	ppm/libppm5.c
#	ppm/convolscripts/ppmsmooth
# This archive created: Wed Nov 22 22:55:36 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/Makefile'" '(4489 characters)'
if test -f 'ppm/Makefile'
then
	echo shar: will not over-write existing file "'ppm/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/Makefile'
X# Makefile for ppm 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
XPGMDIR =	../pgm
XINCLUDEPGM =	-I$(PGMDIR)
XLIBPGM =	$(PGMDIR)/libpgm.a
XDEFPGM =	$(PGMDIR)/pgm.h
XDEFLIBPGM =	$(PGMDIR)/libpgm.h
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 =	$(INCLUDEPGM) $(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPPM =	libppm.a
X
XPORTBINARIES =	giftoppm ilbmtoppm imgtoppm mtvtoppm ppmarith ppmconvol \
X		ppmcscale ppmhist ppmquant ppmscale ppmtogif ppmtoilbm \
X		ppmtopgm ppmtops ppmtorast ppmtoxwd qrttoppm rasttoppm \
X		tgatoppm xwdtoppm
XMATHBINARIES =	ppmpat ppmrotate ppmshear
XBINARIES =	$(PORTBINARIES) $(MATHBINARIES)
X
XMANUALS1 =	giftoppm.1 ilbmtoppm.1 imgtoppm.1 mtvtoppm.1 ppmarith.1 \
X		ppmconvol.1 ppmcscale.1 ppmhist.1 ppmpat.1 ppmquant.1 \
X		ppmrotate.1 ppmscale.1 ppmshear.1 ppmtogif.1 ppmtoilbm.1 \
X		ppmtopgm.1 ppmtops.1 ppmtorast.1 ppmtoxwd.1 qrttoppm.1 \
X		rasttoppm.1 tgatoppm.1 xwdtoppm.1
XMANUALS3 =	libppm.3
XMANUALS5 =	ppm.5
X
Xall:		binaries
Xinstall:	installbinaries installmanuals
X# install:	installbinaries
X
Xbinaries:	$(BINARIES)
X
Xinstallbinaries:	binaries
X	cp $(BINARIES) $(INSTALLBINARIES)
X	cp convolscripts/* $(INSTALLBINARIES)
X
Xinstallmanuals:
X	cp $(MANUALS1) $(INSTALLMANUALS1)
X	cp $(MANUALS3) $(INSTALLMANUALS3)
X	cp $(MANUALS5) $(INSTALLMANUALS5)
X
X# Rule for plain programs.
X$(PORTBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# Rule for math-dependent programs.
X$(MATHBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c -lm $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPPM):	libppm1.o libppm2.o libppm3.o libppm4.o libppm5.o
X	-rm $(LIBPPM)
X	ar rc $(LIBPPM) libppm1.o libppm2.o libppm3.o libppm4.o libppm5.o
X	-ranlib $(LIBPPM)
X
Xlibppm1.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm1.c
X	$(CC) $(ALLCFLAGS) -c libppm1.c
Xlibppm2.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm2.c $(DEFLIBPGM) \
X		$(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libppm2.c
Xlibppm3.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm3.c
X	$(CC) $(ALLCFLAGS) -c libppm3.c
Xlibppm4.o:	ppm.h $(DEFPGM) $(DEFPBM) ppmcmap.h libppm4.c
X	$(CC) $(ALLCFLAGS) -c libppm4.c
Xlibppm5.o:	ppm.h $(DEFPGM) $(DEFPBM) ppmdraw.h libppm5.c
X	$(CC) $(ALLCFLAGS) -c libppm5.c
X
X# Other dependencies.
Xgiftoppm:	giftoppm.c
Xilbmtoppm:	ilbmtoppm.c ilbm.h
Ximgtoppm:	imgtoppm.c
Xmtvtoppm:	mtvtoppm.c
Xppmarith:	ppmarith.c
Xppmconvol:	ppmconvol.c
Xppmcscale:	ppmcscale.c
Xppmhist:	ppmhist.c ppmcmap.h
Xppmpat:		ppmpat.c ppmdraw.h
Xppmquant:	ppmquant.c $(PGMDIR)/dithers.h ppmcmap.h
Xppmrotate:	ppmrotate.c
Xppmscale:	ppmscale.c
Xppmshear:	ppmshear.c
Xppmtogif:	ppmtogif.c ppmcmap.h
Xppmtoilbm:	ppmtoilbm.c ilbm.h ppmcmap.h
Xppmtopgm:	ppmtopgm.c
Xppmtops:	ppmtops.c
Xppmtoxwd:	ppmtoxwd.c $(PBMDIR)/x11wd.h ppmcmap.h
Xppmtorast:	ppmtorast.c $(PBMDIR)/rast.h ppmcmap.h
Xqrttoppm:	qrttoppm.c
Xrasttoppm:	rasttoppm.c $(PBMDIR)/rast.h
Xtgatoppm:	tgatoppm.c tga.h
Xxwdtoppm:	xwdtoppm.c $(PBMDIR)/x11wd.h $(PBMDIR)/x10wd.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 4489 -ne "`wc -c < 'ppm/Makefile'`"
then
	echo shar: error transmitting "'ppm/Makefile'" '(should have been 4489 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/Imakefile'" '(2595 characters)'
if test -f 'ppm/Imakefile'
then
	echo shar: will not over-write existing file "'ppm/Imakefile'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/Imakefile'
X# Imakefile for ppm 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
XPGMDIR =	../pgm
XINCLUDEPGM =	-I$(PGMDIR)
XLIBPGM =	$(PGMDIR)/libpgm.a
XDEFPGM =	$(PGMDIR)/pgm.h
XDEFLIBPGM =	$(PGMDIR)/libpgm.h
X
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h ../pbmplus.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XINCLUDE =	$(INCLUDEPGM) $(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPPM =	libppm.a
X
XPORTBINARIES =	giftoppm ilbmtoppm imgtoppm mtvtoppm ppmarith ppmconvol \
X		ppmcscale ppmhist ppmquant ppmscale ppmtogif ppmtoilbm \
X		ppmtopgm ppmtops ppmtorast ppmtoxwd qrttoppm rasttoppm \
X		tgatoppm xwdtoppm
XMATHBINARIES =	ppmpat ppmrotate ppmshear
XBINARIES =	$(PORTBINARIES) $(MATHBINARIES)
X
XMANUALS1 =	giftoppm.1 ilbmtoppm.1 imgtoppm.1 mtvtoppm.1 ppmarith.1 \
X		ppmconvol.1 ppmcscale.1 ppmhist.1 ppmpat.1 ppmquant.1 \
X		ppmrotate.1 ppmscale.1 ppmshear.1 ppmtogif.1 ppmtoilbm.1 \
X		ppmtopgm.1 ppmtops.1 ppmtorast.1 ppmtoxwd.1 qrttoppm.1 \
X		rasttoppm.1 tgatoppm.1 xwdtoppm.1
XMANUALS3 =	libppm.3
XMANUALS5 =	ppm.5
X
Xall:		$(BINARIES)
X
Xinstall::	all
X	cp $(BINARIES) $(BINDIR)
X	cp convolscripts/ppm* $(BINDIR)
X
Xinstall.man::
X	cp $(MANUALS1) $(MANUALS3) $(MANUALS5) $(MANDIR)
X
X# Rule for plain programs.
X$(PORTBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# Rule for math-dependent programs.
X$(MATHBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c -lm $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPPM):	libppm1.o libppm2.o libppm3.o libppm4.o libppm5.o
X	-rm $(LIBPPM)
X	ar rc $(LIBPPM) libppm1.o libppm2.o libppm3.o libppm4.o libppm5.o
X	-ranlib $(LIBPPM)
X
Xlibppm1.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm1.c
X	$(CC) $(ALLCFLAGS) -c libppm1.c
Xlibppm2.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm2.c $(DEFLIBPGM) \
X		$(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libppm2.c
Xlibppm3.o:	ppm.h $(DEFPGM) $(DEFPBM) libppm.h libppm3.c
X	$(CC) $(ALLCFLAGS) -c libppm3.c
Xlibppm4.o:	ppm.h $(DEFPGM) $(DEFPBM) ppmcmap.h libppm4.c
X	$(CC) $(ALLCFLAGS) -c libppm4.c
Xlibppm5.o:	ppm.h $(DEFPGM) $(DEFPBM) ppmdraw.h libppm5.c
X	$(CC) $(ALLCFLAGS) -c libppm5.c
SHAR_EOF
if test 2595 -ne "`wc -c < 'ppm/Imakefile'`"
then
	echo shar: error transmitting "'ppm/Imakefile'" '(should have been 2595 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppm.5'" '(2850 characters)'
if test -f 'ppm/ppm.5'
then
	echo shar: will not over-write existing file "'ppm/ppm.5'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppm.5'
X.TH ppm 5 "05 September 1989"
X.SH NAME
Xppm - portable pixmap file format
X.SH DESCRIPTION
XThe portable pixmap format is a lowest common denominator color image
Xfile format.
XThe definition is as follows:
X.IP - 2
XA "magic number" for identifying the file type.
XA ppm file's magic number is the two characters "P3".
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 color-component value, again in ASCII decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XWidth * height pixels, each three ASCII decimal values between 0 and the
Xspecified maximum value, starting at the top-left
Xcorner of the pixmap, proceding in normal English reading order.
XThe three values for each pixel represent red, green, and blue, respectively;
Xa value of 0 means that color is off, and the maximum value means that color
Xis maxxed out.
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 pixmap in this format:
X.PP
X.nf
XP3
X# feep.ppm
X4 4
X15
X 0  0  0    0  0  0    0  0  0   15  0 15
X 0  0  0    0 15  7    0  0  0    0  0  0
X 0  0  0    0  0  0    0 15  7    0  0  0
X15  0 15    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 pixmap.
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 "P6" instead of "P3".
X.IP - 2
XThe pixel values are stored as plain bytes, instead of ASCII decimal.
X.IP - 2
XWhitespace is not allowed in the pixels area.
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 PPM 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"
Xgiftoppm(1), ilbmtoppm(1), imgtoppm(1), mtvtoppm(1), qrttoppm(1), rasttoppm(1),
Xtgatoppm(1), xwdtoppm(1),
Xppmtogif(1), ppmtoilbm(1), ppmtopgm(1), ppmtops(1), ppmtorast(1), ppmtoxwd(1),
Xppmarith(1), ppmconvol(1), ppmcscale(1), ppmhist(1), ppmquant(1), ppmrotate(1),
Xppmscale(1), ppmshear(1),
Xpnm(5), pgm(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 2850 -ne "`wc -c < 'ppm/ppm.5'`"
then
	echo shar: error transmitting "'ppm/ppm.5'" '(should have been 2850 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm.3'" '(3775 characters)'
if test -f 'ppm/libppm.3'
then
	echo shar: will not over-write existing file "'ppm/libppm.3'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm.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 ppm 3
X.SH NAME
Xppm - functions to support portable pixelmap programs
X.SH SYNOPSIS
X.Ss
X#include <ppm.h>
Xcc ... libppm.a libpgm.a libpbm.a
X.Se
X.SH DESCRIPTION
X.SS TYPES AND CONSTANTS
X.Ss
Xtypedef gray pixval;
X#define PGM_MAXMAXVAL 255
Xtypedef struct
X    {
X    pixval r, g, b;
X    } pixel;
Xextern pixval ppm_pbmmaxval;
X.Se
XEach
X.IR pixval
Xshould contain only the values between
X.IR 0
Xand
X.IR PGM_MAXMAXVAL .
X.IR ppm_pbmmaxval
Xis the maxval used when a PPM program reads a PBM file.
XNormally it is 1; however, for some programs, a larger value gives better
Xresults.
X.SS PIXEL MANIPULATIONS
X.Ss
Xpixval PPM_GETR(p)
Xpixel p;
X
Xpixval PPM_GETG(p)
Xpixel p;
X
Xpixval PPM_GETB(p)
Xpixel p;
X.Se
XThese three macros retrieve the red, green or blue value from the given
Xpixel.
X.Ss
Xvoid PPM_ASSIGN(p,red,grn,blu)
Xpixel p;
Xpixval red, grn, blu;
X.Se
XThis macro assigns the given red, green and blue values to the pixel.
X.Ss
Xint PPM_EQUAL(p,q)
Xpixel p, q;
X.Se
XThis macro checks two pixels for equality.
X.Ss
Xvoid PPM_CSCALE(newp, p, oldmaxval, newmaxval)
Xpixel newp, p;
Xpixval oldmaxval, newmaxval;
X.Se
XThis macro scales the colors of pixel
X.IR p
Xaccording the old and new maximum values and assigns the new values to
X.IR newp .
XIt is intended to make writing ppmtowhatever easier.
X.Ss
Xdouble PPM_LUMIN(p)
Xpixel p;
X.Se
XThis macro determines the luminance of the pixel
X.IR p .
X.SS PGM MEMORY MANAGEMENT
X.Ss
Xpixel **pgm_allocarray(int cols, int rows)
X.Se
XAllocate an array of pixels.
X.Ss
Xpixel *pgm_allocrow( int cols )
X.Se
XAllocate a row of the given number of pixels.
X.Ss
Xvoid pgm_freearray( pixelrow, rows )
X.Se
XFree the array allocated with
X.IR pgm_allocarray()
Xcontaining the given number
Xof rows.
X.Ss
Xpbm_freerow( pixelrow )
X.Se
XFree a row of pixels.
X.SS READING PBM FILES
X.Ss
Xvoid
Xppm_readppminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xpixval *maxvalP;
X.Se
XRead the header from a pgm file, filling in the rows, cols, maxval and format
Xvariables.
X.Ss
Xvoid
Xppm_readppmrow( file, pixelrow, cols, maxval, format )
XFILE *file;
Xpixel *pixelrow;
Xpixval maxval;
Xint cols, format;
X.Se
XRead a row of pixels into the pixelrow array.
XFormat and cols were filled in by
X.IR ppm_readppminit() .
X.Ss
Xpixel **
Xppm_readppm( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xpixval *maxvalP;
X.Se
XRead an entire pixelmap file into memory, returning the allocated array and
Xfilling in the rows, cols and maxval variables.
XThis function combines
X.IR ppm_readppminit() ,
X.IR ppm_allocarray()
Xand
X.IR ppm_readppmrow() .
X.SS WRITING PGM FILES
X.Ss
Xvoid
Xppm_writeppminit( file, cols, rows, maxval )
XFILE *file;
Xint cols, rows;
Xpixval maxval;
X.Se
XWrite the header for a portable pixelmap file.
X.Ss
Xvoid
Xppm_writeppmrow( file, pixelrow, cols, maxval )
XFILE *file;
Xpixel *pixelrow;
Xint cols;
Xpixval maxval;
X.Se
XWrite a row from a portable pixelmap.
X.Ss
Xvoid
Xppm_writeppm( file, bits, cols, rows, maxval )
XFILE *file;
Xpixel **bits;
Xint cols, rows;
Xpixval maxval;
X.Se
XWrite the header and all data for a portable pixelmap.
XThis function combines
X.IR ppm_writeppminit()
Xand
X.IR ppm_writeppmrow() .
X.Ss
Xpixel ppm_backgroundpixel(pixels, cols, rows)
Xpixel **pixels;
Xint cols;
Xint rows;
X.Se
XIntuit the value of the background.
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 3775 -ne "`wc -c < 'ppm/libppm.3'`"
then
	echo shar: error transmitting "'ppm/libppm.3'" '(should have been 3775 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm1.c'" '(4165 characters)'
if test -f 'ppm/libppm1.c'
then
	echo shar: will not over-write existing file "'ppm/libppm1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm1.c'
X/* libppm1.c - ppm 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 "ppm.h"
X#include "libppm.h"
X#include "pgm.h"
X#include "libpgm.h"
X#include "pbm.h"
X#include "libpbm.h"
X
Xvoid
Xppm_readppminitrest( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xpixval *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 > PPM_MAXMAXVAL )
X	pm_error(
X	    "maxval too large - %d > %d", *maxvalP, PPM_MAXMAXVAL, 0,0,0 );
X    }
X
Xstatic gray *grayrow;
Xstatic bit *bitrow;
X
Xpixval ppm_pbmmaxval = 1;
X
Xvoid
Xppm_readppminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xpixval *maxvalP;
X    {
X    /* Check magic number. */
X    *formatP = pbm_readmagicnumber( file );
X    switch ( *formatP )
X	{
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	ppm_readppminitrest( file, colsP, rowsP, maxvalP );
X	break;
X
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	pgm_readpgminitrest( file, colsP, rowsP, maxvalP );
X	grayrow = pgm_allocrow( *colsP );
X	break;
X
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbminitrest( file, colsP, rowsP );
X	*maxvalP = ppm_pbmmaxval;
X	bitrow = pbm_allocrow( *colsP );
X	break;
X
X	default:
X	pm_error( "bad magic number - not a ppm, pgm, or pbm file", 0,0,0,0,0 );
X	}
X    }
X
Xvoid
Xppm_readppmrow( file, pixelrow, cols, maxval, format )
XFILE *file;
Xpixel *pixelrow;
Xint cols, format;
Xpixval maxval;
X    {
X    register int col;
X    register pixel *pP;
X    register pixval r, g, b;
X    register gray *gP;
X    register bit *bP;
X
X    switch ( format )
X	{
X	case PPM_FORMAT:
X	for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X	    {
X	    r = pbm_getint( file );
X#ifdef DEBUG
X	    if ( r > maxval )
X		pm_error( "r value out of bounds (%u > %u)", r, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    g = pbm_getint( file );
X#ifdef DEBUG
X	    if ( g > maxval )
X		pm_error( "g value out of bounds (%u > %u)", g, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    b = pbm_getint( file );
X#ifdef DEBUG
X	    if ( b > maxval )
X		pm_error( "b value out of bounds (%u > %u)", b, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    PPM_ASSIGN( *pP, r, g, b );
X	    }
X	break;
X
X	case RPPM_FORMAT:
X	for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X	    {
X	    r = pbm_getrawbyte( file );
X#ifdef DEBUG
X	    if ( r > maxval )
X		pm_error( "r value out of bounds (%u > %u)", r, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    g = pbm_getrawbyte( file );
X#ifdef DEBUG
X	    if ( g > maxval )
X		pm_error( "g value out of bounds (%u > %u)", g, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    b = pbm_getrawbyte( file );
X#ifdef DEBUG
X	    if ( b > maxval )
X		pm_error( "b value out of bounds (%u > %u)", b, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	    PPM_ASSIGN( *pP, r, g, b );
X	    }
X	break;
X
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	pgm_readpgmrow( file, grayrow, cols, maxval, format );
X	for ( col = 0, gP = grayrow, pP = pixelrow; col < cols; col++, gP++, pP++ )
X	    {
X	    r = *gP;
X	    PPM_ASSIGN( *pP, r, r, r );
X	    }
X	break;
X
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbmrow( file, bitrow, cols, format );
X	for ( col = 0, bP = bitrow, pP = pixelrow; col < cols; col++, bP++, pP++ )
X	    {
X	    r = ( *bP == PBM_WHITE ) ? maxval : 0;
X	    PPM_ASSIGN( *pP, r, r, r );
X	    }
X	break;
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xpixel **
Xppm_readppm( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xpixval *maxvalP;
X    {
X    pixel **pixels;
X    int row;
X    int format;
X
X    ppm_readppminit( file, colsP, rowsP, maxvalP, &format );
X
X    pixels = ppm_allocarray( *colsP, *rowsP );
X
X    for ( row = 0; row < *rowsP; row++ )
X	ppm_readppmrow( file, pixels[row], *colsP, *maxvalP, format );
X
X    return pixels;
X    }
SHAR_EOF
if test 4165 -ne "`wc -c < 'ppm/libppm1.c'`"
then
	echo shar: error transmitting "'ppm/libppm1.c'" '(should have been 4165 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm2.c'" '(4123 characters)'
if test -f 'ppm/libppm2.c'
then
	echo shar: will not over-write existing file "'ppm/libppm2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm2.c'
X/* libppm2.c - ppm 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 "ppm.h"
X#include "libppm.h"
X
Xvoid
Xppm_writeppminit( file, cols, rows, maxval )
XFILE *file;
Xint cols, rows;
Xpixval maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, RPPM_MAGIC2,
X	    cols, rows, maxval );
X    else
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, PPM_MAGIC2,
X	    cols, rows, maxval );
X#else /*PBMPLUS_RAWBITS*/
X    fprintf(
X	file, "%c%c\n%d %d\n%d\n", PPM_MAGIC1, PPM_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
Xppm_writeppmrowraw( file, pixelrow, cols, maxval )
XFILE *file;
Xpixel *pixelrow;
Xint cols;
Xpixval maxval;
X    {
X    register int col;
X    register pixel *pP;
X    register pixval val;
X
X    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X	{
X	val = PPM_GETR( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "r value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putc( val, file ) == EOF )
X	    pm_perror( 0 );
X	val = PPM_GETG( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "g value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putc( val, file ) == EOF )
X	    pm_perror( 0 );
X	val = PPM_GETB( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "b value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putc( val, file ) == EOF )
X	    pm_perror( 0 );
X        }
X    }
X#endif /*PBMPLUS_RAWBITS*/
X
Xstatic void
Xppm_writeppmrowplain( file, pixelrow, cols, maxval )
XFILE *file;
Xpixel *pixelrow;
Xint cols;
Xpixval maxval;
X    {
X    register int col, charcount;
X    register pixel *pP;
X    register pixval val;
X
X    charcount = 0;
X    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X	{
X	if ( charcount >= 70 )
X	    {
X	    if ( putc( '\n', file ) == EOF )
X		pm_perror( 0 );
X	    charcount = 0;
X	    }
X	val = PPM_GETR( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "r value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putus( val, file ) == EOF )
X	    pm_perror( 0 );
X	if ( putc( ' ', file ) == EOF )
X	    pm_perror( 0 );
X	val = PPM_GETG( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "g value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putus( val, file ) == EOF )
X	    pm_perror( 0 );
X	if ( putc( ' ', file ) == EOF )
X	    pm_perror( 0 );
X	val = PPM_GETB( *pP );
X#ifdef DEBUG
X	if ( val > maxval )
X	    pm_error( "b value out of bounds (%u > %u)", val, maxval, 0,0,0 );
X#endif /*DEBUG*/
X	if ( putus( val, file ) == EOF )
X	    pm_perror( 0 );
X	if ( putc( ' ', file ) == EOF )
X	    pm_perror( 0 );
X	if ( putc( ' ', file ) == EOF )
X	    pm_perror( 0 );
X	charcount += 13;
X	}
X    if ( putc( '\n', file ) == EOF )
X	pm_perror( 0 );
X    }
X
Xvoid
Xppm_writeppmrow( file, pixelrow, cols, maxval )
XFILE *file;
Xpixel *pixelrow;
Xint cols;
Xpixval maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	ppm_writeppmrowraw( file, pixelrow, cols, maxval );
X    else
X	ppm_writeppmrowplain( file, pixelrow, cols, maxval );
X#else /*PBMPLUS_RAWBITS*/
X    ppm_writeppmrowplain( file, pixelrow, cols, maxval );
X#endif /*PBMPLUS_RAWBITS*/
X    }
X
Xvoid
Xppm_writeppm( file, pixels, cols, rows, maxval )
XFILE *file;
Xpixel **pixels;
Xint cols, rows;
Xpixval maxval;
X    {
X    int row;
X
X    ppm_writeppminit( file, cols, rows, maxval );
X
X    for ( row = 0; row < rows; row++ )
X	ppm_writeppmrow( file, pixels[row], cols, maxval );
X    }
SHAR_EOF
if test 4123 -ne "`wc -c < 'ppm/libppm2.c'`"
then
	echo shar: error transmitting "'ppm/libppm2.c'" '(should have been 4123 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm3.c'" '(6268 characters)'
if test -f 'ppm/libppm3.c'
then
	echo shar: will not over-write existing file "'ppm/libppm3.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm3.c'
X/* libppm3.c - ppm utility library part 3
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 "ppm.h"
X#include "ppmcmap.h"
X#include "libppm.h"
X
X#define HASH_SIZE 6553
X/* #define HASH_SIZE 157 */
X
X#ifdef PPM_PACKCOLORS
X#define ppm_hashpixel(p) ( ( (int) (p) * 353 ) % HASH_SIZE )
X#else /*PPM_PACKCOLORS*/
X#define ppm_hashpixel(p) ( ( (int) PPM_GETR(p) * 33023 + (int) PPM_GETG(p) * 30013 + (int) PPM_GETB(p) * 27011 ) % HASH_SIZE )
X#endif /*PPM_PACKCOLORS*/
X
Xcolorhist_vector
Xppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
Xpixel **pixels;
Xint cols, rows, *colorsP;
X    {
X    colorhash_table cht;
X    colorhist_vector chv;
X
X    cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
X    if ( cht == (colorhash_table) 0 )
X	return (colorhist_vector) 0;
X    chv = ppm_colorhashtocolorhist( cht, maxcolors );
X    ppm_freecolorhash( cht );
X    return chv;
X    }
X
Xvoid
Xppm_addtocolorhist( chv, colorsP, maxcolors, color, value, position )
Xcolorhist_vector chv;
Xpixel color;
Xint *colorsP, maxcolors, value, position;
X    {
X    int i, j;
X
X    /* Search colorhist for the color. */
X    for ( i = 0; i < *colorsP; i++ )
X	if ( PPM_EQUAL( chv[i].color, color ) )
X	    {
X	    /* Found it - move to new slot. */
X	    if ( position > i )
X		{
X		for ( j = i; j < position; ++j )
X		    chv[j] = chv[j + 1];
X		}
X	    else if ( position < i )
X		{
X		for ( j = i; j > position; --j )
X		    chv[j] = chv[j - 1];
X		}
X	    chv[position].color = color;
X	    chv[position].value = value;
X	    return;
X	    }
X    if ( *colorsP < maxcolors )
X	{
X	/* Didn't find it, but there's room to add it; so do so. */
X	for ( i = *colorsP; i > position; i-- )
X	    chv[i] = chv[i - 1];
X	chv[position].color = color;
X	chv[position].value = value;
X	(*colorsP)++;
X	}
X    }
X
Xcolorhash_table
Xppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP )
Xpixel **pixels;
Xint cols, rows, *colorsP;
X    {
X    colorhash_table cht;
X    register pixel *pP;
X    colorhist_list chl;
X    int col, row, hash;
X
X    cht = ppm_alloccolorhash( );
X    *colorsP = 0;
X
X    /* Go through the entire image, building a hash table of colors. */
X    for ( row = 0; row < rows; row++ )
X	for ( col = 0, pP = pixels[row]; col < cols; col++, pP++ )
X	    {
X	    hash = ppm_hashpixel( *pP );
X	    for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
X		if ( PPM_EQUAL( chl->ch.color, *pP ) )
X		    break;
X	    if ( chl != (colorhist_list) 0 )
X		chl->ch.value++;
X	    else
X		{
X		if ( (*colorsP)++ > maxcolors )
X		    {
X		    ppm_freecolorhash( cht );
X		    return (colorhash_table) 0;
X		    }
X		chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
X		if ( chl == 0 )
X		    pm_error( "out of memory computing hash table", 0,0,0,0,0 );
X		chl->ch.color = *pP;
X		chl->ch.value = 1;
X		chl->next = cht[hash];
X		cht[hash] = chl;
X		}
X	    }
X    
X    return cht;
X    }
X
Xcolorhash_table
Xppm_alloccolorhash( )
X    {
X    colorhash_table cht;
X    int i;
X
X    cht = (colorhash_table) malloc( HASH_SIZE * sizeof(colorhist_list) );
X    if ( cht == 0 )
X	pm_error( "out of memory allocating hash table", 0,0,0,0,0 );
X
X    for ( i = 0; i < HASH_SIZE; i++ )
X	cht[i] = (colorhist_list) 0;
X
X    return cht;
X    }
X
Xvoid
Xppm_addtocolorhash( cht, color, value )
Xcolorhash_table cht;
Xpixel color;
Xint value;
X    {
X    int hash;
X    colorhist_list chl;
X
X    hash = ppm_hashpixel( color );
X    chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
X    if ( chl == 0 )
X	pm_error( "out of memory adding to hash table", 0,0,0,0,0 );
X    chl->ch.color = color;
X    chl->ch.value = value;
X    chl->next = cht[hash];
X    cht[hash] = chl;
X}
X
Xcolorhist_vector
Xppm_colorhashtocolorhist( cht, maxcolors )
Xcolorhash_table cht;
Xint maxcolors;
X    {
X    colorhist_vector chv;
X    colorhist_list chl;
X    int i, j;
X
X    /* Now collate the hash table into a simple colorhist array. */
X    chv = (colorhist_vector) malloc( maxcolors * sizeof(struct colorhist_item) );
X    /* (Leave room for expansion by caller.) */
X    if ( chv == (colorhist_vector) 0 )
X	pm_error( "out of memory generating histogram", 0,0,0,0,0 );
X
X    /* Loop through the hash table. */
X    j = 0;
X    for ( i = 0; i < HASH_SIZE; i++ )
X	for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next )
X	    {
X	    /* Add the new entry. */
X	    chv[j] = chl->ch;
X	    j++;
X	    }
X
X    /* All done. */
X    return chv;
X    }
X
Xcolorhash_table
Xppm_colorhisttocolorhash( chv, colors )
Xcolorhist_vector chv;
Xint colors;
X    {
X    colorhash_table cht;
X    int i, hash;
X    pixel color;
X    colorhist_list chl;
X
X    cht = ppm_alloccolorhash( );
X
X    for ( i = 0; i < colors; i++ )
X	{
X	color = chv[i].color;
X	hash = ppm_hashpixel( color );
X	for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
X	    if ( PPM_EQUAL( chl->ch.color, color ) )
X		pm_error(
X		    "same color found twice - %d %d %d", PPM_GETR(color),
X		    PPM_GETG(color), PPM_GETB(color), 0,0 );
X	chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
X	if ( chl == (colorhist_list) 0 )
X	    pm_error( "out of memory", 0,0,0,0,0 );
X	chl->ch.color = color;
X	chl->ch.value = i;
X	chl->next = cht[hash];
X	cht[hash] = chl;
X	}
X
X    return cht;
X    }
X
Xint
Xppm_lookupcolor( cht, color )
Xcolorhash_table cht;
Xpixel color;
X    {
X    int hash;
X    colorhist_list chl;
X
X    hash = ppm_hashpixel( color );
X    for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
X	if ( PPM_EQUAL( chl->ch.color, color ) )
X	    return chl->ch.value;
X
X    return -1;
X    }
X
Xvoid
Xppm_freecolorhist( chv )
Xcolorhist_vector chv;
X    {
X    free( (char *) chv );
X    }
X
Xvoid
Xppm_freecolorhash( cht )
Xcolorhash_table cht;
X    {
X    int i;
X    colorhist_list chl, chlnext;
X
X    for ( i = 0; i < HASH_SIZE; i++ )
X	for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext )
X	    {
X	    chlnext = chl->next;
X	    free( (char *) chl );
X	    }
X    free( (char *) cht );
X    }
SHAR_EOF
if test 6268 -ne "`wc -c < 'ppm/libppm3.c'`"
then
	echo shar: error transmitting "'ppm/libppm3.c'" '(should have been 6268 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm4.c'" '(1440 characters)'
if test -f 'ppm/libppm4.c'
then
	echo shar: will not over-write existing file "'ppm/libppm4.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm4.c'
X/* libppm4.c - ppm utility library part 4
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 "ppm.h"
X
Xpixel
Xppm_backgroundpixel( pixels, cols, rows )
Xpixel **pixels;
Xint cols, rows;
X    {
X    pixel bgpixel, ul, ur, ll, lr;
X
X    /* Guess a good background value. */
X    ul = pixels[0][0];
X    ur = pixels[0][cols-1];
X    ll = pixels[rows-1][0];
X    lr = pixels[rows-1][cols-1];
X
X    /* First check for three corners equal. */
X    if ( PPM_EQUAL( ul, ur ) && PPM_EQUAL( ur, ll ) )
X	bgpixel = ul;
X    else if ( PPM_EQUAL( ul, ur ) && PPM_EQUAL( ur, lr ) )
X	bgpixel = ul;
X    else if ( PPM_EQUAL( ul, ll ) && PPM_EQUAL( ll, lr ) )
X	bgpixel = ul;
X    else if ( PPM_EQUAL( ur, ll ) && PPM_EQUAL( ll, lr ) )
X	bgpixel = ur;
X    else
X	/* Nope, so just average the four corners. */
X	PPM_ASSIGN( bgpixel,
X	    PPM_GETR(ul) + PPM_GETR(ur) + PPM_GETR(ll) + PPM_GETR(lr) / 4,
X	    PPM_GETG(ul) + PPM_GETG(ur) + PPM_GETG(ll) + PPM_GETG(lr) / 4,
X	    PPM_GETB(ul) + PPM_GETB(ur) + PPM_GETB(ll) + PPM_GETB(lr) / 4 );
X
X    return bgpixel;
X    }
SHAR_EOF
if test 1440 -ne "`wc -c < 'ppm/libppm4.c'`"
then
	echo shar: error transmitting "'ppm/libppm4.c'" '(should have been 1440 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/libppm5.c'" '(12771 characters)'
if test -f 'ppm/libppm5.c'
then
	echo shar: will not over-write existing file "'ppm/libppm5.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/libppm5.c'
X/* libppm5.c - ppm utility library part 5
X**
X** This library module contains the ppmdraw routines.
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 "ppm.h"
X#include "ppmdraw.h"
X
X
X#define DDA_SCALE 8192
X#define abs(x) ((x) < 0 ? -(x) : (x))
X#define min(x,y) ((x) < (y) ? (x) : (y))
X#define max(x,y) ((x) > (y) ? (x) : (y))
X
X
Xvoid
Xppmd_point_drawproc( pixels, cols, rows, maxval, x, y, clientdata )
Xpixel **pixels;
Xint cols, rows, x, y;
Xpixval maxval;
Xchar *clientdata;
X    {
X    if ( x >= 0 && x < cols && y >= 0 && y < rows )
X	pixels[y][x] = *( (pixel *) clientdata );
X    }
X
X
X/* Simple fill routine. */
X
Xvoid
Xppmd_filledrectangle( pixels, cols, rows, maxval, x, y, width, height, drawprocP, clientdata)
Xpixel **pixels;
Xint cols, rows, x, y, width, height;
Xpixval maxval;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register cx, cy, cwidth, cheight, col, row;
X
X    /* Clip. */
X    cx = x;
X    cy = y;
X    cwidth = width;
X    cheight = height;
X    if ( cx < 0 )
X	{
X	cx = 0;
X	cwidth += x;
X	}
X    if ( cy < 0 )
X	{
X	cy = 0;
X	cheight += y;
X	}
X    if ( cx + cwidth > cols )
X	cwidth = cols - cx;
X    if ( cy + cheight > rows )
X	cheight = rows - cy;
X
X    /* Draw. */
X    for ( row = cy; row < cy + cheight; row++ )
X	for ( col = cx; col < cx + cwidth; col++ )
X	    if ( drawprocP == PPMD_NULLDRAWPROC )
X		pixels[row][col] = *( (pixel *) clientdata );
X	    else
X		(*drawprocP)(
X		    pixels, cols, rows, maxval, col, row, clientdata );
X    }
X
X
X/* Outline drawing stuff. */
X
Xstatic int ppmd_linetype = PPMD_LINETYPE_NORMAL;
X
Xint
Xppmd_setlinetype( type )
Xint type;
X    {
X    int old;
X
X    old = ppmd_linetype;
X    ppmd_linetype = type;
X    return old;
X    }
X
Xstatic int ppmd_lineclip = 1;
X
Xint
Xppmd_setlineclip( clip )
Xint clip;
X    {
X    int old;
X
X    old = ppmd_lineclip;
X    ppmd_lineclip = clip;
X    return old;
X    }
X
Xvoid
Xppmd_line( pixels, cols, rows, maxval, x0, y0, x1, y1, drawprocP, clientdata )
Xpixel **pixels;
Xint cols, rows, x0, y0, x1, y1;
Xpixval maxval;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register int cx0, cy0, cx1, cy1;
X
X    /* Special case zero-length lines. */
X    if ( x0 == x1 && y0 == y1 )
X	{
X	if ( drawprocP == PPMD_NULLDRAWPROC )
X	    ppmd_point_drawproc(
X		pixels, cols, rows, maxval, x0, y0, clientdata );
X	else
X	    (*drawprocP)( pixels, cols, rows, maxval, x0, y0, clientdata );
X	return;
X	}
X
X    /* Clip. */
X    cx0 = x0;
X    cy0 = y0;
X    cx1 = x1;
X    cy1 = y1;
X    if ( ppmd_lineclip )
X	{
X	if ( cx0 < 0 )
X	    {
X	    if ( cx1 < 0 ) return;
X	    cy0 = cy0 + ( cy1 - cy0 ) * ( -cx0 ) / ( cx1 - cx0 );
X	    cx0 = 0;
X	    }
X	else if ( cx0 >= cols )
X	    {
X	    if ( cx1 >= cols ) return;
X	    cy0 = cy0 + ( cy1 - cy0 ) * ( cols - 1 - cx0 ) / ( cx1 - cx0 );
X	    cx0 = cols - 1;
X	    }
X	if ( cy0 < 0 )
X	    {
X	    if ( cy1 < 0 ) return;
X	    cx0 = cx0 + ( cx1 - cx0 ) * ( -cy0 ) / ( cy1 - cy0 );
X	    cy0 = 0;
X	    }
X	else if ( cy0 >= rows )
X	    {
X	    if ( cy1 >= rows ) return;
X	    cx0 = cx0 + ( cx1 - cx0 ) * ( rows - 1 - cy0 ) / ( cy1 - cy0 );
X	    cy0 = rows - 1;
X	    }
X	if ( cx1 < 0 )
X	    {
X	    cy1 = cy1 + ( cy0 - cy1 ) * ( -cx1 ) / ( cx0 - cx1 );
X	    cx1 = 0;
X	    }
X	else if ( cx1 >= cols )
X	    {
X	    cy1 = cy1 + ( cy0 - cy1 ) * ( cols - 1 - cx1 ) / ( cx0 - cx1 );
X	    cx1 = cols - 1;
X	    }
X	if ( cy1 < 0 )
X	    {
X	    cx1 = cx1 + ( cx0 - cx1 ) * ( -cy1 ) / ( cy0 - cy1 );
X	    cy1 = 0;
X	    }
X	else if ( cy1 >= rows )
X	    {
X	    cx1 = cx1 + ( cx0 - cx1 ) * ( rows - 1 - cy1 ) / ( cy0 - cy1 );
X	    cy1 = rows - 1;
X	    }
X
X	/* Check again for zero-length lines. */
X	if ( cx0 == cx1 && cy0 == cy1 )
X	    {
X	    if ( drawprocP == PPMD_NULLDRAWPROC )
X		ppmd_point_drawproc(
X		    pixels, cols, rows, maxval, cx0, cy0, clientdata );
X	    else
X		(*drawprocP)(
X		    pixels, cols, rows, maxval, cx0, cy0, clientdata );
X	    return;
X	    }
X	}
X
X    /* Draw, using a simple DDA. */
X    if ( abs( cx1 - cx0 ) > abs( cy1 - cy0 ) )
X	{ /* Loop over X domain. */
X	register long dy, srow;
X	register int dx, col, row, prevrow;
X
X	if ( cx1 > cx0 )
X	    dx = 1;
X	else
X	    dx = -1;
X	dy = ( cy1 - cy0 ) * DDA_SCALE / abs( cx1 - cx0 );
X	prevrow = row = cy0;
X	srow = row * DDA_SCALE + DDA_SCALE / 2;
X	col = cx0;
X	for ( ; ; )
X	    {
X	    if ( ppmd_linetype == PPMD_LINETYPE_NODIAGS && row != prevrow )
X		{
X		if ( drawprocP == PPMD_NULLDRAWPROC )
X		    pixels[prevrow][col] = *( (pixel *) clientdata );
X		else
X		    (*drawprocP)(
X		        pixels, cols, rows, maxval, col, prevrow, clientdata );
X		prevrow = row;
X		}
X	    if ( drawprocP == PPMD_NULLDRAWPROC )
X		pixels[row][col] = *( (pixel *) clientdata );
X	    else
X		(*drawprocP)(
X		    pixels, cols, rows, maxval, col, row, clientdata );
X	    if ( col == cx1 )
X		break;
X	    srow += dy;
X	    row = srow / DDA_SCALE;
X	    col += dx;
X	    }
X	}
X    else
X	{ /* Loop over Y domain. */
X	register long dx, scol;
X	register int dy, col, row, prevcol;
X
X	if ( cy1 > cy0 )
X	    dy = 1;
X	else
X	    dy = -1;
X	dx = ( cx1 - cx0 ) * DDA_SCALE / abs( cy1 - cy0 );
X	row = cy0;
X	prevcol = col = cx0;
X	scol = col * DDA_SCALE + DDA_SCALE / 2;
X	for ( ; ; )
X	    {
X	    if ( ppmd_linetype == PPMD_LINETYPE_NODIAGS && col != prevcol )
X		{
X		if ( drawprocP == PPMD_NULLDRAWPROC )
X		    pixels[row][prevcol] = *( (pixel *) clientdata );
X		else
X		    (*drawprocP)(
X			pixels, cols, rows, maxval, prevcol, row, clientdata );
X		prevcol = col;
X		}
X	    if ( drawprocP == PPMD_NULLDRAWPROC )
X		pixels[row][col] = *( (pixel *) clientdata );
X	    else
X		(*drawprocP)(
X		    pixels, cols, rows, maxval, col, row, clientdata );
X	    if ( row == cy1 )
X		break;
X	    row += dy;
X	    scol += dx;
X	    col = scol / DDA_SCALE;
X	    }
X	}
X    }
X
X#define SPLINE_THRESH 3
Xvoid
Xppmd_spline3( pixels, cols, rows, maxval, x0, y0, x1, y1, x2, y2, drawprocP, clientdata )
Xpixel **pixels;
Xint cols, rows, x0, y0, x1, y1, x2, y2;
Xpixval maxval;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register int xa, ya, xb, yb, xc, yc, xp, yp;
X
X    xa = ( x0 + x1 ) / 2;
X    ya = ( y0 + y1 ) / 2;
X    xc = ( x1 + x2 ) / 2;
X    yc = ( y1 + y2 ) / 2;
X    xb = ( xa + xc ) / 2;
X    yb = ( ya + yc ) / 2;
X
X    xp = ( x0 + xb ) / 2;
X    yp = ( y0 + yb ) / 2;
X    if ( abs( xa - xp ) + abs( ya - yp ) > SPLINE_THRESH )
X	ppmd_spline3(
X	    pixels, cols, rows, maxval, x0, y0, xa, ya, xb, yb, drawprocP, clientdata );
X    else
X	ppmd_line(
X	    pixels, cols, rows, maxval, x0, y0, xb, yb, drawprocP, clientdata );
X
X    xp = ( x2 + xb ) / 2;
X    yp = ( y2 + yb ) / 2;
X    if ( abs( xc - xp ) + abs( yc - yp ) > SPLINE_THRESH )
X	ppmd_spline3(
X	    pixels, cols, rows, maxval, xb, yb, xc, yc, x2, y2, drawprocP,
X	    clientdata );
X    else
X	ppmd_line(
X	    pixels, cols, rows, maxval, xb, yb, x2, y2, drawprocP, clientdata );
X    }
X
Xvoid
Xppmd_polyspline( pixels, cols, rows, maxval, x0, y0, nc, xc, yc, x1, y1, drawprocP, clientdata )
Xpixel **pixels;
Xint cols, rows, x0, y0, nc, *xc, *yc, x1, y1;
Xpixval maxval;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register int i, x, y, xn, yn;
X
X    x = x0;
X    y = y0;
X    for ( i = 0; i < nc - 1; i++ )
X	{
X	xn = ( xc[i] + xc[i + 1] ) / 2;
X	yn = ( yc[i] + yc[i + 1] ) / 2;
X	ppmd_spline3(
X	    pixels, cols, rows, maxval, x, y, xc[i], yc[i], xn, yn, drawprocP,
X	    clientdata );
X	x = xn;
X	y = yn;
X	}
X    ppmd_spline3(
X	pixels, cols, rows, maxval, x, y, xc[nc - 1], yc[nc - 1], x1, y1,
X	drawprocP, clientdata );
X    }
X
Xvoid
Xppmd_circle( pixels, cols, rows, maxval, cx, cy, radius, drawprocP, clientdata )
Xpixel **pixels;
Xint cols, rows, cx, cy, radius;
Xpixval maxval;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register int x0, y0, x, y, prevx, prevy, nopointsyet;
X    register long sx, sy, e;
X
X    x0 = x = radius;
X    y0 = y = 0;
X    sx = x * DDA_SCALE + DDA_SCALE / 2;
X    sy = y * DDA_SCALE + DDA_SCALE / 2;
X    e = DDA_SCALE / radius;
X    if ( drawprocP == PPMD_NULLDRAWPROC )
X	pixels[y + cy][x + cx] = *( (pixel *) clientdata );
X    else
X	(*drawprocP)( pixels, cols, rows, maxval, x + cx, y + cy, clientdata );
X    nopointsyet = 1;
X    do
X	{
X	prevx = x;
X	prevy = y;
X	sx += e * sy / DDA_SCALE;
X	sy -= e * sx / DDA_SCALE;
X	x = sx / DDA_SCALE;
X	y = sy / DDA_SCALE;
X	if ( x != prevx || y != prevy )
X	    {
X	    nopointsyet = 0;
X	    if ( drawprocP == PPMD_NULLDRAWPROC )
X		pixels[y + cy][x + cx] = *( (pixel *) clientdata );
X	    else
X		(*drawprocP)(
X		    pixels, cols, rows, maxval, x + cx, y + cy, clientdata );
X	    }
X	}
X    while ( nopointsyet || x != x0 || y != y0 );
X    }
X
X
X/* Arbitrary fill stuff. */
X
Xtypedef struct
X    {
X    int x;
X    int y;
X    } coord;
Xtypedef struct
X    {
X    int n;
X    int size;
X    coord *coords;
X    } fillobj;
X
X#define SOME 1000
X
Xstatic int oldclip;
X
Xchar *
Xppmd_fill_init( )
X    {
X    fillobj *fh;
X
X    fh = (fillobj *) malloc( sizeof(fillobj) );
X    if ( fh == 0 )
X	pm_error( "out of memory allocating a fillhandle", 0,0,0,0,0 );
X    fh->n = 0;
X    fh->coords = (coord *) malloc( SOME * sizeof(coord) );
X    if ( fh->coords == 0 )
X	pm_error( "out of memory allocating a fillhandle", 0,0,0,0,0 );
X    fh->coords[0].x = fh->coords[0].y = -27182;
X    fh->size = SOME;
X
X    /* Turn off line clipping. */
X    oldclip = ppmd_setlineclip( 0 );
X    
X    return (char *) fh;
X    }
X
Xvoid
Xppmd_fill_drawproc( pixels, cols, rows, maxval, x, y, clientdata )
Xpixel **pixels;
Xint cols, rows, x, y;
Xpixval maxval;
Xchar *clientdata;
X    {
X    register fillobj *fh;
X    register coord *cp;
X
X    fh = (fillobj *) clientdata;
X    cp = &(fh->coords[fh->n]);
X
X    /* If these are the same coords we saved last time, don't bother. */
X    if ( x == cp->x && y == cp->y )
X	return;
X
X    /* Ok, these are new; check if there's enough room. */
X    if ( fh->n >= fh->size )
X	{
X	fh->size += SOME;
X	fh->coords = (coord *) realloc(
X	    (char *) fh->coords, fh->size * sizeof(coord) );
X	if ( fh->coords == 0 )
X	    pm_error( "out of memory enlarging a fillhandle", 0,0,0,0,0 );
X	cp = &(fh->coords[fh->n]);
X	}
X
X    /* And save 'em. */
X    cp->x = x;
X    cp->y = y;
X    fh->n++;
X    }
X
Xvoid
Xppmd_fill( pixels, cols, rows, maxval, fillhandle, drawprocP, clientdata )
Xpixel **pixels;
Xint cols, rows;
Xpixval maxval;
Xchar *fillhandle;
Xvoid (*drawprocP)();
Xchar *clientdata;
X    {
X    register fillobj *fh;
X    register int i, on, px, py, col;
X    register coord *cp;
X    static int yxcompare();
X
X    fh = (fillobj *) fillhandle;
X
X    /* Restore clipping now. */
X    (void) ppmd_setlineclip( oldclip );
X
X    /* Sort the coords by Y, and secondarily by X. */
X    qsort( (char *) fh->coords, fh->n, sizeof(coord), yxcompare );
X
X    /* Ok, now run through the coords.  This code doesn't deal with
X    ** inflection points too well, but it would not be hard to fix. */
X    on = 0;
X    px = py = -31415;
X    for ( i = 0; i < fh->n; i++ )
X	{
X	cp = &(fh->coords[i]);
X	if ( on )
X	    {
X	    if ( cp->y != py )
X		{ /* Broken span.  Hmm.  Start a new one. */
X		px = cp->x;
X		py = cp->y;
X		}
X	    else
X		if ( cp->x <= px + 1 )
X		    { /* Not an end-of-span, but a continuation of the start. */
X		    if ( py >= 0 && py < rows && px >= 0 && px < cols )
X			if ( drawprocP == PPMD_NULLDRAWPROC )
X			    pixels[py][px] = *( (pixel *) clientdata );
X			else
X			    (*drawprocP)(
X				pixels, cols, rows, maxval, px, py,
X				clientdata );
X		    px = cp->x;
X		    }
X		else
X		    { /* Got a span to fill.  But clip it first. */
X		    if ( py >= 0 && py < rows )
X			{
X			if ( px < 0 )
X			    px = 0;
X			if ( cp->x >= cols )
X			    cp->x = cols - 1;
X			if ( px <= cp->x )
X			    for ( col = px; col <= cp->x; col++ )
X				if ( drawprocP == PPMD_NULLDRAWPROC )
X				    pixels[py][col] = *( (pixel *) clientdata );
X				else
X				    (*drawprocP)(
X					pixels, cols, rows, maxval, col, py,
X					clientdata );
X			}
X		    px = cp->x;
X		    on = 0;
X		    }
X	    }
X	else
X	    {
X	    if ( cp->y == py && cp->x <= px + 1 )
X		{ /* Not a start-of-span, but a continuation of the end. */
X		px = cp->x;
X		if ( py >= 0 && py < rows && px >= 0 && px < cols )
X		    if ( drawprocP == PPMD_NULLDRAWPROC )
X			pixels[py][px] = *( (pixel *) clientdata );
X		    else
X			(*drawprocP)(
X			    pixels, cols, rows, maxval, px, py, clientdata );
X		}
X	    else
X		{
X		px = cp->x;
X		py = cp->y;
X		on = 1;
X		}
X	    }
X	}
X
X    /* All done.  Free up the fillhandle and leave. */
X    free( fh->coords );
X    free( fh );
X    }
X
Xstatic int
Xyxcompare( c1, c2 )
Xcoord *c1, *c2;
X    {
X    if ( c1->y > c2->y )
X	return 1;
X    if ( c1->y < c2->y )
X	return -1;
X    if ( c1->x > c2->x )
X	return 1;
X    if ( c1->x < c2->x )
X	return -1;
X    return 0;
X    }
SHAR_EOF
if test 12771 -ne "`wc -c < 'ppm/libppm5.c'`"
then
	echo shar: error transmitting "'ppm/libppm5.c'" '(should have been 12771 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
if test ! -d 'ppm/convolscripts'
then
	echo shar: creating directory "'ppm/convolscripts'"
	mkdir 'ppm/convolscripts'
fi
echo shar: extracting "'ppm/convolscripts/ppmsmooth'" '(265 characters)'
if test -f 'ppm/convolscripts/ppmsmooth'
then
	echo shar: will not over-write existing file "'ppm/convolscripts/ppmsmooth'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/convolscripts/ppmsmooth'
X#!/bin/csh -f
X#
X# ppmsmooth - smooth out an image by replacing each pixel with the
X#             average of its nine immediate neighbors
X
Xset tmp=/tmp/ppmsm$$
Xrm -f $tmp
X
Xcat > $tmp << 'MOO'
XP2
X3 3
X18
X10 10 10
X10 10 10
X10 10 10
X'MOO'
X
Xppmconvol $tmp $*
X
Xrm -f $tmp
SHAR_EOF
if test 265 -ne "`wc -c < 'ppm/convolscripts/ppmsmooth'`"
then
	echo shar: error transmitting "'ppm/convolscripts/ppmsmooth'" '(should have been 265 characters)'
fi
chmod +x 'ppm/convolscripts/ppmsmooth'
fi # end of overwriting check
#	End of shell archive
exit 0