[comp.sources.misc] v09i021: PBMPLUS part 5 of 19: pbm.shar4 of 4

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

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

#! /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:
#	pbm/pbm.5
#	pbm/libpbm.3
#	pbm/libpbm.h
#	pbm/macp.h
#	pbm/x10wd.h
#	pbm/x11wd.h
#	pbm/bitreverse.h
#	pbm/pbmreduce.c
#	pbm/pbmreduce.1
#	pbm/gemtopbm.c
#	pbm/gemtopbm.1
#	pbm/pbmtogo.c
#	pbm/pbmtogo.1
#	pbm/pbmlife.c
#	pbm/pbmlife.1
#	pbm/pcxtopbm.c
# This archive created: Wed Nov 22 21:13:38 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbm.5'" '(2961 characters)'
if test -f 'pbm/pbm.5'
then
	echo shar: will not over-write existing file "'pbm/pbm.5'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbm.5'
X.TH pbm 5 "21 September 1989"
X.SH NAME
Xpbm - portable bitmap file format
X.SH DESCRIPTION
XThe portable bitmap format is a lowest common denominator monochrome
Xfile format.
XIt was originally designed to make it reasonable to mail bitmaps
Xbetween different types of machines using the typical stupid network
Xmailers we have today.
XNow it serves as the common language of a large family of bitmap
Xconversion filters.
XThe definition is as follows:
X.IP - 2
XA "magic number" for identifying the file type.
XA pbm file's magic number is the two characters "P1".
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
XWidth * height bits, each either '1' or '0', starting at the top-left
Xcorner of the bitmap, proceding in normal English reading order.
X.IP - 2
XThe character '1' means black, '0' means white.
X.IP - 2
XWhitespace in the bits section is ignored.
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 bitmap in this format:
X.PP
X.nf
XP1
X# feep.pbm
X24 7
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 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0
X0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0
X0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0
X0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
X0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 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 bitmap.
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 "P4" instead of "P1".
X.IP - 2
XThe bits are stored eight per byte, high bit first low bit last.
X.IP - 2
XNo whitespace is allowed in the bits section.
X.IP - 2
XThe files are eight times smaller and many times faster to read and write.
X.SH "SEE ALSO"
Xbrushtopbm(1), cmuwmtopbm(1), g3topbm(1), icontopbm(1), gemtopbm(1),
Xmacptopbm(1), mgrtopbm(1), pbmlife(1),
Xpbmmake(1), pbmmask(1), pbmpaste(1), pbmreduce(1), pbmtoascii(1),
Xpbmtobbnbg(1), pbmtocmuwm(1), pbmtog3(1), pbmtogo(1), pbmtoicon(1), pbmtolj(1),
Xpbmtomacp(1), pbmtomgr(1), pbmtoptx(1), pbmtorast(1), pbmtox10bm(1),
Xpbmtoxbm(1), pbmtoxwd(1), pbmupc(1), pcxtopbm(1), picttopbm(1), rasttopbm(1),
Xxbmtopbm(1), xwdtopbm(1),
Xpnm(5), pgm(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 2961 -ne "`wc -c < 'pbm/pbm.5'`"
then
	echo shar: error transmitting "'pbm/pbm.5'" '(should have been 2961 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/libpbm.3'" '(2403 characters)'
if test -f 'pbm/libpbm.3'
then
	echo shar: will not over-write existing file "'pbm/libpbm.3'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/libpbm.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 pbm 3
X.SH NAME
Xpbm - functions to support portable bitmap programs
X.SH SYNOPSIS
X.Ss
X#include <pbm.h>
Xcc ... libpbm.a
X.Se
X.SH DESCRIPTION
X.SS TYPES AND CONSTANTS
X.Ss
Xtypedef unsigned char bit;
X#define PBM_WHITE 0
X#define PBM_BLACK 1
X.Se
XEach
X.IR bit
Xshould contain only the values of
X.IR white
Xor
X.IR black .
X.SS PBM MEMORY MANAGEMENT
X.Ss
Xbit **pbm_allocarray(int cols, int rows)
X.Se
XAllocate an array of bits.
X.Ss
Xbit *pbm_allocrow( int cols )
X.Se
XAllocate a row of the given number of bits.
X.Ss
Xvoid pbm_freearray( bitrow, rows )
X.Se
XFree the array allocated with
X.IR pbm_allocarray()
Xcontaining the given number
Xof rows.
X.Ss
Xpbm_freerow( bitrow )
X.Se
XFree a row of bits.
X.SS READING PBM FILES
X.Ss
Xvoid
Xpbm_readpbminit( file, colsP, rowsP, formatP )
XFILE *file;
Xint *colsP, *rowsP, *formatP;
X.Se
XRead the header from a pbm file, filling in the rows, cols and format
Xvariables.
X.Ss
Xvoid
Xpbm_readpbmrow( file, bitrow, cols, format )
XFILE *file;
Xbit *bitrow;
Xint cols, format;
X.Se
XRead a row of bits into the bitrow array.
XFormat and cols were filled in by
X.IR pbm_readpbminit() .
X.Ss
Xbit **
Xpbm_readpbm( file, colsP, rowsP )
XFILE *file;
Xint *colsP, *rowsP;
X.Se
XRead an entire bitmap file into memory, returning the allocated array and
Xfilling in the rows and cols variables.
XThis function combines
X.IR pbm_readpbminit() ,
X.IR pbm_allocarray()
Xand
X.IR pbm_readpbmrow() .
X.SS WRITING PBM FILES
X.Ss
Xvoid
Xpbm_writepbminit( file, cols, rows )
XFILE *file;
Xint cols, rows;
X.Se
XWrite the header for a portable bitmap file.
X.Ss
Xvoid
Xpbm_writepbmrow( file, bitrow, cols )
XFILE *file;
Xbit *bitrow;
Xint cols;
X.Se
XWrite a row from a portable bitmap.
X.Ss
Xvoid
Xpbm_writepbm( file, bits, cols, rows )
XFILE *file;
Xbit **bits;
Xint cols, rows;
X.Se
XWrite the header and all data for a portable bitmap.
XThis function combines
X.IR pbm_writepbminit()
Xand
X.IR pbm_writepbmrow() .
X.SH "SEE ALSO"
Xpgm(3), ppm(3)
X.SH AUTHOR
XManual by Tony Hansen.
X
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 2403 -ne "`wc -c < 'pbm/libpbm.3'`"
then
	echo shar: error transmitting "'pbm/libpbm.3'" '(should have been 2403 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/libpbm.h'" '(636 characters)'
if test -f 'pbm/libpbm.h'
then
	echo shar: will not over-write existing file "'pbm/libpbm.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/libpbm.h'
X/* libpbm.h - internal header file for libpbm portable bitmap library
X*/
X
X#ifndef _LIBPBM_H_
X#define _LIBPBM_H_
X
X/* Magic constants. */
X
X#define PBM_MAGIC1 'P'
X#define PBM_MAGIC2 '1'
X#define RPBM_MAGIC2 '4'
X#define PBM_FORMAT (PBM_MAGIC1 * 256 + PBM_MAGIC2)
X#define RPBM_FORMAT (PBM_MAGIC1 * 256 + RPBM_MAGIC2)
X
X/* And here are some routines internal to the pbm library. */
X
Xchar pbm_getc( /* FILE *file */ );
Xunsigned char pbm_getrawbyte( /* FILE *file */ );
Xint pbm_getint( /* FILE *file */ );
X
Xint pbm_readmagicnumber( /* FILE *file */ );
X
Xvoid pbm_readpbminitrest( /* FILE *file, int *colsP, int *rowsP */ );
X
X#endif /*_LIBPBM_H_*/
SHAR_EOF
if test 636 -ne "`wc -c < 'pbm/libpbm.h'`"
then
	echo shar: error transmitting "'pbm/libpbm.h'" '(should have been 636 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/macp.h'" '(217 characters)'
if test -f 'pbm/macp.h'
then
	echo shar: will not over-write existing file "'pbm/macp.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/macp.h'
X/* macp.h - header file for MacPaint files
X*/
X
X#ifndef _MACP_H_
X#define _MACP_H_
X
X#define	HEADER_LENGTH	512
X#define	MAX_LINES	720
X#define	BYTES_WIDE	72
X#define MAX_COLS	576	/* = BYTES_WIDE * 8 */
X
X#endif /*_MACP_H_*/
SHAR_EOF
if test 217 -ne "`wc -c < 'pbm/macp.h'`"
then
	echo shar: error transmitting "'pbm/macp.h'" '(should have been 217 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/x10wd.h'" '(1011 characters)'
if test -f 'pbm/x10wd.h'
then
	echo shar: will not over-write existing file "'pbm/x10wd.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/x10wd.h'
X/* x10wd.h - the following defs are taken from various X10 header files
X*/
X
X#ifndef _X10WD_H_
X#define _X10WD_H_
X
X#define XYFormat 0
X#define ZFormat 1
X
X#define X10WD_FILE_VERSION 6
Xtypedef struct {
X    int header_size;		/* Size of the entire file header (bytes). */
X    int file_version;		/* X10WD_FILE_VERSION */
X    int display_type;		/* Display type. */
X    int display_planes;		/* Number of display planes. */
X    int pixmap_format;		/* Pixmap format. */
X    int pixmap_width;		/* Pixmap width. */
X    int pixmap_height;		/* Pixmap height. */
X    short window_width;		/* Window width. */
X    short window_height;	/* Window height. */
X    short window_x;		/* Window upper left X coordinate. */
X    short window_y;		/* Window upper left Y coordinate. */
X    short window_bdrwidth;	/* Window border width. */
X    short window_ncolors;	/* number of Color entries in this window */
X    } X10WDFileHeader;
X
Xtypedef struct {
X    int pixel;
X    unsigned short red, green, blue;
X    } X10Color;
X
X#endif /*_X10WD_H_*/
SHAR_EOF
if test 1011 -ne "`wc -c < 'pbm/x10wd.h'`"
then
	echo shar: error transmitting "'pbm/x10wd.h'" '(should have been 1011 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/x11wd.h'" '(1880 characters)'
if test -f 'pbm/x11wd.h'
then
	echo shar: will not over-write existing file "'pbm/x11wd.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/x11wd.h'
X/* x11wd.h - the following defs are taken from various X.V11R2 header files
X*/
X
X#ifndef _X11WD_H_
X#define _X11WD_H_
X
X#define LSBFirst	0
X#define MSBFirst	1
X
X#define XYBitmap	0
X#define XYPixmap	1
X#define ZPixmap		2
X
X#define StaticGray	0
X#define GrayScale	1
X#define StaticColor	2
X#define PseudoColor	3
X#define TrueColor	4
X#define DirectColor	5
X
Xtypedef unsigned long xwdval;
X#define X11WD_FILE_VERSION 7
Xtypedef struct {
X    xwdval header_size;		/* Size of the entire file header (bytes). */
X    xwdval file_version;	/* X11WD_FILE_VERSION */
X    xwdval pixmap_format;	/* Pixmap format */
X    xwdval pixmap_depth;	/* Pixmap depth */
X    xwdval pixmap_width;	/* Pixmap width */
X    xwdval pixmap_height;	/* Pixmap height */
X    xwdval xoffset;		/* Bitmap x offset */
X    xwdval byte_order;		/* MSBFirst, LSBFirst */
X    xwdval bitmap_unit;		/* Bitmap unit */
X    xwdval bitmap_bit_order;	/* MSBFirst, LSBFirst */
X    xwdval bitmap_pad;		/* Bitmap scanline pad */
X    xwdval bits_per_pixel;	/* Bits per pixel */
X    xwdval bytes_per_line;	/* Bytes per scanline */
X    xwdval visual_class;	/* Class of colormap */
X    xwdval red_mask;		/* Z red mask */
X    xwdval green_mask;		/* Z green mask */
X    xwdval blue_mask;		/* Z blue mask */
X    xwdval bits_per_rgb;	/* Log base 2 of distinct color values */
X    xwdval colormap_entries;	/* Number of entries in colormap */
X    xwdval ncolors;		/* Number of Color structures */
X    xwdval window_width;	/* Window width */
X    xwdval window_height;	/* Window height */
X    long window_x;		/* Window upper left X coordinate */
X    long window_y;		/* Window upper left Y coordinate */
X    xwdval window_bdrwidth;	/* Window border width */
X    } X11WDFileHeader;
X
Xtypedef struct {
X    unsigned long pixel;
X    unsigned short red, green, blue;
X    char flags;			/* do_red, do_green, do_blue */
X    char pad;
X    } X11XColor;
X
X#endif /*_X11WD_H_*/
SHAR_EOF
if test 1880 -ne "`wc -c < 'pbm/x11wd.h'`"
then
	echo shar: error transmitting "'pbm/x11wd.h'" '(should have been 1880 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/bitreverse.h'" '(2283 characters)'
if test -f 'pbm/bitreverse.h'
then
	echo shar: will not over-write existing file "'pbm/bitreverse.h'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/bitreverse.h'
X/*
X** bitreverse.h
X**
X** This particular array seems to be useful in a lot of bitmap
X** conversion programs.  It's not used in pbm because bits are
X** stored one per byte, for easier manipulation.  But if you wanted
X** to write, for example, a program to directly convert Sun raster
X** format into X bitmaps, you could use this.
X**
X** Of course, you could also use this fairly slick chunk of code:
X**
X**     c = ((c >>  1) & 0x55) | ((c <<  1) & 0xaa);
X**     c = ((c >>  2) & 0x33) | ((c <<  2) & 0xcc);
X**     c = ((c >>  4) & 0x0f) | ((c <<  4) & 0xf0);
X*/
X
X#ifndef _BITR_H_
X#define _BITR_H_
X
Xstatic unsigned char bitreverse[256] = {
X    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
X    0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
X    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
X    0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
X    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
X    0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
X    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
X    0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
X    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
X    0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
X    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
X    0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
X    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
X    0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
X    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
X    0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
X    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
X    0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
X    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
X    0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
X    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
X    0x3f, 0xbf, 0x7f, 0xff};
X
X#endif /*_BITR_H_*/
SHAR_EOF
if test 2283 -ne "`wc -c < 'pbm/bitreverse.h'`"
then
	echo shar: error transmitting "'pbm/bitreverse.h'" '(should have been 2283 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmreduce.c'" '(4684 characters)'
if test -f 'pbm/pbmreduce.c'
then
	echo shar: will not over-write existing file "'pbm/pbmreduce.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmreduce.c'
X/* pbmreduce.c - read a portable bitmap and reduce it N times
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 "pbm.h"
X#ifdef SYSV
X#include <string.h>
X#define srandom srand
X#define random rand
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 bit **bitslice, *newbitrow, *nbP;
X    int argn, n, rows, cols, format, newrows, newcols;
X    int row, col, limitcol, subrow, subcol, count, direction;
X    char *usage = "[-floyd|-fs | -threshold] [-value <val>] N [pbmfile]";
X    int halftone;
X#define QT_FS 1
X#define QT_THRESH 2
X#define SCALE 1024
X#define HALFSCALE 512
X    long threshval, sum, *thiserr, *nexterr, *temperr;
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    halftone = QT_FS;
X    threshval = HALFSCALE;
X
X    while ( argn < argc && argv[argn][0] == '-' )
X	{
X	if ( strncmp(argv[argn],"-fs",max(strlen(argv[argn]),2)) == 0 ||
X	     strncmp(argv[argn],"-floyd",max(strlen(argv[argn]),2)) == 0 )
X	    halftone = QT_FS;
X	else if ( strncmp(argv[argn],"-threshold",max(strlen(argv[argn]),2)) == 0 )
X	    halftone = QT_THRESH;
X	else if ( strncmp(argv[argn],"-value",max(strlen(argv[argn]),2)) == 0 )
X	    {
X	    float f;
X
X	    argn++;
X	    if ( argn == argc || sscanf( argv[argn], "%g", &f ) != 1 ||
X		 f < 0.0 || f > 1.0 )
X		pm_usage( usage );
X	    threshval = f * SCALE;
X	    }
X	else
X	    pm_usage( usage );
X	argn++;
X	}
X
X    if ( argn == argc )
X	pm_usage( usage );
X    if ( sscanf( argv[argn], "%d", &n ) != 1 )
X	pm_usage( usage );
X    if ( n < 2 )
X	pm_error( "N must be greater than 1", 0,0,0,0,0 );
X    argn++;
X
X    if ( argn == argc )
X	ifd = stdin;
X    else
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    pbm_readpbminit( ifd, &cols, &rows, &format );
X    bitslice = pbm_allocarray( cols, n );
X
X    newrows = rows / n;
X    newcols = cols / n;
X    pbm_writepbminit( stdout, newcols, newrows );
X    newbitrow = pbm_allocrow( newcols );
X
X    if ( halftone == QT_FS )
X	{
X	/* Initialize Floyd-Steinberg. */
X	thiserr = (long *) malloc( ( newcols + 2 ) * sizeof(long) );
X	nexterr = (long *) malloc( ( newcols + 2 ) * sizeof(long) );
X	if ( thiserr == 0 || nexterr == 0 )
X	    pm_error( "out of memory", 0,0,0,0,0 );
X
X	srandom( (int) time( 0 ) );
X	for ( col = 0; col < newcols + 2; col++ )
X	    thiserr[col] = ( random( ) % SCALE - HALFSCALE ) / 4;
X	    /* (random errors in [-SCALE/8 .. SCALE/8]) */
X	}
X    direction = 1;
X
X    for ( row = 0; row < newrows; row++ )
X	{
X	for ( subrow = 0; subrow < n; subrow++ )
X	    pbm_readpbmrow( ifd, bitslice[subrow], cols, format );
X
X	if ( halftone == QT_FS )
X	    for ( col = 0; col < newcols + 2; col++ )
X		nexterr[col] = 0;
X	if ( direction )
X	    {
X	    col = 0;
X	    limitcol = newcols;
X	    nbP = newbitrow;
X	    }
X	else
X	    {
X	    col = newcols - 1;
X	    limitcol = -1;
X	    nbP = &(newbitrow[col]);
X	    }
X
X	do
X	    {
X	    sum = 0;
X	    count = 0;
X	    for ( subrow = 0; subrow < n; subrow++ )
X		for ( subcol = 0; subcol < n; subcol++ )
X		    if ( row * n + subrow < rows && col * n + subcol < cols )
X			{
X			count += 1;
X			if ( bitslice[subrow][col * n + subcol] == PBM_WHITE )
X			    sum += 1;
X			}
X	    sum = ( sum * SCALE ) / count;
X
X	    if ( halftone == QT_FS )
X		sum += thiserr[col + 1];
X
X	    if ( sum >= threshval )
X		{
X		*nbP = PBM_WHITE;
X		if ( halftone == QT_FS )
X		    sum = sum - threshval - HALFSCALE;
X		}
X	    else
X		*nbP = PBM_BLACK;
X
X	    if ( halftone == QT_FS )
X		{
X		if ( direction )
X		    {
X		    thiserr[col + 2] += ( sum * 7 ) / 16;
X		    nexterr[col    ] += ( sum * 3 ) / 16;
X		    nexterr[col + 1] += ( sum * 5 ) / 16;
X		    nexterr[col + 2] += ( sum     ) / 16;
X		    }
X		else
X		    {
X		    thiserr[col    ] += ( sum * 7 ) / 16;
X		    nexterr[col + 2] += ( sum * 3 ) / 16;
X		    nexterr[col + 1] += ( sum * 5 ) / 16;
X		    nexterr[col    ] += ( sum     ) / 16;
X		    }
X		}
X	    if ( direction )
X		{
X		col++;
X		nbP++;
X		}
X	    else
X		{
X		col--;
X		nbP--;
X		}
X	    }
X	while ( col != limitcol );
X
X	pbm_writepbmrow( stdout, newbitrow, newcols );
X
X	if ( halftone == QT_FS )
X	    {
X	    temperr = thiserr;
X	    thiserr = nexterr;
X	    nexterr = temperr;
X	    direction = ! direction;
X	    }
X	}
X
X    pm_close( ifd );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 4684 -ne "`wc -c < 'pbm/pbmreduce.c'`"
then
	echo shar: error transmitting "'pbm/pbmreduce.c'" '(should have been 4684 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmreduce.1'" '(1249 characters)'
if test -f 'pbm/pbmreduce.1'
then
	echo shar: will not over-write existing file "'pbm/pbmreduce.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmreduce.1'
X.TH pbmreduce 1 "02 August 1989"
X.SH NAME
Xpbmreduce - read a portable bitmap and reduce it N times
X.SH SYNOPSIS
Xpbmreduce [-floyd|-fs | -threshold] [-value <val>] N [pbmfile]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XReduces it by a factor of N, and produces a portable bitmap as output.
XBy default, the halftoning after the reduction is done via
Xboustrophedonic Floyd-Steinberg error diffusion; however, the -thresh
Xflag can be used to specify simple thresholding.  This gives better
Xresults when reducing line drawings.
X.PP
XThe -value flag alters the thresholding value for all quantizations.
XIt should be a real number between 0 and 1.
XAbove 0.5 means darker images; below 0.5 means lighter.
X.PP
XAll flags can be abbreviated to their shortest unique prefix.
X.SH "SEE ALSO"
Xpnmenlarge(1), ppmscale(1), pgmtopbm(1), pbm(5)
X.SH AUTHOR
XCopyright (C) 1988 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 1249 -ne "`wc -c < 'pbm/pbmreduce.1'`"
then
	echo shar: error transmitting "'pbm/pbmreduce.1'" '(should have been 1249 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/gemtopbm.c'" '(5175 characters)'
if test -f 'pbm/gemtopbm.c'
then
	echo shar: will not over-write existing file "'pbm/gemtopbm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/gemtopbm.c'
X/*
X * Convert a GEM .img file to a portable bitmap file.
X *
X * Author: Diomidis D. Spinellis
X * (C) Copyright 1988 Diomidis D. Spinellis.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind.  The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof.  In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X * Comments and additions should be sent to the author:
X *
X *                     Diomidis D. Spinellis
X *                     1 Myrsinis Str.
X *                     GR-145 62 Kifissia
X *                     GREECE
X *
X */
X
X#include <stdio.h>
X#include <assert.h>
X#include "pbm.h"
X#include "libpbm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
X/*
X * Handle systems that do CR-LF translation on reading / writing and
X * little endians (some guesswork is involved).
X */
X#ifdef MSDOS
X#define LITTLE_ENDIAN
X#endif /*MSDOS*/
X#ifdef xenix
X#define LITTLE_ENDIAN
X#endif /*xenix*/
X#ifdef sun386
X#define LITTLE_ENDIAN
X#endif /*sun386*/
X
X
X/* Seek from current position */
X#ifndef SEEK_CUR
X#define SEEK_CUR 1
X#endif /*SEEK_CUR*/
X
X/*
X * File header structure
X */
Xstruct header {
X	short           version;/* Image file version */
X	unsigned short  hlen;	/* Header length in bytes */
X	unsigned short  planes;	/* Number of planes */
X	unsigned short  patlen;	/* Pattern definition length (bytes) */
X	unsigned short  pxlen;	/* Pixel height (microns) */
X	unsigned short  pxht;	/* Pixel height (microns) */
X	unsigned short  linewid;/* Scan line width (bytes) */
X	unsigned short  nitems;	/* Number of scan line items */
X};
X
X/*
X * Scan item header
X */
Xstruct line {
X	char            d1, d2;	/* Should be 0 */
X	char            d3;	/* Should be 0xff */
X	char            count;	/* Repetition count */
X};
X
Xchar            pattern[256];
X
X
Xstatic void byteswap();
Xstatic void pbmout();
Xextern int      errno;
Xextern char    *sys_errlist[];
X#define strerror(x) (sys_errlist[x])
X
Xvoid
Xmain(argc, argv)
X	int             argc;
X	char           *argv[];
X{
X	int             debug = 0;
X	FILE           *f;
X	struct header   hd;
X	int             x;
X	int             i, j, k, l;
X	int             c, cc;
X	int		rows, cols;
X	bit		*bitrow;
X
X	pm_progname = argv[0];
X
X	/* Check if the compiler alligns structures the way we want */
X	assert( sizeof( struct header ) == 16 ) ;
X
X	if (argc > 1 && !strcmp(argv[1], "-d")) {
X		argc--;
X		argv[1] = argv[0];
X		argv++;
X		debug++;
X	}
X
X	if (argc != 2)
X		pm_usage("[-d] <gemfile>");
X
X	f = pm_openr( argv[1] );
X
X	if (fread(&hd, sizeof hd, 1, f) != 1)
X		pm_error( "read %s", strerror(errno), 0,0,0,0 );
X
X#ifdef LITTLE_ENDIAN
X	byteswap((unsigned short *) &hd, sizeof hd / 2);
X#endif /*LITTLE_ENDIAN*/
X
X	if( fseek(f, (long) hd.hlen * 2 - sizeof(struct header), SEEK_CUR) == -1 )
X		pm_error( "fseek %s", strerror(errno), 0,0,0,0 );
X
X	if (debug)
X		fprintf(stderr,
X			" version\t\t%d\n hlen\t\t%d\n planes\t\t%d\n patlen\t\t%d\n pxlen\t\t%d\n pxht\t\t%d\n linewid\t\t%d\n nitems\t\t%d\n",
X		        hd.version, hd.hlen, hd.planes, hd.patlen, hd.pxlen,
X		        hd.pxht, hd.linewid, hd.nitems);
X
X	cols = hd.linewid % 8 == 0 ? hd.linewid : hd.linewid + 8 - hd.linewid % 8;
X	rows = hd.nitems;
X	pbm_writepbminit( stdout, cols, rows );
X	bitrow = pbm_allocrow( cols );
X
X	for (i = 0; i < hd.nitems; i++) {
X		x = 0;
X		while (x < hd.linewid) {
X			switch (c = getc(f)) {
X			case 0x80:	/* Bit String */
X				c = getc(f);	/* Byte count */
X				if (debug)
X					fprintf(stderr,
X						"Bit string of %d bytes\n", c);
X				for (j = 0; j < c; j++) {
X					cc = getc(f);
X					for (k = 0x80; k; k >>= 1) {
X						bitrow[x] = (k & cc) ? PBM_BLACK : PBM_WHITE;
X						x++;
X				}
X				}
X				break;
X			case 0:		/* Pattern run */
X				c = getc(f);	/* Repeat count */
X				if (debug)
X					fprintf(stderr,
X						"Pattern run of %d repetitions\n",
X						c);
X				fread(pattern, 1, hd.patlen, f);
X				for (j = 0; j < c; j++)
X					for (l = 0; l < hd.patlen; l++)
X						for (k = 0x80; k; k >>= 1) {
X							bitrow[x] = (k & pattern[l]) ? PBM_BLACK : PBM_WHITE;
X							x++;
X						}
X				break;
X
X			default:	/* Solid run */
X				if (debug)
X					fprintf(stderr,
X						"Solid run of %d bytes %s\n",
X						c & 0x7f,
X						c & 0x80 ? "on" : "off");
X				for (i = 0; i < c & 0x7f; i++) {
X					bitrow[x] = (c & 0x80) ? PBM_BLACK : PBM_WHITE;
X					x++;
X				}
X				break;
X
X			case EOF:	/* End of file */
X				pm_error( "end of file reached", 0,0,0,0,0 );
X
X			}
X		}
X		pbm_writepbmrow( stdout, bitrow, cols );
X	}
X	pm_close( f );
X	exit(0);
X}
X
X#ifdef LITTLE_ENDIAN
Xstatic void
Xbyteswap(data, n)
X	unsigned short *data;
X	int             n;
X{
X	register        i;
X	char           *p, c;
X
X	for (i = 0, p = (char *) data; i < n; i++, p++) {
X		c = *p;
X		*p = *(p + 1);
X		*++p = c;
X	}
X}
X#endif /*LITTLE_ENDIAN*/
SHAR_EOF
if test 5175 -ne "`wc -c < 'pbm/gemtopbm.c'`"
then
	echo shar: error transmitting "'pbm/gemtopbm.c'" '(should have been 5175 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/gemtopbm.1'" '(807 characters)'
if test -f 'pbm/gemtopbm.1'
then
	echo shar: will not over-write existing file "'pbm/gemtopbm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/gemtopbm.1'
X.TH gemtopbm 1 "3 December 1988"
X.SH NAME
Xgemtopbm - convert a GEM .img file into a portable bitmap
X.SH SYNOPSIS
Xgemtopbm [-d] gemfile
X.SH DESCRIPTION
XReads a GEM .img file as input.
XProduces a portable bitmap as output.
X.PP
XNote that there is currently no pbmtogem tool.
X.SH OPTIONS
X.TP
X.B \-d
XProduce output describing the contents of the .img file.
X.SH BUGS
XIt does not support file containing more than one plane.
X.SH "SEE ALSO"
Xpbm(5)
X.SH AUTHOR
XCopyright (C) 1988 Diomidis D. Spinellis
X(dds@cc.ic.ac.uk)
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted,
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in
Xsupporting documentation.
SHAR_EOF
if test 807 -ne "`wc -c < 'pbm/gemtopbm.1'`"
then
	echo shar: error transmitting "'pbm/gemtopbm.1'" '(should have been 807 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmtogo.c'" '(3115 characters)'
if test -f 'pbm/pbmtogo.c'
then
	echo shar: will not over-write existing file "'pbm/pbmtogo.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmtogo.c'
X/* pbmtogo.c - read a portable bitmap and produce a GraphOn terminal raster file
X**	
X**	based on pbmtolj.c
X**
X**	Bo Thide', Swedish Institute of Space Physics, bt@irfu.se
X**				   
X**	misfeatures: 
X**		No 2D compression, no positioning
X**
X** Copyright (C) 1988 by Jef Poskanzer, Michael Haberler, and Bo Thide'.
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 "pbm.h"
X#ifdef SYSV
X#include <string.h>
X#else /*SYSV*/
X#include <strings.h>
X#endif /*SYSV*/
X
X    
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register bit *bitrow, *bP;
X    int argn, rows, cols, format, rucols, padright, row, col;
X    char *usage = "[-c] [pbmfile]";
X
X    pm_progname = argv[0];
X
X    argn = 2;
X
X    /* Check for flags. */
X    if ( argc > argn )
X	{
X	if ( argv[argn][0] == '-' )
X	    {
X	    if ( strcmp( argv[argn], "-c" ) == 0 )
X		pm_error( "compression not implemented yet", 0,0,0,0,0 );
X	    argn++;
X	    }
X	else
X	    pm_usage( usage );
X	}
X
X    if ( argc > argn + 1 )
X	pm_usage( usage );
X
X    if ( argc == argn )
X	ifd = pm_openr( argv[argn-1] );
X    else
X	ifd = stdin;
X
X    pbm_readpbminit( ifd, &cols, &rows, &format );
X    bitrow = pbm_allocrow( cols );
X
X    /* Round cols up to the nearest multiple of 8. */
X    rucols = ( cols + 7 ) / 8;
X    rucols = rucols * 8;
X    padright = rucols - cols;
X
X    putinit( );
X
X    /* Star donwloading screen raster*/
X    printf( "\033P0;0;1;4;101;%d;%d;101!R", rows + 100, rucols + 100 );
X    for ( row = 0; row < rows; row++ )
X	{
X	pbm_readpbmrow( ifd, bitrow, cols, format );
X	/* Transfer raster graphics */
X	printf( "%d/",rucols / 8 );  /* No. of bytes per row */
X        for ( col = 0, bP = bitrow; col < cols; col++, bP++ )
X	    putbit( *bP );
X	for ( col = 0; col < padright; col++ )
X	    putbit( 0 );
X        }
X
X    pm_close( ifd );
X
X    putrest( );
X
X    exit( 0 );
X    }
X
X
Xint item, bitsperitem, bitshift, itemsperline, firstitem;
X
Xputinit( )
X    {
X    /* Enter graphics window */
X    printf( "\0331" );
X
X    /* Erase graphics window */
X    printf( "\033\014" );
X
X    /* Set graphics window in raster mode */
X    printf( "\033r" );
X
X    /* Select standard Tek coding **/
X    printf( "\033[=11l" );
X
X    itemsperline = 0;
X    bitsperitem = 1;
X    item = 0;
X    bitshift = 7;
X    firstitem = 1;
X    }
X
Xputbit( b )
Xbit b;
X    {
X    if ( b == PBM_BLACK )
X	item += 1 << bitshift;
X    bitshift--;
X    if ( bitsperitem == 8 ) {
X	putitem( );
X        bitshift = 7;
X    }
X    bitsperitem++;
X    }
X
Xputrest( )
X    {
X    if ( bitsperitem > 1 )
X	putitem( );
X
X    /* end raster downloading */
X    printf( "\033\134" );
X
X    /* Exit raster mode */
X    printf( "\033t" );
X
X    /* Exit graphics window
X    printf( "\0332" ); */
X    }
X
Xputitem( )
X    {
X    putchar( item );
X    bitsperitem = 0;
X    item = 0;
X    }
SHAR_EOF
if test 3115 -ne "`wc -c < 'pbm/pbmtogo.c'`"
then
	echo shar: error transmitting "'pbm/pbmtogo.c'" '(should have been 3115 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmtogo.1'" '(956 characters)'
if test -f 'pbm/pbmtogo.1'
then
	echo shar: will not over-write existing file "'pbm/pbmtogo.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmtogo.1'
X.TH pbmtogo 1 "12 December 1988"
X.SH NAME
Xpbmtogo - convert a portable bitmap into GraphOn graphics
X.SH SYNOPSIS
Xpbmtogo [-c] [ <pbmfile> ]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XProduces GraphOn graphics as output.
XBe sure to set up your GraphOn with the following modes: 8 bits / no parity;
Xobeys no XON/XOFF; NULs are accepted.  These are all on the Comm menu.
X.PP
XThe -c flag specifies compression, which is not implemented yet.
X.PP
XNote that there is no gotopbm tool.
X.SH "SEE ALSO"
Xpbm(5)
X.SH AUTHOR
XCopyright (C) 1988 by Jef Poskanzer, Michael Haberler, and Bo Thide'.
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 956 -ne "`wc -c < 'pbm/pbmtogo.1'`"
then
	echo shar: error transmitting "'pbm/pbmtogo.1'" '(should have been 956 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmlife.c'" '(2145 characters)'
if test -f 'pbm/pbmlife.c'
then
	echo shar: will not over-write existing file "'pbm/pbmlife.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmlife.c'
X/* pbmlife.c - read a portable bitmap and apply Conway's rules of Life to it
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 "pbm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    register bit **bits, *bitrow;
X    int rows, cols, row, col, count;
X
X    pm_progname = argv[0];
X
X    if ( argc > 2 )
X	pm_usage( "[pbmfile]" );
X
X    if ( argc == 2 )
X	ifd = pm_openr( argv[1] );
X    else
X	ifd = stdin;
X
X    bits = pbm_readpbm( ifd, &cols, &rows );
X    pbm_writepbminit( stdout, cols, rows );
X    bitrow = pbm_allocrow( cols );
X
X    pm_close( ifd );
X
X    for ( row = 0; row < rows; row++ )
X	{
X        for ( col = 0; col < cols; col++ )
X	    {
X	    /* Check the neighborhood, with an unrolled double loop. */
X	    count = 0;
X	    if ( row - 1 >= 0 )
X		{
X		/* upper left */
X		if ( col - 1 >= 0 && bits[row - 1][col - 1] )
X		    count++;
X		/* upper center */
X		if ( bits[row - 1][col] )
X		    count++;
X		/* upper right */
X		if ( col + 1 < cols && bits[row - 1][col + 1] )
X		    count++;
X		}
X	    /* left */
X	    if ( col - 1 >= 0 && bits[row][col - 1] )
X		count++;
X	    /* right */
X	    if ( col + 1 < cols && bits[row][col + 1] )
X		count++;
X	    if ( row + 1 < rows )
X		{
X		/* lower left */
X		if ( col - 1 >= 0 && bits[row + 1][col - 1] )
X		    count++;
X		/* lower center */
X		if ( bits[row + 1][col] )
X		    count++;
X		/* lower right */
X		if ( col + 1 < cols && bits[row + 1][col + 1] )
X		    count++;
X		}
X
X	    /* And compute the new value. */
X	    if ( bits[row][col] )
X		if ( count == 2 || count == 3 )
X		    bitrow[col] = 1;
X		else
X		    bitrow[col] = 0;
X	    else
X		if ( count == 3 )
X		    bitrow[col] = 1;
X		else
X		    bitrow[col] = 0;
X	    }
X	pbm_writepbmrow( stdout, bitrow, cols );
X	}
X
X    exit( 0 );
X    }
SHAR_EOF
if test 2145 -ne "`wc -c < 'pbm/pbmlife.c'`"
then
	echo shar: error transmitting "'pbm/pbmlife.c'" '(should have been 2145 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pbmlife.1'" '(695 characters)'
if test -f 'pbm/pbmlife.1'
then
	echo shar: will not over-write existing file "'pbm/pbmlife.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pbmlife.1'
X.TH pbmlife 1 "14 December 1988"
X.SH NAME
Xpbmlife - apply Conway's rules of Life to a portable bitmap
X.SH SYNOPSIS
Xpbmlife [pbmfile]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XApplys the rules of Life to it and produces a portable bitmap as output.
X.SH "SEE ALSO"
Xpbm(5)
X.SH AUTHOR
XCopyright (C) 1988 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 695 -ne "`wc -c < 'pbm/pbmlife.1'`"
then
	echo shar: error transmitting "'pbm/pbmlife.1'" '(should have been 695 characters)'
fi
fi # end of overwriting check
if test ! -d 'pbm'
then
	echo shar: creating directory "'pbm'"
	mkdir 'pbm'
fi
echo shar: extracting "'pbm/pcxtopbm.c'" '(3518 characters)'
if test -f 'pbm/pcxtopbm.c'
then
	echo shar: will not over-write existing file "'pbm/pcxtopbm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbm/pcxtopbm.c'
X/* pcxtopbm.c - convert PC paintbrush (.pcx) files to portable bitmaps
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** This program is based on the pcx2rf program by:
X**   Mike Macgirvin
X**   Stanford Relativity Gyro Program GP-B
X**   Stanford, Calif. 94503
X**   ARPA: mike@relgyro.stanford.edu
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X
Xvoid read_pcx(), spread_byte();
X
Xmain( argc, argv)
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    unsigned char pcxhd[128];
X    int cnt, b;
X    int xmin;
X    int xmax;
X    int ymin;
X    int ymax;
X    int bytes_per_row;
X    register bit **bits;
X
X    pm_progname = argv[0];
X
X    if ( argc > 2 )
X	pm_usage( "[pcxfile]" );
X
X    /* Open input file. */
X    if ( argc == 2 )
X	ifd = pm_openr( argv[1] );
X    else
X	ifd = stdin;
X
X    /* Read .pcx header. */
X    for ( cnt = 0; cnt < 128; cnt++ )
X	{
X	b = getc( ifd );
X	if ( b == EOF )
X	    pm_error( "incomplete .pcx header", 0,0,0,0,0 );
X	pcxhd[cnt] = b;
X	}
X
X    /* Calculate raster header and swap bytes. */
X    xmin = pcxhd[4] + ( 256 * pcxhd[5] );
X    ymin = pcxhd[6] + ( 256 * pcxhd[7] );
X    xmax = pcxhd[8] + ( 256 * pcxhd[9] );
X    ymax = pcxhd[10] + ( 256 * pcxhd[11] );
X    xmax = xmax - xmin + 1;
X    ymax = ymax - ymin + 1;
X    bytes_per_row = pcxhd[66] + ( 256 * pcxhd[67] );
X
X    /* Allocate pbm array. */
X    bits = pbm_allocarray( xmax + 8, ymax );
X    /* + 8 allows for slop turning bytes to bits; it's easier than checking. */
X
X    /* Read compressed bitmap. */
X    read_pcx( ifd, bytes_per_row, bits, ymax );
X    pm_close( ifd );
X
X    /* Write pbm. */
X    pbm_writepbm( stdout, bits, xmax, ymax );
X
X    /* All done. */
X    exit( 0 );
X    }
X
X
Xvoid
Xread_pcx( ifd, bytes_per_row, bits, rows )
XFILE *ifd;
Xint bytes_per_row;
Xbit **bits;
Xint rows;
X    {
X    /* Goes like this:  Read a byte.  If the two high bits are set, then the
X    ** low 6 bits contain a repeat count, and the byte to repeat is the next
X    ** byte in the file.  If the two high bits are not set, then this is the
X    ** byte to write.  
X    */
X    int row = 0;
X    int col = 0;
X    int bytes_this_row = 0;
X    int b, i, cnt;
X
X    while ( (b = fgetc( ifd )) != EOF )
X	{
X	if ( b & 0xC0 == 0xC0 )
X	    {
X	    cnt = b & 0x3F;
X	    b = fgetc( ifd );
X	    if ( b == EOF )
X		pm_error( "unexpected end of file on input", 0,0,0,0,0 );
X	    for ( i = 0; i < cnt; i++ )
X		{
X		if ( row >= rows )
X		    {
X		    fprintf( stderr, "junk in file after bitmap - ignoring\n" );
X		    return;
X		    }
X		spread_byte( 255 - b, &(bits[row][col]) );
X		col += 8;
X		bytes_this_row++;
X		if ( bytes_this_row == bytes_per_row )
X		    {
X		    row++;
X		    col = 0;
X		    bytes_this_row = 0;
X		    }
X		}
X	    }
X	else
X	    {
X	    if ( row >= rows )
X		{
X		fprintf( stderr, "junk in file after bitmap - ignoring\n" );
X		return;
X		}
X	    spread_byte( 255 - b, &(bits[row][col]) );
X	    col += 8;
X	    bytes_this_row++;
X	    if ( bytes_this_row == bytes_per_row )
X		{
X		row++;
X		col = 0;
X		bytes_this_row = 0;
X		}
X	    }
X	}
X    }
X
X
Xvoid
Xspread_byte( b, bits )
Xint b;
Xbit *bits;
X    {
X    int i, j;
X
X    for ( i = 0, j = 7; i < 8; i++, j-- )
X	bits[j] = ( b & ( 1 << i ) ) ? PBM_BLACK : PBM_WHITE;
X    }
SHAR_EOF
if test 3518 -ne "`wc -c < 'pbm/pcxtopbm.c'`"
then
	echo shar: error transmitting "'pbm/pcxtopbm.c'" '(should have been 3518 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0