Leisner.Henr@XEROX.COM (Marty) (11/29/89)
Compiling the following program with gcc 1.36 on a sun386i causes it to abort with the optimizer on. mlsun% gcc -O -c ppmconvol.c gcc: Program cc1 got fatal signal 6. mlsun% gcc -c ppmconvol.c mlsun% Enclosed is a shar file of the program and necessary headers to compile the program. #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of shell archive." # Contents: pbm.h pbmplus.h pgm.h ppm.h ppmconvol.c # Wrapped by marty@mlsun on Wed Nov 29 08:52:28 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'pbm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pbm.h'\" else echo shar: Extracting \"'pbm.h'\" \(937 characters\) sed "s/^X//" >'pbm.h' <<'END_OF_FILE' X/* pbm.h - header file for libpbm portable bitmap library X*/ X X#ifndef _PBM_H_ X#define _PBM_H_ X X#include "pbmplus.h" X Xtypedef unsigned char bit; X#define PBM_WHITE 0 X#define PBM_BLACK 1 X X/* Declarations of routines. */ X X#define pbm_allocarray( cols, rows ) ((bit **) pm_allocarray( cols, rows, sizeof(bit) )) X#define pbm_allocrow( cols ) ((bit *) pm_allocrow( cols, sizeof(bit) )) X#define pbm_freearray( bitrow, rows ) pm_freearray( bitrow, rows ) X#define pbm_freerow( bitrow ) pm_freerow( bitrow ) X Xbit **pbm_readpbm( /* FILE *file, int *colsP, int *rowsP */ ); Xvoid pbm_readpbminit( /* FILE *file, int *colsP, int *rowsP, int *formatP */ ); Xvoid pbm_readpbmrow( /* FILE *file, bit *bitrow, int cols, int format */ ); X Xvoid pbm_writepbm( /* FILE *file, bit **bits, int cols, int rows */ ); Xvoid pbm_writepbminit( /* FILE *file, int cols, int rows */ ); Xvoid pbm_writepbmrow( /* FILE *file, bit *bitrow, int cols */ ); X X#endif /*_PBM_H_*/ END_OF_FILE echo shar: NEWLINE appended to \"'pbm.h'\" if test 938 -ne `wc -c <'pbm.h'`; then echo shar: \"'pbm.h'\" unpacked with wrong size! fi # end of 'pbm.h' fi if test -f 'pbmplus.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pbmplus.h'\" else echo shar: Extracting \"'pbmplus.h'\" \(4252 characters\) sed "s/^X//" >'pbmplus.h' <<'END_OF_FILE' X/* pbmplus.h - header file for PBM, PGM, PPM, and PNM X*/ X X#ifndef _PBMPLUS_H_ X#define _PBMPLUS_H_ X X#if ! ( defined(BSD) || defined(SYSV) ) X/* CONFIGURE: If your system is >= 4.2BSD, set the BSD option; if you're a X** System V site, set the SYSV option. If you're an ANSI C site, you're X** probably better off setting SYSV. This mostly has to do with string X** functions. X*/ X#define BSD X/* #define SYSV */ X#endif X X/* CONFIGURE: If you want to enable writing "raw" files, set this option. X** "Raw" files are smaller, and much faster to read and write, but you X** must have a filesystem that allows all 256 ASCII characters to be read X** and written. Also, you will no longer be able to mail P?M files without X** using uuencode or the equivalent. Note that reading "raw" files works X** whether writing is enabled or not. X*/ X#define PBMPLUS_RAWBITS X X/* CONFIGURE: On some systems, the putc() macro is broken and will return X** EOF when you write out a 255. For example, ULTRIX does this. This X** only matters if you have defined RAWBITS. To test whether your system X** is broken this way, go ahead and compile things with RAWBITS defined, X** and then try "pbmmake -b 8 1 > file". If it works, fine. If not, X** define BROKENPUTC1 and try again - if that works, good. Otherwise, X** BROKENPUTC2 is guaranteed to work, although it's 1.9 times slower. X*/ X/* #define PBMPLUS_BROKENPUTC1 */ X/* #define PBMPLUS_BROKENPUTC2 */ X X#ifdef PBMPLUS_BROKENPUTC1 X#undef putc X/* This is a fixed version of putc() that should work on most Unix systems. */ X#define putc(x,p) (--(p)->_cnt>=0? ((int)(unsigned char)(*(p)->_ptr++=(unsigned char)(x))) : _flsbuf((unsigned char)(x),p)) X#endif /*PBMPLUS_BROKENPUTC1*/ X#ifdef PBMPLUS_BROKENPUTC2 X#undef putc X/* For this one, putc() becomes a function, defined in pbm/libpbm1.c. */ X#endif /*PBMPLUS_BROKENPUTC2*/ X X/* CONFIGURE: PGM can store gray values as either bytes or shorts. For most X** applications, bytes will be big enough, and the memory savings can be X** substantial. However, if you need more than 8 bits of resolution, then X** define this symbol. X** X** If you are not making PGM, you can ignore this. X*/ X/* #define PGM_BIGGRAYS */ X X/* CONFIGURE: Normally, PPM handles a pixel as a struct of three grays. X** It can also be configured to pack the three values into a single longword, X** 10 bits each. If you have configured PGM with the PGM_BIGGRAYS option X** (store grays as shorts), AND you don't need more than 10 bits for each X** color component, AND you care more about memory use than speed, then X** this option might be a win. Under these circumstances it will make X** some of the programs use 1.5 times less space, but all of the programs X** will run about 1.4 times slower. X** X** If you are not using PGM_BIGGRAYS, then this option is useless -- it X** doesn't save any space, but it still slows things down. X** X** If you are not making PPM, you can ignore this. X*/ X/* #define PPM_PACKCOLORS */ X X/* CONFIGURE: uncomment this to enable debugging checks. */ X/* #define DEBUG */ X X/* End of configurable definitions. */ X X/* Variable-sized arrays definitions. */ X Xchar **pm_allocarray( /* int cols, int rows, size */ ); Xchar *pm_allocrow( /* int cols, size */); Xvoid pm_freearray( /* char **its, int rows */ ); Xvoid pm_freerow( /* char *itrow */ ); X X/* Error handling definitions. */ X Xextern char *pm_progname; /* every main() must assign argv[0] to this */ Xvoid pm_message( /* char *fmt, arg, arg, arg, arg, arg */ ); Xvoid pm_error( /* char *fmt, arg, arg, arg, arg, arg */ ); /* doesn't return */ Xvoid pm_perror( /* char *reason */ ); /* doesn't return */ Xvoid pm_usage( /* char *usage */ ); /* doesn't return */ X X/* File open/close that handles "-" as stdin and checks errors. */ X XFILE *pm_openr( /* char *name */ ); Xvoid pm_close( /* FILE *f */ ); X X/* Endian I/O. */ X Xint pm_readbigshort( /* FILE *in, short *sP */ ); Xint pm_writebigshort( /* FILE *out, short s */ ); Xint pm_readbiglong( /* FILE *in, long *lP */ ); Xint pm_writebiglong( /* FILE *out, long l */ ); Xint pm_readlittleshort( /* FILE *in, short *sP */ ); Xint pm_writelittleshort( /* FILE *out, short s */ ); Xint pm_readlittlelong( /* FILE *in, long *lP */ ); Xint pm_writelittlelong( /* FILE *out, long l */ ); X X#endif /*_PBMPLUS_H_*/ END_OF_FILE echo shar: NEWLINE appended to \"'pbmplus.h'\" if test 4253 -ne `wc -c <'pbmplus.h'`; then echo shar: \"'pbmplus.h'\" unpacked with wrong size! fi # end of 'pbmplus.h' fi if test -f 'pgm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pgm.h'\" else echo shar: Extracting \"'pgm.h'\" \(1323 characters\) sed "s/^X//" >'pgm.h' <<'END_OF_FILE' 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_*/ END_OF_FILE echo shar: NEWLINE appended to \"'pgm.h'\" if test 1324 -ne `wc -c <'pgm.h'`; then echo shar: \"'pgm.h'\" unpacked with wrong size! fi # end of 'pgm.h' fi if test -f 'ppm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ppm.h'\" else echo shar: Extracting \"'ppm.h'\" \(2446 characters\) sed "s/^X//" >'ppm.h' <<'END_OF_FILE' X/* ppm.h - header file for libppm portable pixelmap library X*/ X X#ifndef _PPM_H_ X#define _PPM_H_ X X#include "pgm.h" X Xtypedef gray pixval; X X#ifdef PPM_PACKCOLORS X X#define PPM_MAXMAXVAL 1023 Xtypedef unsigned long pixel; X#define PPM_GETR(p) (((p) & 0x3ff00000) >> 20) X#define PPM_GETG(p) (((p) & 0xffc00) >> 10) X#define PPM_GETB(p) ((p) & 0x3ff) X#define PPM_ASSIGN(p,red,grn,blu) (p) = ((pixel) (red) << 20) | ((pixel) (grn) << 10) | (pixel) (blu) X#define PPM_EQUAL(p,q) ((p) == (q)) X X#else /*PPM_PACKCOLORS*/ X X#define PPM_MAXMAXVAL PGM_MAXMAXVAL Xtypedef struct X { X pixval r, g, b; X } pixel; X#define PPM_GETR(p) ((p).r) X#define PPM_GETG(p) ((p).g) X#define PPM_GETB(p) ((p).b) X#define PPM_ASSIGN(p,red,grn,blu) do { (p).r = (red); (p).g = (grn); (p).b = (blu); } while ( 0 ) X#define PPM_EQUAL(p,q) ( (p).r == (q).r && (p).g == (q).g && (p).b == (q).b ) X X#endif /*PPM_PACKCOLORS*/ X X/* Declarations of routines. */ X X#define ppm_allocarray( cols, rows ) ((pixel **) pm_allocarray( cols, rows, sizeof(pixel) )) X#define ppm_allocrow( cols ) ((pixel *) pm_allocrow( cols, sizeof(pixel) )) X#define ppm_freearray( pixelrow, rows ) pm_freearray( pixelrow, rows ) X#define ppm_freerow( pixelrow ) pm_freerow( pixelrow ) X Xpixel **ppm_readppm( /* FILE *file, int *colsP, int *rowsP, pixval *maxvalP */ ); Xvoid ppm_readppminit( /* FILE *file, int *colsP, int *rowsP, pixval *maxvalP, int *formatP */ ); Xvoid ppm_readppmrow( /* FILE *file, pixel *pixelrow, int cols, pixval maxval, int format */ ); X Xvoid ppm_writeppm( /* FILE *file, pixel **pixels, int cols, int rows, pixval maxval */ ); Xvoid ppm_writeppminit( /* FILE *file, int cols, int rows, pixval maxval */ ); Xvoid ppm_writeppmrow( /* FILE *file, pixel *pixelrow, int cols, pixval maxval */ ); X Xpixel ppm_backgroundpixel( /* pixel **pixels, int cols, int rows */ ); X Xextern pixval ppm_pbmmaxval; X/* This is the maxval used when a PPM program reads a PBM file. Normally X** it is 1; however, for some programs, a larger value gives better results X*/ X X/* Color scaling macro -- to make writing ppmtowhatever easier. */ X X#define PPM_CSCALE(newp,p,oldmaxval,newmaxval) \ X PPM_ASSIGN( (newp), \ X (int) PPM_GETR(p) * (newmaxval) / (oldmaxval), \ X (int) PPM_GETG(p) * (newmaxval) / (oldmaxval), \ X (int) PPM_GETB(p) * (newmaxval) / (oldmaxval) ) X X/* Luminance macro. */ X X#define PPM_LUMIN(p) ( 0.299 * PPM_GETR(p) + 0.587 * PPM_GETG(p) + 0.114 * PPM_GETB(p) ) X X#endif /*_PPM_H_*/ END_OF_FILE echo shar: NEWLINE appended to \"'ppm.h'\" if test 2447 -ne `wc -c <'ppm.h'`; then echo shar: \"'ppm.h'\" unpacked with wrong size! fi # end of 'ppm.h' fi if test -f 'ppmconvol.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ppmconvol.c'\" else echo shar: Extracting \"'ppmconvol.c'\" \(4498 characters\) sed "s/^X//" >'ppmconvol.c' <<'END_OF_FILE' X/* ppmconvol.c - general MxN convolution on a portable pixmap 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 "ppm.h" X Xmain( argc, argv ) Xint argc; Xchar *argv[]; X { X FILE *cifd, *ifd; X pixel **cpixels, **pixelbuf, *outputrow, p; X int argn, crows, ccols, ccolso2, crowso2, rows, cols, format, crow, row; X register int ccol, col; X pixval cmaxval, maxval, r, g, b; X float **rweights, **gweights, **bweights, rsum, gsum, bsum; X char *usage = "<convolutionfile> [ppmfile]"; X X pm_progname = argv[0]; X X argn = 1; X X if ( argn == argc ) X pm_usage( usage ); X cifd = pm_openr( argv[argn] ); X argn++; 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 ppm_pbmmaxval = 255; /* use larger value for better results */ X X /* Read in the convolution matrix. */ X cpixels = ppm_readppm( cifd, &ccols, &crows, &cmaxval ); X pm_close( cifd ); X if ( ccols % 2 != 1 || crows % 2 != 1 ) X pm_error( X "the convolution matrix must have an odd number of rows and columns", X 0,0,0,0,0 ); X ccolso2 = ccols / 2; X crowso2 = crows / 2; X X ppm_readppminit( ifd, &cols, &rows, &maxval, &format ); X if ( cols < ccols || rows < crows ) X pm_error( X "the image is smaller than the convolution matrix", 0,0,0,0,0 ); X X /* Set up the normalized weights. */ X rweights = (float **) pm_allocarray( ccols, crows, sizeof(float) ); X gweights = (float **) pm_allocarray( ccols, crows, sizeof(float) ); X bweights = (float **) pm_allocarray( ccols, crows, sizeof(float) ); X rsum = gsum = bsum = 0; X for ( crow = 0; crow < crows; crow++ ) X for ( ccol = 0; ccol < ccols; ccol++ ) X { X rsum += rweights[crow][ccol] = X ( PPM_GETR(cpixels[crow][ccol]) * 2.0 / cmaxval - 1.0 ); X gsum += gweights[crow][ccol] = X ( PPM_GETG(cpixels[crow][ccol]) * 2.0 / cmaxval - 1.0 ); X bsum += bweights[crow][ccol] = X ( PPM_GETB(cpixels[crow][ccol]) * 2.0 / cmaxval - 1.0 ); X } X if ( rsum < 0.9 || rsum > 1.1 || gsum < 0.9 || gsum > 1.1 || X bsum < 0.9 || bsum > 1.1 ) X fprintf( stderr, "WARNING: this convolution matrix is biased.\n" ); X X /* Allocate space for one convolution-matrix's worth of rows, plus X ** a row output buffer. */ X pixelbuf = ppm_allocarray( cols, crows ); X outputrow = ppm_allocrow( cols ); X X ppm_writeppminit( stdout, cols, rows, maxval ); X X /* Read in one convolution-matrix's worth of image, less one row. */ X for ( row = 0; row < crows - 1; row++ ) X { X ppm_readppmrow( ifd, pixelbuf[row], cols, maxval, format ); X /* Write out just the part we're not going to convolve. */ X if ( row < crowso2 ) X ppm_writeppmrow( stdout, pixelbuf[row], cols, maxval ); X } X X /* Now the rest of the image -- read in the row at the end of X ** pixelbuf, and convolve and write out the row in the middle. X */ X for ( ; row < rows; row++ ) X { X ppm_readppmrow( ifd, pixelbuf[row % crows], cols, maxval, format ); X X for ( col = 0; col < cols; col++ ) X if ( col < ccolso2 || col >= cols - ccolso2 ) X outputrow[col] = pixelbuf[(row - crowso2) % crows][col]; X else X { X rsum = gsum = bsum = 0.0; X for ( crow = 0; crow < crows; crow++ ) X for ( ccol = 0; ccol < ccols; ccol++ ) X { X p = pixelbuf[(row+1+crow) % crows][col-ccolso2+ccol]; X rsum += PPM_GETR( p ) * rweights[crow][ccol]; X gsum += PPM_GETG( p ) * gweights[crow][ccol]; X bsum += PPM_GETB( p ) * bweights[crow][ccol]; X } X if ( rsum < 0.0 ) r = 0; X else if ( rsum > maxval ) r = maxval; X else r = rsum + 0.5; X if ( gsum < 0.0 ) g = 0; X else if ( gsum > maxval ) g = maxval; X else g = gsum + 0.5; X if ( bsum < 0.0 ) b = 0; X else if ( bsum > maxval ) b = maxval; X else b = bsum + 0.5; X PPM_ASSIGN( outputrow[col], r, g, b ); X } X X ppm_writeppmrow( stdout, outputrow, cols, maxval ); X } X pm_close( ifd ); X X /* Now write out the remaining unconvolved rows in pixelbuf. */ X for ( ; row < rows + crowso2; row++ ) X ppm_writeppmrow( X stdout, pixelbuf[(row - crowso2) % crows], cols, maxval ); X X exit( 0 ); X } END_OF_FILE echo shar: NEWLINE appended to \"'ppmconvol.c'\" if test 4499 -ne `wc -c <'ppmconvol.c'`; then echo shar: \"'ppmconvol.c'\" unpacked with wrong size! fi # end of 'ppmconvol.c' fi echo shar: End of shell archive. exit 0 marty ARPA: leisner.henr@xerox.com GV: leisner.henr NS: leisner:wbst139:xerox UUCP: hplabs!arisia!leisner