PBMPLUS, part 10 of 18

Jef Poskanzer pokey at well.UUCP
Thu Sep 14 21:25:25 AEST 1989


#! /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/libppm1.c
#	ppm/libppm2.c
#	ppm/libppm3.c
#	ppm/libppm4.c
#	ppm/libppm5.c
#	ppm/convolscripts/ppmsmooth
# This archive created: Thu Sep 14 03:43:40 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'" '(4728 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 -fstrength-reduce -fcombine-regs
X# CFLAGS =	-O
XCFLAGS =	-g
X# CFLAGS =	
X# LDFLAGS =	-s
XLDFLAGS =	
XINSTALLBINARIES =	/usr/new/pbm
XINSTALLMANUALS =	n
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 ppmtoxwd qrttoppm tgatoppm xwdtoppm
XMATHBINARIES =	ppmpat ppmrotate ppmshear
XSUNBINARIES =	ppmtorast rasttoppm
X
XPORTMANUALS =	giftoppm.1 ilbmtoppm.1 imgtoppm.1 mtvtoppm.1 ppm.5 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 ppmtoxwd.1 qrttoppm.1 tgatoppm.1 xwdtoppm.1
XSUNMANUALS =	ppmtorast.1 rasttoppm.1
X
X# CONFIGURE: If you are not on a Sun, switch around the commenting here
X# to avoid compiling the Sun-specific programs:
XBINARIES =	$(PORTBINARIES) $(MATHBINARIES) $(SUNBINARIES)
X# BINARIES =	$(PORTBINARIES) $(MATHBINARIES)
XMANUALS =	$(PORTMANUALS) $(SUNMANUALS)
X# MANUALS =	$(PORTMANUALS)
X
Xall:		binaries
Xinstall:	installbinaries
X
Xbinaries:	$(BINARIES)
X
Xinstallbinaries:	binaries
X	cp $(BINARIES) $(INSTALLBINARIES)
X
Xinstallmanuals:
X	cp $(MANUALS) /usr/man/man$(INSTALLMANUALS)
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# Rule for pixrect-dependent programs.
X$(SUNBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPPM) $(LIBPGM) $(LIBPBM) -lpixrect
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 ppmcmap.h $(PGMDIR)/dithers.h
Xppmrotate:	ppmrotate.c
Xppmscale:	ppmscale.c
Xppmshear:	ppmshear.c
Xppmtogif:	ppmtogif.c
Xppmtoilbm:	ppmtoilbm.c ilbm.h
Xppmtopgm:	ppmtopgm.c
Xppmtops:	ppmtops.c
Xppmtoxwd:	ppmtoxwd.c $(PBMDIR)/x11wd.h
Xppmtorast:	ppmtorast.c ppmcmap.h
Xqrttoppm:	qrttoppm.c
Xrasttoppm:	rasttoppm.c
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	$(IRULESRC)/Imake.tmpl \
X	$(IRULESRC)/Imake.rules \
X	$(IRULESRC)/site.def \
X	$(IRULESRC)/$(MACROFILE)
X	- at 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 4728 -ne "`wc -c < 'ppm/Makefile'`"
then
	echo shar: error transmitting "'ppm/Makefile'" '(should have been 4728 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'" '(3057 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 ppmtoxwd qrttoppm tgatoppm xwdtoppm
XMATHBINARIES =	ppmpat ppmrotate ppmshear
XSUNBINARIES =	ppmtorast rasttoppm
X
XPORTMANUALS =	giftoppm.1 ilbmtoppm.1 imgtoppm.1 mtvtoppm.1 ppm.5 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 ppmtoxwd.1 qrttoppm.1 tgatoppm.1 xwdtoppm.1
XSUNMANUALS =	ppmtorast.1 rasttoppm.1
X
X# CONFIGURE: If you are not on a Sun, switch around the commenting here
X# to avoid compiling the Sun-specific programs:
XBINARIES =	$(PORTBINARIES) $(MATHBINARIES) $(SUNBINARIES)
X# BINARIES =	$(PORTBINARIES) $(MATHBINARIES)
XMANUALS =	$(PORTMANUALS) $(SUNMANUALS)
X# MANUALS =	$(PORTMANUALS)
X
Xall:		binaries
Xinstall:	installbinaries
X
Xbinaries:	$(BINARIES)
X
Xinstallbinaries:	binaries
X	cp $(BINARIES) $(INSTALLBINARIES)
X
Xinstallmanuals:
X	cp $(MANUALS) /usr/man/man$(INSTALLMANUALS)
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# Rule for pixrect-dependent programs.
X$(SUNBINARIES):	ppm.h $(DEFPGM) $(DEFPBM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPPM) $(LIBPGM) $(LIBPBM) -lpixrect
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 3057 -ne "`wc -c < 'ppm/Imakefile'`"
then
	echo shar: error transmitting "'ppm/Imakefile'" '(should have been 3057 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/libppm1.c'" '(4141 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 4141 -ne "`wc -c < 'ppm/libppm1.c'`"
then
	echo shar: error transmitting "'ppm/libppm1.c'" '(should have been 4141 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'" '(4574 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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
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		{
X		perror( "ppm_writeppmrow" );
X		exit( 1 );
X		}
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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
X	if ( putc( ' ', file ) == EOF )
X	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
X	if ( putc( ' ', file ) == EOF )
X	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
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	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
X	if ( putc( ' ', file ) == EOF )
X	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
X	if ( putc( ' ', file ) == EOF )
X	    {
X	    perror( "ppm_writeppmrow" );
X	    exit( 1 );
X	    }
X	charcount += 13;
X	}
X    if ( putc( '\n', file ) == EOF )
X	{
X	perror( "ppm_writeppmrow" );
X	exit( 1 );
X	}
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 4574 -ne "`wc -c < 'ppm/libppm2.c'`"
then
	echo shar: error transmitting "'ppm/libppm2.c'" '(should have been 4574 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'" '(6148 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	    for ( j = i - 1; j >= position; j-- )
X		chv[j + 1] = chv[j];
X	    chv[position].color = color;
X	    chv[position].value = value;
X	    return;
X	    }
X    if ( *colorsP < maxcolors && *colorsP != 2 )
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 6148 -ne "`wc -c < 'ppm/libppm3.c'`"
then
	echo shar: error transmitting "'ppm/libppm3.c'" '(should have been 6148 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



More information about the Alt.sources mailing list