[comp.sources.misc] v09i034: PBMPLUS part 18 of 19: pnm.shar1 of 1

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

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

#! /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:
#	pnm/Makefile
#	pnm/Imakefile
#	pnm/pnm.5
#	pnm/libpnm.3
#	pnm/libpnm1.c
#	pnm/libpnm2.c
#	pnm/libpnm3.c
#	pnm/pnm.h
#	pnm/pnmcat.c
#	pnm/pnmcat.1
#	pnm/pnmcrop.c
#	pnm/pnmcrop.1
#	pnm/pnmcut.c
#	pnm/pnmcut.1
# This archive created: Wed Nov 22 22:56:01 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/Makefile'" '(3711 characters)'
if test -f 'pnm/Makefile'
then
	echo shar: will not over-write existing file "'pnm/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/Makefile'
X# Makefile for pnm 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
X# CONFIGURE: You can compile PNM without PPM.  If you don't want PPM,
X# comment out the next five lines.  This will make the PNM programs use
X# less memory.
XPPMOPT =	-DPPM
XPPMDIR =	../ppm
XINCLUDEPPM =	-I$(PPMDIR)
XLIBPPM =	$(PPMDIR)/libppm.a
XDEFPPM =	$(PPMDIR)/ppm.h ../pbmplus.h
XDEFLIBPPM =	$(PPMDIR)/libppm.h
X
X# CONFIGURE: Likewise here: if you don't have PGM, comment these lines out.
XPGMOPT =	-DPGM
XPGMDIR =	../pgm
XINCLUDEPGM =	-I$(PGMDIR)
XLIBPGM =	$(PGMDIR)/libpgm.a
XDEFPGM =	$(PGMDIR)/pgm.h
XDEFLIBPGM =	$(PGMDIR)/libpgm.h
X
X# PBM is required, don't comment these lines out.
XPBMOPT =	-DPBM
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XSHELL =		/bin/sh
XINCLUDE =	$(INCLUDEPPM) $(INCLUDEPGM) $(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(PPMOPT) $(PGMOPT) $(PBMOPT) $(INCLUDE)
XLIBPNM =	libpnm.a
X
XBINARIES =	pnmcat pnmcrop pnmcut pnmenlarge pnmflip pnminvert pnmpaste \
X		pnmtile
X
XMANUALS1 =	pnmcat.1 pnmcrop.1 pnmcut.1 pnmenlarge.1 pnmflip.1 \
X		pnminvert.1 pnmpaste.1 pnmtile.1
XMANUALS3 =	libpnm.3
XMANUALS5 =	pnm.5
X
Xall:		binaries
X
Xinstall:	installbinaries installmanuals
X# install:	installbinaries
X
Xbinaries:	$(BINARIES)
X
Xinstallbinaries:	binaries
X	cp $(BINARIES) $(INSTALLBINARIES)
X
Xinstallmanuals:
X	cp $(MANUALS1) $(INSTALLMANUALS1)
X	cp $(MANUALS3) $(INSTALLMANUALS3)
X	cp $(MANUALS5) $(INSTALLMANUALS5)
X
X# Rule for plain programs.
X$(BINARIES):	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) $(LIBPNM) \
X			$(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPNM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPNM):	libpnm1.o libpnm2.o libpnm3.o
X	-rm $(LIBPNM)
X	ar rc $(LIBPNM) libpnm1.o libpnm2.o libpnm3.o
X	-ranlib $(LIBPNM)
X
Xlibpnm1.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm1.c
X	$(CC) $(ALLCFLAGS) -c libpnm1.c
Xlibpnm2.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm2.c $(DEFLIBPPM) \
X		$(DEFLIBPGM) $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpnm2.c
Xlibpnm3.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm3.c $(DEFLIBPPM) \
X		$(DEFLIBPGM) $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpnm3.c
X
X# Other dependencies.
Xpnmcat:		pnmcat.c
Xpnmcrop:	pnmcrop.c
Xpnmcut:		pnmcut.c
Xpnmenlarge:	pnmenlarge.c
Xpnmflip:	pnmflip.c
Xpnminvert:	pnminvert.c
Xpnmpaste:	pnmpaste.c
Xpnmtile:	pnmtile.c
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 3711 -ne "`wc -c < 'pnm/Makefile'`"
then
	echo shar: error transmitting "'pnm/Makefile'" '(should have been 3711 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/Imakefile'" '(2348 characters)'
if test -f 'pnm/Imakefile'
then
	echo shar: will not over-write existing file "'pnm/Imakefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/Imakefile'
X# Imakefile for pnm 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# CONFIGURE: You can compile PNM without PPM.  If you don't want PPM,
X# comment out the next five lines.  This will make the PNM programs use
X# less memory.
XPPMOPT =	-DPPM
XPPMDIR =	../ppm
XINCLUDEPPM =	-I$(PPMDIR)
XLIBPPM =	$(PPMDIR)/libppm.a
XDEFPPM =	$(PPMDIR)/ppm.h ../pbmplus.h
XDEFLIBPPM =	$(PPMDIR)/libppm.h
X
X# CONFIGURE: Likewise here: if you don't have PGM, comment these lines out.
XPGMOPT =	-DPGM
XPGMDIR =	../pgm
XINCLUDEPGM =	-I$(PGMDIR)
XLIBPGM =	$(PGMDIR)/libpgm.a
XDEFPGM =	$(PGMDIR)/pgm.h
XDEFLIBPGM =	$(PGMDIR)/libpgm.h
X
X# PBM is required, don't comment these lines out.
XPBMOPT =	-DPBM
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XINCLUDE =	$(INCLUDEPPM) $(INCLUDEPGM) $(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(PPMOPT) $(PGMOPT) $(PBMOPT) $(INCLUDE)
XLIBPNM =	libpnm.a
X
XBINARIES =	pnmcat pnmcrop pnmcut pnmenlarge pnmflip pnminvert pnmpaste \
X		pnmtile
X
XMANUALS1 =	pnmcat.1 pnmcrop.1 pnmcut.1 pnmenlarge.1 pnmflip.1 \
X		pnminvert.1 pnmpaste.1 pnmtile.1
XMANUALS3 =	libpnm.3
XMANUALS5 =	pnm.5
X
Xall:		$(BINARIES)
X
Xinstall::	all
X	cp $(BINARIES) $(BINDIR)
X
Xinstall.man::
X	cp $(MANUALS1) $(MANUALS3) $(MANUALS5) $(MANDIR)
X
X# Rule for plain programs.
X$(BINARIES):	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) $(LIBPNM) \
X			$(LIBPPM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPNM) $(LIBPPM) $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPNM):	libpnm1.o libpnm2.o libpnm3.o
X	-rm $(LIBPNM)
X	ar rc $(LIBPNM) libpnm1.o libpnm2.o libpnm3.o
X	-ranlib $(LIBPNM)
X
Xlibpnm1.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm1.c
X	$(CC) $(ALLCFLAGS) -c libpnm1.c
Xlibpnm2.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm2.c $(DEFLIBPPM) \
X		$(DEFLIBPGM) $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpnm2.c
Xlibpnm3.o:	pnm.h $(DEFPPM) $(DEFPGM) $(DEFPBM) libpnm3.c $(DEFLIBPPM) \
X		$(DEFLIBPGM) $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpnm3.c
SHAR_EOF
if test 2348 -ne "`wc -c < 'pnm/Imakefile'`"
then
	echo shar: error transmitting "'pnm/Imakefile'" '(should have been 2348 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnm.5'" '(820 characters)'
if test -f 'pnm/pnm.5'
then
	echo shar: will not over-write existing file "'pnm/pnm.5'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnm.5'
X.TH pnm 5 "08 August 1989"
X.SH NAME
Xpnm - portable anymap file format
X.SH DESCRIPTION
XThe pnm programs operate on portable bitmaps, graymaps, and pixmaps,
Xproduced by the PBM, PGM, and PPM toolkits.
XThere is no file format associated with pnm itself.
X.SH "SEE ALSO"
Xpnmcatlr(1), pnmcattb(1), pnmcrop(1), pnmcut(1), pnmenlarge(1), pnmflip(1),
Xpnminvert(1), pnmpaste(1), pnmtile(1)
Xppm(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 820 -ne "`wc -c < 'pnm/pnm.5'`"
then
	echo shar: error transmitting "'pnm/pnm.5'" '(should have been 820 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/libpnm.3'" '(1471 characters)'
if test -f 'pnm/libpnm.3'
then
	echo shar: will not over-write existing file "'pnm/libpnm.3'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/libpnm.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 pnm 3
X.SH NAME
Xpnm - functions to support portable anymap programs
X.SH SYNOPSIS
X.Ss
X#include <pbm.h>
Xcc ... libpbm.a
X.Se
X.SH DESCRIPTION
X.SS MESSAGE MANAGEMENT
X.Ss
Xchar *pm_progname;
X.Se
XThis variable should be set at the beginning of all programs to point to
Xargv[0].
X.Ss
Xvoid
Xpm_message( fmt, ... )
Xchar *fmt;
X.Se
XUse this function to write an informational message.
X.Ss
Xvoid
Xpm_error( fmt, ... )
Xchar *fmt;
X.Se
XUse this function to write an error message (and exit).
X.Ss
Xvoid
Xpm_usage( usage )
Xchar *usage;
X.Se
XUse this function to write a usage message.
XThe string should indicate what arguments are to be provided to the program.
X.SS GENERIC FILE MANAGEMENT
X.Ss
XFILE *
Xpm_openr( name )
Xchar *name;
X.Se
XOpen the given file for reading, with appropriate error checking.
XA filename of ``-'' is taken as equivalent to stdin.
X.Ss
Xvoid
Xpm_close( f )
XFILE *f;
X.Se
XClose the file descriptor, with appropriate error checking.
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.
X
SHAR_EOF
if test 1471 -ne "`wc -c < 'pnm/libpnm.3'`"
then
	echo shar: error transmitting "'pnm/libpnm.3'" '(should have been 1471 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/libpnm1.c'" '(2930 characters)'
if test -f 'pnm/libpnm1.c'
then
	echo shar: will not over-write existing file "'pnm/libpnm1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/libpnm1.c'
X/* libpnm1.c - pnm 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 "pnm.h"
X
X#ifdef PPM
X#include "ppm.h"
X#include "libppm.h"
X#endif /*PPM*/
X
X#ifdef PGM
X#include "pgm.h"
X#include "libpgm.h"
Xstatic gray *grayrow;
X#endif /*PGM*/
X
X#ifdef PBM
X#include "pbm.h"
X#include "libpbm.h"
Xstatic bit *bitrow;
X#endif /*PBM*/
X
Xvoid
Xpnm_readpnminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xxelval *maxvalP;
X    {
X#ifdef PGM
X    gray gmaxval;
X#endif /*PGM*/
X
X    /* Check magic number. */
X    *formatP = pbm_readmagicnumber( file );
X    switch ( *formatP )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	ppm_readppminitrest( file, colsP, rowsP, maxvalP );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	pgm_readpgminitrest( file, colsP, rowsP, &gmaxval );
X	*maxvalP = (xelval) gmaxval;
X	grayrow = pgm_allocrow( *colsP );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbminitrest( file, colsP, rowsP );
X	bitrow = pbm_allocrow( *colsP );
X	break;
X#endif /*PBM*/
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
Xpnm_readpnmrow( file, xelrow, cols, maxval, format )
XFILE *file;
Xxel *xelrow;
Xxelval maxval;
Xint cols, format;
X    {
X    register int col;
X    register xel *xP;
X#ifdef PGM
X    register gray *gP;
X#endif /*PGM*/
X#ifdef PBM
X    register bit *bP;
X#endif /*PBM*/
X
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	ppm_readppmrow( file, (pixel *) xelrow, cols, (pixval) maxval, format );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	pgm_readpgmrow( file, grayrow, cols, (gray) maxval, format );
X	for ( col = 0, xP = xelrow, gP = grayrow; col < cols; col++, xP++, gP++ )
X	    PNM_ASSIGN1( *xP, *gP );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbmrow( file, bitrow, cols, format );
X	for ( col = 0, xP = xelrow, bP = bitrow; col < cols; col++, xP++, bP++ )
X	    PNM_ASSIGN1( *xP, *bP );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xxel **
Xpnm_readpnm( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xxelval *maxvalP;
X    {
X    xel **xels;
X    int row;
X
X    pnm_readpnminit( file, colsP, rowsP, maxvalP, formatP );
X
X    xels = pnm_allocarray( *colsP, *rowsP );
X
X    for ( row = 0; row < *rowsP; row++ )
X	pnm_readpnmrow( file, xels[row], *colsP, *maxvalP, *formatP );
X
X    return xels;
X    }
SHAR_EOF
if test 2930 -ne "`wc -c < 'pnm/libpnm1.c'`"
then
	echo shar: error transmitting "'pnm/libpnm1.c'" '(should have been 2930 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/libpnm2.c'" '(2619 characters)'
if test -f 'pnm/libpnm2.c'
then
	echo shar: will not over-write existing file "'pnm/libpnm2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/libpnm2.c'
X/* libpnm2.c - pnm 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 "pnm.h"
X
X#ifdef PPM
X#include "ppm.h"
X#include "libppm.h"
X#endif /*PPM*/
X
X#ifdef PGM
X#include "pgm.h"
X#include "libpgm.h"
Xstatic gray *grayrow;
X#endif /*PGM*/
X
X#ifdef PBM
X#include "pbm.h"
X#include "libpbm.h"
Xstatic bit *bitrow;
X#endif /*PBM*/
X
Xvoid
Xpnm_writepnminit( file, cols, rows, maxval, format )
XFILE *file;
Xint cols, rows, format;
Xxelval maxval;
X    {
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	ppm_writeppminit( file, cols, rows, (pixval) maxval );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	pgm_writepgminit( file, cols, rows, (gray) maxval );
X	grayrow = pgm_allocrow( cols );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_writepbminit( file, cols, rows );
X	bitrow = pbm_allocrow( cols );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xvoid
Xpnm_writepnmrow( file, xelrow, cols, maxval, format )
XFILE *file;
Xxel *xelrow;
Xxelval maxval;
Xint cols, format;
X    {
X    register int col;
X    register xel *xP;
X#ifdef PGM
X    register gray *gP;
X#endif /*PGM*/
X#ifdef PBM
X    register bit *bP;
X#endif /*PBM*/
X
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	ppm_writeppmrow( file, (pixel *) xelrow, cols, (pixval) maxval );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	for ( col = 0, gP = grayrow, xP = xelrow; col < cols; col++, gP++, xP++ )
X	    *gP = PNM_GET1( *xP );
X	pgm_writepgmrow( file, grayrow, cols, (gray) maxval );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	for ( col = 0, bP = bitrow, xP = xelrow; col < cols; col++, bP++, xP++ )
X	    *bP = PNM_GET1( *xP );
X	pbm_writepbmrow( file, bitrow, cols );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xvoid
Xpnm_writepnm( file, xels, cols, rows, maxval, format )
XFILE *file;
Xxel **xels;
Xxelval maxval;
Xint cols, rows, format;
X    {
X    int row;
X
X    pnm_writepnminit( file, cols, rows, maxval, format );
X
X    for ( row = 0; row < rows; row++ )
X	pnm_writepnmrow( file, xels[row], cols, maxval, format );
X    }
SHAR_EOF
if test 2619 -ne "`wc -c < 'pnm/libpnm2.c'`"
then
	echo shar: error transmitting "'pnm/libpnm2.c'" '(should have been 2619 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/libpnm3.c'" '(10288 characters)'
if test -f 'pnm/libpnm3.c'
then
	echo shar: will not over-write existing file "'pnm/libpnm3.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/libpnm3.c'
X/* libpnm3.c - pnm 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 "pnm.h"
X
X#ifdef PPM
X#include "ppm.h"
X#include "libppm.h"
X#endif /*PPM*/
X
X#ifdef PGM
X#include "pgm.h"
X#include "libpgm.h"
X#endif /*PGM*/
X
X#ifdef PBM
X#include "pbm.h"
X#include "libpbm.h"
X#endif /*PBM*/
X
Xxel
Xpnm_backgroundxel( xels, cols, rows, maxval, format )
Xxel **xels;
Xxelval maxval;
Xint cols, rows, format;
X    {
X    xel bgxel, ul, ur, ll, lr;
X
X    /* Guess a good background value. */
X    ul = xels[0][0];
X    ur = xels[0][cols-1];
X    ll = xels[rows-1][0];
X    lr = xels[rows-1][cols-1];
X
X    /* First check for three corners equal. */
X    if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, ll ) )
X	bgxel = ul;
X    else if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, lr ) )
X	bgxel = ul;
X    else if ( PNM_EQUAL( ul, ll ) && PNM_EQUAL( ll, lr ) )
X	bgxel = ul;
X    else if ( PNM_EQUAL( ur, ll ) && PNM_EQUAL( ll, lr ) )
X	bgxel = ur;
X    /* Nope, check for two corners equal. */
X    else if ( PNM_EQUAL( ul,  ur ) || PNM_EQUAL( ul,  ll ) ||
X	      PNM_EQUAL( ul,  lr ) )
X	bgxel = ul;
X    else if ( PNM_EQUAL( ur,  ll ) || PNM_EQUAL( ul,  lr ) )
X	bgxel = ur;
X    else if ( PNM_EQUAL( ll,  lr ) )
X	bgxel = ll;
X    else
X	{
X	/* Nope, we have to average the four corners.  This breaks the
X	** rules of pnm, but oh well.  Let's try to do it portably. */
X	switch ( format )
X	    {
X#ifdef PPM
X	    case PPM_FORMAT:
X	    case RPPM_FORMAT:
X	    PPM_ASSIGN( bgxel,
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	    break;
X#endif /*PPM*/
X
X#ifdef PGM
X	    case PGM_FORMAT:
X	    case RPGM_FORMAT:
X	    {
X	    gray gul, gur, gll, glr;
X	    gul = (gray) PNM_GET1( ul );
X	    gur = (gray) PNM_GET1( ur );
X	    gll = (gray) PNM_GET1( ll );
X	    glr = (gray) PNM_GET1( lr );
X	    PNM_ASSIGN1( bgxel, ( ( gul + gur + gll + glr ) / 4 ) );
X	    break;
X	    }
X#endif /*PGM*/
X
X#ifdef PBM
X	    case PBM_FORMAT:
X	    case RPBM_FORMAT:
X	    pm_error(
X		"pnm_backgroundxel: four bits no two of which equal each other??",
X		0,0,0,0,0 );
X#endif /*PBM*/
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	}
X
X    return bgxel;
X    }
X
Xxel
Xpnm_backgroundxelrow( xelrow, cols, maxval, format )
Xxel *xelrow;
Xxelval maxval;
Xint cols, format;
X    {
X    xel bgxel, l, r;
X
X    /* Guess a good background value. */
X    l = xelrow[0];
X    r = xelrow[cols-1];
X
X    /* First check for both corners equal. */
X    if ( PNM_EQUAL( l, r ) )
X	bgxel = l;
X    else
X	{
X	/* Nope, we have to average the two corners.  This breaks the
X	** rules of pnm, but oh well.  Let's try to do it portably. */
X	switch ( format )
X	    {
X#ifdef PPM
X	    case PPM_FORMAT:
X	    case RPPM_FORMAT:
X	    PPM_ASSIGN( bgxel, PPM_GETR(l) + PPM_GETR(r) / 2,
X		PPM_GETG(l) + PPM_GETG(r) / 2, PPM_GETB(l) + PPM_GETB(r) / 2 );
X	    break;
X#endif /*PPM*/
X
X#ifdef PGM
X	    case PGM_FORMAT:
X	    case RPGM_FORMAT:
X	    {
X	    gray gl, gr;
X	    gl = (gray) PNM_GET1( l );
X	    gr = (gray) PNM_GET1( r );
X	    PNM_ASSIGN1( bgxel, ( ( gl + gr ) / 2 ) );
X	    break;
X	    }
X#endif /*PGM*/
X
X#ifdef PBM
X	    case PBM_FORMAT:
X	    case RPBM_FORMAT:
X	    {
X	    int col, blacks;
X	    bit b;
X	    /* One black, one white.  Gotta count. */
X	    for ( col = 0, blacks = 0; col < cols; ++col )
X		{
X		b = (bit) PNM_GET1( xelrow[col] );
X		if ( b == PBM_BLACK )
X		    ++blacks;
X		}
X	    if ( blacks >= cols / 2 )
X		PNM_ASSIGN1( bgxel, PBM_BLACK );
X	    else
X		PNM_ASSIGN1( bgxel, PBM_WHITE );
X	    break;
X	    }
X#endif /*PBM*/
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	}
X
X    return bgxel;
X    }
X
Xxel
Xpnm_whitexel( maxval, format )
Xxelval maxval;
Xint format;
X    {
X    xel x;
X
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	PPM_ASSIGN( x, maxval, maxval, maxval );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	PNM_ASSIGN1( x, maxval );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	PNM_ASSIGN1( x, (xelval) PBM_WHITE );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X
X    return x;
X    }
X
Xxel
Xpnm_blackxel( maxval, format )
Xxelval maxval;
Xint format;
X    {
X    xel x;
X
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	PPM_ASSIGN( x, 0, 0, 0 );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	PNM_ASSIGN1( x, (xelval) 0 );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	PNM_ASSIGN1( x, (xelval) PBM_BLACK );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X
X    return x;
X    }
X
Xxel
Xpnm_invertxel( x, maxval, format )
Xxel x;
Xxelval maxval;
Xint format;
X    {
X    switch ( format )
X	{
X#ifdef PPM
X	case PPM_FORMAT:
X	case RPPM_FORMAT:
X	PPM_ASSIGN(
X	    x, maxval - PPM_GETR( x ),
X	    maxval - PPM_GETG( x ), maxval - PPM_GETB( x ) );
X	break;
X#endif /*PPM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	PNM_ASSIGN1( x, (gray) maxval - (gray) PNM_GET1( x ) );
X	break;
X#endif /*PGM*/
X
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	PNM_ASSIGN1(
X	    x, ( (bit) PNM_GET1( x ) == PBM_WHITE ) ? PBM_BLACK : PBM_WHITE );
X	break;
X#endif /*PBM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    return x;
X    }
X
Xvoid
Xpnm_promoteformat( xels, cols, rows, maxval, format, newmaxval, newformat )
Xxel **xels;
Xxelval maxval, newmaxval;
Xint cols, rows, format, newformat;
X    {
X    int row;
X
X    for ( row = 0; row < rows; ++row )
X	pnm_promoteformatrow(
X	    xels[row], cols, maxval, format, newmaxval, newformat );
X    }
X
Xvoid
Xpnm_promoteformatrow( xelrow, cols, maxval, format, newmaxval, newformat )
Xxel *xelrow;
Xxelval maxval, newmaxval;
Xint cols, format, newformat;
X    {
X    register int col;
X    register xel *xP;
X
X#ifdef PPM
X    if ( ( ( format == PPM_FORMAT || format == RPPM_FORMAT ) &&
X	   ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ||
X	     newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) ||
X	 ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
X	   ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
X	pm_error( "pnm_promoteformatrow: can't promote downwards!", 0,0,0,0,0 );
X#else /*PPM*/
X# ifdef PGM
X    if ( ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
X	   ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
X	pm_error( "pnm_promoteformatrow: can't promote downwards!", 0,0,0,0,0 );
X# else /*PGM*/
X#  ifdef PBM
X    /* If only PBM is defined, we can just return. */
X    return;
X#  endif /*PBM*/
X# endif /*PGM*/
X#endif /*PPM*/
X
X#ifdef PPM
X    if ( ( ( format == PPM_FORMAT || format == RPPM_FORMAT ) &&
X           ( newformat == PPM_FORMAT || newformat == RPPM_FORMAT ) ) ||
X         ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
X           ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ) ) ||
X         ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
X           ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
X#else /*PPM*/
X# ifdef PGM
X    if ( ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
X           ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ) ) ||
X         ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
X           ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
X# else /*PGM*/
X#  ifdef PBM
X    if ( ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
X           ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
X#  endif /*PBM*/
X# endif /*PGM*/
X#endif /*PPM*/
X	{
X#ifdef PBM
X	if ( format == PBM_FORMAT || format == RPBM_FORMAT )
X	    return;
X#endif /*PBM*/
X	if ( newmaxval < maxval )
X	    pm_error(
X		"pnm_promoteformatrow: can't decrease maxval -- try using ppmcscale",
X		0,0,0,0,0 );
X	if ( newmaxval == maxval )
X	    return;
X	/* Increase maxval. */
X	switch ( format )
X	    {
X#ifdef PGM
X	    case PGM_FORMAT:
X	    case RPGM_FORMAT:
X	    for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		PNM_ASSIGN1(
X		    *xP, (int) PNM_GET1(*xP) * newmaxval / maxval );
X	    break;
X#endif /*PGM*/
X
X#ifdef PPM
X	    case PPM_FORMAT:
X	    case RPPM_FORMAT:
X	    for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		PPM_CSCALE( *xP, *xP, maxval, newmaxval );
X	    break;
X#endif /*PPM*/
X
X	    default:
X	    pm_error( "shouldn't happen", 0,0,0,0,0 );
X	    }
X	return;
X	}
X
X    switch ( format )
X	{
X#ifdef PBM
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	switch ( newformat )
X	    {
X#ifdef PGM
X	    case PGM_FORMAT:
X	    case RPGM_FORMAT:
X	    for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		PNM_ASSIGN1(
X		    *xP, ( PNM_GET1(*xP) == PBM_WHITE ) ? newmaxval : (xelval) 0 );
X	    break;
X#endif /*PGM*/
X
X#ifdef PPM
X	    case PPM_FORMAT:
X	    case RPPM_FORMAT:
X	    for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		if ( PNM_GET1(*xP) == PBM_WHITE )
X		    PPM_ASSIGN( *xP, newmaxval, newmaxval, newmaxval );
X		else
X		    PPM_ASSIGN( *xP, 0, 0, 0 );
X	    break;
X#endif /*PPM*/
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	break;
X#endif /*PBM*/
X
X#ifdef PGM
X	case PGM_FORMAT:
X	case RPGM_FORMAT:
X	switch ( newformat )
X	    {
X#ifdef PPM
X	    case PPM_FORMAT:
X	    case RPPM_FORMAT:
X	    if ( newmaxval < maxval )
X		pm_error(
X		    "pnm_promoteformatrow: can't decrease maxval -- try using ppmcscale",
X		    0,0,0,0,0 );
X	    if ( newmaxval == maxval )
X		{
X		for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		    PPM_ASSIGN(
X			*xP, PNM_GET1(*xP), PNM_GET1(*xP), PNM_GET1(*xP) );
X		}
X	    else
X		{ /* Increase maxval. */
X		for ( col = 0, xP = xelrow; col < cols; col++, xP++ )
X		    PPM_ASSIGN(
X			*xP, (int) PNM_GET1(*xP) * newmaxval / maxval,
X			(int) PNM_GET1(*xP) * newmaxval / maxval,
X			(int) PNM_GET1(*xP) * newmaxval / maxval );
X		}
X	    break;
X#endif /*PPM*/
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	break;
X#endif /*PGM*/
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
SHAR_EOF
if test 10288 -ne "`wc -c < 'pnm/libpnm3.c'`"
then
	echo shar: error transmitting "'pnm/libpnm3.c'" '(should have been 10288 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnm.h'" '(2174 characters)'
if test -f 'pnm/pnm.h'
then
	echo shar: will not over-write existing file "'pnm/pnm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnm.h'
X/* pnm.h - header file for libpnm portable anymap library
X*/
X
X#ifndef _PNM_H_
X#define _PNM_H_
X
X#ifdef PPM
X
X#include "ppm.h"
Xtypedef pixel xel;
Xtypedef pixval xelval;
X
X#define PNM_GET1(p) PPM_GETB(p)
X#define PNM_ASSIGN1(p,v) PPM_ASSIGN(p,0,0,v)
X#define PNM_EQUAL(p,q) PPM_EQUAL(p,q)
X
X#else /*PPM*/
X# ifdef PGM
X
X#include "pgm.h"
Xtypedef gray xel;
Xtypedef gray xelval;
X#define PNM_GET1(p) (p)
X#define PNM_ASSIGN1(p,v) (p) = (v)
X#define PNM_EQUAL(p,q) ( (p) == (q) )
X
X# else /*PGM*/
X#  ifdef PBM
X
X#include "pbm.h"
Xtypedef bit xel;
Xtypedef bit xelval;
X#define PNM_GET1(p) (p)
X#define PNM_ASSIGN1(p,v) (p) = (v)
X#define PNM_EQUAL(p,q) ( (p) == (q) )
X
X#  endif /*PBM*/
X# endif /*PGM*/
X#endif /*PPM*/
X
X/* Declarations of routines. */
X
X#define pnm_allocarray( cols, rows ) ((xel **) pm_allocarray( cols, rows, sizeof(xel) ))
X#define pnm_allocrow( cols ) ((xel *) pm_allocrow( cols, sizeof(xel) ))
X#define pnm_freearray( xelrow, rows ) pm_freearray( xelrow, rows )
X#define pnm_freerow( xelrow ) pm_freerow( xelrow )
X
Xxel **pnm_readpnm( /* FILE *file, int *colsP, int *rowsP, xelval *maxvalP, int *formatP */ );
Xvoid pnm_readpnminit( /* FILE *file, int *colsP, int *rowsP, xelval *maxvalP, int *formatP */ );
Xvoid pnm_readpnmrow( /* FILE *file, xel *xelrow, int cols, xelval maxval, int format */ );
X
Xvoid pnm_writepnm( /* FILE *file, xel **xels, int cols, int rows, xelval maxval, int format */ );
Xvoid pnm_writepnminit( /* FILE *file, int cols, int rows, xelval maxval, int format */ );
Xvoid pnm_writepnmrow( /* FILE *file, xel *xelrow, int cols, xelval maxval, int format */ );
X
Xxel pnm_backgroundxel( /* xel **xels, int cols, int rows, xelval maxval, int format */ );
Xxel pnm_backgroundxelrow( /* xel *xelrow, int cols, xelval maxval, int format */ );
Xxel pnm_whitexel( /* xelval maxval, int format */ );
Xxel pnm_blackxel( /* xelval maxval, int format */ );
Xxel pnm_invertxel( /* xel x, xelval maxval, int format */ );
Xvoid pnm_promoteformat( /* xel **xels, int cols, int rows, xelval maxval, int format, xelval newmaxval, int newformat */ );
Xvoid pnm_promoteformatrow( /* xel *xelrow, int cols, xelval maxval, int format, xelval newmaxval, int newformat */ );
X
X#endif /*_PNM_H_*/
SHAR_EOF
if test 2174 -ne "`wc -c < 'pnm/pnm.h'`"
then
	echo shar: error transmitting "'pnm/pnm.h'" '(should have been 2174 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcat.c'" '(5095 characters)'
if test -f 'pnm/pnmcat.c'
then
	echo shar: will not over-write existing file "'pnm/pnmcat.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcat.c'
X/* pnmcat.c - concatenate portable anymaps
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 "pnm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
X#define MAXFILES 100
X#define max(a,b) ((a) > (b) ? (a) : (b))
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd[MAXFILES];
X    register xel *newxelrow;
X    xel *xelrow[MAXFILES], background[MAXFILES];
X    xelval maxval[MAXFILES], newmaxval;
X    int argn, backdefault, backblack, lrflag, tbflag, nfiles;
X    int rows[MAXFILES], cols[MAXFILES], format[MAXFILES], newformat;
X    register i, row, col;
X    int newrows, newcols, new, pad;
X    char *usage = "[-white|-black] pnmfile pnmfile ...";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    backdefault = 1;
X    lrflag = tbflag = 0;
X
X    /* Check for flags. */
X    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
X	{
X	if ( strncmp(argv[argn],"-white",max(strlen(argv[argn]),2)) == 0 )
X	    {
X	    backdefault = 0;
X	    backblack = 0;
X	    }
X	else if ( strncmp(argv[argn],"-black",max(strlen(argv[argn]),2)) == 0 )
X	    {
X	    backdefault = 0;
X	    backblack = 1;
X	    }
X	else if ( strncmp(argv[argn],"-lr",max(strlen(argv[argn]),2)) == 0 ||
X	          strncmp(argv[argn],"-leftright",max(strlen(argv[argn]),2)) == 0 )
X	    lrflag = 1;
X	else if ( strncmp(argv[argn],"-tb",max(strlen(argv[argn]),2)) == 0 ||
X	          strncmp(argv[argn],"-topbottom",max(strlen(argv[argn]),2)) == 0 )
X	    tbflag = 1;
X	else
X	    pm_usage( usage );
X	argn++;
X	}
X
X    if ( lrflag && tbflag )
X	pm_error( "only one of -lr and -tb may be specified", 0,0,0,0,0 );
X    if ( ! ( lrflag || tbflag ) )
X	pm_error( "one of -lr or -tb must be specified", 0,0,0,0,0 );
X
X    if ( argn < argc )
X	{
X	nfiles = argc - argn;
X	for ( i = 0; i < nfiles; i++ )
X	    ifd[i] = pm_openr( argv[argn+i] );
X	}
X    else
X	{
X	nfiles = 1;
X	ifd[0] = stdin;
X	}
X
X    newcols = 0;
X    newrows = 0;
X    for ( i = 0; i < nfiles; i++ )
X	{
X	pnm_readpnminit( ifd[i], &cols[i], &rows[i], &maxval[i], &format[i] );
X	if ( i == 0 )
X	    {
X	    newmaxval = maxval[i];
X	    newformat = format[i];
X	    }
X	else if ( format[i] > newformat )
X	    {
X	    newmaxval = maxval[i];
X	    newformat = format[i];
X	    }
X	xelrow[i] = pnm_allocrow( cols[i] );
X	if ( lrflag )
X	    {
X	    newcols += cols[i];
X	    if ( rows[i] > newrows )
X		newrows = rows[i];
X	    }
X	else
X	    {
X	    newrows += rows[i];
X	    if ( cols[i] > newcols )
X		newcols = cols[i];
X	    }
X	}
X    for ( i = 0; i < nfiles; i++ )
X	{
X	/* Read first row just to get a good guess at the background. */
X	pnm_readpnmrow( ifd[i], xelrow[i], cols[i], maxval[i], format[i] );
X	pnm_promoteformatrow(
X	    xelrow[i], cols[i], maxval[i], format[i], newmaxval, newformat );
X	if (  backdefault )
X	    background[i] =
X		pnm_backgroundxelrow(
X		    xelrow[i], cols[i], newmaxval, newformat );
X	else
X	    if ( backblack )
X		background[i] = pnm_blackxel( newmaxval, newformat );
X	    else
X		background[i] = pnm_whitexel( newmaxval, newformat );
X	}
X
X    newxelrow = pnm_allocrow( newcols );
X
X    pnm_writepnminit( stdout, newcols, newrows, newmaxval, newformat );
X
X    if ( lrflag )
X	{
X	for ( row = 0; row < newrows; row++ )
X	    {
X	    new = 0;
X	    for ( i = 0; i < nfiles; i++ )
X		{
X		pad = ( newrows - rows[i] ) / 2;
X		if ( row >= pad + 1 && row < pad + rows[i] )
X		    {
X		    pnm_readpnmrow(
X			ifd[i], xelrow[i], cols[i], maxval[i], format[i] );
X		    pnm_promoteformatrow(
X			xelrow[i], cols[i], maxval[i], format[i],
X			newmaxval, newformat );
X		    }
X		for ( col = 0; col < cols[i]; col++ )
X		    if ( row >= pad && row < pad + rows[i] )
X			newxelrow[new+col] = xelrow[i][col];
X		    else
X			newxelrow[new+col] = background[i];
X		new += cols[i];
X		}
X	    pnm_writepnmrow( stdout, newxelrow, newcols, newmaxval, newformat );
X	    }
X	}
X    else
X	{
X	new = 0;
X	i = 0;
X	pad = ( newcols - cols[i] ) / 2;
X	for ( row = 0; row < newrows; row++ )
X	    {
X	    if ( row - new >= rows[i] )
X		{
X		new += rows[i];
X		++i;
X		if ( i >= nfiles )
X		    pm_error( "shouldn't happen", 0,0,0,0,0 );
X		pad = ( newcols - cols[i] ) / 2;
X		}
X	    if ( row - new > 0 )
X		{
X		pnm_readpnmrow(
X		    ifd[i], xelrow[i], cols[i], maxval[i], format[i] );
X		pnm_promoteformatrow(
X		    xelrow[i], cols[i], maxval[i], format[i],
X		    newmaxval, newformat );
X		}
X	    for ( col = 0; col < pad; col++ )
X		newxelrow[col] = background[i];
X	    for ( col = 0; col < cols[i]; col++ )
X		newxelrow[pad+col] = xelrow[i][col];
X	    for ( col = pad+cols[i]; col < newcols; col++ )
X		newxelrow[col] = background[i];
X	    pnm_writepnmrow( stdout, newxelrow, newcols, newmaxval, newformat );
X	    }
X	}
X
X    for ( i = 0; i < nfiles; i++ )
X	pm_close( ifd[i] );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 5095 -ne "`wc -c < 'pnm/pnmcat.c'`"
then
	echo shar: error transmitting "'pnm/pnmcat.c'" '(should have been 5095 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcat.1'" '(1073 characters)'
if test -f 'pnm/pnmcat.1'
then
	echo shar: will not over-write existing file "'pnm/pnmcat.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcat.1'
X.TH pnmcat 1 "12 March 1989"
X.SH NAME
Xpnmcat - concatenate portable anymaps
X.SH SYNOPSIS
Xpnmcat [-white|-black] -leftright|-lr|-topbottom|-tb pnmfile pnmfile ...
X.SH DESCRIPTION
XReads portable anymaps as input.
XConcatenates them either left to right or top to bottom, and produces a
Xportable anymap as output.
XIf the anymaps are not all the same height (left-right) or width (top-bottom),
Xthe smaller ones are centered with the edges filled in.
XThe -white and -black flags specify what color to use for this fill -- if
Xneither is specified, the program makes a guess.
X.PP
XAll flags can be abbreviated to their shortest unique prefix.
X.SH "SEE ALSO"
Xpnm(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 1073 -ne "`wc -c < 'pnm/pnmcat.1'`"
then
	echo shar: error transmitting "'pnm/pnmcat.1'" '(should have been 1073 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcrop.c'" '(3652 characters)'
if test -f 'pnm/pnmcrop.c'
then
	echo shar: will not over-write existing file "'pnm/pnmcrop.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcrop.c'
X/* pnmcrop.c - crop a portable anymap
X**
X** Copyright (C) 1988 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 "pnm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
X#define max(a,b) ((a) > (b) ? (a) : (b))
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register xel **xels, *xP;
X    xel background;
X    xelval maxval;
X    int argn, format, backdefault, backblack;
X    int rows, cols, row, col, newrows, newcols;
X    int top, bottom, left, right;
X    char *usage = "[-white|-black] [pnmfile]";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    backdefault = 1;
X
X    /* Check for flags. */
X    if ( argn < argc && argv[argn][0] == '-' )
X	{
X	if ( strncmp(argv[argn],"-white",max(strlen(argv[argn]),2)) == 0 )
X	    {
X	    backdefault = 0;
X	    backblack = 0;
X	    }
X	else if ( strncmp(argv[argn],"-black",max(strlen(argv[argn]),2)) == 0 )
X	    {
X	    backdefault = 0;
X	    backblack = 1;
X	    }
X	else
X	    pm_usage( usage );
X	argn++;
X	}
X
X    if ( argn != argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    xels = pnm_readpnm( ifd, &cols, &rows, &maxval, &format );
X    pm_close( ifd );
X
X    if ( backdefault )
X	background = pnm_backgroundxel( xels, cols, rows, maxval, format );
X    else
X	if ( backblack )
X	    background = pnm_blackxel( maxval, format );
X	else
X	    background = pnm_whitexel( maxval, format );
X
X    /* Find first non-background line. */
X    for ( top = 0; top < rows; top++ )
X	for ( col = 0, xP = xels[top]; col < cols; col++, xP++ )
X	    if ( ! PNM_EQUAL( *xP, background ) )
X		goto gottop;
Xgottop:
X
X    /* Find last non-background line. */
X    for ( bottom = rows - 1; bottom >= top; bottom-- )
X	for ( col = 0, xP = xels[bottom]; col < cols; col++, xP++ )
X	    if ( ! PNM_EQUAL( *xP, background ) )
X		goto gotbottom;
Xgotbottom:
X
X    /* Find first non-background column.  To avoid massive paging on
X    ** large anymaps, we use a different loop than the above two cases. */
X    left = cols - 1;
X    for ( row = top; row <= bottom; row++ )
X	{
X	int thisleft;
X
X	for ( thisleft = 0; thisleft < left; thisleft++ )
X	    if ( ! PNM_EQUAL( xels[row][thisleft], background ) )
X		{
X		left = thisleft;
X		break;
X		}
X	}
X
X    /* Find last non-background column.  Again, use row-major loop. */
X    right = left + 1;
X    for ( row = top; row <= bottom; row++ )
X	{
X	int thisright;
X
X	for ( thisright = cols - 1; thisright > right; thisright-- )
X	    if ( ! PNM_EQUAL( xels[row][thisright], background ) )
X		{
X		right = thisright;
X		break;
X		}
X	}
X
X    if ( top > 0 )
X	fprintf( stderr, "(cropping %d rows off the top)\n", top );
X    if ( bottom < rows - 1 )
X	fprintf( stderr, "(cropping %d rows off the bottom)\n", rows - 1 - bottom );
X    if ( left > 0 )
X	fprintf( stderr, "(cropping %d cols off the left)\n", left );
X    if ( right < cols - 1 )
X	fprintf( stderr, "(cropping %d cols off the right)\n", cols - 1 - right );
X
X    /* Now write out the new anymap. */
X    newcols = right - left + 1;
X    newrows = bottom - top + 1;
X    pnm_writepnminit( stdout, newcols, newrows, maxval, format );
X    for ( row = top; row <= bottom; row++ )
X	pnm_writepnmrow( stdout, &(xels[row][left]), newcols, maxval, format );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 3652 -ne "`wc -c < 'pnm/pnmcrop.c'`"
then
	echo shar: error transmitting "'pnm/pnmcrop.c'" '(should have been 3652 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcrop.1'" '(903 characters)'
if test -f 'pnm/pnmcrop.1'
then
	echo shar: will not over-write existing file "'pnm/pnmcrop.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcrop.1'
X.TH pnmcrop 1 "25 February 1989"
X.SH NAME
Xpnmcrop - crop a portable anymap
X.SH SYNOPSIS
Xpnmcrop [-white|-black] [pnmfile]
X.SH DESCRIPTION
XReads a portable anymap as input.
XRemoves edges that are the background color,
Xand produces a portable anymap as output.
XBy default, it makes a guess as to what the background
Xcolor is.
XYou can override the default with the -white and -black flags.
X.PP
XAll flags can be abbreviated to their shortest unique prefix.
X.SH "SEE ALSO"
Xpnmcut(1), pnm(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 903 -ne "`wc -c < 'pnm/pnmcrop.1'`"
then
	echo shar: error transmitting "'pnm/pnmcrop.1'" '(should have been 903 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcut.c'" '(2247 characters)'
if test -f 'pnm/pnmcut.c'
then
	echo shar: will not over-write existing file "'pnm/pnmcut.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcut.c'
X/* pnmcut.c - cut a rectangle out of a portable anymap
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 "pnm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register xel *xelrow;
X    xelval maxval;
X    int rows, cols, format, x, y, width, height, row;
X    char *usage = "x y width height [pnmfile]";
X
X    pm_progname = argv[0];
X
X    if ( argc < 5 || argc > 6 )
X	pm_usage( usage );
X
X    if ( sscanf( argv[1], "%d", &x ) != 1 )
X	pm_usage( usage );
X    if ( sscanf( argv[2], "%d", &y ) != 1 )
X	pm_usage( usage );
X    if ( sscanf( argv[3], "%d", &width ) != 1 )
X	pm_usage( usage );
X    if ( sscanf( argv[4], "%d", &height ) != 1 )
X	pm_usage( usage );
X
X    if ( x < 0 )
X	pm_error( "x is less than 0", 0,0,0,0,0 );
X    if ( y < 0 )
X	pm_error( "y is less than 0", 0,0,0,0,0 );
X    if ( width < 1 )
X	pm_error( "width is less than 1", 0,0,0,0,0 );
X    if ( height < 1 )
X	pm_error( "height is less than 1", 0,0,0,0,0 );
X
X    if ( argc == 6 )
X	ifd = pm_openr( argv[5] );
X    else
X	ifd = stdin;
X
X    pnm_readpnminit( ifd, &cols, &rows, &maxval, &format );
X    xelrow = pnm_allocrow( cols );
X
X    if ( x >= cols )
X	pm_error(
X	    "x is too large -- the anymap has only %d cols", cols, 0,0,0,0 );
X    if ( y >= rows )
X	pm_error(
X	    "y is too large -- the anymap has only %d rows", rows, 0,0,0,0 );
X    if ( x + width > cols )
X	pm_error(
X	    "x + width is too large by %d xels", x + width - cols, 0,0,0,0 );
X    if ( y + height > rows )
X	pm_error(
X	    "y + height is too large by %d xels", y + height - rows, 0,0,0,0 );
X
X    pnm_writepnminit( stdout, width, height, maxval, format );
X    for ( row = 0; row < y + height; row++ )
X	{
X	pnm_readpnmrow( ifd, xelrow, cols, maxval, format );
X	if ( row >= y )
X	    pnm_writepnmrow( stdout, &(xelrow[x]), width, maxval, format );
X	}
X
X    pm_close( ifd );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 2247 -ne "`wc -c < 'pnm/pnmcut.c'`"
then
	echo shar: error transmitting "'pnm/pnmcut.c'" '(should have been 2247 characters)'
fi
fi # end of overwriting check
if test ! -d 'pnm'
then
	echo shar: creating directory "'pnm'"
	mkdir 'pnm'
fi
echo shar: extracting "'pnm/pnmcut.1'" '(703 characters)'
if test -f 'pnm/pnmcut.1'
then
	echo shar: will not over-write existing file "'pnm/pnmcut.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pnm/pnmcut.1'
X.TH pnmcut 1 "21 February 1989"
X.SH NAME
Xpnmcut - cut a rectangle out of a portable anymap
X.SH SYNOPSIS
Xpnmcut x y width height [pnmfile]
X.SH DESCRIPTION
XReads a portable anymap as input.
XExtracts the specified rectangle,
Xand produces a portable anymap as output.
X.SH "SEE ALSO"
Xpnm(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 703 -ne "`wc -c < 'pnm/pnmcut.1'`"
then
	echo shar: error transmitting "'pnm/pnmcut.1'" '(should have been 703 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0