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