PBMPLUS, part 8 of 18

Jef Poskanzer pokey at well.UUCP
Thu Sep 14 21:25:07 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:
#	pgm/Makefile
#	pgm/Imakefile
#	pgm/pgm.5
#	pgm/libpgm1.c
#	pgm/libpgm2.c
#	pgm/pgm.h
#	pgm/libpgm.h
#	pgm/fstopgm.c
#	pgm/fstopgm.1
#	pgm/hipstopgm.c
#	pgm/hipstopgm.1
#	pgm/pgmenhance.c
#	pgm/pgmenhance.1
#	pgm/pgmhist.c
#	pgm/pgmhist.1
#	pgm/pgmnorm.c
#	pgm/pgmnorm.1
# This archive created: Thu Sep 14 03:43:36 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/Makefile'" '(2824 characters)'
if test -f 'pgm/Makefile'
then
	echo shar: will not over-write existing file "'pgm/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/Makefile'
X# Makefile for pgm tools.
X#
X# Copyright (C) 1989 by Jef Poskanzer.
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation.  This software is provided "as is" without express or
X# implied warranty.
X
X# Default values, usually overridden by top-level Makefile.
X# CC =		cc
XCC =		gcc -fstrength-reduce -fcombine-regs
X# CFLAGS =	-O
XCFLAGS =	-g
X# CFLAGS =	
X# LDFLAGS =	-s
XLDFLAGS =	
XINSTALLBINARIES =	/usr/new/pbm
XINSTALLMANUALS =	n
X
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h ../pbmplus.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XINCLUDE =	$(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPGM =	libpgm.a
X
XPORTBINARIES =	fitstopgm fstopgm hipstopgm pgmenhance pgmhist pgmnorm \
X		pgmtopbm pgmtops psidtopgm
X
XPORTMANUALS =	fitstopgm.1 fstopgm.1 hipstopgm.1 pgm.5 pgmenhance.1 pgmhist.1 \
X		pgmnorm.1 pgmtopbm.1 pgmtops.1 psidtopgm.1
X
XBINARIES =	$(PORTBINARIES)
XMANUALS =	$(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):	pgm.h $(DEFPBM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPGM):	libpgm1.o libpgm2.o
X	-rm $(LIBPGM)
X	ar rc $(LIBPGM) libpgm1.o libpgm2.o
X	-ranlib $(LIBPGM)
X
Xlibpgm1.o:	pgm.h $(DEFPBM) libpgm.h libpgm1.c
X	$(CC) $(ALLCFLAGS) -c libpgm1.c
Xlibpgm2.o:	pgm.h $(DEFPBM) libpgm.h libpgm2.c $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpgm2.c
X
X# Other dependencies.
Xfitstopgm:	fitstopgm.c
Xfstopgm:	fstopgm.c
Xhipstopgm:	hipstopgm.c
Xpgmenhance:	pgmenhance.c
Xpgmhist:	pgmhist.c
Xpgmnorm:	pgmnorm.c
Xpgmtopbm:	pgmtopbm.c dithers.h $(DEFPBM)
Xpgmtops:	pgmtops.c
Xpsidtopgm:	psidtopgm.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	$(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 2824 -ne "`wc -c < 'pgm/Makefile'`"
then
	echo shar: error transmitting "'pgm/Makefile'" '(should have been 2824 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/Imakefile'" '(1566 characters)'
if test -f 'pgm/Imakefile'
then
	echo shar: will not over-write existing file "'pgm/Imakefile'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/Imakefile'
X# Imakefile for pgm tools.
X#
X# Copyright (C) 1989 by Jef Poskanzer.
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation.  This software is provided "as is" without express or
X# implied warranty.
X
XPBMDIR =	../pbm
XINCLUDEPBM =	-I$(PBMDIR)
XLIBPBM =	$(PBMDIR)/libpbm.a
XDEFPBM =	$(PBMDIR)/pbm.h ../pbmplus.h
XDEFLIBPBM =	$(PBMDIR)/libpbm.h
X
XINCLUDE =	$(INCLUDEPBM)
XALLCFLAGS =	$(CFLAGS) $(INCLUDE)
XLIBPGM =	libpgm.a
X
XPORTBINARIES =	fitstopgm fstopgm hipstopgm pgmenhance pgmhist pgmnorm \
X		pgmtopbm pgmtops psidtopgm
X
XPORTMANUALS =	fitstopgm.1 fstopgm.1 hipstopgm.1 pgm.5 pgmenhance.1 pgmhist.1 \
X		pgmnorm.1 pgmtopbm.1 pgmtops.1 psidtopgm.1
X
XBINARIES =	$(PORTBINARIES)
XMANUALS =	$(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):	pgm.h $(DEFPBM) $(LIBPGM) $(LIBPBM)
X	$(CC) $(ALLCFLAGS) $(LDFLAGS) -o $@ $@.c $(LIBPGM) $(LIBPBM)
X
X# And library.
X$(LIBPGM):	libpgm1.o libpgm2.o
X	-rm $(LIBPGM)
X	ar rc $(LIBPGM) libpgm1.o libpgm2.o
X	-ranlib $(LIBPGM)
X
Xlibpgm1.o:	pgm.h $(DEFPBM) libpgm.h libpgm1.c
X	$(CC) $(ALLCFLAGS) -c libpgm1.c
Xlibpgm2.o:	pgm.h $(DEFPBM) libpgm.h libpgm2.c $(DEFLIBPBM)
X	$(CC) $(ALLCFLAGS) -c libpgm2.c
SHAR_EOF
if test 1566 -ne "`wc -c < 'pgm/Imakefile'`"
then
	echo shar: error transmitting "'pgm/Imakefile'" '(should have been 1566 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgm.5'" '(2908 characters)'
if test -f 'pgm/pgm.5'
then
	echo shar: will not over-write existing file "'pgm/pgm.5'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgm.5'
X.TH pgm 5 "01 August 1989"
X.SH NAME
Xpgm - portable graymap file format
X.SH DESCRIPTION
XThe portable graymap format is a lowest common denominator grayscale
Xfile format.
XThe definition is as follows:
X.IP - 2
XA "magic number" for identifying the file type.
XA pgm file's magic number is the two characters "P2".
X.IP - 2
XWhitespace (blanks, TABs, CRs, LFs).
X.IP - 2
XA width, formatted as ASCII characters in decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XA height, again in ASCII decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XThe maximum gray value, again in ASCII decimal.
X.IP - 2
XWhitespace.
X.IP - 2
XWidth * height gray values, each in ASCII decimal, between 0 and the specified
Xmaximum value, separated by whitespace, starting at the top-left
Xcorner of the graymap, proceding in normal English reading order.
XA value of 0 means black, and the maximum value means white.
X.IP - 2
XCharacters from a "#" to the next end-of-line are ignored (comments).
X.IP - 2
XNo line should be longer than 70 characters.
X.PP
XHere is an example of a small graymap in this format:
X.PP
X.nf
XP2
X# feep.pgm
X24 7
X15
X0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
X0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
X0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
X0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
X0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
X0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
X0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
X.fi
X.PP
XPrograms that read this format should be as lenient as possible,
Xaccepting anything that looks remotely like a graymap.
X.PP
XThere is also a variant on the format, available
Xby setting the RAWBITS option at compile time.  This variant is
Xdifferent in the following ways:
X.IP - 2
XThe "magic number" is "P5" instead of "P2".
X.IP - 2
XThe gray values are stored as plain bytes, instead of ASCII decimal.
X.IP - 2
XNo whitespace is allowed in the grays section.
X.IP - 2
XThe files are smaller and many times faster to read and write.
X.PP
XNote that this raw format can only be used for maxvals less than
Xor equal to 255.
XIf you use the PGM library and try to write a file with a larger maxval,
Xit will automatically fall back on the slower but more general ASCII
Xformat.
X.SH "SEE ALSO"
Xfitstopgm(1), fstopgm(1), hipstopgm(1), pgmenhance(1), pgmhist(1), pgmnorm(1),
Xpgmtopbm(1), pgmtops(1), psidtopgm(1),
Xpnm(5), pbm(5), ppm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 2908 -ne "`wc -c < 'pgm/pgm.5'`"
then
	echo shar: error transmitting "'pgm/pgm.5'" '(should have been 2908 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm1.c'" '(2968 characters)'
if test -f 'pgm/libpgm1.c'
then
	echo shar: will not over-write existing file "'pgm/libpgm1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm1.c'
X/* libpgm1.c - pgm utility library part 1
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#include "libpgm.h"
X#include "pbm.h"
X#include "libpbm.h"
X
Xvoid
Xpgm_readpgminitrest( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xgray *maxvalP;
X    {
X    /* Read size. */
X    *colsP = pbm_getint( file );
X    *rowsP = pbm_getint( file );
X
X    /* Read maxval. */
X    *maxvalP = pbm_getint( file );
X    if ( *maxvalP > PGM_MAXMAXVAL )
X	pm_error(
X	    "maxval too large - %d > %d\n", *maxvalP, PGM_MAXMAXVAL, 0,0,0 );
X    }
X
Xstatic bit *bitrow;
X
Xgray pgm_pbmmaxval = 1;
X
Xvoid
Xpgm_readpgminit( file, colsP, rowsP, maxvalP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
Xgray *maxvalP;
X    {
X    /* Check magic number. */
X    *formatP = pbm_readmagicnumber( file );
X    switch ( *formatP )
X	{
X        case PGM_FORMAT:
X        case RPGM_FORMAT:
X	pgm_readpgminitrest( file, colsP, rowsP, maxvalP );
X	break;
X
X        case PBM_FORMAT:
X        case RPBM_FORMAT:
X	pbm_readpbminitrest( file, colsP, rowsP );
X	*maxvalP = pgm_pbmmaxval;
X	bitrow = pbm_allocrow( *colsP );
X	break;
X
X	default:
X	pm_error( "bad magic number - not a pgm or pbm file", 0,0,0,0,0 );
X	}
X    }
X
Xvoid
Xpgm_readpgmrow( file, grayrow, cols, maxval, format )
XFILE *file;
Xgray *grayrow;
Xint cols, format;
Xgray maxval;
X    {
X    register int col;
X    register gray *gP;
X    register bit *bP;
X
X    switch ( format )
X	{
X	case PGM_FORMAT:
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    *gP = pbm_getint( file );
X#ifdef DEBUG
X	    if ( *gP > maxval )
X		pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif DEBUG
X	    }
X	break;
X	
X	case RPGM_FORMAT:
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    *gP = pbm_getrawbyte( file );
X#ifdef DEBUG
X	    if ( *gP > maxval )
X		pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif DEBUG
X	    }
X	break;
X	
X	case PBM_FORMAT:
X	case RPBM_FORMAT:
X	pbm_readpbmrow( file, bitrow, cols, format );
X	for ( col = 0, gP = grayrow, bP = bitrow; col < cols; col++, gP++, bP++ )
X	    *gP = ( *bP == PBM_WHITE ) ? maxval : 0;
X	break;
X
X	default:
X	pm_error( "can't happen", 0,0,0,0,0 );
X	}
X    }
X
Xgray **
Xpgm_readpgm( file, colsP, rowsP, maxvalP )
XFILE *file;
Xint *colsP, *rowsP;
Xgray *maxvalP;
X    {
X    gray **grays;
X    int row;
X    int format;
X
X    pgm_readpgminit( file, colsP, rowsP, maxvalP, &format );
X
X    grays = pgm_allocarray( *colsP, *rowsP );
X
X    for ( row = 0; row < *rowsP; row++ )
X	pgm_readpgmrow( file, grays[row], *colsP, *maxvalP, format );
X
X    return grays;
X    }
SHAR_EOF
if test 2968 -ne "`wc -c < 'pgm/libpgm1.c'`"
then
	echo shar: error transmitting "'pgm/libpgm1.c'" '(should have been 2968 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm2.c'" '(3197 characters)'
if test -f 'pgm/libpgm2.c'
then
	echo shar: will not over-write existing file "'pgm/libpgm2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm2.c'
X/* libpgm2.c - pgm utility library part 2
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X#include "libpgm.h"
X
Xvoid
Xpgm_writepgminit( file, cols, rows, maxval )
XFILE *file;
Xint cols, rows;
Xgray maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, RPGM_MAGIC2,
X	    cols, rows, maxval );
X    else
X	fprintf(
X	    file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
X	    cols, rows, maxval );
X#else PBMPLUS_RAWBITS
X    fprintf(
X	file, "%c%c\n%d %d\n%d\n", PGM_MAGIC1, PGM_MAGIC2,
X	cols, rows, maxval );
X#endif PBMPLUS_RAWBITS
X    }
X
Xstatic int
Xputus( n, file )
Xunsigned short n;
XFILE *file;
X    {
X    if ( n >= 10 )
X	if ( putus( n / 10, file ) == EOF )
X	    return EOF;
X    return putc( n % 10 + '0', file );
X    }
X
X#ifdef PBMPLUS_RAWBITS
Xstatic void
Xpgm_writepgmrowraw( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X    register int col;
X    register gray *gP;
X
X    for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	{
X#ifdef DEBUG
X	if ( *gP > maxval )
X	    pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif DEBUG
X	if ( putc( *gP, file ) == EOF )
X	    {
X	    perror( "pgm_writepgmrow" );
X	    exit( 1 );
X	    }
X	}
X    }
X#endif PBMPLUS_RAWBITS
X
Xstatic void
Xpgm_writepgmrowplain( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X    register int col, charcount;
X    register gray *gP;
X
X    charcount = 0;
X    for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	{
X	if ( charcount >= 70 )
X	    {
X	    if ( putc( '\n', file ) == EOF )
X		{
X		perror( "pgm_writepgmrow" );
X		exit( 1 );
X		}
X	    charcount = 0;
X	    }
X#ifdef DEBUG
X	if ( *gP > maxval )
X	    pm_error( "value out of bounds (%u > %u)", *gP, maxval, 0,0,0 );
X#endif DEBUG
X	if ( putus( (unsigned long) *gP, file ) == EOF )
X	    {
X	    perror( "pgm_writepgmrow" );
X	    exit( 1 );
X	    }
X	if ( putc( ' ', file ) == EOF )
X	    {
X	    perror( "pgm_writepgmrow" );
X	    exit( 1 );
X	    }
X	charcount += 4;
X	}
X    if ( putc( '\n', file ) == EOF )
X	{
X	perror( "pgm_writepgmrow" );
X	exit( 1 );
X	}
X    }
X
Xvoid
Xpgm_writepgmrow( file, grayrow, cols, maxval )
XFILE *file;
Xgray *grayrow;
Xint cols;
Xgray maxval;
X    {
X#ifdef PBMPLUS_RAWBITS
X    if ( maxval <= 255 )
X	pgm_writepgmrowraw( file, grayrow, cols, maxval );
X    else
X	pgm_writepgmrowplain( file, grayrow, cols, maxval );
X#else PBMPLUS_RAWBITS
X    pgm_writepgmrowplain( file, grayrow, cols, maxval );
X#endif PBMPLUS_RAWBITS
X    }
X
Xvoid
Xpgm_writepgm( file, grays, cols, rows, maxval )
XFILE *file;
Xgray **grays;
Xint cols, rows;
Xgray maxval;
X    {
X    int row;
X
X    pgm_writepgminit( file, cols, rows, maxval );
X
X    for ( row = 0; row < rows; row++ )
X	pgm_writepgmrow( file, grays[row], cols, maxval );
X    }
SHAR_EOF
if test 3197 -ne "`wc -c < 'pgm/libpgm2.c'`"
then
	echo shar: error transmitting "'pgm/libpgm2.c'" '(should have been 3197 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgm.h'" '(1311 characters)'
if test -f 'pgm/pgm.h'
then
	echo shar: will not over-write existing file "'pgm/pgm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgm.h'
X/* pgm.h - header file for libpgm portable graymap library
X*/
X
X#ifndef _PGM_H_
X#define _PGM_H_
X
X#include "pbm.h"
X
X#ifdef PGM_BIGGRAYS
Xtypedef unsigned short gray;
X#define PGM_MAXMAXVAL 65535
X#else PGM_BIGGRAYS
Xtypedef unsigned char gray;
X#define PGM_MAXMAXVAL 255
X#endif PGM_BIGGRAYS
X
X/* Declarations of routines. */
X
X#define pgm_allocarray( cols, rows ) ((gray **) pm_allocarray( cols, rows, sizeof(gray) ))
X#define pgm_allocrow( cols ) ((gray *) pm_allocrow( cols, sizeof(gray) ))
X#define pgm_freearray( grayrow, rows ) pm_freearray( grayrow, rows )
X#define pgm_freerow( grayrow ) pm_freerow( grayrow )
X
Xgray **pgm_readpgm( /* FILE *file, int *colsP, int *rowsP, gray *maxvalP */ );
Xvoid pgm_readpgminit( /* FILE *file, int *colsP, int *rowsP, gray *maxvalP, int *formatP */ );
Xvoid pgm_readpgmrow( /* FILE *file, gray *grayrow, int cols, gray maxval, int format */ );
X
Xvoid pgm_writepgm( /* FILE *file, gray **grays, int cols, int rows, gray maxval */ );
Xvoid pgm_writepgminit( /* FILE *file, int cols, int rows, gray maxval */ );
Xvoid pgm_writepgmrow( /* FILE *file, gray *grayrow, int cols, gray maxval */ );
X
Xextern gray pgm_pbmmaxval;
X/* This is the maxval used when a PGM program reads a PBM file.  Normally
X** it is 1; however, for some programs, a larger value gives better results
X*/
X
X#endif _PGM_H_
SHAR_EOF
if test 1311 -ne "`wc -c < 'pgm/pgm.h'`"
then
	echo shar: error transmitting "'pgm/pgm.h'" '(should have been 1311 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/libpgm.h'" '(480 characters)'
if test -f 'pgm/libpgm.h'
then
	echo shar: will not over-write existing file "'pgm/libpgm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/libpgm.h'
X/* libpgm.h - internal header file for libpgm portable graymap library
X*/
X
X#ifndef _LIBPGM_H_
X#define _LIBPGM_H_
X
X/* Magic constants. */
X
X#define PGM_MAGIC1 'P'
X#define PGM_MAGIC2 '2'
X#define RPGM_MAGIC2 '5'
X#define PGM_FORMAT (PGM_MAGIC1 * 256 + PGM_MAGIC2)
X#define RPGM_FORMAT (PGM_MAGIC1 * 256 + RPGM_MAGIC2)
X
X
X/* And here are some routines internal to the pgm library. */
X
Xvoid pgm_readpgminitrest( /* FILE *file, int *colsP, int *rowsP, int *maxvalP */ );
X
X#endif _LIBPGM_H_
SHAR_EOF
if test 480 -ne "`wc -c < 'pgm/libpgm.h'`"
then
	echo shar: error transmitting "'pgm/libpgm.h'" '(should have been 480 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/fstopgm.c'" '(3280 characters)'
if test -f 'pgm/fstopgm.c'
then
	echo shar: will not over-write existing file "'pgm/fstopgm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/fstopgm.c'
X/* fstopgm.c - read a Usenix FaceSaver file and produce a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#ifdef	SYSV
X#include <string.h>
X#else	SYSV
X#include <strings.h>
X#endif	SYSV
X#include "pgm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray **grays, *gP;
X    int argn, row;
X    register int col;
X    gray maxval;
X    int rows = 0, cols = 0, depth = 0, xrows = 0, xcols = 0, xdepth = 0;
X#define STRSIZE 1000
X    char buf[STRSIZE], firstname[STRSIZE], lastname[STRSIZE], email[STRSIZE];
X    int gethexit();
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn < argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( "[fsfile]" );
X
X    /* Read the FaceSaver header. */
X    for ( ; ; )
X	{
X	if ( fgets( buf, STRSIZE, ifd ) == (char *) 0 )
X	    pm_error( "error reading header", 0,0,0,0,0 );
X
X	/* Blank line ends header. */
X	if ( strlen( buf ) == 1 )
X	    break;
X
X	if ( sscanf( buf, "FirstName: %s\n", firstname ) == 1 )
X	    ;
X	else if ( sscanf( buf, "LastName: %s\n", lastname ) == 1 )
X	    ;
X	else if ( sscanf( buf, "E-mail: %s\n", email ) == 1 )
X	    ;
X	else if ( sscanf( buf, "PicData: %d %d %d\n",
X			  &cols, &rows, &depth ) == 3 )
X	    {
X	    if ( depth != 8 )
X		pm_error(
X		    "can't handle 'PicData' depth other than 8", 0,0,0,0,0 );
X	    }
X	else if ( sscanf( buf, "Image: %d %d %d\n",
X			  &xcols, &xrows, &xdepth ) == 3 )
X	    {
X	    if ( xdepth != 8 )
X		pm_error(
X		    "can't handle 'Image' depth other than 8", 0,0,0,0,0 );
X	    }
X	}
X    if ( cols <= 0 || rows <= 0 )
X	pm_error( "invalid header", 0,0,0,0,0 );
X    maxval = 255;
X    if ( xcols != 0 && xrows != 0 && ( xcols != cols || xrows != rows ) )
X	{
X	float rowratio, colratio;
X
X	rowratio = (float) xrows / (float) rows;
X	colratio = (float) xcols / (float) cols;
X	fprintf(
X	    stderr,
X	    "(Warning: non-square pixels; to fix do a 'ppmscale -%cscale %g | ppmtopgm'.)\n",
X	    rowratio > colratio ? 'y' : 'x',
X	    rowratio > colratio ? rowratio / colratio : colratio / rowratio );
X	}
X
X    /* Now read the hex bits. */
X    grays = pgm_allocarray( cols, rows );
X    for ( row = rows - 1; row >= 0; row--)
X	{
X	for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
X	    {
X	    *gP = gethexit( ifd ) << 4;
X	    *gP += gethexit( ifd );
X	    }
X	}
X    pm_close( ifd );
X
X    /* And write out the graymap. */
X    pgm_writepgm( stdout, grays, cols, rows, maxval );
X
X    exit( 0 );
X    }
X
Xint
Xgethexit( ifd )
XFILE *ifd;
X    {
X    register int i;
X    register char c;
X
X    for ( ; ; )
X	{
X	i = getc( ifd );
X	if ( i == EOF )
X	    pm_error( "premature EOF", 0,0,0,0,0 );
X	c = (char) i;
X	if ( c >= '0' && c <= '9' )
X	    return c - '0';
X	else if ( c >= 'A' && c <= 'F' )
X	    return c - 'A' + 10;
X	else if ( c >= 'a' && c <= 'f' )
X	    return c - 'a' + 10;
X	/* Else ignore - whitespace. */
X	}
X    }
SHAR_EOF
if test 3280 -ne "`wc -c < 'pgm/fstopgm.c'`"
then
	echo shar: error transmitting "'pgm/fstopgm.c'" '(should have been 3280 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/fstopgm.1'" '(667 characters)'
if test -f 'pgm/fstopgm.1'
then
	echo shar: will not over-write existing file "'pgm/fstopgm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/fstopgm.1'
X.TH fstopgm 1 "06 April 89"
X.SH NAME
Xfstopgm - convert a Usenix FaceSaver file into a portable graymap
X.SH SYNOPSIS
Xfstopgm [fsfile]
X.SH DESCRIPTION
XReads a Usenix FaceSaver file as input.
XProduces a portable graymap as output.
X.SH "SEE ALSO"
Xpgm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 667 -ne "`wc -c < 'pgm/fstopgm.1'`"
then
	echo shar: error transmitting "'pgm/fstopgm.1'" '(should have been 667 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/hipstopgm.c'" '(4222 characters)'
if test -f 'pgm/hipstopgm.c'
then
	echo shar: will not over-write existing file "'pgm/hipstopgm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/hipstopgm.c'
X/* hipstopgm.c - read a HIPS file and produce a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#ifdef	SYSV
X#include <string.h>
X#else	SYSV
X#include <strings.h>
X#endif	SYSV
X#include "pgm.h"
X
Xstruct HIPS_Header {
X    char *orig_name;	/* An indication of the originator of this sequence. */
X    char *seq_name;	/* The sequence name. */
X    int num_frame;	/* The number of frames in this sequence. */
X    char *orig_date;	/* The date the sequence was originated. */
X    int rows;		/* The number of rows in each image, the height. */
X    int cols;		/* The number of columns in each image, the width. */
X    int bits_per_pixel;	/* The number of significant bits per pixel. */
X    int bit_packing;	/* Nonzero if the bits were packed such as to
X			   eliminate any unused bits resulting from a
X			   bits_per_pixel value which was not an even
X			   multiple of eight. */
X    int pixel_format;	/* An indication of the format of each pixel.
X    char *seq_history;	/* A description of the sequence of transformations
X			   leading up to the current image. */
X    char *seq_desc;	/* A free form description of the contents of the
X			   sequence. */
X    };
X#define HIPS_PFBYTE 0
X#define HIPS_PFSHORT 1
X#define HIPS_PFINT 2
X#define HIPS_PFFLOAT 3
X#define HIPS_PFCOMPLEX 4
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray *grayrow, *gP;
X    int argn, row;
X    register int col;
X    gray maxval;
X    int rows, cols;
X    struct HIPS_Header h;
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn < argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( "[hipsfile]" );
X
X    read_hips_header( ifd, &h );
X
X    cols = h.cols;
X    rows = h.rows * h.num_frame;
X
X    switch ( h.pixel_format )
X	{
X	case HIPS_PFBYTE:
X	if ( h.bits_per_pixel != 8 )
X	    pm_error(
X		"can't handle unusual bits_per_pixel %d", h.bits_per_pixel,
X		0,0,0,0 );
X	if ( h.bit_packing != 0 )
X	    pm_error( "can't handle bit_packing", 0,0,0,0,0 );
X	maxval = 255;
X	break;
X
X	default:
X	pm_error( "unknown pixel format %d", h.pixel_format, 0,0,0,0 );
X	}
X
X    pgm_writepgminit( stdout, cols, rows, maxval );
X    grayrow = pgm_allocrow( cols );
X    for ( row = 0; row < rows; row++)
X	{
X	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
X	    {
X	    int ich;
X
X	    switch ( h.pixel_format )
X		{
X		case HIPS_PFBYTE:
X		ich = getc( ifd );
X		if ( ich == EOF )
X		    pm_error( "premature EOF", 0,0,0,0,0 );
X		*gP = (gray) ich;
X		break;
X
X		default:
X		pm_error( "can't happen", 0,0,0,0,0 );
X		}
X	    }
X	pgm_writepgmrow( stdout, grayrow, cols, maxval );
X	}
X    pm_close( ifd );
X
X    exit( 0 );
X    }
X
Xread_hips_header( fd, hP )
XFILE *fd;
Xstruct HIPS_Header *hP;
X    {
X    char buf[5000];
X
X    /* Read and toss orig_name. */
X    read_line( fd, buf, 5000 );
X
X    /* Read and toss seq_name. */
X    read_line( fd, buf, 5000 );
X
X    /* Read num_frame. */
X    read_line( fd, buf, 5000 );
X    hP->num_frame = atoi( buf );
X
X    /* Read and toss orig_date. */
X    read_line( fd, buf, 5000 );
X
X    /* Read rows. */
X    read_line( fd, buf, 5000 );
X    hP->rows = atoi( buf );
X
X    /* Read cols. */
X    read_line( fd, buf, 5000 );
X    hP->cols = atoi( buf );
X
X    /* Read bits_per_pixel. */
X    read_line( fd, buf, 5000 );
X    hP->bits_per_pixel = atoi( buf );
X
X    /* Read bit_packing. */
X    read_line( fd, buf, 5000 );
X    hP->bit_packing = atoi( buf );
X
X    /* Read pixel_format. */
X    read_line( fd, buf, 5000 );
X    hP->pixel_format = atoi( buf );
X
X    /* Now read and toss lines until we get one with just a period. */
X    do
X	{
X	read_line( fd, buf, 5000 );
X	}
X    while ( strcmp( buf, ".\n" ) != 0 );
X    }
X
Xread_line( fd, buf, size )
XFILE *fd;
Xchar *buf;
Xint size;
X    {
X    if ( fgets( buf, size, fd ) == NULL )
X	pm_error( "error reading header", 0,0,0,0,0 );
X    }
SHAR_EOF
if test 4222 -ne "`wc -c < 'pgm/hipstopgm.c'`"
then
	echo shar: error transmitting "'pgm/hipstopgm.c'" '(should have been 4222 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/hipstopgm.1'" '(853 characters)'
if test -f 'pgm/hipstopgm.1'
then
	echo shar: will not over-write existing file "'pgm/hipstopgm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/hipstopgm.1'
X.TH hipstopgm 1 "24 August 89"
X.SH NAME
Xhipstopgm - convert a HIPS file into a portable graymap
X.SH SYNOPSIS
Xhipstopgm [hipsfile]
X.SH DESCRIPTION
XReads a HIPS file as input.
XProduces a portable graymap as output.
X.PP
XIf the HIPS file contains more than one frame in sequence, hipstopgm
Xwill concatenate all the frames vertically.
X.PP
XHIPS is a format developed at the Human Information Processing
XLaboratory, NYU.
X.SH "SEE ALSO"
Xpgm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 853 -ne "`wc -c < 'pgm/hipstopgm.1'`"
then
	echo shar: error transmitting "'pgm/hipstopgm.1'" '(should have been 853 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmenhance.c'" '(2974 characters)'
if test -f 'pgm/pgmenhance.c'
then
	echo shar: will not over-write existing file "'pgm/pgmenhance.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmenhance.c'
X/* pgmenhance.c - edge-enhance a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register gray **grays, *newgrayrow, *ngP;
X    int argn, n, rows, cols, row, col;
X    float phi, omphi;
X    gray maxval, sum;
X    long newval;
X    char *usage = "[-N] [pgmfile]  ( 1 <= N <= 9, default = 9 )";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    n = 9;
X
X    if ( argn < argc )
X	{
X	if ( argv[argn][0] == '-' )
X	    {
X	    if ( sscanf( &(argv[argn][1]), "%d", &n ) != 1 )
X		pm_usage( usage );
X	    if ( n < 1 || n > 9 )
X		pm_usage( usage );
X	    argn++;
X	    }
X	}
X
X    if ( argn != argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    pgm_pbmmaxval = 255;	/* use a larger value for better (?) results */
X    grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
X
X    pgm_writepgminit( stdout, cols, rows, maxval );
X    newgrayrow = pgm_allocrow( cols );
X
X    /* The edge enhancing technique is taken from Philip R. Thompson's "xim"
X    ** program, which in turn took it from section 6 of "Digital Halftones by
X    ** Dot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
X    ** October 1987, which in turn got it from two 1976 papers by J. F. Jarvis
X    ** et. al.
X    */
X    phi = n / 10.0;
X    omphi = 1.0 - phi;
X
X    /* Row 0. */
X    for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
X	*ngP = grays[0][col];
X    pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X
X    /* Other rows. */
X    for ( row = 1; row < rows - 1; row++ )
X	{
X	ngP = newgrayrow;
X	*ngP = grays[row][0];
X	ngP++;
X	for ( col = 1; col < cols - 1; col++, ngP++ )
X	    {
X	    /* Compute the sum of the neighborhood. */
X	    sum =
X		grays[row-1][col-1] + grays[row-1][col] + grays[row-1][col+1] +
X		grays[row  ][col-1] + grays[row  ][col] + grays[row  ][col+1] +
X		grays[row+1][col-1] + grays[row+1][col] + grays[row+1][col+1];
X	    /* Now figure new value. */
X	    newval =
X		(long) ( ( grays[row][col] - phi * sum / 9 ) / omphi + 0.5 );
X	    if ( newval < 0 )
X		newgrayrow[col] = 0;
X	    else if ( newval > maxval )
X		newgrayrow[col] = maxval;
X	    else
X		newgrayrow[col] = newval;
X	    }
X	newgrayrow[cols - 1] = grays[row][cols - 1];
X	pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X	}
X
X    /* Last row. */
X    for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
X	*ngP = grays[rows - 1][col];
X    pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
X
X    pm_close( ifd );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 2974 -ne "`wc -c < 'pgm/pgmenhance.c'`"
then
	echo shar: error transmitting "'pgm/pgmenhance.c'" '(should have been 2974 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmenhance.1'" '(1114 characters)'
if test -f 'pgm/pgmenhance.1'
then
	echo shar: will not over-write existing file "'pgm/pgmenhance.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmenhance.1'
X.TH pgmenhance 1 "13 January 1989"
X.SH NAME
Xpgmenhance - edge-enhance a portable graymap
X.SH SYNOPSIS
Xpgmenhance [-N] [pgmfile]
X.SH DESCRIPTION
XReads a portable graymap as input.
XEnhances the edges, and writes a portable graymap as output.
XThe optional -N argument should be a digit from 1 to 9.
X1 is the lowest level of enhancement, 9 is the highest,
XThe default is 9.
X.PP
XThe edge enhancing technique is taken from Philip R. Thompson's "xim"
Xprogram, which in turn took it from section 6 of "Digital Halftones by
XDot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
XOctober 1987, which in turn got it from two 1976 papers by J. F. Jarvis
Xet. al.
X.SH "SEE ALSO"
Xpgm(5), pbm(5)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 1114 -ne "`wc -c < 'pgm/pgmenhance.1'`"
then
	echo shar: error transmitting "'pgm/pgmenhance.1'" '(should have been 1114 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmhist.c'" '(1970 characters)'
if test -f 'pgm/pgmhist.c'
then
	echo shar: will not over-write existing file "'pgm/pgmhist.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmhist.c'
X/* pgmhist.c - print a histogram of the values in a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pgm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    gray maxval, **grays;
X    register gray *gP;
X    int argn, rows, cols, row;
X    int i, *hist, *rcount, count, size;
X    register int col;
X    char *usage = "[pgmfile]";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn < argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
X
X    pm_close( ifd );
X
X    /* Build histogram. */
X    hist = (int *) malloc( ( maxval + 1 ) * sizeof(int) );
X    rcount = (int *) malloc( ( maxval + 1 ) * sizeof(int) );
X    if ( hist == (int *) 0 || rcount == (int *) 0 )
X	pm_error( "out of memory", 0,0,0,0,0 );
X    for ( i = 0; i <= maxval; i++ )
X	hist[i] = 0;
X    for ( row = 0; row < rows; row++ )
X        for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
X	    hist[(int) *gP]++;
X
X    /* Compute count-down */
X    count = 0;
X    for ( i = maxval; i >= 0; i-- )
X	{
X	count += hist[i];
X	rcount[i] = count;
X	}
X
X    /* And print it. */
X    printf( "value\tcount\tb%%\tw%%\n" );
X    printf( "-----\t-----\t--\t--\n" );
X    count = 0;
X    size = rows * cols;
X    for ( i = 0; i <= maxval; i++ )
X	if ( hist[i] > 0 )
X	    {
X	    count += hist[i];
X	    printf(
X		"%d\t%d\t%5.3g%%\t%5.3g%%\n", i, hist[i],
X		(float) count * 100.0 / size, (float) rcount[i] * 100.0 / size );
X	    }
X
X    exit( 0 );
X    }
SHAR_EOF
if test 1970 -ne "`wc -c < 'pgm/pgmhist.c'`"
then
	echo shar: error transmitting "'pgm/pgmhist.c'" '(should have been 1970 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmhist.1'" '(690 characters)'
if test -f 'pgm/pgmhist.1'
then
	echo shar: will not over-write existing file "'pgm/pgmhist.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmhist.1'
X.TH pgmhist 1 "28 February 1989"
X.SH NAME
Xpgmhist - print a histogram of the values in a portable graymap
X.SH SYNOPSIS
Xpgmhist [pgmfile]
X.SH DESCRIPTION
XReads a portable graymap as input.
XPrints a histogram of the gray values.
X.SH "SEE ALSO"
Xpgmnorm(1), pgm(5), ppmhist(1)
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 690 -ne "`wc -c < 'pgm/pgmhist.1'`"
then
	echo shar: error transmitting "'pgm/pgmhist.1'" '(should have been 690 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmnorm.c'" '(4505 characters)'
if test -f 'pgm/pgmnorm.c'
then
	echo shar: will not over-write existing file "'pgm/pgmnorm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmnorm.c'
X/* pgmnorm.c - read a portable graymap and normalize the contrast
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#ifdef	SYSV
X#include <string.h>
X#else	SYSV
X#include <strings.h>
X#endif	SYSV
X#include "pgm.h"
X
X#define max(a,b) ((a) > (b) ? (a) : (b))
X#define MAXMAXVAL 1023
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    gray maxval, **grays;
X    register gray range, *gP;
X    int argn, rows, cols, row, hist[MAXMAXVAL+1], i, size, cutoff, count;
X    float bpercent, wpercent;
X    int bvalue, wvalue;
X    int specbpercent, specbvalue, specwpercent, specwvalue;
X    register int col;
X    char *usage = "[-bpercent <n> | -bvalue <n>] [-wpercent <n> | -wvalue <n>] [pgmfile]";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    bpercent = 2.0;
X    wpercent = 1.0;
X    specbpercent = specbvalue = specwpercent = specwvalue = 0;
X
X    while ( argn + 1 < argc && argv[argn][0] == '-' )
X	{
X	if ( strncmp(argv[argn],"-bpercent",max(strlen(argv[argn]),3)) == 0 )
X	    {
X	    if ( specbvalue )
X		pm_error(
X		    "only one of -bpercent and -bvalue may be specified",
X		    0,0,0,0,0 );
X	    if ( sscanf( argv[argn+1], "%g", &bpercent ) != 1 )
X		pm_usage( usage );
X	    if ( bpercent < 0.0  || bpercent > 100.0 )
X		pm_error(
X		    "black percentage must between 0 and 100", 0,0,0,0,0 );
X	    specbpercent = 1;
X	    }
X	else if ( strncmp(argv[argn],"-bvalue",max(strlen(argv[argn]),3)) == 0 )
X	    {
X	    if ( specbpercent )
X		pm_error(
X		    "only one of -bpercent and -bvalue may be specified",
X		    0,0,0,0,0 );
X	    if ( sscanf( argv[argn+1], "%d", &bvalue ) != 1 )
X		pm_usage( usage );
X	    if ( bvalue < 0 )
X		pm_error( "black value must be >= 0", 0,0,0,0,0 );
X	    specbvalue = 1;
X	    }
X	else if ( strncmp(argv[argn],"-wpercent",max(strlen(argv[argn]),3)) == 0 )
X	    {
X	    if ( specwvalue )
X		pm_error(
X		    "only one of -wpercent and -wvalue may be specified",
X		    0,0,0,0,0 );
X	    if ( sscanf( argv[argn+1], "%g", &wpercent ) != 1 )
X		pm_usage( usage );
X	    if ( wpercent < 0.0 || wpercent > 100.0 )
X		pm_error(
X		    "white percentage must be between 0 and 100", 0,0,0,0,0 );
X	    specwpercent = 1;
X	    }
X	else if ( strncmp(argv[argn],"-wvalue",max(strlen(argv[argn]),3)) == 0 )
X	    {
X	    if ( specwpercent )
X		pm_error(
X		    "only one of -wpercent and -wvalue may be specified",
X		    0,0,0,0,0 );
X	    if ( sscanf( argv[argn+1], "%d", &wvalue ) != 1 )
X		pm_usage( usage );
X	    if ( wvalue < 0 )
X		pm_error( "white value must be >= 0", 0,0,0,0,0 );
X	    specwvalue = 1;
X	    }
X	else
X	    pm_usage( usage );
X	argn += 2;
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    grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
X
X    pm_close( ifd );
X
X    if ( ( ! specbvalue ) || ( ! specwvalue ) )
X	{
X	/* Build histogram. */
X	for ( i = 0; i <= maxval; i++ )
X	    hist[i] = 0;
X	for ( row = 0; row < rows; row++ )
X	    for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
X		hist[*gP]++;
X	size = rows * cols;
X	if ( ! specbvalue )
X	    { /* Compute bvalue from bpercent. */
X	    cutoff = size * bpercent / 100.0;
X	    count = 0;
X	    for ( bvalue = 0; bvalue <= maxval; bvalue++ )
X		{
X		count += hist[bvalue];
X		if ( count > cutoff )
X		break;
X		}
X	    }
X	if ( ! specwvalue )
X	    { /* Compute wvalue from wpercent. */
X	    cutoff = size * wpercent / 100.0;
X	    count = 0;
X	    for ( wvalue = maxval; wvalue >= 0; wvalue-- )
X		{
X		count += hist[wvalue];
X		if ( count > cutoff )
X		    break;
X		}
X	    }
X	}
X
X    /* Now rescale so that bvalue maps to 0, wvalue maps to maxval. */
X    fprintf(
X	stderr, "(Remapping %d..%d to %d..%d.)\n", bvalue, wvalue, 0, maxval );
X    pgm_writepgminit( stdout, cols, rows, maxval );
X    range = wvalue - bvalue;
X    for ( row = 0; row < rows; row++ )
X	{
X        for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
X	    {
X	    if ( *gP <= bvalue )
X		*gP = 0;
X	    else if ( *gP >= wvalue )
X		*gP = maxval;
X	    else
X		*gP = ( *gP - bvalue ) * maxval / range;
X	    }
X	pgm_writepgmrow( stdout, grays[row], cols, maxval );
X	}
X
X    exit( 0 );
X    }
SHAR_EOF
if test 4505 -ne "`wc -c < 'pgm/pgmnorm.c'`"
then
	echo shar: error transmitting "'pgm/pgmnorm.c'" '(should have been 4505 characters)'
fi
fi # end of overwriting check
if test ! -d 'pgm'
then
	echo shar: creating directory "'pgm'"
	mkdir 'pgm'
fi
echo shar: extracting "'pgm/pgmnorm.1'" '(1382 characters)'
if test -f 'pgm/pgmnorm.1'
then
	echo shar: will not over-write existing file "'pgm/pgmnorm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pgm/pgmnorm.1'
X.TH pgmnorm 1 "28 February 1989"
X.SH NAME
Xpgmnorm - normalize the contrast in a portable graymap
X.SH SYNOPSIS
Xpgmnorm [-bpercent <n> | -bvalue <n>] [-wpercent <n> | -wvalue] [pgmfile]
X.SH DESCRIPTION
XReads a portable graymap as input.
XNormalizes the contrast by forcing the lightest pixels to white, the
Xdarkest pixels to black, and linearly rescaling the ones in between;
Xand produces a portable graymap as output.
X.PP
XBy default, the darkest 2 percent of all pixels are mapped to black, and
Xthe lightest 1 percent are mapped to white.
XYou can override these percentages by using the -bpercent and -wpercent flags,
Xor you can specify the exact pixel values to be mapped by using the
X-bvalue and -wvalue flags.
XAppropriate numbers for the flags can be gotten from the pgmhist tool.
X.PP
XAll flags can be abbreviated to their shortest unique prefix.
X.SH "SEE ALSO"
Xpgmhist(1), pgm(5)
X.SH AUTHOR
XPartially based on the fbnorm filter in Michael Mauldin's "Fuzzy Pixmap"
Xpackage.
X
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 1382 -ne "`wc -c < 'pgm/pgmnorm.1'`"
then
	echo shar: error transmitting "'pgm/pgmnorm.1'" '(should have been 1382 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Alt.sources mailing list