/* IFFTOPS - ILBM IFF format file to PostScript translator.	*/
/*	Version 3.0 - LeRoy Fundingsland - 12/12/88 - SRC	*/
/*								*/
/*	This code has been compiled and tested under both Sun	*/
/*	UNIX (V3.5) and Commodore AmigaDOS (V1.2). On the	*/
/*	Amiga the Lattice 4.0 compiler was used ("lc -Lm").	*/

/*              CLAZ.c  v2.0                     */
/*              by Steve Ludtke                  */
/*              Created : 05/31/87               */

/*	Re-written Oct-Dec 1988 by LeRoy Fundingsland		*/
/*		Supercomputing Research Center			*/
/*			Lanham, MD				*/
/*		funding@metropolis.super.org			*/
/*								*/
/*	Changes:						*/
/*	- code re-structured for readability and maintain-	*/
/*		ability (my opinion (mostly:-))			*/
/*	- comments added for readability (but mostly just so I	*/
/*		could understand the code)			*/
/*	- code extended, with IFDEFs, to be compilable on SUN	*/
/*		systems (or nearly any 4.2BSD derived system,	*/
/*		I expect)					*/
/*	- extended to generate color postscript output (as of	*/
/*		the above date, color postscript output		*/
/*		devices may be pretty rare but we have one and	*/
/*		I think they will be be increasingly common in	*/
/*		the future)					*/
/*	- code extended, again with IFDEFs, to contain a rough	*/
/*		attempt at reducing the grainyness of the	*/
/*		output image (ref. "SMOOTH_INCLUDE")		*/
/*	- added the function for the image to be arbitrarily	*/
/*		rotated						*/
/*								*/
/*	TODO:							*/
/*	- place all of the initialization of default		*/
/*		values to happen at compile time		*/
/*	- make sure that every value in the "cmap" array is	*/
/*		non-negative					*/
/*	- QUESTION: when an Amiga process exits is the		*/
/*		programmer guaranteed that all system resources	*/
/*		are released? (specifically MALLOCed memory)?	*/

			/* the following DEFINE is for		/* 1 */
			/* IFDEFing code which is specific to	/* 1 */
			/* the QMS ColorScript-100 laser	/* 1 */
			/* printer.				/* 1 */
#define QMS							/* 1 */
#define SMOOTH_INCLUDE						/* 1 */
			/* The code in this file has been	/* 1 */
			/* constructed so that one, and only	/* 1 */
			/* one, of the following "environment"	/* 1 */
			/* "define"s should be included in the	/* 1 */
			/* active code at any time.		/* 1 */
/*								/# 1 #/
#define AMIGA							/* 1 */
#define SUN							/* 1 */

#include<stdio.h>
#include<math.h>

#ifdef AMIGA							/* 1 */
#undef NULL							/* 1 */
#include<exec/types.h>
#endif AMIGA							/* 1 */
#ifdef SUN							/* 1 */
#define BYTE	char						/* 1 */
#define UBYTE	unsigned char					/* 1 */
#define WORD	short						/* 1 */
#define UWORD	unsigned short					/* 1 */
#define LONG	int						/* 1 */
#endif SUN							/* 1 */

			/* define IFF structures */
struct CMAP {
	UBYTE r,g,b;
};

struct BMHD {
	UWORD w,h;
	WORD x,y;
	UBYTE npl;
	UBYTE masking,compression,pad1;
	UWORD tcolor;
	UBYTE xas,yas;
	WORD pWid,pHig;
};

char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',		/* 1 */
		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};	/* 1 */
								/* 1 */
#ifdef SUN							/* 1 */
#define TRUE	1						/* 1 */
#define FALSE	0						/* 1 */
#endif SUN							/* 1 */
int blacknwhite = TRUE;						/* 1 */
								/* 1 */
char *filename_err1 =						/* 1 */
	"ERROR: Too many file names on the command line\n";	/* 1 */
char *filename_data1 =						/* 1 */
    "\t(input=\"%s\", output=\"%s\", error string=\"%s\")\n\n";	/* 1 */

			/* smoothing related declarations	/* 1 */
int smooth = 0;							/* 1 */
int width, height;						/* 1 */
			/* pointers to storage where pixel	/* 1 */
			/* values are held during smoothing	/* 1 */
char *pixelrow, *smoothrow;					/* 1 */


char *malloc();
void putval1();							/* 1 */
void putval2();							/* 1 */

void								/* 1 */
main(argc, argv)
    int argc; char *argv[];{
	struct BMHD mhd;
	long len1, len2, cnt, m, h, i, j, k, lr, lb, lg,
		x1, x2, y1, y2, showpage;
	int fl1, b;
	int rotate = 0;						/* 1 */
	BYTE t;
	UBYTE cmap[100];
	char *raster=NULL, *rp, *infile=NULL, inspace[80],	/* 1 */
		*outfile=NULL, c, *misc=NULL;			/* 1 */
	LONG msc1[3], msc2[2];					/* 1 */
	FILE *fin, *fout;

	if(argc == 1){						/* 1 */
usage:								/* 1 */
		printf("Usage is: ifftops ");			/* 1 */
		printf("[-c] [-h]");				/* 1 */
#ifdef SMOOTH_INCLUDE						/* 1 */
		printf(" [-s]");				/* 1 */
#endif SMOOTH_INCLUDE						/* 1 */
		printf(" [-r <degrees>]\n");			/* 1 */
		printf("\t\t[-p <x-start>,<y-start>,");		/* 1 */
		printf("<x-scale>,<y-scale>]\n");		/* 1 */
		printf("\t\t<input file> [<output-file>]\n");	/* 1 */
		if(raster != NULL)				/* 1 */
			free(raster);				/* 1 */
		if(misc != NULL)				/* 1 */
			free(misc);				/* 1 */
		exit();						/* 1 */
	}							/* 1 */

	showpage=1; x1=10; y1=10; x2=550; y2=480;		/* 1 */
#ifdef QMS							/* 1 */
	y1 = (14*72)/16;	/* mechanical paper handlng */	/* 1 */
#endif QMS							/* 1 */

			/* Get enough memory, figure out filespecs */
	raster = malloc(200000);
	if (raster == NULL)
		{ printf("Not enough memory. (1)\n"); exit(0); }/* 1 */
	misc = malloc(2000);
	if(misc == NULL)					/* 1 */
		{ printf("Not enough memory. (2)\n"); exit(0); }/* 1 */

			/* parse command line arguments		*/
	for(argc--,argv++; argc > 0; argc--, argv++){		/* 1 */
		if(argv[0][0] == '-'){				/* 1 */
			switch(argv[0][1]){			/* 1 */
			case 'c':	/* "color" output */	/* 1 */
				blacknwhite = FALSE;		/* 1 */
				break;				/* 1 */
			case 'h':	/* "hold" printout */	/* 1 */
				showpage = FALSE;		/* 1 */
				break;				/* 1 */
			case 'p':	/* "position" image */	/* 1 */
				if(argv[0][2] != 0)		/* 1 */
					goto bad_p_flag;	/* 1 */
				argc--; argv++;			/* 1 */
				if(argc < 1)			/* 1 */
					goto bad_p_flag;	/* 1 */
				i =				/* 1 */
				sscanf(argv[0],"%ld,%ld,%ld,%ld",/* 1 */
					&x1, &y1, &x2, &y2);	/* 1 */
				if(i != 4){			/* 1 */
bad_p_flag:				printf("Bad format ");	/* 1 */
					printf("for 'p' flag\n");/* 1 */
					goto usage;		/* 1 */
				}				/* 1 */
				break;				/* 1 */
			case 'r':	/* "rotate" image */	/* 1 */
				if(argv[0][2] != 0)		/* 1 */
					goto bad_r_flag;	/* 1 */
				argc--; argv++;			/* 1 */
				if(argc < 1)			/* 1 */
					goto bad_r_flag;	/* 1 */
				i =				/* 1 */
				sscanf(argv[0],"%ld",&rotate);	/* 1 */
				if(i != 1){			/* 1 */
bad_r_flag:				printf("Bad format ");	/* 1 */
					printf("for 'r' flag\n");/* 1 */
					goto usage;		/* 1 */
				}				/* 1 */
				if(rotate >= 360  ||		/* 1 */
						rotate <= -360)	/* 1 */
					goto bad_r_flag;	/* 1 */
				break;				/* 1 */
#ifdef SMOOTH_INCLUDE						/* 1 */
			case 's':	/* "smooth" image */	/* 1 */
/*
				if(argv[0][2] == 0){		/* 1 */
					smooth = 1;		/* 1 */
/*
					break;			/* 1 */
/*
				}				/* 1 */
#ifdef NEVERDEF
				sscanf(&argv[0][2], "%d", &smooth);
				if(smooth == 0)			/* 1 */
					goto usage;		/* 1 */
				if(smooth < 1  ||  smooth > 3){	/* 1 */
					printf("Invalid \"smooth\" ");
					printf("value.\n");	/* 1 */
					exit(1);		/* 1 */
				}				/* 1 */
#endif NEVERDEF
				break;				/* 1 */
#endif SMOOTH_INCLUDE						/* 1 */
			default:				/* 1 */
				printf("Unknown flag '%c'\n",	/* 1 */
						*argv[1]);	/* 1 */
				exit(1);			/* 1 */
			}					/* 1 */
		}						/* 1 */
		else {		/* file designator */		/* 1 */
				/* maximum of two files allowed	/* 1 */
				/* the first one is the input	/* 1 */
				/* file, the second, if it	/* 1 */
				/* exists is the output file	/* 1 */
			if(infile == NULL)			/* 1 */
				infile = *argv;			/* 1 */
			else if(outfile == NULL)		/* 1 */
				outfile = *argv;		/* 1 */
			else{					/* 1 */
				printf(filename_err1);		/* 1 */
				printf(filename_data1, infile,	/* 1 */
					outfile, *argv);	/* 1 */
				goto usage;			/* 1 */
			}					/* 1 */
		}						/* 1 */
	}		/* end of argument parsing FOR loop */	/* 1 */
	if(infile == NULL){					/* 1 */
		printf("ERROR: input file name required.\n\n");	/* 1 */
		goto usage;					/* 1 */
	}							/* 1 */

	
	printf("\n\n                IFFTOPS - IFF to POSTSCRIPT");
	printf(" converter V3.0\n");
	printf("                           By LeRoy Fundingsland\n");
	printf("                             (via Steve Ludtke)\n");
	printf("                          N\251 - No Copyright 1988\n");
	printf("\n");
	printf("File in : ");
	if(infile != NULL)					/* 1 */
		printf("%s\n", infile);
	else{		/* no input file supplied	*/
		infile = inspace;				/* 1 */
		scanf("%s", infile);
	}
	if(outfile == NULL)					/* 1 */
		outfile = "out.ps";

	fin = fopen(infile, "r");
	if(fin == NULL)
		{ printf("Sorry, can't open input file.\n"); exit(0); }
	if ((fread((char *)msc1,12,1,fin)) == 0)		/* 1 */
		{ printf("Sorry, input file problem #1\n"); exit (0); }
/*								/# 1 #/
	len1 = (long *)&msc1[4];
*/								/* 1 */
	len1 = msc1[1];						/* 1 */
	printf("main : %d,%4s\n", len1, (char *)&msc1[0]);	/* 1 */
	cnt = 14;

	/* len1=# bytes in file according to IFF */
	/* msc2=the name of the current chunk */
	/* len2=# bytes in current chunk */
	/* by the way, UNID is symply any chunk the program	*/
	/*	doesn't deal with */

			/* Reads in the IFF file : */

	while(cnt < len1){
		fl1 = 0;
		if ((fread((char *)msc2,8,1,fin)) == 0)		/* 1 */
			{printf("Sorry, bad input file. \n"); exit(0);}
/*								/# 1 #/
		len2 = (long *)&msc2[4];
*/								/* 1 */
		len2 = msc2[1];					/* 1 */

		if (strncmp((char *)msc2,"CMAP",4) == 0) {	/* 1 */
			if ((fread(cmap,len2,1,fin)) == 0)
			    { printf("Sorry, bad CMAP. \n"); exit(0); }
			printf("CMAP\n");
			fl1 = 1;
		}

		if (strncmp((char *)msc2,"BMHD",4) == 0) {	/* 1 */
			if ((fread((char *)&mhd,len2,1,fin)) == 0)
			    { printf("Sorry, bad BMHD. \n"); exit(0); }
			printf("BMHD\n");
			fl1 = 1;
		}

		if (strncmp((char *)msc2,"BODY",4) == 0) {	/* 1 */
			printf("BODY\n");
#ifdef DEBUG							/* 1 */
printf("\t\tlength of BODY chunk (from file) = %d\n", len2);	/*999*/
#endif DEBUG							/* 1 */
			fl1 = 1;
			m = 0; rp = raster;
			if (mhd.compression == 1) {
				while (m <= len2) {
					t = getc(fin); m++;
					if (t >= 0) {
						t++;
						fread(rp,(long) t,1,fin);
						rp += t;
						m += t;
					}
					if (t<0) {
						t=(-t)+1;
						c=getc(fin);
						m++;
						for (i=0; i<t; i++) {
							*rp=c; rp++;
						}
					}
				}
			}
			if (mhd.compression == 0) {
				if((fread(rp,len2,1,fin)) == 0){
					printf("Sorry, bad BODY. \n");
					exit(0);
				}
				printf("No Compression\n");
			}
			if (mhd.compression > 1) {
				printf("Sorry, unknown compression type.\n");
				exit(0);
			}
		}		/* end of "BODY" IF statement	*/

		if (fl1 == 0) {
			if (len2 > 2000) {
				printf("Sorry, UNID too long.\n");
				exit(0);
			}
			if ((fread(misc,len2,1,fin)) == 0) {
				printf("Sorry, UNID bad. \n");
				exit(0);
			}
			printf("UNID\n");
		}
	
	  	cnt += len2;
		cnt += 8;
	}		/* end of IFF-file-reading WHILE loop	*/

#ifdef DEBUG							/* 1 */
printf("Total bytes read into \"raster\" = %d\n", rp-raster);	/*999*/
#endif DEBUG							/* 1 */
	fclose(fin);

			/* inform user if file already exists	/* 1 */
			/* and is being appended to		/* 1 */
	if((fout=fopen(outfile,"r")) != NULL){			/* 1 */
		printf("Output file, \"%s\", already exists.\n",/* 1 */
						outfile);	/* 1 */
		printf("Output is being appended to this file.\n");
		fclose(fout);					/* 1 */
	}							/* 1 */
	if ((fout=fopen(outfile,"a")) == NULL) {
		printf("Sorry, cannot open output file.\n");
		exit(0);
	}

/* Standard POSTSCRIPT program, the only part following the data is */
/* the showpage command. */

	if(smooth){						/* 1 */
		width = mhd.w * 2;				/* 1 */
		height = mhd.h * 2;				/* 1 */
			/* the "pixelrow" array is sized at one	/* 1 */
			/* byte for each pixel because it will	/* 1 */
			/* hold the ASCII-HEX (see "hex" array)	/* 1 */
			/* value for each pixel.		/* 1 */
			/* (3 bytes for each pixel if color)	/* 1 */
		if(blacknwhite == TRUE)				/* 1 */
			pixelrow = malloc(width);		/* 1 */
		else		/* color */			/* 1 */
			pixelrow = malloc(width * 3);		/* 1 */
		if(pixelrow == NULL)				/* 1 */
		{ printf("Not enough memory. (3)\n"); exit(0); }/* 1 */
			/* the same for the "smoothrow" array	/* 1 */
		if(blacknwhite == TRUE)				/* 1 */
			smoothrow = malloc(width);		/* 1 */
		else		/* color */			/* 1 */
			smoothrow = malloc(width * 3);		/* 1 */
		if(smoothrow == NULL)				/* 1 */
		{ printf("Not enough memory. (4)\n"); exit(0); }/* 1 */
	}							/* 1 */
	else{							/* 1 */
		width = mhd.w;					/* 1 */
		height = mhd.h;					/* 1 */
	}							/* 1 */
								/* 1 */
	fprintf(fout, "%%!\r");					/* 1 */
	fprintf(fout,"[0 0 0 0 0 0] defaultmatrix setmatrix\r");/* 1 */
			/* the length of the postscript		/* 1 */
			/* "picture string" (picstr) must equal	/* 1 */
			/* the width of the picture in pixels	/* 1 */
			/* (mhd.w) times the number of bytes of	/* 1 */
			/* data supplyed per pixel (0.5 for	/* 1 */
			/* B&W, 1.5 for color). This is so that	/* 1 */
			/* every time the "image" command	/* 1 */
			/* invokes the reading procedure, all	/* 1 */
			/* N bytes representing one scan line	/* 1 */
			/* are read.				/* 1 */
	fprintf(fout,"/picstr %d string def\r",
		(int)(width * (blacknwhite ? 0.5 : 1.5)));	/* 1 */
	fprintf(fout,"%ld %ld translate\r",x1,y1);
	if(rotate)						/* 1 */
		fprintf(fout, "%d rotate\r", rotate);		/* 1 */
	fprintf(fout,"%ld %ld scale\r",x2,y2);
	fprintf(fout, "%d %d 4 [%d 0 0 -%d 0 %d]\r",
		width, height, width, height, height);		/* 1 */
	fprintf(fout,"{currentfile picstr readhexstring pop}");
#ifdef QMS							/* 1 */
	if(blacknwhite == FALSE)				/* 1 */
		fprintf(fout, " false 3 colorimage\r");		/* 1 */
	else					/* color! */	/* 1 */
#endif QMS							/* 1 */
	fprintf(fout, " image\r");

			/* calculate and output file */

	lb = lr = lg = 0;
	printf("rast size : %d     #planes : %d\n",
				mhd.w*mhd.h/8, mhd.npl);	/* 1 */
			/* what does this do?			*/
	for (h=0; h<96; h++)
		cmap[h] = cmap[h]/16;
	for (h=0; h<mhd.h; h++) {
		for (i=0; i<mhd.w/8; i++) {
			for(k=7;k>=0;k--) {
				b=0;
				for(j=0; j<mhd.npl; j++) {
					c = (raster[h*(mhd.w/8)*mhd.npl+i+((mhd.npl-j-1)*mhd.w/8)]);
					c = c>>k;
					c &= 1;
					b |= c;
					b <<= 1;
				}
				b >>= 1;

					/* this is for HAM pictures */
				if (mhd.npl == 6) {
					c = (b&48) >> 4;
					b &= 15;
					if (c == 0) {
						b *= 3;
						lr = cmap[b];
						lb = cmap[b+1];
						lg = cmap[b+2];
					}
					if (c == 1) lb = b;
					if (c == 2) lr = b;
					if (c == 3) lg = b;
				}
				if (mhd.npl != 6) {
					b &= 31;
					b *= 3;
					lr = cmap[b];
					lb = cmap[b+1];
					lg = cmap[b+2];
				}
				if(blacknwhite){		/* 1 */
					m = lr+lb+lg; m = m/3;
					if (m < 0) m = 0;
					if (m > 14) m = 14;
#ifdef SMOOTH_INCLUDE						/* 1 */
					putval1(m, fout, h,	/* 1 */
						(i*8) + (7-k));	/* 1 */
#else SMOOTH_INCLUDE						/* 1 */
					putc(hex[m], fout);
#endif SMOOTH_INCLUDE						/* 1 */
				}				/* 1 */
				else{		/* color! */	/* 1 */
#ifdef SMOOTH_INCLUDE						/* 1 */
					putval2(lr,lg,lb,fout,	/* 1 */
						h,(i*8)+(7-k));	/* 1 */
#else SMOOTH_INCLUDE						/* 1 */
					putc(hex[lr], fout);
					putc(hex[lg], fout);
					putc(hex[lb], fout);
#endif SMOOTH_INCLUDE						/* 1 */
				}				/* 1 */
			}
		}
	}		/* end of map-header-count FOR loop	*/

	fprintf(fout,"\r");
	if(showpage)						/* 1 */
		fprintf(fout,"showpage\r");

	fclose(fout);
	printf("Done !!!\n");
	free(misc);
	free(raster);
#ifdef DEBUG							/* 1 */
printf("\n\tmhd.w = %d    mhd.h = %d\n", mhd.w, mhd.h);		/*999*/
printf("\twidth = %d    height = %d\n", width, height);		/*999*/
#endif DEBUG							/* 1 */
}


#ifdef SMOOTH_INCLUDE						/* 1 */
void								/* 1 */
putval1(pixelval, fout, rownum, pixelnum)			/* 1 */
    char pixelval;		/* the binary value */		/* 1 */
    int rownum, pixelnum;
    FILE *fout;{
	int i;
	char tempval;

			/* NOTE: the raw values are placed in	*/
			/* the odd numbered elements of the	*/
			/* arrays and the averaged values are	*/
			/* placed in the even numbered elements.*/
			/* The exception to this is the zeroth	*/
			/* pixels and row. Since these values	*/
			/* cannot be produced (because there is	*/
			/* no previous value to average with)	*/
			/* they are initialized with the value	*/
			/* of the zeroth pixel (which also	*/
			/* exists in array element numbered "1")*/
	if(smooth){
		if(rownum == 0){
			if(pixelnum == 0){
				smoothrow[0] = pixelval;
				smoothrow[1] = pixelval;
				pixelrow[0] = pixelval;
				pixelrow[1] = pixelval;
			}
			else{
				smoothrow[(2*pixelnum)+1] =
							pixelval;
				pixelrow[(2*pixelnum)+1] =
							pixelval;
	
				tempval =
				(pixelrow[(2*pixelnum)-1] +
					pixelval) / 2;
				smoothrow[2*pixelnum] = tempval;
				pixelrow[2*pixelnum] = tempval;
			}
		}
		else{		/* rownum != 0	*/
			if(pixelnum == 0){
				smoothrow[1] =
				(pixelrow[1] + pixelval) / 2;
				pixelrow[1] = pixelval;
				smoothrow[0] = smoothrow[1];
				pixelrow[0] = pixelval;
			}
			else{
				smoothrow[(2*pixelnum)+1] =
				(pixelrow[(2*pixelnum)+1] +
					pixelval) / 2;
	
				pixelrow[(2*pixelnum)+1] =
							pixelval;
	
				tempval =
				(pixelrow[(2*pixelnum)-1] +
					pixelval) / 2;
				smoothrow[2*pixelnum] =
				(pixelrow[2*pixelnum] +
					tempval) / 2;
	
				pixelrow[2*pixelnum] = tempval;
			}
		}

			/* if the last pixel in the row has	*/
			/* been processed then write the two	*/
			/* rows to the output file.		*/
		if(pixelnum == ((width/2) - 1)){
			for(i=0; i < width; i++)
				putc(hex[smoothrow[i]], fout);
			for(i=0; i < width; i++)
				putc(hex[pixelrow[i]], fout);
		}
	}
	else				/* no smoothing	*/
		putc(hex[pixelval], fout);
}


#define SETPIXELS(array,index,r,g,b)			/* 1 */\
		array[(3*index)+0] = r;			/* 1 */\
		array[(3*index)+1] = g;			/* 1 */\
		array[(3*index)+2] = b;			/* 1 */

#define AVE0PIX(array,index,val)			/* 1 */\
		((array[(3*index)+0]+val)/2)
#define AVE1PIX(array,index,val)			/* 1 */\
		((array[(3*index)+1]+val)/2)
#define AVE2PIX(array,index,val)			/* 1 */\
		((array[(3*index)+2]+val)/2)

void								/* 1 */
putval2(redval, greenval, blueval, fout, rownum, pixelnum)	/* 1 */
    char redval, greenval, blueval;	/* the binary value */	/* 1 */
    int rownum, pixelnum;
    FILE *fout;{
	int i;
	char tempred, tempgreen, tempblue;

			/* NOTE: the raw values are placed in	*/
			/* the odd numbered elements of the	*/
			/* arrays and the averaged values are	*/
			/* placed in the even numbered elements.*/
			/* The exception to this is the zeroth	*/
			/* pixels and row. Since these values	*/
			/* cannot be produced (because there is	*/
			/* no previous value to average with)	*/
			/* they are initialized with the value	*/
			/* of the zeroth pixel (which also	*/
			/* exists in array element numbered "1")*/
	if(smooth){
		if(rownum == 0){
			if(pixelnum == 0){
				SETPIXELS(smoothrow,0,redval,
						greenval,blueval)
				SETPIXELS(smoothrow,1,redval,
						greenval,blueval)
				SETPIXELS(pixelrow,0,redval,
						greenval,blueval)
				SETPIXELS(pixelrow,1,redval,
						greenval,blueval)
			}
			else{
					/* store raw values	*/
				SETPIXELS(smoothrow,((2*pixelnum)+1),
					redval,greenval,blueval)
				SETPIXELS(pixelrow,((2*pixelnum)+1),
					redval,greenval,blueval)
	
					/* calculate and store	*/
					/* averaged values	*/
				tempred =
				(pixelrow[(3*((2*pixelnum)-1))+0] +
					redval) / 2;
				tempgreen =
				(pixelrow[(3*((2*pixelnum)-1))+1] +
					greenval) / 2;
				tempblue =
				(pixelrow[(3*((2*pixelnum)-1))+2] +
					blueval) / 2;
				SETPIXELS(smoothrow,(2*pixelnum),
					tempred,tempgreen,tempblue)
				SETPIXELS(pixelrow,(2*pixelnum),
					tempred,tempgreen,tempblue)
			}
		}
		else{		/* rownum != 0	*/
			if(pixelnum == 0){
				SETPIXELS(smoothrow,1,
					AVE0PIX(pixelrow,1,redval),
					AVE1PIX(pixelrow,1,greenval),
					AVE2PIX(pixelrow,1,blueval))
				SETPIXELS(pixelrow,1,redval,
						greenval,blueval)
				SETPIXELS(smoothrow,0,smoothrow[3],
					smoothrow[4],smoothrow[5])
				SETPIXELS(pixelrow,0,redval,
						greenval,blueval)
			}
			else{
				SETPIXELS(smoothrow,((2*pixelnum)+1),
			AVE0PIX(pixelrow,((2*pixelnum)+1),redval),
			AVE1PIX(pixelrow,((2*pixelnum)+1),greenval),
			AVE2PIX(pixelrow,((2*pixelnum)+1),blueval))
/*
				smoothrow[(2*pixelnum)+1] =
				(pixelrow[(2*pixelnum)+1] +
					pixelval) / 2;
*/
	
				SETPIXELS(pixelrow,((2*pixelnum)+1),
					redval,greenval,blueval)
	
					/* calculate and store	*/
					/* averaged values	*/
				tempred =
				(pixelrow[(3*((2*pixelnum)-1))+0] +
					redval) / 2;
				tempgreen =
				(pixelrow[(3*((2*pixelnum)-1))+1] +
					greenval) / 2;
				tempblue =
				(pixelrow[(3*((2*pixelnum)-1))+2] +
					blueval) / 2;
				SETPIXELS(smoothrow,(2*pixelnum),
			AVE0PIX(pixelrow,(2*pixelnum),tempred),
			AVE1PIX(pixelrow,(2*pixelnum),tempgreen),
			AVE2PIX(pixelrow,(2*pixelnum),tempblue))
/*
				smoothrow[2*pixelnum] =
				(pixelrow[2*pixelnum] +
					tempval) / 2;
*/
	
				SETPIXELS(pixelrow,(2*pixelnum),
					tempred,tempgreen,tempblue)
			}
		}

			/* if the last pixel in the row has	*/
			/* been processed then write the two	*/
			/* rows to the output file.		*/
		if(pixelnum == ((width/2) - 1)){
			for(i=0; i < width; i++){
				putc(hex[smoothrow[(3*i)+0]], fout);
				putc(hex[smoothrow[(3*i)+1]], fout);
				putc(hex[smoothrow[(3*i)+2]], fout);
			}
			for(i=0; i < width; i++){
				putc(hex[pixelrow[(3*i)+0]], fout);
				putc(hex[pixelrow[(3*i)+1]], fout);
				putc(hex[pixelrow[(3*i)+2]], fout);
			}
		}
	}
	else{				/* no smoothing	*/
		putc(hex[redval], fout);
		putc(hex[greenval], fout);
		putc(hex[blueval], fout);
	}
}
#endif SMOOTH_INCLUDE						/* 1 */
