pokey@well.UUCP (Jef Poskanzer) (09/14/89)
#! /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 -@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