PBMPLUS, part 13 of 18

Jef Poskanzer pokey at well.UUCP
Thu Sep 14 21:25:51 AEST 1989


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	ppm/ppmpat.1
#	ppm/ppmconvol.c
#	ppm/ppmconvol.1
#	ppm/ppmtopgm.c
#	ppm/ppmtopgm.1
#	ppm/ppmtorast.c
#	ppm/ppmtorast.1
#	ppm/rasttoppm.c
#	ppm/rasttoppm.1
# This archive created: Thu Sep 14 03:43:45 1989
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmpat.1'" '(1746 characters)'
if test -f 'ppm/ppmpat.1'
then
	echo shar: will not over-write existing file "'ppm/ppmpat.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmpat.1'
X.TH pbmpat 1 "04 September 1989"
X.SH NAME
Xpbmpat - make a pretty pixmap
X.SH SYNOPSIS
Xpbmpat -gingham2|-g2|-gingham3|-g3|-madras|-tartan|-poles|-squig|camo|-anticamo <width> <height>
X.SH DESCRIPTION
XProduces a portable pixmap of the specified width and height,
Xwith a pattern in it.
XThe different flags specify various different pattern types:
X.IP -gingham2 10
XA gingham check pattern.  Can be tiled.
X.IP -gingham3 10
XA slightly more complicated gingham.  Can be tiled.
X.IP -madras 10
XA madras plaid.  Can be tiled.
X.IP -tartan 10
XA tartan plaid.  Can be tiled.
X.IP -poles 10
XColor gradients centered on randomly-placed poles.
XMay need to be run through ppmquant.
X.IP -squig 10
XSquiggley tubular pattern.  Can be tiled.
XMay need to be run through ppmquant.
X.IP -camo 10
XCamouflage pattern.
XMay need to be run through ppmquant.
X.IP -anticamo 10
XAnti-camouflage pattern -- like -camo, but ultra-bright colors.
XMay need to be run through ppmquant.
X.PP
XThis program is mainly to demonstrate use of the ppmdraw routines, a
Xsimple but powerful drawing library.
XSee the ppmdraw.h include file for more info on using these routines.
X.PP
XAll flags can be abbreviated to their shortest unique prefix.
X.SH REFERENCES
XSome of the patterns are from "Designer's Guide to Color 3" by Jeanne Allen.
X.SH "SEE ALSO"
Xppmtile(1), ppmquant(1), 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 1746 -ne "`wc -c < 'ppm/ppmpat.1'`"
then
	echo shar: error transmitting "'ppm/ppmpat.1'" '(should have been 1746 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmconvol.c'" '(4498 characters)'
if test -f 'ppm/ppmconvol.c'
then
	echo shar: will not over-write existing file "'ppm/ppmconvol.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmconvol.c'
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    }
SHAR_EOF
if test 4498 -ne "`wc -c < 'ppm/ppmconvol.c'`"
then
	echo shar: error transmitting "'ppm/ppmconvol.c'" '(should have been 4498 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmconvol.1'" '(1506 characters)'
if test -f 'ppm/ppmconvol.1'
then
	echo shar: will not over-write existing file "'ppm/ppmconvol.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmconvol.1'
X.TH ppmconvol 1 "14 April 1989"
X.SH NAME
Xppmconvol - general MxN convolution on a portable pixmap
X.SH SYNOPSIS
Xppmconvol <convolutionfile> [ppmfile]
X.SH DESCRIPTION
XReads two portable pixmaps as input.
XConvolves the second using the first,
Xand writes a portable pixmap as output.
X.PP
XConvolution means replacing each pixel with a weighted average of the
Xnearby pixels.  The weights and the area to average are determined by
Xthe convolution matrix.
XThe unsigned numbers in the convolution file are offset by -maxval/2 to
Xmake signed numbers, and then normalized, so the actual values in the
Xconvolution file are only relative.
X.PP
XHere is a sample convolution file;
Xit does a simple average of the immediate neighbors, resulting
Xin a smoothed image:
X.nf
X    P1
X    3 3
X    1 1 1
X    1 1 1
X    1 1 1
X.fi
X.PP
XThe convolution file will usually be a bitmap or graymap instead of a pixmap,
Xso that the same convolution gets applied to each color component.
XHowever, if you want to use a pixmap and do a different convolution to
Xdifferent colors, you can certainly do that.
X.SH "SEE ALSO"
Xppm(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 1506 -ne "`wc -c < 'ppm/ppmconvol.1'`"
then
	echo shar: error transmitting "'ppm/ppmconvol.1'" '(should have been 1506 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmtopgm.c'" '(7454 characters)'
if test -f 'ppm/ppmtopgm.c'
then
	echo shar: will not over-write existing file "'ppm/ppmtopgm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmtopgm.c'
X/* ppmtopgm.c - convert a portable pixmap to a portable graymap
X**
X** Copyright (C) 1989 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "ppm.h"
X#include "pgm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    pixel *pixelrow;
X    register pixel *pP;
X    gray *grayrow;
X    register gray *gP;
X    int rows, cols, format, row;
X    register int col;
X    pixval maxval;
X
X    /* Lookup tables for fast RGB -> luminance calculation. */
X    static int times77[256] = {
X	    0,    77,   154,   231,   308,   385,   462,   539,
X	  616,   693,   770,   847,   924,  1001,  1078,  1155,
X	 1232,  1309,  1386,  1463,  1540,  1617,  1694,  1771,
X	 1848,  1925,  2002,  2079,  2156,  2233,  2310,  2387,
X	 2464,  2541,  2618,  2695,  2772,  2849,  2926,  3003,
X	 3080,  3157,  3234,  3311,  3388,  3465,  3542,  3619,
X	 3696,  3773,  3850,  3927,  4004,  4081,  4158,  4235,
X	 4312,  4389,  4466,  4543,  4620,  4697,  4774,  4851,
X	 4928,  5005,  5082,  5159,  5236,  5313,  5390,  5467,
X	 5544,  5621,  5698,  5775,  5852,  5929,  6006,  6083,
X	 6160,  6237,  6314,  6391,  6468,  6545,  6622,  6699,
X	 6776,  6853,  6930,  7007,  7084,  7161,  7238,  7315,
X	 7392,  7469,  7546,  7623,  7700,  7777,  7854,  7931,
X	 8008,  8085,  8162,  8239,  8316,  8393,  8470,  8547,
X	 8624,  8701,  8778,  8855,  8932,  9009,  9086,  9163,
X	 9240,  9317,  9394,  9471,  9548,  9625,  9702,  9779,
X	 9856,  9933, 10010, 10087, 10164, 10241, 10318, 10395,
X	10472, 10549, 10626, 10703, 10780, 10857, 10934, 11011,
X	11088, 11165, 11242, 11319, 11396, 11473, 11550, 11627,
X	11704, 11781, 11858, 11935, 12012, 12089, 12166, 12243,
X	12320, 12397, 12474, 12551, 12628, 12705, 12782, 12859,
X	12936, 13013, 13090, 13167, 13244, 13321, 13398, 13475,
X	13552, 13629, 13706, 13783, 13860, 13937, 14014, 14091,
X	14168, 14245, 14322, 14399, 14476, 14553, 14630, 14707,
X	14784, 14861, 14938, 15015, 15092, 15169, 15246, 15323,
X	15400, 15477, 15554, 15631, 15708, 15785, 15862, 15939,
X	16016, 16093, 16170, 16247, 16324, 16401, 16478, 16555,
X	16632, 16709, 16786, 16863, 16940, 17017, 17094, 17171,
X	17248, 17325, 17402, 17479, 17556, 17633, 17710, 17787,
X	17864, 17941, 18018, 18095, 18172, 18249, 18326, 18403,
X	18480, 18557, 18634, 18711, 18788, 18865, 18942, 19019,
X	19096, 19173, 19250, 19327, 19404, 19481, 19558, 19635 };
X    static int times150[256] = {
X	    0,   150,   300,   450,   600,   750,   900,  1050,
X	 1200,  1350,  1500,  1650,  1800,  1950,  2100,  2250,
X	 2400,  2550,  2700,  2850,  3000,  3150,  3300,  3450,
X	 3600,  3750,  3900,  4050,  4200,  4350,  4500,  4650,
X	 4800,  4950,  5100,  5250,  5400,  5550,  5700,  5850,
X	 6000,  6150,  6300,  6450,  6600,  6750,  6900,  7050,
X	 7200,  7350,  7500,  7650,  7800,  7950,  8100,  8250,
X	 8400,  8550,  8700,  8850,  9000,  9150,  9300,  9450,
X	 9600,  9750,  9900, 10050, 10200, 10350, 10500, 10650,
X	10800, 10950, 11100, 11250, 11400, 11550, 11700, 11850,
X	12000, 12150, 12300, 12450, 12600, 12750, 12900, 13050,
X	13200, 13350, 13500, 13650, 13800, 13950, 14100, 14250,
X	14400, 14550, 14700, 14850, 15000, 15150, 15300, 15450,
X	15600, 15750, 15900, 16050, 16200, 16350, 16500, 16650,
X	16800, 16950, 17100, 17250, 17400, 17550, 17700, 17850,
X	18000, 18150, 18300, 18450, 18600, 18750, 18900, 19050,
X	19200, 19350, 19500, 19650, 19800, 19950, 20100, 20250,
X	20400, 20550, 20700, 20850, 21000, 21150, 21300, 21450,
X	21600, 21750, 21900, 22050, 22200, 22350, 22500, 22650,
X	22800, 22950, 23100, 23250, 23400, 23550, 23700, 23850,
X	24000, 24150, 24300, 24450, 24600, 24750, 24900, 25050,
X	25200, 25350, 25500, 25650, 25800, 25950, 26100, 26250,
X	26400, 26550, 26700, 26850, 27000, 27150, 27300, 27450,
X	27600, 27750, 27900, 28050, 28200, 28350, 28500, 28650,
X	28800, 28950, 29100, 29250, 29400, 29550, 29700, 29850,
X	30000, 30150, 30300, 30450, 30600, 30750, 30900, 31050,
X	31200, 31350, 31500, 31650, 31800, 31950, 32100, 32250,
X	32400, 32550, 32700, 32850, 33000, 33150, 33300, 33450,
X	33600, 33750, 33900, 34050, 34200, 34350, 34500, 34650,
X	34800, 34950, 35100, 35250, 35400, 35550, 35700, 35850,
X	36000, 36150, 36300, 36450, 36600, 36750, 36900, 37050,
X	37200, 37350, 37500, 37650, 37800, 37950, 38100, 38250 };
X    static int times29[256] = {
X	    0,    29,    58,    87,   116,   145,   174,   203,
X	  232,   261,   290,   319,   348,   377,   406,   435,
X	  464,   493,   522,   551,   580,   609,   638,   667,
X	  696,   725,   754,   783,   812,   841,   870,   899,
X	  928,   957,   986,  1015,  1044,  1073,  1102,  1131,
X	 1160,  1189,  1218,  1247,  1276,  1305,  1334,  1363,
X	 1392,  1421,  1450,  1479,  1508,  1537,  1566,  1595,
X	 1624,  1653,  1682,  1711,  1740,  1769,  1798,  1827,
X	 1856,  1885,  1914,  1943,  1972,  2001,  2030,  2059,
X	 2088,  2117,  2146,  2175,  2204,  2233,  2262,  2291,
X	 2320,  2349,  2378,  2407,  2436,  2465,  2494,  2523,
X	 2552,  2581,  2610,  2639,  2668,  2697,  2726,  2755,
X	 2784,  2813,  2842,  2871,  2900,  2929,  2958,  2987,
X	 3016,  3045,  3074,  3103,  3132,  3161,  3190,  3219,
X	 3248,  3277,  3306,  3335,  3364,  3393,  3422,  3451,
X	 3480,  3509,  3538,  3567,  3596,  3625,  3654,  3683,
X	 3712,  3741,  3770,  3799,  3828,  3857,  3886,  3915,
X	 3944,  3973,  4002,  4031,  4060,  4089,  4118,  4147,
X	 4176,  4205,  4234,  4263,  4292,  4321,  4350,  4379,
X	 4408,  4437,  4466,  4495,  4524,  4553,  4582,  4611,
X	 4640,  4669,  4698,  4727,  4756,  4785,  4814,  4843,
X	 4872,  4901,  4930,  4959,  4988,  5017,  5046,  5075,
X	 5104,  5133,  5162,  5191,  5220,  5249,  5278,  5307,
X	 5336,  5365,  5394,  5423,  5452,  5481,  5510,  5539,
X	 5568,  5597,  5626,  5655,  5684,  5713,  5742,  5771,
X	 5800,  5829,  5858,  5887,  5916,  5945,  5974,  6003,
X	 6032,  6061,  6090,  6119,  6148,  6177,  6206,  6235,
X	 6264,  6293,  6322,  6351,  6380,  6409,  6438,  6467,
X	 6496,  6525,  6554,  6583,  6612,  6641,  6670,  6699,
X	 6728,  6757,  6786,  6815,  6844,  6873,  6902,  6931,
X	 6960,  6989,  7018,  7047,  7076,  7105,  7134,  7163,
X	 7192,  7221,  7250,  7279,  7308,  7337,  7366,  7395 };
X
X    pm_progname = argv[0];
X
X    if ( argc > 2 )
X	pm_usage( "[ppmfile]" );
X
X    if ( argc == 2 )
X	ifd = pm_openr( argv[1] );
X    else
X	ifd = stdin;
X
X    ppm_readppminit( ifd, &cols, &rows, &maxval, &format );
X    pgm_writepgminit( stdout, cols, rows, maxval );
X    pixelrow = ppm_allocrow( cols );
X    grayrow = pgm_allocrow( cols );
X
X    for ( row = 0; row < rows; row++ )
X	{
X	ppm_readppmrow( ifd, pixelrow, cols, maxval, format );
X	if ( maxval <= 255 )
X	    /* Use fast approximation to 0.299 r + 0.587 g + 0.114 b. */
X	    for ( col = 0, pP = pixelrow, gP = grayrow;
X		  col < cols;
X		  col++, pP++, gP++ )
X		*gP = (gray)
X		    ( ( times77[PPM_GETR( *pP )] + times150[PPM_GETG( *pP )] +
X		        times29[PPM_GETB( *pP )] ) >> 8 );
X	else
X	    /* Can't use fast approximation, so fall back on floats. */
X	    for ( col = 0, pP = pixelrow, gP = grayrow;
X		  col < cols;
X		  col++, pP++, gP++ )
X		*gP = (gray) ( PPM_LUMIN( *pP ) + 0.5 );
X	pgm_writepgmrow( stdout, grayrow, cols, maxval );
X	}
X
X    pm_close( ifd );
X
X    exit( 0 );
X    }
SHAR_EOF
if test 7454 -ne "`wc -c < 'ppm/ppmtopgm.c'`"
then
	echo shar: error transmitting "'ppm/ppmtopgm.c'" '(should have been 7454 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmtopgm.1'" '(1028 characters)'
if test -f 'ppm/ppmtopgm.1'
then
	echo shar: will not over-write existing file "'ppm/ppmtopgm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmtopgm.1'
X.TH ppmtopgm 1 "23 December 1988"
X.SH NAME
Xppmtopgm - convert a portable pixmap into a portable graymap
X.SH SYNOPSIS
Xppmtopgm [ppmfile]
X.SH DESCRIPTION
XReads a portable pixmap as input.
XProduces a portable graymap as output.
XThe quantization formula used is .299 r + .587 g + .114 b.
X.PP
XNote that there is no pgmtoppm converter because any ppm program can
Xread pgm (and pbm) files automagically.
X.SH QUOTE
X.nf
XCold-hearted orb that rules the night
XRemoves the colors from our sight
XRed is gray, and yellow white
XBut we decide which is right
XAnd which is a quantization error.
X.fi
X.SH "SEE ALSO"
Xppm(5), pgm(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 1028 -ne "`wc -c < 'ppm/ppmtopgm.1'`"
then
	echo shar: error transmitting "'ppm/ppmtopgm.1'" '(should have been 1028 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmtorast.c'" '(7995 characters)'
if test -f 'ppm/ppmtorast.c'
then
	echo shar: will not over-write existing file "'ppm/ppmtorast.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmtorast.c'
X/* ppmtorast.c - read a portable pixmap and produce a Sun rasterfile
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#include "ppmcmap.h"
X
X/* This program compiles only on Suns. */
X#include <pixrect/pixrect_hs.h>
X
X#define MAXCOLORS 256
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    pixel **pixels, *pixelrow, onepixel, p;
X    register pixel *pP;
X    colorhist_vector chv;
X    colorhash_table cht;
X    int argn, pr_type, xflag, rows, cols, i;
X    int depth, colors, linesize, row;
X    register int col;
X    pixval maxval;
X    struct pixrect *pr;
X    colormap_t *pr_colormapP;
X    short *data, s;
X    register short *sp;
X    int bitcount, bytenum, color;
X    colormap_t *make_pr_colormap();
X    char *usage = "[-s] [-x] [ppmfile]";
X
X    pm_progname = argv[0];
X
X    argn = 1;
X    pr_type = RT_BYTE_ENCODED;
X    xflag = 0;
X
X    while ( argn < argc && argv[argn][0] == '-' )
X	{
X	if ( ( argv[argn][1] == 's' || argv[argn][1] == 'S' ) &&
X	     argv[argn][2] == '\0' )
X	    {
X	    pr_type = RT_STANDARD;
X	    argn++;
X	    }
X	else if ( ( argv[argn][1] == 'x' || argv[argn][1] == 'X' ) &&
X	     argv[argn][2] == '\0' )
X	    {
X	    xflag = 1;
X	    argn++;
X	    }
X	else
X	    pm_usage( usage );
X	}
X
X    if ( argn != argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( usage );
X
X    pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
X
X    pm_close( ifd );
X
X    /* Figure out the proper depth and colormap. */
X    fprintf( stderr, "(Computing colormap..." );
X    fflush( stderr );
X    chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
X    if ( chv == (colorhist_vector) 0 )
X	{
X	fprintf(
X	    stderr, "  Too many colors - proceeding to write a 24-bit\n" );
X	fprintf(
X	    stderr, "non-mapped rasterfile.  If you want 8 bits, try running the\n" );
X	fprintf( stderr, "pixmap through 'ppmquant 256'.)\n" );
X	depth = 24;
X	pr_colormapP = (colormap_t *) 0;
X	}
X    else
X	{
X	fprintf( stderr, "  Done.  %d colors found.)\n", colors );
X
X	if ( maxval != 255 )
X	    for ( i = 0; i < colors; i++ )
X		PPM_CSCALE( chv[i].color, chv[i].color, maxval, 255 );
X
X	if ( xflag )
X	    {
X	    /* Force black to slot 0 and white to slot 1, if possible. */
X	    PPM_ASSIGN( p, 0, 0, 0 );
X	    ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
X	    PPM_ASSIGN( p, 255, 255, 255 );
X	    ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
X	    }
X	else
X	    {
X	    /* Force white to slot 0 and black to slot 1, if possible. */
X	    PPM_ASSIGN( p, 255, 255, 255 );
X	    ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
X	    PPM_ASSIGN( p, 0, 0, 0 );
X	    ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
X	    }
X
X	/* Now turn the ppm colormap into the appropriate Sun colormap. */
X	if ( colors == 2 )
X	    {
X	    /* Monochrome - no problem. */
X	    depth = 1;
X	    if ( PPM_GETR( chv[0].color ) == 255 &&
X		 PPM_GETG( chv[0].color ) == 255 &&
X		 PPM_GETB( chv[0].color ) == 255 &&
X	         PPM_GETR( chv[1].color ) == 0 &&
X		 PPM_GETG( chv[1].color ) == 0 &&
X		 PPM_GETB( chv[1].color ) == 0 )
X		{
X		/* Default colormap. */
X		pr_colormapP = (colormap_t *) 0;
X		}
X	    else
X		pr_colormapP = make_pr_colormap( chv, colors );
X	    onepixel = chv[1].color;
X	    }
X	else
X	    {
X	    depth = 8;
X	    pr_colormapP = make_pr_colormap( chv, colors );
X	    cht = ppm_colorhisttocolorhash( chv, colors );
X	    }
X	ppm_freecolorhist( chv );
X	}
X    if ( maxval > 255 )
X	fprintf(
X	    stderr, "(Maxval is not 255 -- automatically rescaling colors.)\n");
X    
X    /* Allocate space for the Sun-format image. */
X    if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect *) 0 )
X	pm_error( "unable to create new pixrect", 0,0,0,0,0 );
X    data = ( (struct mpr_data *) pr->pr_data )->md_image;
X    linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
X
X    /* And compute the Sun image.  The variables at this point are:
X    **   chv is null or not
X    **   depth is 1, 8, or 24
X    */
X    for ( row = 0; row < rows; row++ )
X	{
X	pixelrow = pixels[row];
X	sp = data;
X	switch ( depth )
X	    {
X	    case 1:
X	    bitcount = 15;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( maxval != 255 )
X		    PPM_CSCALE( *pP, *pP, maxval, 255 );
X		if ( PPM_EQUAL( *pP, onepixel ) )
X		    *sp |= 1 << bitcount;
X		bitcount--;
X		if ( bitcount < 0 )
X		    {
X		    sp++;
X		    bitcount = 15;
X		    }
X		}
X	    break;
X
X	    case 8:
X	    /* If depth is 8, we have a valid cht (yes, t). */
X	    bytenum = 0;
X	    s = 0;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( maxval != 255 )
X		    PPM_CSCALE( *pP, *pP, maxval, 255 );
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    s = 0;
X		    }
X		color = ppm_lookupcolor( cht, *pP );
X		if ( color == -1 )
X		    pm_error(
X			"color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
X			row, col, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP) );
X		if ( bytenum == 0 )
X		    s = color << 8;
X		else
X		    {
X		    s += color;
X		    *sp = s;
X		    }
X		bytenum++;
X		}
X	    break;
X
X	    case 24:
X	    /* If depth is 24, we are guaranteed NOT to have a valid chv. */
X	    bytenum = 0;
X	    s = 0;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( maxval != 255 )
X		    PPM_CSCALE( *pP, *pP, maxval, 255 );
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    s = 0;
X		    }
X		if ( bytenum == 0 )
X		    s = PPM_GETR( *pP ) << 8;
X		else
X		    {
X		    s += PPM_GETR( *pP );
X		    *sp = s;
X		    }
X		bytenum++;
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    s = 0;
X		    }
X		if ( bytenum == 0 )
X		    s = PPM_GETG( *pP ) << 8;
X		else
X		    {
X		    s += PPM_GETG( *pP );
X		    *sp = s;
X		    }
X		bytenum++;
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    s = 0;
X		    }
X		if ( bytenum == 0 )
X		    s = PPM_GETB( *pP ) << 8;
X		else
X		    {
X		    s += PPM_GETB( *pP );
X		    *sp = s;
X		    }
X		bytenum++;
X		}
X	    break;
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	data += linesize / sizeof(short);
X	}
X
X#ifdef sun386
X    /* Force a flip to 80386 format. */
X    ( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
X    pr_flip( pr );
X#endif sun386
X
X    /* Finally, write the sucker out. */
X    pr_dump( pr, stdout, pr_colormapP, pr_type, 0 );
X
X    exit( 0 );
X    }
X
Xcolormap_t *
Xmake_pr_colormap( chv, colors )
Xcolorhist_vector chv;
Xint colors;
X    {
X    colormap_t *pr_colormapP;
X    int i;
X
X    pr_colormapP = (colormap_t *) malloc( sizeof(colormap_t) );
X    if ( pr_colormapP == 0 )
X	pm_error( "out of memory", 0,0,0,0,0 );
X    pr_colormapP->type = RMT_EQUAL_RGB;
X    pr_colormapP->length = colors;
X    pr_colormapP->map[0] =
X	(unsigned char *) malloc( colors * sizeof(unsigned char) );
X    pr_colormapP->map[1] =
X	(unsigned char *) malloc( colors * sizeof(unsigned char) );
X    pr_colormapP->map[2] =
X	(unsigned char *) malloc( colors * sizeof(unsigned char) );
X    if ( pr_colormapP->map[0] == 0 || pr_colormapP->map[1] == 0 ||
X	 pr_colormapP->map[2] == 0 )
X	pm_error( "out of memory", 0,0,0,0,0 );
X
X    for ( i = 0; i < colors; i++ )
X	{
X	pr_colormapP->map[0][i] = PPM_GETR( chv[i].color );
X	pr_colormapP->map[1][i] = PPM_GETG( chv[i].color );
X	pr_colormapP->map[2][i] = PPM_GETB( chv[i].color );
X	}
X
X    return pr_colormapP;
X    }
X
X#ifdef notdef
Xdump_map( chv, colors )
Xcolorhist_vector chv;
Xint colors;
X    {
X    int i;
X
X    for ( i = 0; i < colors; i++ )
X	fprintf(
X	    stderr, "%d: %d %d %d  (%d)\n", i, PPM_GETR(chv[i].color),
X	    PPM_GETG(chv[i].color), PPM_GETB(chv[i].color), chv[i].count );
X    }
X#endif notdef
SHAR_EOF
if test 7995 -ne "`wc -c < 'ppm/ppmtorast.c'`"
then
	echo shar: error transmitting "'ppm/ppmtorast.c'" '(should have been 7995 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/ppmtorast.1'" '(1662 characters)'
if test -f 'ppm/ppmtorast.1'
then
	echo shar: will not over-write existing file "'ppm/ppmtorast.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/ppmtorast.1'
X.TH ppmtorast 1 "31 March 1989"
X.SH NAME
Xppmtorast - convert a portable pixmap into a Sun raster file
X.SH SYNOPSIS
Xppmtorast [-s] [-x] [ppmfile]
X.SH DESCRIPTION
XReads a portable pixmap as input.
XProduces a Sun raster file as output.
XNOTE: since it uses Sun-specific include files and libraries, ppmtorast
Xwill compile only on Suns.
X.PP
XColor values in Sun raster files are eight bits wide, so ppmtorast will
Xautomatically scale colors to have a maxval of 255.
XAn extra ppmcscale step is not necessary.
X.PP
XThe -s flag forces the result to be in RT_STANDARD form; otherwise,
Xit defaults to RT_BYTE_ENCODED, which is smaller but, well, less standard.
X.PP
XThe -x flag has to do with the color map.
XNormally, ppmtorast attempts to rearrange or add to the colormap so
Xthat white is in slot 0 and black is in slot 1 -- the standard Sun
Xdefault colormap.
XHowever, if you are doing screenloads from within Xsun, on a CG2,
Xyou want the opposite -- black in slot 0 and white in slot 1.
X(Why would you be doing something this silly?  Well, I have
Xsometimes found it useful.)
XSo, the -x flag sets this.
X.PP
XThe pbmtorast filter is significantly faster if your images are just
Xblack and white.
X.SH "SEE ALSO"
Xrasttoppm(1), ppm(5), pbmtorast(1), rasttopbm(1)
X.SH AUTHOR
XCopyright (C) 1989 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 1662 -ne "`wc -c < 'ppm/ppmtorast.1'`"
then
	echo shar: error transmitting "'ppm/ppmtorast.1'" '(should have been 1662 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/rasttoppm.c'" '(5285 characters)'
if test -f 'ppm/rasttoppm.c'
then
	echo shar: will not over-write existing file "'ppm/rasttoppm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/rasttoppm.c'
X/* rasttoppm.c - read a Sun raster file and produce 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
X/* This program compiles only on Suns. */
X#include <pixrect/pixrect_hs.h>
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    struct rasterfile header;
X    colormap_t pr_colormap;
X    struct pixrect *pr, *pr_load_image( );
X    register pixel *pixelrow, *pP;
X    int argn, rows, cols, depth, row, col, mask, bytenum;
X    pixval maxval, r, g, b;
X    pixel zero, one;
X    int linesize;
X    short *data, *sp;
X    unsigned char byte;
X
X    pm_progname = argv[0];
X
X    argn = 1;
X
X    if ( argn != argc )
X	{
X	ifd = pm_openr( argv[argn] );
X	argn++;
X	}
X    else
X	ifd = stdin;
X
X    if ( argn != argc )
X	pm_usage( "[rastfile]" );
X
X    /* Read in the raster file.  First the header. */
X    if ( pr_load_header( ifd, &header ) != 0 )
X	pm_error( "unable to read in raster file header", 0,0,0,0,0 );
X
X    cols = header.ras_width;
X    rows = header.ras_height;
X    depth = header.ras_depth;
X
X    if ( cols <= 0 )
X	pm_error( "invalid cols: %d", cols, 0,0,0,0 );
X    if ( rows <= 0 )
X	pm_error( "invalid rows: %d", rows, 0,0,0,0);
X
X    /* If there is a color map, read it. */
X    if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
X	{
X	if ( pr_load_colormap( ifd, &header, &pr_colormap ) != 0 )
X	    pm_error( "unable to skip colormap data", 0,0,0,0,0 );
X	}
X
X    /* Check the depth and color map. */
X    switch ( depth )
X	{
X	case 1:
X	if ( header.ras_maptype == RMT_NONE && header.ras_maplength == 0 )
X	    {
X	    maxval = 255;
X	    PPM_ASSIGN( zero, maxval, maxval, maxval );
X	    PPM_ASSIGN( one, 0, 0, 0 );
X	    }
X	else if ( header.ras_maptype == RMT_EQUAL_RGB &&
X		  header.ras_maplength == 6 )
X	    {
X	    maxval = 255;
X	    PPM_ASSIGN(
X		zero, pr_colormap.map[0][0], pr_colormap.map[1][0],
X		pr_colormap.map[2][0] );
X	    PPM_ASSIGN(
X		one, pr_colormap.map[0][1], pr_colormap.map[1][1],
X		pr_colormap.map[2][1] );
X	    }
X	else
X	    pm_error(
X		"this depth-1 rasterfile has a non-standard colormap - type %d length %d",
X		header.ras_maptype, header.ras_maplength, 0,0,0 );
X	break;
X
X	case 8:
X	if ( header.ras_maptype != RMT_EQUAL_RGB )
X	    pm_error(
X		"this depth-8 rasterfile has a non-standard colormap - type %d length %d",
X		header.ras_maptype, header.ras_maplength, 0,0,0 );
X	maxval = 255;
X	break;
X
X	case 24:
X	if ( header.ras_maptype != RMT_NONE || header.ras_maplength != 0 )
X	    pm_error(
X		"this depth-24 rasterfile has a colormap - can't handle it",
X		0,0,0,0,0 );
X	maxval = 255;
X	break;
X
X	default:
X	pm_error(
X	    "invalid depth: %d.  PPM can only handle depth 1, 8, or 24.",
X	    depth, 0,0,0,0 );
X	}
X
X    /* Now load the data.  The pixrect returned is a memory pixrect. */
X    if ( ( pr = pr_load_image( ifd, &header, NULL ) ) == NULL )
X	pm_error(
X	    "unable to read in the image from the raster file", 0,0,0,0,0 );
X
X#ifdef sun386
X    /* Force a flip to 680x0 format. */
X    pr_flip( pr );
X    ( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
X    pr_flip( pr );
X#endif
X
X    linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
X    data = ( (struct mpr_data *) pr->pr_data )->md_image;
X
X    pm_close( ifd );
X
X    /* Now write out the PPM. */
X    ppm_writeppminit( stdout, cols, rows, maxval );
X    pixelrow = ppm_allocrow( cols );
X
X    for ( row = 0; row < rows; row++ )
X	{
X	sp = data;
X	switch ( depth )
X	    {
X	    case 1:
X	    mask = 0x8000;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( mask == 0 )
X		    {
X		    sp++;
X		    mask = 0x8000;
X		    }
X		if ( *sp & mask )
X		    *pP = one;
X		else
X		    *pP = zero;
X		mask = mask >> 1;
X		}
X	    break;
X
X	    case 8:
X	    bytenum = 0;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    }
X		if ( bytenum == 0 )
X		    byte = ( *sp & 0xff00 ) >> 8;
X		else
X		    byte = *sp & 0xff;
X		PPM_ASSIGN(
X		    *pP, pr_colormap.map[0][byte], pr_colormap.map[1][byte],
X		    pr_colormap.map[2][byte] );
X		bytenum++;
X		}
X	    break;
X
X	    case 24:
X	    bytenum = 0;
X	    for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
X		{
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    }
X		if ( bytenum == 0 )
X		    r = ( *sp & 0xff00 ) >> 8;
X		else
X		    r = *sp & 0xff;
X		bytenum++;
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    }
X		if ( bytenum == 0 )
X		    g = ( *sp & 0xff00 ) >> 8;
X		else
X		    g = *sp & 0xff;
X		bytenum++;
X		if ( bytenum == 2 )
X		    {
X		    sp++;
X		    bytenum = 0;
X		    }
X		if ( bytenum == 0 )
X		    b = ( *sp & 0xff00 ) >> 8;
X		else
X		    b = *sp & 0xff;
X		bytenum++;
X		PPM_ASSIGN( *pP, r, g, b );
X		}
X	    break;
X
X	    default:
X	    pm_error( "can't happen", 0,0,0,0,0 );
X	    }
X	data += linesize / sizeof(short);
X	ppm_writeppmrow( stdout, pixelrow, cols, maxval );
X	}
X
X    exit( 0 );
X    }
SHAR_EOF
if test 5285 -ne "`wc -c < 'ppm/rasttoppm.c'`"
then
	echo shar: error transmitting "'ppm/rasttoppm.c'" '(should have been 5285 characters)'
fi
fi # end of overwriting check
if test ! -d 'ppm'
then
	echo shar: creating directory "'ppm'"
	mkdir 'ppm'
fi
echo shar: extracting "'ppm/rasttoppm.1'" '(869 characters)'
if test -f 'ppm/rasttoppm.1'
then
	echo shar: will not over-write existing file "'ppm/rasttoppm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'ppm/rasttoppm.1'
X.TH rasttoppm 1 "23 December 1988"
X.SH NAME
Xrasttoppm - convert a Sun raster file into a portable pixmap
X.SH SYNOPSIS
Xrasttoppm [rastfile]
X.SH DESCRIPTION
XReads a Sun raster file as input.
XProduces a portable pixmap as output.
XNOTE: since it uses Sun-specific include files and libraries, ppmtorast
Xwill compile only on Suns.
X.PP
XThe rasttopbm filter is significantly faster if your images are just
Xblack and white.
X.SH "SEE ALSO"
Xppmtorast(1), 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 869 -ne "`wc -c < 'ppm/rasttoppm.1'`"
then
	echo shar: error transmitting "'ppm/rasttoppm.1'" '(should have been 869 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Alt.sources mailing list