www.pudn.com > 医学算法.rar > disn.c


#include	
#include	

/*
	disn - quantize a N x N picture to 8 bits

	Carl Crawford
	Purdue University
	W. Lafayette, IN. 47907

	March 23, 1980

	modified by
	Jonathan Lotz
	Purdue University
	W. Lafayette, IN. 47907

	April 4, 1982

		Added better comand parser, and made prog so that one can
		specify the dimention (n) of the picture.
*/
/*

	syntax: disn [if=pic.r] [of=pic] [n=64] [-r] [min=  ] [max=  ]

	Added -r flag		Summer 1981
	Made the -f option default unless a min and max are listed.
					Malcolm     12/7/81
*/

char    *ifn =  "pic.r",
	*ofn =  "pic";
int	n = 512,        /*parameter: # of data points wide the picture is*/
	n2;             /*n squared or 512, whichever is smaller*/
float   min,max;        /*min and max of the input file or specified as parameters*/
int     fma = 1,        /*boolian weather to look for min or max in data file*/
	fmi = 1;
	specn = 0;      /*boolian weather n was specified as a parameter*/
FILE    *ifd,*ofd;
float   buf[512];       /*temperary buffer*/
float	scale;
char    z[512];         /*array to hold pixels*/
int     Rflg = 0;
char	*table[] = {
		"min",
		"max",
		"n",
		"if",
		"of",
		0
	};


main(argc,argv)
	int     argc;
	char	**argv;
{
	register long	i=0;
	register	j=1,k=0;	/*loop variables*/
	char    cc;

	while(++argv,--argc){

		/*remember old way of specifying min and max*/
		/*check for min and max specified as just numbers with no identifiers*/
		if(argc ==2 && 
		    (**argv == '-' || **argv == '+' || **argv == '.' || 
		    (**argv >= '0' && **argv <= '9')) ) {
			min=atof (*argv);      /*assign minimum*/
			max=atof (argv[1]);    /*and maximum */
			fmi = 0;               /*don't look for new min and*/
			fma = 0;               /*max later */
			break;                 /*end of arguments*/
		}
		if(**argv == '-')while(cc = *++*argv)switch(cc){

		case 'r':       /* reverse black and white */
			Rflg = 1;
			break;
		default:
			fprintf(stderr,"bad flag: -%c\n",cc);
			exit(1);
		}else	switch(comm(*argv)){

		case 1:         /* min */
			min = atof(*argv + 4);
			fmi = 0;                /*don't look for new min later*/
			break;
		case 2:         /* max */
			max = atof(*argv + 4);
			fma =0;                 /*don't look for new max later*/
			break;
		case 3:         /* n */
			n = atoi(*argv + 2);
			if(n < 1 || n > 512){
			  fprintf(stderr,"disn error: bad n\n");
			  exit(1);
			}
			specn=1;        /*user specified n*/
			break;
		case 4:		/* ifn */
			ifn = *argv + 3;
			break;
		case 5:		/* ofn */
			ofn = *argv + 3;
			break;
		}
	}

	if((ifd = fopen(ifn,"r")) == NULL){
		fprintf(stderr,"disn error: can't open: %s\n",ifn);
		exit(1);
	}
	if((ofd = fopen(ofn,"w")) == NULL){
		fprintf(stderr,"disn error: can't create: pic\n");
		exit(1);
	}
	if ((long)n*n > 512) 
		n2=512;        		/* # of bytes to read at a time*/
	else
		n2 = (long)n*n;
	if(fma || fmi){               	/* find min or max in file*/
	    if (fmi) 
		min= HUGE;
	    if (fma) 
		max= -HUGE;
	    i = 0;
	    j = 1;
	    while(j >= 1 && i < (long)n*n) {
		j=fread(buf,sizeof(float),n2,ifd);  /* get buf of data*/
	    	if (j > 0){
			i += j;		/* count number of data points */
					/* remember arrays origin at zero */
		      	k=(i>n*n&&specn) ? j+n*n-i-1 : j-1;
		      	while (k>=0){
				if(buf[k] > max && fma)
					max = buf[k];  /*get new max value*/
				if(buf[k] < min && fmi)
					min = buf[k];  /*get new min value*/
				k-=1;
			}
	    	}
	    }
	    fclose(ifd);                /*reset file*/
	    ifd = fopen(ifn,"r");
	}
	if(max == min){
		fprintf(stderr,"disn error: max = min\n");
		exit(1);
	}
	scale = 255. / (max - min);
	i=(specn) ? n*n : 32000;      /*read all points or only n by n*/
	while(i>0){                   /*32000 is "largest file length*/
	  j=fread(buf,sizeof(float),n2,ifd);
	  if (j==0){
	     if (specn==1)  
		fprintf(stderr,"warning: unexpected eof\n");
	     break;  /*tell user his specified n was too large*/
	  }
	  i-=j;
	  j=k= (specn&&i<0) ? j+i : j;
	  k-=1;                            /*remember arrays origin at zero*/
	  while (k>=0) {
	  	if(buf[k] > max)
			buf[k] = max;
	    	if (buf[k] < min)
			buf[k] = min;
	  	z[k]=floor((buf[k]-min)*scale);
	  	if (Rflg)
			z[k] = 255 - z[k];
	  	k-=1;
	  }
	fwrite(z,1,j,ofd);
	}
}
comm(s)
	char	*s;
{
	register	int	i,j,r;

	for(i=0;table[i];i++){
		for(j=0;(r=table[i][j]) == s[j] && r;j++);
		if(r == 0 && s[j] == '=' && s[j+1] )return(i+1);
	}
	fprintf(stderr,"bad option: %s\n",s);
	exit(1);
}