示例#1
0
文件: Mequal.c 项目: 1014511134/src
int main (int argc, char* argv[])
{
    int i3, n3, n1, n2, n12, i, col, accum;
    unsigned char* dat;
    int range[NCOL];
    sf_file in=NULL, out=NULL;

    sf_init (argc, argv);
    in = sf_input("in");
    out = sf_output("out");

    if (SF_UCHAR != sf_gettype(in)) sf_error("Need uchar type");
    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&n2)) n2=1;
    n3 = sf_leftsize(in,2);
    n12 = n1*n2;

    dat = sf_ucharalloc(n12);

    for (i3=0; i3 < n3; i3++) {
	sf_ucharread(dat, n12, in);

	for (col=0; col < NCOL; col++) {
	    range[col] = 0;
	}

	for (i=0; i < n12; i++) {
	    col = dat[i];
	    range[col]++;
	}

	for (accum=0, col=0; col < NCOL; col++) {
	    accum += range[col];
	    range[col] = accum*(NCOL-1)/n12;
	}
  
	for (i=0; i < n12; i++) {
	    col = dat[i];
	    dat[i] = range[col];
	}

	sf_ucharwrite(dat, n12, out);
    }


    exit (0);
}
示例#2
0
文件: grey.c 项目: 1014511134/src
int main(int argc, char* argv[])
{
    int n1, n2, n3, gainstep, panel, it, nreserve, i1, i2, i3, j, orient;
    float o1, o2, o3, d1, d2, d3, gpow, clip, pclip, phalf, bias=0., minmax[2];
    float pbias, gain=0., x1, y1, x2, y2, **data=NULL, f, barmin, barmax, dat;
    bool transp, yreverse, xreverse, allpos, polarity, symcp, verb;
    bool eclip=false, egpow=false, barreverse, mean=false;
    bool scalebar, nomin=true, nomax=true, framenum, sfbyte, sfbar, charin;
    char *gainpanel, *color, *barfile;
    unsigned char tbl[TSIZE+1], **buf, tmp, *barbuf[1];
    enum {GAIN_EACH=-3,GAIN_ALL=-2,NO_GAIN=-1};
    off_t pos;
    sf_file in, out=NULL, bar=NULL;
    
    sf_init(argc,argv);
    in = sf_input("in");

    sfbyte = (bool) (NULL != strstr (sf_getprog(),"byte"));
    sfbar = (bool) (NULL != strstr (sf_getprog(),"bar"));

    if (sfbyte) {
	out = sf_output("out");
	sf_settype(out,SF_UCHAR);
    } else if (sfbar) {
	bar = sf_output("out");
	sf_settype(bar,SF_UCHAR);
    } else {
	vp_init();
    }

    charin = (bool) (SF_UCHAR == sf_gettype(in));

    if (charin && sfbyte) sf_error("Cannot input uchar to byte");

    if (!charin && SF_FLOAT != sf_gettype(in)) sf_error("Need float input");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&n2)) n2=1;
    n3 = sf_leftsize(in,2);

    if (!sf_histfloat(in,"o1",&o1)) o1=0.;
    if (!sf_histfloat(in,"o2",&o2)) o2=0.;
    if (!sf_histfloat(in,"o3",&o3)) o3=0.;

    if (!sf_histfloat(in,"d1",&d1)) d1=1.;
    if (!sf_histfloat(in,"d2",&d2)) d2=1.;
    if (!sf_histfloat(in,"d3",&d3)) d3=1.;

    if (!sf_getbool("transp",&transp)) transp=true;
    /* if y, transpose the display axes */
    if (!sf_getbool("yreverse",&yreverse)) yreverse=true;
    /* if y, reverse the vertical axis */
    if (!sf_getbool("xreverse",&xreverse)) xreverse=false;
    /* if y, reverse the horizontal axis */

    if (transp) {
	orient = 3;
    } else {	
	orient = (xreverse==yreverse)? 0:2;
    }

    if (!charin) {
	panel = NO_GAIN; /* no need for gain */
	
	phalf=85.;
	egpow = false;
	if (!sf_getfloat("gpow",&gpow)) {
	    gpow=1.;
	    /*( gpow=1 raise data to gpow power for display )*/
	} else if (gpow <= 0.) {
	    gpow=0.;
	    egpow = true;
	    sf_getfloat("phalf",&phalf);
	    /* percentage for estimating gpow */
	    if (phalf <=0. || phalf > 100.)
		sf_error("phalf=%g should be > 0 and <= 100",phalf);
	    panel = 0;
	}
	
	pclip=99.;
	eclip = (bool) (!sf_getfloat("clip",&clip));
	/* data clip */
	if (eclip) {	    
	    clip = 0.;
	    sf_getfloat("pclip",&pclip);
	    /* data clip percentile (default is 99) */
	    if (pclip <=0. || pclip > 100.)
		sf_error("pclip=%g should be > 0 and <= 100",pclip);
	    panel = 0;
	} else if (clip <= 0.) {
	    sf_warning("clip=%g <= 0",clip);
	    clip = FLT_EPSILON;
	}

	if (0==panel) {
	    if (!sf_getint("gainstep",&gainstep)) gainstep=0.5+n1/256.;
	    /* subsampling for gpow and clip estimation */
	    if (gainstep <= 0) gainstep=1;

	    gainpanel = sf_getstring("gainpanel");
	    /* gain reference: 'a' for all, 'e' for each, or number */
	    if (NULL != gainpanel) {
		switch (gainpanel[0]) {
		    case 'a': 
			panel=GAIN_ALL; 
			break;
		    case 'e': 
			panel=GAIN_EACH;
			break;
		    default:
			if (0 ==sscanf(gainpanel,"%d",&panel) || 
			    panel < 1 || panel > n3) 
			    sf_error("gainpanel= should be all,"
				     " each, or a number"
				     " between 1 and %d",n3);
			panel--;
			break;
		}
		free (gainpanel); 
	    } 

	    sf_unpipe(in,sf_filesize(in)*sizeof(float));
	} 

	if (!sf_getbool("allpos",&allpos)) allpos=false;
	/* if y, assume positive data */
	if (!sf_getbool("mean",&mean)) mean=false;
	/* if y, bias on the mean value */
	if (!sf_getfloat("bias",&pbias)) pbias=0.;
	/* value mapped to the center of the color table */
	if (!sf_getbool("polarity",&polarity)) polarity=false;
	/* if y, reverse polarity (white is high by default) */
	if (!sf_getbool("symcp",&symcp)) symcp=false;
	/* if y, assume symmetric color palette of 255 colors */
	if (!sf_getbool("verb",&verb)) verb=false;
	/* verbosity flag */
    } /* if !charin */

    barfile = sf_getstring("bar");
    /* file for scalebar data */

    if (sfbyte) {
	scalebar = (bool) (NULL != barfile);
	if (scalebar) sf_putstring(out,"bar",barfile);
    } else if (sfbar) {
	scalebar = true;
    } else {
	if (!sf_getbool ("wantscalebar",&scalebar) && 
	    !sf_getbool ("scalebar",&scalebar)) scalebar = false;
	/* if y, draw scalebar */	
    }
    if (scalebar) {
	nomin = (bool) (!sf_getfloat("minval",&barmin));
	/* minimum value for scalebar (default is the data minimum) */
	nomax = (bool) (!sf_getfloat("maxval",&barmax));
	/* maximum value for scalebar (default is the data maximum) */
	
	barbuf[0] = sf_ucharalloc(VP_BSIZE);

	if (!sf_getbool("barreverse",&barreverse)) barreverse=false;
	/* if y, go from small to large on the bar scale */

	if (sfbyte || sfbar) {
	    if (sfbyte) {
		bar = sf_output("bar");
		sf_settype(bar,SF_UCHAR);
	    }
	    sf_putint(bar,"n1",VP_BSIZE+2*sizeof(float));
	    sf_putint(bar,"n2",1);
	    sf_putint(bar,"n3",n3);

	    if (!nomin) sf_putfloat(bar,"minval",barmin);
	    if (!nomax) sf_putfloat(bar,"maxval",barmax);
	} else if (charin) {
	    if (NULL == barfile) {
		barfile=sf_histstring(in,"bar");
		if (NULL == barfile) sf_error("Need bar=");
	    }

	    bar = sf_input(barfile);
	    if (SF_UCHAR != sf_gettype(bar)) sf_error("Need uchar in bar");

	    if (nomin) nomin = (bool) (!sf_histfloat(bar,"minval",&barmin));
	    if (nomax) nomax = (bool) (!sf_histfloat(bar,"maxval",&barmax));
	}
    }

    if (!sf_getbool("wantframenum",&framenum)) framenum = (bool) (n3 > 1);
    /* if y, display third axis position in the corner */

    x1 = o1-0.5*d1;
    x2 = o1+(n1-1)*d1+0.5*d1;
    y1 = o2-0.5*d2;
    y2 = o2+(n2-1)*d2+0.5*d2;

    if (!sfbyte && !sfbar) {
	vp_stdplot_init (x1, x2, y1, y2, transp, false, yreverse, false);
	vp_frame_init(in,"tlb",false);
/*	if (scalebar && !nomin && !nomax) 
	vp_barframe_init (in,barmin,barmax); */
    }

    if (transp) {
	f=x1; x1=y1; y1=f;
	f=x2; x2=y2; y2=f;
    }

    if (yreverse) {
	f=y1; y1=y2; y2=f;
    }

    if (xreverse) {
	f=x1; x1=x2; x2=f;
    }

    buf = sf_ucharalloc2(n1,n2);

    if (!charin) {
	data = sf_floatalloc2(n1,n2);

	if (GAIN_ALL==panel || panel >= 0) {
	    pos = sf_tell(in);
	    if (panel > 0) sf_seek(in,
				   pos+panel*n1*n2*sizeof(float),
				   SEEK_SET);
	    vp_gainpar (in,data,n1,n2,gainstep,
			pclip,phalf,&clip,&gpow,mean,&pbias,
			n3,panel,panel);
	    if (verb) sf_warning("panel=%d bias=%g clip=%g gpow=%g",
				 panel,pbias,clip,gpow);
	    if (sfbyte) sf_putfloat(out,"clip",clip);
	    sf_seek(in,pos,SEEK_SET); /* rewind */
	}
    }

    if (!sfbyte && !sfbar) {
	/* initialize color table */
	if (NULL == (color = sf_getstring("color"))) color="i";
	/* color scheme (default is i) */
	if (!sf_getint ("nreserve",&nreserve)) nreserve = 8;
	/* reserved colors */
	vp_rascoltab (nreserve, color);
    }

    for (i3=0; i3 < n3; i3++) {	
	if (!charin) {
	    if (GAIN_EACH == panel) {
		if (eclip) clip=0.;
		if (egpow) gpow=0.;
		vp_gainpar (in,data,n1,n2,gainstep,
			    pclip,phalf,&clip,&gpow,
			    mean,&pbias,n3,0,n3);
		if (verb) sf_warning("bias=%g clip=%g gpow=%g",pbias,clip,gpow);
	    } else {
		sf_floatread(data[0],n1*n2,in);
	    }
	    
	    if (1 == panel || GAIN_EACH == panel || 0==i3) { 
		/* initialize the conversion table */
		if(!allpos) { /* negative and positive values */
		    for (it=1; it<=TSIZE/2; it++) {
		        if (symcp) {
			    tbl[TSIZE-it] = (gpow != 1.)?
			        254*(pow(((TSIZE-2.0*it)/TSIZE),gpow)+1.)/2.+1.:
			        254*(    ((TSIZE-2.0*it)/TSIZE)      +1.)/2.+1.;
			    tbl[it] = 255 - tbl[TSIZE-it] + 1.0;
			} else {
			    tbl[TSIZE-it] = (gpow != 1.)?
			        252*(pow(((TSIZE-2.0*it)/TSIZE),gpow)+1.)/2.+3.:
			        252*(    ((TSIZE-2.0*it)/TSIZE)      +1.)/2.+3.;
			    tbl[it] = 255 - tbl[TSIZE-it] + 2.0;
			}
		    }
		    bias = TSIZE/2.;
		    gain = TSIZE/(2.*clip);
		} else { /* all positive */
		    if (symcp) {
			for (it=1; it < TSIZE ; it++) {
			    tbl[it] = 255*((it-1.0)/TSIZE) + 1.0;
			}
		    } else {
			for (it=1; it < TSIZE ; it++) {
			    tbl[it] = 256*((it-1.0)/TSIZE);
			}
		    }
		    bias = 0.;
		    gain = TSIZE/clip;		
		}
		tbl[0] = tbl[1];
		tbl[TSIZE] = tbl[TSIZE-1];
		if (polarity) { /* switch polarity */
		    for (it=0; it<=TSIZE; it++) {
			tbl[it]=255-tbl[it];
		    }
		}
	    }
	    
	    /* convert to bytes */
	    for (i2=0; i2 < n2; i2++) {
		for (i1=0; i1 < n1; i1++) {
		    j = (data[i2][i1]-pbias)*gain + bias;
		    if      (j < 0) j=0;
		    else if (j > TSIZE) j=TSIZE;
		    buf[i2][i1] = tbl[j];
		}
	    }
	} else {
	    sf_ucharread(buf[0],n1*n2,in);
	}

	if (!sfbyte && !sfbar) {
	    if (yreverse) {
		for (i2=0; i2 < n2; i2++) {
		    for (i1=0; i1 < n1/2; i1++) {			
			tmp = buf[i2][i1];
			buf[i2][i1] = buf[i2][n1-1-i1];
			buf[i2][n1-1-i1] = tmp;
		    }
		}
	    } 
	    
	    if ((xreverse && transp) || (!xreverse && !transp)) {
		for (i2=0; i2 < n2/2; i2++) {
		    for (i1=0; i1 < n1; i1++) {
			tmp = buf[i2][i1];
			buf[i2][i1] = buf[n2-1-i2][i1];
			buf[n2-1-i2][i1] = tmp;
		    }
		}
	    }
	
	    if (i3 > 0) vp_erase (); 	

	    if (framenum) vp_framenum(o3+i3*d3);
	    vp_frame(); 
	    vp_uraster (buf, false, 256, n1, n2, 
			x1, y1, x2, y2, orient);
	    vp_simpleframe();
	}
	
	if (scalebar) {
	    if (!charin) {
		if (nomin) barmin = data[0][0];
		if (nomax) barmax = data[0][0];
		if (nomin || nomax) {
		    for (i2=0; i2 < n2; i2++) {
			for (i1=0; i1 < n1; i1++) {
			    dat = data[i2][i1];
			    if (nomin && barmin > dat) barmin = dat;
			    if (nomax && barmax < dat) barmax = dat;
			}
		    }
		}
		
		for (it=0; it < VP_BSIZE; it++) {
		    if (barreverse) {
			dat = (barmin*it + barmax*(VP_BSIZE-1-it))/(VP_BSIZE-1);
		    } else {
			dat = (barmax*it + barmin*(VP_BSIZE-1-it))/(VP_BSIZE-1);
		    }
		    j = (dat-pbias)*gain + bias;
		    if      (j < 0) j=0;
		    else if (j > TSIZE) j=TSIZE;
		    barbuf[0][it] = tbl[j];
		} 
	    } else {
		sf_floatread(minmax,2,bar);
		sf_ucharread(barbuf[0],VP_BSIZE,bar);

		if (nomin) barmin=minmax[0];
		if (nomax) barmax=minmax[1];
	    }

	    if (sfbyte || sfbar) {
		sf_floatwrite(&barmin,1,bar);
		sf_floatwrite(&barmax,1,bar);
		sf_ucharwrite(barbuf[0],VP_BSIZE,bar);
	    } else {
		if (barreverse) {
		    vp_barframe_init (in,barmax,barmin);
		} else {
		    vp_barframe_init (in,barmin,barmax);
		}
		vp_barraster(VP_BSIZE, barbuf);
	    }
	} /* if scalebar */

	if (sfbyte) {
	    sf_ucharwrite(buf[0],n1*n2,out);
	} else if (!sfbar) {
	    vp_purge();
	} 
    } /* i3 loop */


    exit (0);
}
示例#3
0
sf_esc_slowness3 sf_esc_slowness3_init (sf_file vspline, bool verb)
/*< Initialize object >*/
{
    FILE *stream;
    bool spl;
    sf_esc_slowness3 esc_slow = (sf_esc_slowness3)sf_alloc (1, sizeof (struct EscSlowness3));

    if (sf_gettype (vspline) != SF_UCHAR)
        sf_error ("Wrong data type in velocity spline file");
    if (!sf_histbool (vspline, "splines", &spl) || !spl)
        sf_error ("No spline data in velocity spline file");

    if (!sf_histint (vspline, "Nz", &esc_slow->nz)) sf_error ("No Nz= in velocity spline file");
    if (!sf_histfloat (vspline, "Dz", &esc_slow->dz)) sf_error ("No Dz= in velocity spline file");
    if (!sf_histfloat (vspline, "Oz", &esc_slow->oz)) sf_error ("No Oz= in velocity spline file");
    if (!sf_histint (vspline, "Nx", &esc_slow->nx)) sf_error ("No Nx= in velocity spline file");
    if (!sf_histfloat (vspline, "Dx", &esc_slow->dx)) sf_error ("No Dx= in velocity spline file");
    if (!sf_histfloat (vspline, "Ox", &esc_slow->ox)) sf_error ("No Ox= in velocity spline file");
    if (!sf_histint (vspline, "Ny", &esc_slow->ny)) sf_error ("No Ny= in velocity spline file");
    if (!sf_histfloat (vspline, "Dy", &esc_slow->dy)) sf_error ("No Dy= in velocity spline file");
    if (!sf_histfloat (vspline, "Oy", &esc_slow->oy)) sf_error ("No Oy= in velocity spline file");

    esc_slow->zmin = esc_slow->oz;
    esc_slow->zmax = esc_slow->oz + (esc_slow->nz - 1)*esc_slow->dz;
    esc_slow->xmin = esc_slow->ox;
    esc_slow->xmax = esc_slow->ox + (esc_slow->nx - 1)*esc_slow->dx;
    esc_slow->ymin = esc_slow->oy;
    esc_slow->ymax = esc_slow->oy + (esc_slow->ny - 1)*esc_slow->dy;

    if (verb) {
        sf_warning ("Splined velocity model dimensions: nz=%d, z=[%g, %g]", esc_slow->nz,
                    esc_slow->zmin, esc_slow->zmax);
        sf_warning ("Splined velocity model dimensions: nx=%d, x=[%g, %g]", esc_slow->nx,
                    esc_slow->xmin, esc_slow->xmax);
        sf_warning ("Splined velocity model dimensions: ny=%d, y=[%g, %g]", esc_slow->ny,
                    esc_slow->ymin, esc_slow->ymax);
    }

    sf_ucharread ((unsigned char*)&(esc_slow->velspline),  sizeof(multi_UBspline_3d_s),
                  vspline);

    esc_slow->aniso = (esc_slow->velspline.num_splines != 1);

    if (verb) {
        sf_warning ("Number of velocity spline coefficients: %lu",
                    esc_slow->velspline.nc/(size_t)sizeof(float));
        if (esc_slow->aniso) {
            if (1 == esc_slow->velspline.num_splines)
                sf_warning ("Assuming isotropic velocity model");
            else if (3 == esc_slow->velspline.num_splines)
                sf_warning ("Assuming anisotropic VTI velocity model");
            else if (5 == esc_slow->velspline.num_splines)
                sf_warning ("Assuming anisotropic TTI velocity model");
            else
                sf_error ("Incorrect splined velocity model");
        }
    }

    stream = sf_filestream (vspline);
    esc_slow->offs = ftello (stream);
#ifdef HAVE_SSE
    if (sizeof(multi_UBspline_3d_s) % 64)
        esc_slow->offs += 64 - (sizeof(multi_UBspline_3d_s) % 64);
#endif

    if (stream != stdin
#ifdef HAVE_SSE
        && 0 == (esc_slow->offs % 64)
#endif
        ) {
        esc_slow->mmaped = (unsigned char*)mmap (NULL, (size_t)esc_slow->offs +
                                                       (size_t)esc_slow->velspline.nc,
                                                 PROT_READ, MAP_SHARED,
                                                 fileno (stream), 0);
        if (esc_slow->mmaped == MAP_FAILED)
            sf_error ("Velocity spline coefficients mmap failed: %s", strerror (errno));
        esc_slow->velspline.coefs = (float*)(esc_slow->mmaped + esc_slow->offs);
    } else {
        if (stream == stdin)
            sf_warning ("Velocity coefficients file appears to be stdin");
        else
            sf_warning ("Velocity coefficients file does not have the right padding");
        sf_warning ("mmap is not possible for velocity coefficients");
#ifndef HAVE_SSE
        esc_slow->velspline.coefs = (float*)sf_ucharalloc (esc_slow->velspline.nc);
#else
        posix_memalign ((void**)&esc_slow->velspline.coefs, 64, esc_slow->velspline.nc);
#endif
        sf_ucharread ((unsigned char*)esc_slow->velspline.coefs,
                      esc_slow->velspline.nc, vspline);
        esc_slow->mmaped = NULL;
    }
    init_einspline ();

    if (verb)
        sf_warning ("Size of splined velocity model: %g Mb", 1e-6*(float)esc_slow->velspline.nc);

    return esc_slow;
}
示例#4
0
int main(int argc, char* argv[])
{
    bool color;
    int n1, i2, n2, nc, nbuf;
    unsigned char *grey=NULL;
    sf_file in=NULL;
    TIFF *tiffout=NULL;
    FILE *tiffin=NULL;
    char *tiffname=NULL, buf[BUFSIZ];

    sf_init(argc,argv);
    in = sf_input("in");

    fclose(sf_tempfile(&tiffname,"w"));
    tiffout = TIFFOpen(tiffname,"wb");

    if (tiffout == NULL) sf_error("can't open file %s\n", tiffname);

    if (SF_UCHAR != sf_gettype(in)) sf_error("Need unsigned char in input");

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_getbool("color",&color)) color=(bool)(3==n1);

    if (color) {
	nc = n1;
	if (!sf_histint(in,"n2",&n1)) sf_error("No n2= in input");
	if (!sf_histint(in,"n3",&n2)) sf_error("No n3= in input");
    } else {
	nc = 1;
	if (!sf_histint(in,"n2",&n2)) sf_error("No n2= in input");
    }

    grey = sf_ucharalloc (n1*n2*nc);
    sf_ucharread(grey,n1*n2*nc,in);    

    TIFFSetField(tiffout,TIFFTAG_IMAGEWIDTH,n1);
    TIFFSetField(tiffout,TIFFTAG_IMAGELENGTH,n2);
    TIFFSetField(tiffout,TIFFTAG_SAMPLESPERPIXEL,nc);
    TIFFSetField(tiffout,TIFFTAG_BITSPERSAMPLE,8);
    TIFFSetField(tiffout,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
    TIFFSetField(tiffout,TIFFTAG_PHOTOMETRIC, 
		 (3==nc)? PHOTOMETRIC_RGB: PHOTOMETRIC_MINISBLACK);
    TIFFSetField(tiffout,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tiffout, TIFFTAG_ROWSPERSTRIP, 1);

    for (i2 = 0; i2 < n2; i2++) {
	if (TIFFWriteScanline(tiffout, grey+i2*n1*nc, i2, 0) < 0) 
	    sf_error("Trouble writing TIFF file");
    }

    TIFFClose(tiffout);
    tiffin = fopen(tiffname,"rb");

    while (1) {
	nbuf = fread(buf,1,BUFSIZ,tiffin);
	if (nbuf <= 0) break;
	fwrite(buf,1,nbuf,stdout);
    }

    fclose(tiffin);
    unlink(tiffname);

    exit(0);
}
示例#5
0
sf_cram_survey3 sf_cram_survey3_init (sf_file survey, bool verb)
/*< Initialize object >*/
{
    FILE *stream;
    size_t offs;
    float dsx, dsy, dhx, dhy;
    sf_cram_survey3 cram_survey = (sf_cram_survey3)sf_alloc (1, sizeof (struct CRAMSurvey3));

    if (sf_gettype (survey) != SF_UCHAR)
        sf_error ("Wrong data type in the survey info file");

    if (!sf_histlargeint (survey, "n1", (off_t*)&cram_survey->sz)) sf_error ("No n1= in survey");
    if (!sf_histbool (survey, "Istri", &cram_survey->tri)) sf_error ("No Istri= in survey");
    if (!sf_histlargeint (survey, "Nshot", (off_t*)&cram_survey->ns)) sf_error ("No Nshot= in survey");
    if (!sf_histlargeint (survey, "Nrec", (off_t*)&cram_survey->nh)) sf_error ("No Nrec= in survey");
    if (cram_survey->tri) {
        if (!sf_histint (survey, "Nstri", &cram_survey->nst)) sf_error ("No Nstri= in survey");
        if (!sf_histlargeint (survey, "Nhtri", (off_t*)&cram_survey->nht)) sf_error ("No Nhtri= in survey");
    }

    stream = sf_filestream (survey);
    cram_survey->offs = ftello (stream);

    if (stream != stdin) {
        cram_survey->mmaped = (unsigned char*)mmap (NULL, cram_survey->offs + cram_survey->sz,
                                                    PROT_READ, MAP_SHARED,
                                                    fileno (stream), 0);
        if (cram_survey->mmaped == MAP_FAILED)
            sf_error ("Survey info file mmap failed: %s", strerror (errno));
        offs = cram_survey->offs;
        /* Array of number of receivers in each shot */
        cram_survey->ih = (size_t*)(cram_survey->mmaped + offs);
        offs += (size_t)cram_survey->ns*(size_t)sizeof(size_t);
        /* Shot coordinates */
        cram_survey->s = (float*)(cram_survey->mmaped + offs);
        offs += (size_t)cram_survey->ns*(size_t)(sizeof(float)*2);
        /* Min/max coordinates for every shot */
        cram_survey->mm = (float*)(cram_survey->mmaped + offs);
        offs += (size_t)cram_survey->ns*(size_t)(sizeof(float)*4);
        /* Receiver coordinates */
        cram_survey->h = (float*)(cram_survey->mmaped + offs);
        offs += (size_t)cram_survey->nh*(size_t)(sizeof(float)*2);
        if (cram_survey->tri) {
            /* Array of number of triangles in each receiver triangulation */
            cram_survey->ihtr = (size_t*)(cram_survey->mmaped + offs);
            offs += (size_t)cram_survey->ns*(size_t)sizeof(size_t);
            /* Shot triangulation */
            cram_survey->sh = (int*)(cram_survey->mmaped + offs);
            offs += (size_t)cram_survey->nst*(size_t)(sizeof(int)*3);
            /* Receiver triangulation */
            cram_survey->hh = (int*)(cram_survey->mmaped + offs);
        }
    } else {
        sf_warning ("Survey info file appears to be stdin");
        sf_warning ("mmap is not possible for the survey info");

        cram_survey->s = sf_floatalloc ((size_t)cram_survey->ns*(size_t)2);
        cram_survey->ih = (size_t*)sf_alloc ((size_t)cram_survey->ns, sizeof(size_t));
        cram_survey->mm = sf_floatalloc ((size_t)cram_survey->ns*(size_t)4);
        cram_survey->h = sf_floatalloc ((size_t)cram_survey->nh*(size_t)2);
        cram_survey->ihtr = (size_t*)sf_alloc ((size_t)cram_survey->ns, sizeof(size_t));
        cram_survey->sh = sf_intalloc ((size_t)cram_survey->nst*(size_t)3);
        cram_survey->hh = sf_intalloc ((size_t)cram_survey->nht*(size_t)3);
    
        sf_ucharread ((unsigned char*)cram_survey->ih,
                      cram_survey->ns*(size_t)sizeof(size_t), survey);
        sf_ucharread ((unsigned char*)cram_survey->s,
                      cram_survey->ns*(size_t)(sizeof(float)*2), survey);
        sf_ucharread ((unsigned char*)cram_survey->s,
                      cram_survey->ns*(size_t)(sizeof(float)*4), survey);
        sf_ucharread ((unsigned char*)cram_survey->h,
                      cram_survey->nh*(size_t)(sizeof(float)*2), survey);
        if (cram_survey->tri) {
            sf_ucharread ((unsigned char*)cram_survey->ihtr,
                          cram_survey->ns*(size_t)sizeof(size_t), survey);
            sf_ucharread ((unsigned char*)cram_survey->sh,
                          cram_survey->nst*(size_t)(sizeof(int)*3), survey);
            sf_ucharread ((unsigned char*)cram_survey->hh,
                          cram_survey->nht*(size_t)(sizeof(int)*3), survey);
        }
        cram_survey->mmaped = NULL;
    }

    if (verb) {
        sf_warning ("Using %d shots, %d receivers", cram_survey->ns, cram_survey->nh);
        if (cram_survey->tri)
            sf_warning ("Using %d shot triangles, %lu receiver triangles",
                        cram_survey->nst, cram_survey->nht);
    }

    dsx = dsy = dhx = dhy = 0.0125;
    /* Determine source and receiver samplings from loaded coordinates */
    if (cram_survey->ns > 1) {
        dsx = fabsf (cram_survey->s[2] - cram_survey->s[0]);
        dsy = fabsf (cram_survey->s[3] - cram_survey->s[1]);
    }
    if (cram_survey->nh > 1) {
        dhx = fabsf (cram_survey->h[2] - cram_survey->h[0]);
        dhy = fabsf (cram_survey->h[3] - cram_survey->h[1]);
    }
    if (1 == cram_survey->ns) {
        dsx = dhx;
        dsy = dhy;
    }
    cram_survey->ds = hypotf (dsx, dsy);
    cram_survey->dh = hypotf (dhx, dhy);

    if (verb)
        sf_warning ("Using %g shot sampling, %g receiver sampling",
                    cram_survey->ds, cram_survey->dh);

    return cram_survey;
}
示例#6
0
文件: Mescscd3.c 项目: 1014511134/src
int main (int argc, char* argv[]) {
    size_t nc;
    off_t nsp;
    int ma, mb;
    int ith = 1, na, nb, nab, ncv, icpu, ncpu, tout, tdel;
    int i, iab, iab0, iab1, port, nthreads, tmpfile = 0;
#ifdef LINUX
    int inet = 0;
#endif
    multi_UBspline_3d_s *scsplines = NULL;
    sf_file in, scgrid = NULL, out;
    FILE *logf;
    char sbuffer[MAX_BUF];
    char *str = NULL;
    /* Fork variables */
    pid_t pid, sid;
    /* Server network variables */
    char *ip = NULL;
    int rc, on = 1, ijob, bsiz;
    int listen_sd, new_sd, njobs = 0;
    struct sockaddr_in serv_addr, client_addr;
    struct timeval timeout;
    fd_set sset;
    socklen_t clen;
    /* Threading */
    sf_escscd3_work *rwork, *qjobs, *old_qjobs;
    pthread_t pthread;
    pthread_mutex_t smutex;

    sf_init (argc, argv);

    in = sf_input ("in");
    /* Angular grid map */

    out = sf_output ("out");
    /* Dummy output */

    if (!sf_histint (in, "icpu", &icpu)) icpu = 0;
    /* Current CPU number */
    if (!sf_histint (in, "ncpu", &ncpu)) ncpu = 1;
    /* Total number of CPUs */

    if (!sf_getint ("nab", &nab)) nab = 1;
    /* Number of angular blocks to keep in memory per daemon */
    if (!sf_getint ("port", &port)) port = 29542;
    /* TCP port for listening */
    if (!sf_getint ("ith", &ith)) ith = 0;
    /* Make every ith process a daemon */

    memset (&serv_addr, 0, sizeof (serv_addr));

#ifdef LINUX
    if (!sf_getint ("inet", &inet)) inet = 1;
    /* Network interface index */
#endif

    if (ith) {
#ifdef LINUX
        if ((ip = sf_escscd3_local_ip (inet)))
#else
        if ((ip = sf_escscd3_local_ip ()))
#endif
        {
            if (0 == icpu % ith)
                sf_warning ("Assuming IP address %s [CPU %d]", ip, icpu);
            serv_addr.sin_family = AF_INET; /* Internet address family */
            serv_addr.sin_addr.s_addr = inet_addr (ip);   /* Server IP address */
            serv_addr.sin_port = htons ((uint16_t)port); /* Server port */
        } else
            sf_error ("Can not determine local IP address, shutting down [CPU %d]", icpu);
    } else
        sf_warning ("No processes are selected to run as daemons, shutting down [CPU %d]", icpu);

    if (ith && icpu % ith)
        sf_warning ("Making room for the daemon on CPU %d, shutting down [CPU %d]", (icpu/ith)*ith, icpu);

    if (!sf_getint ("ma", &ma)) ma = 20;
    /* How many azimuth angles to expect per request */
    if (!sf_getint ("mb", &mb)) mb = 20;
    /* How many inclination angles to expect per request */
    if (!sf_getint ("nthreads", &nthreads)) nthreads = 2*ncpu;
    /* Number of threads (connections) per daemon */
    if (!sf_getint ("timeout", &tout)) tout = 10;
    /* Inactivity time before shutdown (mins) */
    if (!sf_getint ("tdelay", &tdel)) tdel = 0;
    /* Time delay before accessing data, tdel*icpu (secs) */

    if (ith && 0 == (icpu % ith))
        sf_warning ("Running no more than %d threads on %s [CPU %d]", nthreads, ip, icpu);

    if (!sf_getstring ("scgrid")) sf_error ("Need scgrid=");
    /* Grid of supercells of local escape solutions */
    scgrid = sf_input ("scgrid");

    if (!sf_histlargeint (scgrid, "n1", &nsp)) sf_error ("No n1= in supercell file");
    /* Size of one angular direction */
    if (!sf_histint (scgrid, "Nb", &nb)) sf_error ("No Nb= in supercell file");
    /* Number of inclination angles */
    if (!sf_histint (scgrid, "Na", &na)) sf_error ("No Na= in supercell file");
    /* Number of azimuth angles */

    sf_settype (out, SF_UCHAR);
    sf_putlargeint (out, "n1", sizeof (serv_addr) + 2*sizeof (int));
    sf_putfloat (out, "o1", 0.0);
    sf_putfloat (out, "d1", 1.0);
    sf_putstring (out, "label1", "Supercell grid distributed access info");
    sf_putstring (out, "unit1", "");
    sf_putint (out, "n2", 1);
    sf_putfloat (out, "o2", 0.0);
    sf_putfloat (out, "d2", 1.0);
    sf_putstring (out, "label2", "");
    sf_putstring (out, "unit2", "");
    sf_putint (out, "n3", 1);
    sf_putfloat (out, "o3", 0.0);
    sf_putfloat (out, "d3", 1.0);
    sf_putstring (out, "label3", "");
    sf_putstring (out, "unit3", "");

    sf_putint (out, "Ndaemon", ith ? ncpu/ith : 0);
    sf_putint (out, "Port", port);
    sf_putint (out, "Ma", ma);
    sf_putint (out, "Mb", mb);
    sf_putstring (out, "Remote", ith ? "y" : "n");

    if (nab >= na*nb)
        nab = na*nb;
    /* Number of daemons for a full coverage */
    ncv = na*nb/nab;
    if ((na*nb) % nab)
        sf_error ("na*nb should be divisible by nab");
    if (ith && (ncpu % ncv))
        sf_error ("Non-integer number of coverages");
    if (ncpu*nab < na*nb)
        sf_error ("Incomplete angle coverage");
    sf_putint (out, "Nab", nab);
    sf_putint (out, "Ncv", ncv);

    /* Determine how much data from the supercell grid to hold per CPU */
    if (ith && 0 == (icpu % ith)) {
        iab0 = ((icpu / ith)*nab) % (na*nb);
        iab1 = iab0 + nab - 1;
        sf_warning ("Serving angular patch from iab=%d to iab=%d [CPU %d]",
                    iab0, iab1, icpu);
    } else {
        /* No daemon for this CPU */
        iab0 = nab;
        iab1 = -nab;
    }

    sf_ucharwrite ((unsigned char*)&serv_addr, sizeof (serv_addr), out);
    sf_ucharwrite ((unsigned char*)&iab0, sizeof (int), out);
    sf_ucharwrite ((unsigned char*)&iab1, sizeof (int), out);

    if (ith && 0 == (icpu % ith)) {
        /* Temporary file for synchronizing forked processes */
        str = strdup ("/tmp/sfescscd3.XXXXXX");
        tmpfile = mkstemp (str);
        /* Daemonize */
        pid = fork ();
        if (pid < 0)
            sf_error ("fork() failed, errno=%d", errno);
        if (0 == pid)
            lockf (tmpfile, F_LOCK, 0);
        else
            sleep (1);
    } else
        pid = 1;

    /* Read spline coefficients for the determined range of angles */
    if (ith && 0 == (icpu % ith) && 0 == pid) {
        /* Stream socket for incoming connections on */
        listen_sd = socket (ESC_SCD3_FAMILY, SOCK_STREAM, 0);
        if (listen_sd < 0)
            sf_error ("socket() failed [CPU %d], errno=%d", icpu, errno);
/*      
        new_sd = connect (listen_sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
        if (0 == new_sd) {
            sf_warning ("Daemon is already running [CPU %d]", icpu);
            close (new_sd);
            close (listen_sd);
            lockf (tmpfile, F_ULOCK, 1);
            close (tmpfile);
            free (str);
            return 0;
        }
*/
        sleep ((tdel + 1)*(icpu/ith));
        nc = 0;
        scsplines = (multi_UBspline_3d_s*)sf_alloc ((size_t)(iab1 - iab0 + 1),
                                                    sizeof(multi_UBspline_3d_s));
        for (iab = iab0; iab <= iab1; iab++) {
            i = iab;
            if (i < 0)
                i += na*nb;
            else if (i >= na*nb)
                i -= na*nb;
            sf_seek (scgrid, (off_t)i*(off_t)nsp, SEEK_SET);
            sf_ucharread ((unsigned char*)&scsplines[iab - iab0], sizeof(multi_UBspline_3d_s), scgrid);
            scsplines[iab - iab0].coefs = sf_floatalloc (scsplines[iab - iab0].nc/sizeof(float));
            sf_ucharread ((unsigned char*)scsplines[iab - iab0].coefs, scsplines[iab - iab0].nc, scgrid);
            nc += scsplines[iab - iab0].nc;
        }
        sf_warning ("%g Mb of spline coefficients buffered [CPU %d]", 1e-6*(float)nc, icpu);
        sf_warning ("Running as a daemon now [CPU %d]", icpu);
    }

    if (tmpfile && pid != 0) {
        /* Wait for the parent to complete data preparation */
        while (lockf (tmpfile, F_LOCK, 1))
            sleep (1);
        sf_warning ("Exiting parent process [CPU %d]", icpu);
        close (tmpfile);
        unlink (str);
        free (str);
    }

    sf_fileclose (scgrid);
    sf_fileclose (in);
    sf_fileclose (out);

    if (pid > 0)
        return 0;

    /* Change the file mode mask */
    umask (0);
    /* Create a new SID for the child process */
    sid = setsid ();
    if (sid < 0)
        sf_error ("setsid() failed [CPU %d], errno=%d", icpu, errno);
    /* Change to the root directory to prevent locking the current one */
/*
    if ((chdir ("/")) < 0)
        sf_error ("chdir() failed [CPU %d]", icpu);
*/

    /*************************************/
    /* Server part, use non-blocking I/O */
    /*************************************/

    /* Allow socket descriptor to be reuseable */
    if (setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR,
                    (char *)&on, sizeof(on)) < 0) {
        close (listen_sd);
        sf_error ("setsockopt() failed [CPU %d], errno=%d", icpu, errno);
    }
    /* Set socket to be non-blocking; all of the sockets for
       the incoming connections will also be non-blocking */
    if (ioctl (listen_sd, FIONBIO, (char *)&on) < 0) {
        close (listen_sd);
        sf_error ("ioctl() failed [CPU %d], errno=%d", icpu, errno);
    }

    /* Bind the socket */
    memset (&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(port);
    if (bind (listen_sd,
              (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        close (listen_sd);
        sf_error ("bind() failed [CPU %d], errno=%d", icpu, errno);
    }

    /* Set the listen back log */
    if (listen (listen_sd, nthreads) < 0) {
        close (listen_sd);
        sf_error ("listen() failed [CPU %d], errno=%d", icpu, errno);
    }

    pthread_mutex_init (&smutex, NULL);

    /* Open log file */
    snprintf (sbuffer, MAX_BUF, "sfescscd3_%s_%d.log", ip, icpu/ith);
    logf = fopen (sbuffer, "w+");
    fprintf (logf, "Listening on %s [CPU %d]\n", ip, icpu);
    fprintf (logf, "Servicing angle patch %d - %d\n", iab0, iab1);
    fflush (logf);
    sf_warning ("Log file is %s [CPU %d]", sbuffer, icpu);

    /* Buffer for job requests */
    old_qjobs = NULL;
    qjobs = sf_escscd3_alloc_work (nthreads, ma, mb);
    /* Position in the buffer for the next client */
    ijob = 0;
    clen = sizeof(client_addr);

    /* Release the child before starting the server loop */
    lockf (tmpfile, F_ULOCK, 1);
    close (tmpfile);
    free (str);
    fclose (stderr);

    /* Wait for incoming connections */
    do {
        FD_ZERO(&sset);
        FD_SET(listen_sd, &sset);
        timeout.tv_sec  = tout*60;
        timeout.tv_usec = 0;
        /* Wait for incoming connections */
        rc = select (listen_sd + 1, &sset, NULL, NULL, &timeout);
        if (rc < 0) {
            fprintf (logf, "select() failed\n");
            fflush (logf);
            return -1;
        }

        /* Check to see if the timeout has expired */
        if (0 == rc) {
            pthread_mutex_lock (&smutex);
            rc = njobs;
            pthread_mutex_unlock (&smutex);            
            if (0 == rc) {
                tout = -1;
                break;
            }
            fprintf (logf, "select() timeout, work is still in progress, postponing shutdown\n");
            fflush (logf);
            continue;
        }

        /* Accept the incoming connection */
        new_sd = accept (listen_sd, (struct sockaddr*)&client_addr, &clen);
        if (new_sd < 0) {
            if (errno != EWOULDBLOCK && errno != EAGAIN) {
                fprintf (logf, "accept() failed\n");
                fflush (logf);
                return -1;
            }
            break;
        }
        ip = inet_ntoa (client_addr.sin_addr);
        on = 1;
        if (ioctl (new_sd, FIONBIO, (char *)&on) < 0) {
            fprintf (logf, "ioctl() failed for a new socket\n");
            fflush (logf);
            close (new_sd);
            break;
        }
        on = 1;
        if (setsockopt (new_sd, SOL_SOCKET, SO_REUSEADDR,
                        (char *)&on, sizeof(on)) < 0) {
            fprintf (logf, "setsockopt() failed for a new socket\n");
            fflush (logf);
            close (new_sd);
            break;
        }
        on = 1;
#ifndef TCP_CORK
        if (setsockopt (new_sd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) { 
            fprintf (logf, "Can not set TCP_NODELAY for a new connection\n");
            close (new_sd);
            break;
        }
#endif
#ifdef SO_NOSIGPIPE
        on = 1;
        if (setsockopt (new_sd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)) < 0) {
            fprintf (logf, "Can not set SO_NOSIGPIPE for a new connection\n");
            fprintf (logf, "Rejecting connection from %s\n", ip);
            fflush (logf);
            close (new_sd);
            break;
        }
#endif
        bsiz = sizeof(sf_esc_scgrid3_areq)*ma*mb*SCGRID3_MAX_STENCIL;
        if (setsockopt (new_sd, SOL_SOCKET, SO_RCVBUF, &bsiz, sizeof(int)) < 0) {
            fprintf (logf, "Can not set SO_RCVBUF for a new connection\n");
            close (new_sd);
            break;
        }
        bsiz = sizeof(sf_esc_scgrid3_avals)*ma*mb*SCGRID3_MAX_STENCIL;
        if (setsockopt (new_sd, SOL_SOCKET, SO_SNDBUF, &bsiz, sizeof(int)) < 0) {
            fprintf (logf, "Can not set SO_SNDBUF for a new connection\n");
            close (new_sd);
            break;
        }

        /* Connection with the new client has been established,
           prepare data for processing its requests */
        rwork = &qjobs[ijob];                    
        rwork->sd = new_sd;
        rwork->iab0 = iab0;
        rwork->iab1 = iab1;
        rwork->nab = na*nb;
        rwork->scsplines = scsplines;
        rwork->logf = logf;
        rwork->nd = ma*mb*SCGRID3_MAX_STENCIL;
        rwork->smutex = &smutex;
        rwork->njobs = &njobs;
        rwork->is = 0;
        rwork->ir = 0;
        rwork->ns = 0;
        rwork->nr = 0;

        pthread_mutex_lock (&smutex);
        if (njobs < nthreads) {
            if (pthread_create (&pthread, NULL,
                                sf_escscd3_process_requests, (void*)rwork) != 0) {
                fprintf (logf, "pthread_create() failed\n");
                close (new_sd);
                pthread_mutex_unlock (&smutex);
                break;
            }
            njobs++;
            ijob++;
            /* Find a free block for the new client incoming requests */
            if (ijob == nthreads) {
                if (old_qjobs)
                    sf_escscd3_free_work (old_qjobs);
                old_qjobs = qjobs;
                qjobs = sf_escscd3_alloc_work (nthreads, ma, mb);
                ijob = 0;
            }
            fprintf (logf, "Accepted client from %s, socket %d\n", ip, new_sd);
            fflush (logf);
        } else {
            fprintf (logf, "Reached maximum allowed number of threads, rejecting connection from %s\n", ip);
            close (new_sd);
        }
        pthread_mutex_unlock (&smutex);
    } while (true);

    if (tout < 0)
        fprintf (logf, "Shutting down on timeout\n");
    fflush (logf);
    close (listen_sd);

    /* Clean up */
    pthread_mutex_destroy (&smutex);
    if (old_qjobs)
        sf_escscd3_free_work (old_qjobs);
    sf_escscd3_free_work (qjobs);

    for (iab = iab0; iab <= iab1; iab++) {
        free (scsplines[iab - iab0].coefs);
    }
    free (scsplines);
    fclose (logf);

    return 0;
}
示例#7
0
文件: graph.c 项目: housian0724/src
int main(int argc, char* argv[])
{
    bool transp, start, scalebar, nomin=true, nomax=true, barreverse, framenum;
    int n1, n2, n3, i1, i2, i3, len, nreserve;
    float min1, max1, min2, max2, o3, d3, o1, d1, xi, yi, tt;
    float **x, **y, **tmp, *symbolsz=NULL, symsize, xc, yc;    
    float ***data=NULL, barmin, barmax, minmax[2];
    char *symbol, sym[2]=" ", *color=NULL, *barfile;
    unsigned char **z=NULL, *barbuf[1];
    sf_datatype type;
    sf_file in, depth, bar=NULL;

    sf_init(argc,argv);
    in = sf_input("in");
    vp_init();

    if (NULL != sf_getstring("depth")) {
	depth = sf_input("depth"); /* values for colored plots */
	if (SF_UCHAR != sf_gettype(depth)) 
	    sf_error("Need uchar in depth");
    } else {
	depth = NULL;
    }

    if (!sf_histint(in,"n1",&n1)) sf_error("No n1= in input");
    if (!sf_histint(in,"n2",&n2)) n2=1;
    n = n1*n2;
    n3 = sf_leftsize(in,2);
    if (n3 > 1) {
	if (!sf_histfloat(in,"o3",&o3)) o3=0.;
	if (!sf_histfloat(in,"d3",&d3)) d3=1.;
    }

    x = sf_floatalloc2(n1,n2);
    y = sf_floatalloc2(n1,n2);
    t = sf_floatalloc(n);

    if (!sf_getbool("scalebar",&scalebar)) scalebar=false;
    /* if y, draw scalebar */

    if (!sf_getbool("wantframenum",&framenum)) framenum = (bool) (n3 > 1);
    /* if y, display third axis position in the corner */
    
    if (NULL != depth) {
	z = sf_ucharalloc2(n1,n2);
	/* initialize color table */
	if (NULL == (color = sf_getstring("color"))) color="j";
	/* color scheme (default is j) */
	if (!sf_getint ("nreserve",&nreserve)) nreserve = 8;
	/* reserved colors */
	vp_rascoltab(nreserve,color);

	if (scalebar) {
	    barfile = sf_getstring("bar");
	    /* file for scalebar data */
	    if (NULL == barfile) {
		barfile=sf_histstring(depth,"bar");
		if (NULL == barfile) sf_error("Need bar=");
	    }

	    nomin = (bool) (!sf_getfloat("minval",&barmin));
	    /* minimum value for scalebar (default is the data minimum) */
	    nomax = (bool) (!sf_getfloat("maxval",&barmax));
	    /* maximum value for scalebar (default is the data maximum) */
	
	    bar = sf_input(barfile);
	    if (SF_UCHAR != sf_gettype(bar)) sf_error("Need uchar in bar");

	    if (nomin) nomin = (bool) (!sf_histfloat(bar,"minval",&barmin));
	    if (nomax) nomax = (bool) (!sf_histfloat(bar,"maxval",&barmax));

	    barbuf[0] = (unsigned char*) sf_alloc(VP_BSIZE,sizeof(unsigned char));

	    if (!sf_getbool("barreverse",&barreverse)) barreverse=false;
	    /* if y, go from small to large on the bar scale */
	}
    } 

    if (!sf_getfloat("pclip",&pclip)) pclip=100.; /* clip percentile */

    type = sf_gettype(in);
    switch (type) {
	case SF_FLOAT:
	    if (!sf_histfloat(in,"o1",&o1)) o1=0.;
	    if (!sf_histfloat(in,"d1",&d1)) d1=1.;
	    
	    for (i2=0; i2 < n2; i2++) {
		for (i1=0; i1 < n1; i1++) {
		    x[i2][i1] = o1 + i1*d1;
		}
	    }
	    break;
	case SF_COMPLEX:
	    data = sf_floatalloc3(2,n1,n2);
	    break;
	default:
	    sf_error("Wrong data type (need float or complex)");
    }

    vp_plot_init(n2);

    symbol = sf_getstring("symbol");
    /* if set, plot with symbols instead of lines */
    if (NULL != symbol) {
	len = strlen(symbol);
	if (len < n2) {
	    symbol = (char*) sf_realloc(symbol,n2,sizeof(char));
	    for (i2=len; i2 < n2; i2++) {
		symbol[i2] = symbol[i2 % len];
	    }
	}

	symbolsz = sf_floatalloc(n2);
	if (!sf_getfloats("symbolsz",symbolsz,n2)) {
	    /* symbol size (default is 2) */
	    for (i2 = 0; i2 < n2; i2++)
		symbolsz[i2] = 2./33.;
	} else {
	    for (i2 = 0; i2 < n2; i2++)
		symbolsz[i2] /= 33.;
	}
    }

    if (!sf_getbool ("transp",&transp)) transp=false;
    /* if y, transpose the axes */
 
    for (i3 = 0; i3 < n3; i3++) {
	if (SF_COMPLEX == type) {
	    sf_floatread(data[0][0],2*n,in);
	    for (i2=0; i2 < n2; i2++) {
		for (i1=0; i1 < n1; i1++) {
		    x[i2][i1] = data[i2][i1][0];
		    y[i2][i1] = data[i2][i1][1];
		}
	    }
	    getminmax(x[0],&min1,&max1);
	} else {
	    sf_floatread(y[0],n,in);
	    min1=o1;
	    max1=o1+(n1-1)*d1;
	}
	getminmax(y[0],&min2,&max2);

	if (NULL != depth) sf_ucharread(z[0],n,depth);
	
	vp_stdplot_init (min1, max1, min2, max2,
			 transp,false,false,true);
	vp_frame_init(in,"blt",false);

	if (transp) {
	    tmp=x; x=y; y=tmp;
	    tt=max1; max1=max2; max2=tt;
	    tt=min1; min1=min2; min2=tt;
	}

	if (i3 > 0) vp_erase();

	if (framenum) vp_framenum(o3+i3*d3);
	vp_frame();

	for (i2=0; i2 < n2; i2++) {
	    vp_plot_set (i2);
	    
	    symsize = 2./33.;
	    if (NULL != symbol) {
		sym[0] = symbol[i2];
		symsize = symbolsz[i2];
	    } 

	    start = true;

	    for (i1=0; i1 < n1; i1++) {
		xi = x[i2][i1];
		yi = y[i2][i1];
		if (NULL != depth) vp_color(z[i2][i1]+256);

		if (isfinite(xi) && 
		    isfinite(yi)) {
		    if (NULL != symbol) {
			vp_umove(xi,yi);
			vp_where (&xc, &yc);
			vp_tjust (TH_SYMBOL, TV_SYMBOL);
			vp_gtext (xc,yc,symsize,0.,0.,symsize,sym);
		    } else if (start) {
			vp_umove(xi,yi);
			start=false;
		    } else {
			vp_udraw(xi,yi);
		    }
		} else {
		    start=true;
		}
	    }
	}

	if (depth && scalebar) {
	    sf_floatread(minmax,2,bar);
	    sf_ucharread(barbuf[0],VP_BSIZE,bar);

	    if (nomin) barmin=minmax[0];
	    if (nomax) barmax=minmax[1];

	    if (barreverse) {
		vp_barframe_init (depth,barmax,barmin);
	    } else {
		vp_barframe_init (depth,barmin,barmax);
	    }
	    vp_barraster(VP_BSIZE, barbuf);
	}
	
	if (transp) {
	    tmp=x; x=y; y=tmp;
	    tt=max1; max1=max2; max2=tt;
	    tt=min1; min1=min2; min2=tt;
	}
    } 
   

    exit(0);
}