📄 fgettr.c
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved. *//* FGETTR: $Revision: 1.43 $; $Date: 2006/03/29 22:44:17 $ *//*********************** self documentation **********************//****************************************************************************FGETTR - Routines to get an SU trace from a file fgettr get a fixed-length segy trace from a file by file pointerfvgettr get a variable-length segy trace from a file by file pointerfgettra get a fixed-length trace from disk file by trace numbergettr macro using fgettr to get a trace from stdinvgettr macro using vfgettr to get a trace from stdingettra macro using fgettra to get a trace from stdin by trace number *****************************************************************************Function Prototype:int fgettr(FILE *fp, segy *tp);int fvgettr(FILE *fp, segy *tp);int fgettra(FILE *fp, segy *tp, int itr);*****************************************************************************Returns:fgettr, fvgettr:int: number of bytes read on current trace (0 after last trace)fgettra:int: number of traces in disk file Macros defined in segy.h#define gettr(x) fgettr(stdin, (x))#define vgettr(x) fgettr(stdin, (x))Usage example: segy tr; ... while (gettr(&tr)) { tr.offset = abs(tr.offset); puttr(&tr); } ...*****************************************************************************Authors: SEP: Einar Kjartansson, Stew Levin CWP: Shuki Ronen, Jack Cohen****************************************************************************//* * Revised: 7/2/95 Stewart A. Levin Mobil * Major rewrite: Use xdr library for portable su output file * format. Merge fgettr and fgettra into same source file. * Make input from multiple streams work (at long last!). * Revised: 11/22/95 Stewart A. Levin Mobil * Always set ntr for DISK input. This fixes susort failure. * Revised: 1/9/96 jkc CWP * Set lastfp on nread <=0 return, too. * Revised: 28 Mar, 2006 Stewart A. Levin Landmark Graphics * Reworked XDR to support random seeks on > 2GB files * and to read big endian SHORTPACK data on little endian machines. *//**************** end self doc ********************************/#ifndef TEST#ifdef SU_LINE_HEADERint out_line_hdr=1;#elseint out_line_hdr=0;#endif#include "su.h"#include "segy.h"int isebcdic_txt( unsigned char* ,int len);int isascii_txt( unsigned char* ,int len);int in_line_hdr=0;unsigned char su_text_hdr[3200];bhed su_binary_hdr;#ifdef SUXDR/********************************************code using XDR*********************************************/#include "su_xdr.h"#include "header.h"static struct insegyinfo { FILE *infp; /* FILE * ptr for search */ struct insegyinfo *nextinfo; /* linked list pointer */ unsigned off_t itr; /* number of traces read */ int nsfirst; /* samples from 1st header */ unsigned short bytesper; /* bytes per datum */ int nsegy; /* segy bytes from nsfirst */ unsigned off_t ntr; /* traces in input,if known */ FileType ftype; /* file type of input *fp */ XDR *segy_xdr; /* allocated XDR structure */ char *buf; /* buffer for trace I/O */ unsigned int bufstart; /* "offset" of start of buf */} *insegylist = (struct insegyinfo *) NULL;static FILE *lastfp = (FILE *) NULL;static struct insegyinfo *infoptr, **oldinfoptr;staticvoid searchlist(FILE *fp){ oldinfoptr = &insegylist; for(infoptr = insegylist; infoptr != ((struct insegyinfo *) NULL); infoptr = infoptr->nextinfo) { if(fp == infoptr->infp) break; oldinfoptr = &infoptr->nextinfo; }}staticint dataread(struct insegyinfo *iptr, segy *tp, cwp_Bool fixed_length){ unsigned int nsread = fixed_length?iptr->nsfirst:tp->ns; unsigned int databytes = infoptr->bytesper*nsread; int nread; int itest = 1; char *ctest = (char *) (&itest); /* read trace data */ switch(tp->trid) { case CHARPACK: nread = efread((char *) (&((tp->data)[0])),1,databytes, iptr->infp); case SHORTPACK: nread = efread((char *) (&((tp->data)[0])),1,databytes, iptr->infp); if(ctest[0]) swab((char *) (&((tp->data)[0])), (char *) (&((tp->data)[0])), databytes); break; default: nread = efread(((char *) (iptr->buf))+HDRBYTES,1,databytes, iptr->infp); if(nread != databytes || FALSE == xdr_vector(iptr->segy_xdr, (char *) (&((tp->data)[0])), nsread,sizeof(float),(xdrproc_t) xdr_float)) nread = 0; else nread = databytes; break; } if(nread > 0 && nread != databytes) err("%s: on trace #%ld, tried to read %d bytes, " "read %d bytes", __FILE__, (infoptr->itr)+1, databytes, nread); return(nread);}staticint fgettr_internal(FILE *fp, segy *tp, cwp_Bool fixed_length){ unsigned int startpos; /* xdr stream offset */ int nread; /* bytes seen by fread calls */ off_t curoff; if(fp != lastfp) /* search linked list for possible alternative */ searchlist(fp); if (infoptr == ((struct insegyinfo *) NULL)) { /* initialize new segy input stream */ unsigned int databytes; /* bytes from nsfirst */ /* allocate new segy input information table */ *oldinfoptr = (struct insegyinfo *) malloc(sizeof(struct insegyinfo)); infoptr = *oldinfoptr; infoptr->nextinfo = (struct insegyinfo *) NULL; /* save FILE * ptr */ infoptr->infp = fp; infoptr->itr = 0; infoptr->ntr = -1; /* allocate XDR struct and associate FILE * ptr */ infoptr->segy_xdr = (XDR *) malloc(sizeof(XDR)); switch (infoptr->ftype = filestat(fileno(fp))) { case DIRECTORY: err("%s: segy input can't be a directory", __FILE__); case TTY: err("%s: segy input can't be tty", __FILE__); break; default: /* the rest are ok */ break; } /* xdrstdio_create(infoptr->segy_xdr,fp,XDR_DECODE); */ infoptr->buf = ealloc1(sizeof(segy),sizeof(char)); xdrmem_create(infoptr->segy_xdr, infoptr->buf, sizeof(segy), XDR_DECODE); infoptr->bufstart = xdr_getpos(infoptr->segy_xdr); /* retrieve segy trace header */ nread = efread(infoptr->buf ,1 ,HDRBYTES ,infoptr->infp); if(nread != HDRBYTES || FALSE == xdrhdrsub(infoptr->segy_xdr,tp)) err("%s: bad first header", __FILE__); /* Have the header, now for the data */ infoptr->nsfirst = tp->ns; if (infoptr->nsfirst > SU_NFLTS) err("%s: unable to handle %d > %d samples per trace", __FILE__, infoptr->nsfirst, SU_NFLTS); switch(tp->trid) { case CHARPACK: infoptr->bytesper = sizeof(char); break; case SHORTPACK: infoptr->bytesper = 2*sizeof(char); break; default: infoptr->bytesper = BYTES_PER_XDR_UNIT; break; } databytes = infoptr->bytesper * tp->ns; infoptr->nsegy = databytes + HDRBYTES; nread = dataread(infoptr, tp, fixed_length); switch (nread) { case 0: err("%s: no data on first trace", __FILE__); default: if (nread != databytes) err("%s: first trace: tried to read %d bytes " "read %d bytes", __FILE__, databytes, nread); else nread += HDRBYTES; } if(infoptr->ftype == DISK) { /* compute ntr */ curoff = eftello(fp); efseeko(fp,(off_t) 0,SEEK_END); infoptr->ntr = eftello(fp)/infoptr->nsegy; efseeko(fp, curoff, SEEK_SET); /* restore location */ } } else { /* Not first entry */ xdr_setpos(infoptr->segy_xdr, infoptr->bufstart); nread = efread(infoptr->buf ,1 ,HDRBYTES ,infoptr->infp); if ( nread != HDRBYTES || FALSE == xdrhdrsub(infoptr->segy_xdr,tp)) nread=0; if(nread == HDRBYTES) nread += dataread(infoptr, tp, fixed_length); if (nread <= 0) { lastfp = infoptr->infp; return 0; } if (fixed_length && (tp->ns != infoptr->nsfirst)) err("%s: on trace #%ld, " "number of samples in header (%d) " "differs from number for first trace (%d)", __FILE__, infoptr->itr, tp->ns, infoptr->nsfirst); } ++(infoptr->itr); lastfp = infoptr->infp; return (nread);}int fgettr(FILE *fp, segy *tp){ return(fgettr_internal(fp,tp,cwp_true));}int fvgettr(FILE *fp, segy *tp){ return(fgettr_internal(fp,tp,cwp_false));}int fgettra(FILE *fp, segy *tp, int itr){ int nread; if(lastfp != fp) /* search for match */ searchlist(fp); if(infoptr == (struct insegyinfo *) NULL) { /* get first trace */ if(0 >= fgettr(fp, tp)) return(0); /* error return */ switch(infoptr->ftype) { case TTY: warn("stdin not redirected"); break; case DISK: /* correct */ break; default: err("%s: input must be disk file",__FILE__); break; } efseeko(fp,(off_t) 0,SEEK_END); infoptr->ntr = eftello(fp)/infoptr->nsegy; } /* end first entry initialization */ /* Check on requested trace number */ if(itr >= infoptr->ntr) err("%s: trying to read off end of file",__FILE__); /* Position file pointer at start of requested trace */ if(0 > efseeko(fp, ((off_t) itr) * ((off_t) infoptr->nsegy), SEEK_SET)) { err("%s: unable to seek xdr disk file to trace %d",__FILE__,itr); } nread=fgettr(fp, tp); if(nread != infoptr->nsegy) err("%s: read %d bytes with %d bytes in trace", __FILE__,nread,infoptr->nsegy); if(tp->ns != infoptr->nsfirst) warn("%s: header ns field = %d differs from first trace = %d", __FILE__,tp->ns,infoptr->nsfirst); return(infoptr->ntr);}#else /**********************************************************code without XDR ***********************************************************/#include "header.h"static struct insegyinfo { FILE *infp; /* FILE * ptr for search */ struct insegyinfo *nextinfo; /* linked list pointer */ unsigned off_t itr; /* number of traces read */ int nsfirst; /* samples from 1st header */ unsigned short bytesper; /* bytes per datum */ unsigned off_t nsegy; /* segy bytes from nsfirst */ unsigned off_t ntr; /* traces in input,if known */ FileType ftype; /* file type of input *fp */} *insegylist = (struct insegyinfo *) NULL;static FILE *lastfp = (FILE *) NULL;static struct insegyinfo *infoptr, **oldinfoptr;staticvoid searchlist(FILE *fp){ oldinfoptr = &insegylist; for(infoptr = insegylist; infoptr != ((struct insegyinfo *) NULL); infoptr = infoptr->nextinfo) { if(fp == infoptr->infp) break; oldinfoptr = &infoptr->nextinfo; }}staticint dataread(segy *tp, struct insegyinfo *iptr, cwp_Bool fixed_length){ unsigned int nsread = fixed_length?iptr->nsfirst:tp->ns; unsigned int databytes = infoptr->bytesper*nsread; int nread = (int) efread((char *) (&((tp->data)[0])),1, databytes, iptr->infp); if(nread > 0 && nread != databytes) err("%s: on trace #%ld, tried to read %d bytes, " "read %d bytes ", __FILE__, (infoptr->itr)+1, databytes, nread); return(nread);}staticint fgettr_internal(FILE *fp, segy *tp, cwp_Bool fixed_length) { int nread; /* bytes seen by fread calls */ unsigned char buf[240]; /* buffer for test for line header */ /* search linked list for possible alternative */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -