/* file: revise.c G. Moody 8 February 1991 Last revised: 18 May 2018 ------------------------------------------------------------------------------- revise: Convert obsolete-format header files into new ones Copyright (C) 1999 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . You may contact the author by e-mail (wfdb@physionet.org) or postal mail (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, please visit PhysioNet (http://www.physionet.org/). _______________________________________________________________________________ */ #include #include #include #ifndef __STDC__ extern double atof(); extern void exit(); #endif #ifndef BSD #include #else #include #endif WFDB_FILE *iheader; WFDB_Siginfo si[WFDB_MAXSIG]; WFDB_Time nsamples; main(argc, argv) int argc; char *argv[]; { char *record; int nsig; if (argc < 2) { (void)fprintf(stderr, "usage: %s record\n", argv[0]); (void)fprintf(stderr, " This program converts obsolete-format header files into new ones.\n"); exit(1); } record = argv[1]; if (strncmp(record, "header.", 7) == 0) record += 7; if ((nsig = readoldheader(record, si)) < 0) exit(2); (void)setheader(record, si, (unsigned)nsig); exit(0); /*NOTREACHED*/ } int readoldheader(record, siarray) char *record; WFDB_Siginfo *siarray; { char linebuf[256], *p; WFDB_Frequency f; WFDB_Signal s; WFDB_Time ns; unsigned int i; static char sep[] = " \t\n"; #ifndef atof double atof(); #endif #ifndef atol long atol(); #endif /* Try to open the header file. */ if ((iheader = wfdb_open("header", record, WFDB_READ)) == NULL) { wfdb_error("init: can't open header for record %s\n", record); return (-1); } /* Get the first token (the record name) from the first non-empty, non-comment line. */ do { if (fgets(linebuf, 256, iheader->fp) == NULL) { wfdb_error("init: can't find record name in record %s header\n", record); return (-2); } } while ((p = strtok(linebuf, sep)) == NULL || *p == '#'); if (iheader->fp != stdin && strcmp(p, record) != 0) { wfdb_error("init: record name in record %s header is incorrect\n", record); return (-2); } /* Identify which type of header file is being read by trying to get another token from the line which contains the record name. (Old-style headers have only one token on the first line, but new-style headers have two or more.) */ if (p = strtok((char *)NULL, sep)) { (void)fprintf(stderr, "The header for record %s appears not to be an old-style header.\n", record); return (-2); } else { /* We come here if there were no other tokens on the line which contained the record name. The file appears to be an old-style header file. */ WFDB_Group g, ng; int mpx; /* Determine the number of signal groups. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } ng = atoi(p); /* Now get information for each signal group. */ for (g = s = 0; g < ng; g++) { /* Set the group number for the first signal in the group. */ siarray[s].group = g; /* Get the signal file name. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL || (siarray[s].fname = (char *)malloc((unsigned)(strlen(p) + 1))) == NULL) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } (void)strcpy(siarray[s].fname, p); /* Determine the gain. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } siarray[s].gain = atof(p); /* Determine the sampling frequency. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL || (f = atof(p)) <= 0.) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } (void)setsampfreq(f); /* Determine the format, block size, and number of signals in this group. In old-style headers these three quantities are encoded into two fields. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } i = (unsigned)atoi(p); mpx = (p = strtok((char *)NULL, sep)) ? atoi(p) : 1; if (mpx == 0) mpx = 1; if (i != 8 && i != 16) { siarray[s].bsize = i; if (mpx < 0) { mpx = -mpx; siarray[s].fmt = 8; } else siarray[s].fmt = 16; } else { siarray[s].fmt = i; siarray[s].bsize = 0; } /* Determine the ADC resolution. */ siarray[s].adcres = (p = strtok((char *)NULL, sep)) ? atoi(p) : WFDB_DEFRES; /* Determine the ADC zero. */ siarray[s].adczero = (p = strtok((char *)NULL, sep)) ? atoi(p) : 0; /* Determine the initial value. */ if (fgets(linebuf, 256, iheader->fp) == NULL || (p = strtok(linebuf, sep)) == NULL) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } siarray[s].initval = atoi(p); /* Determine the number of samples. */ ns = (p = strtok((char *)NULL, sep)) ? atol(p) : 0L; if (ns < 0L) { wfdb_error("init: incorrect format in record %s header\n", record); return (-2); } if (nsamples == (WFDB_Time)0L) nsamples = ns; else if (ns > (WFDB_Time)0L && ns != nsamples) { wfdb_error("warning (init):\n"); wfdb_error(" record %s durations are inconsistent\n", record); /* nsamples must match the shortest record duration. */ if (nsamples > ns) nsamples = ns; } /* Determine the checksum. */ if (p = strtok((char *)NULL, sep)) { siarray[s].cksum = atoi(p); siarray[s].nsamp = ns; } else { siarray[s].cksum = 0; siarray[s].nsamp = (WFDB_Time)0L; } /* If this signal group contains more than one signal, make additional copies of the siginfo structure for the other signals. */ while (++s < WFDB_MAXSIG && --mpx > 0) siarray[s] = siarray[s-1]; if (s == WFDB_MAXSIG && (mpx > 0 || g < ng - 1)) { wfdb_error("init: too many signals in record %s\n", record); return (-2); } } /* Now generate signal descriptions for each signal. */ for (i = 0; i < s; i++) { if ((siarray[i].desc=(char *)malloc((unsigned)(strlen(record)+20))) == NULL) { wfdb_error("init: insufficient memory\n"); return (-2); } else (void)sprintf(siarray[i].desc, "record %s, signal %d", record, i); } } return (s); /* return number of available signals */ }