diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/app/rdsamp.c wfdb-10.5.0/app/rdsamp.c --- wfdb-10.4.25/app/rdsamp.c 2009-11-06 12:13:54.000000000 -0500 +++ wfdb-10.5.0/app/rdsamp.c 2010-03-16 10:23:37.000000000 -0400 @@ -1,9 +1,9 @@ /* file: rdsamp.c G. Moody 23 June 1983 - Last revised: 6 November 2009 + Last revised: 16 March 2010 ------------------------------------------------------------------------------- rdsamp: Print an arbitrary number of samples from each signal -Copyright (C) 1983-2009 George B. Moody +Copyright (C) 1983-2010 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 @@ -203,8 +203,8 @@ if (maxl && (to == 0L || to > from + maxl)) to = from + maxl; - /* Adjust timeunits if starting time is undefined. */ - if (timeunits == TIMSTR || timeunits == HHMMSS) { + /* Adjust timeunits if starting time or date is undefined. */ + if (timeunits == TIMSTR) { char *p = timstr(0L); if (*p != '[') timeunits = HHMMSS; else if (strlen(p) < 16) timeunits = SHORTTIMSTR; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/app/wrsamp.c wfdb-10.5.0/app/wrsamp.c --- wfdb-10.4.25/app/wrsamp.c 2010-01-21 15:11:33.000000000 -0500 +++ wfdb-10.5.0/app/wrsamp.c 2010-03-12 12:18:48.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wrsamp.c G. Moody 10 August 1993 - Last revised: 21 January 2010 + Last revised: 1 March 2010 ------------------------------------------------------------------------------- wrsamp: Select fields or columns from a file and generate a WFDB record @@ -32,18 +32,6 @@ /* The following definition yields dither with a triangular PDF in (-1,1). */ #define DITHER (((double)rand() + (double)rand())/RAND_MAX - 1.0) -/* Dynamic memory allocation macros */ -#define MEMERR(P, N, S) \ - { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ - (size_t)N, (size_t)S, #P); \ - exit(1); } -#define SFREE(P) { if (P) { free (P); P = 0; } } -#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } -#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } -#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } -#define SSTRCPY(P, Q) { if (Q) { \ - SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } - char *pname; char *read_line(FILE *ifile, char rsep) @@ -59,7 +47,7 @@ SREALLOC(buf, length+2, sizeof(char)); } if (c == EOF) { - free(buf); + SFREE(buf); return (buf = NULL); } buf[i++] = c; @@ -107,18 +95,14 @@ /* The function parseline() parses its first argument, a null-terminated string ('line'), into a Tokenarray ('ta'). On return, the token pointers (ta->token[]) -address locations within 'line', and the character that immediately follows -each token is replaced with a null. +address null-terminated tokens copied from 'line'; 'line' is not altered. -The second argument of parseline, ta, is a pointer to a Tokenarray (defined -above). If ta is NULL on entry, parseline allocates and returns a Tokenarray -that is sufficiently large to accomodate all of the tokens in 'line'. -Otherwise, parseline returns the number of tokens found in ta->ntokens, and the +The function returns the number of tokens found in ta->ntokens, and the token array on return contains either ta->ntokens or ta->maxtokens valid elements, whichever is smaller. If ta->ntokens > ta->maxtokens, the token array contains pointers to the first ta->maxtokens tokens. -The third and final argument of parseline, pmode, is a pointer to a Parsemode +The second argument of parseline, pmode, is a pointer to a Parsemode (also defined above). The caller can set up pmode to specify which characters in 'line' are token delimiters, which pairs of characters can be used to quote a token that may have embedded delimiters, whether to treat consecutive @@ -138,18 +122,18 @@ { "''", "\"\"", "()", "[]", "{}", "<>", NULL } /* quote characters */ }; -Tokenarray *parseline(char *line, Tokenarray *ta, Parsemode *pmode) +static char *tbuf; +static Tokenarray *ta; + +Tokenarray *parseline(char *line, Parsemode *pmode) { - int i, n = 0, state = 0; - char d, *p = line-1, *q = NULL; + int i, m = (strlen(line) + 1)/2, n = 0, state = 0; + char d, *p, *q = NULL; - if (ta == NULL) { - int m = (strlen(line) + 1)/2; - if (ta = (Tokenarray *)malloc(sizeof(int)*2 + sizeof(char *)*m)) - ta->maxtokens = m; - else - return (NULL); - } + SSTRCPY(tbuf, line); + p = tbuf-1; + SREALLOC(ta, sizeof(int)*2 + sizeof(char *)*m, 1); + ta->maxtokens = m; if (pmode == NULL) pmode = &defpmode; @@ -380,7 +364,7 @@ labels = line_has_alpha(line); /* parse it into tokens */ - ta = parseline(line, NULL, NULL); + ta = parseline(line, NULL); /* read selected column numbers into fv[...] */ if (i < argc) { @@ -438,7 +422,15 @@ si[i].fmt = format; si[i].spf = 1; si[i].bsize = 0; - si[i].adcres = WFDB_DEFRES; + switch (format) { + case 80: si[i].adcres = 8; break; + case 310: + case 311: si[i].adcres = 10; break; + case 212: si[i].adcres = 12; break; + case 24: si[i].adcres = 24; break; + case 32: si[i].adcres = 32; break; + default: si[i].adcres = WFDB_DEFRES; + } si[i].adczero = 0; si[i].baseline = 0; while (*gain == ' ') @@ -463,8 +455,7 @@ exit(4); } if (line_has_alpha(line)) { - free(ta); - ta = parseline(line, NULL, NULL); + ta = parseline(line, NULL); /* Copy units strings after trimming any surrounding spaces, parentheses, or brackets, and after replacing embedded spaces with underscores. */ @@ -511,8 +502,7 @@ /* read and copy samples */ while (line != NULL && (t1 == 0L || t++ < t1)) { - free(ta); - ta = parseline(line, NULL, NULL); + ta = parseline(line, NULL); for (i = 0; i < nf; i++) { double v; @@ -535,6 +525,12 @@ if (record != NULL) (void)newheader(record); wfdbquit(); + SFREE(fv); + SFREE(scalef); + SFREE(si); + SFREE(ta); + SFREE(tbuf); + SFREE(vout); exit(0); } diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/app/xform.c wfdb-10.5.0/app/xform.c --- wfdb-10.4.25/app/xform.c 2009-03-04 14:12:08.000000000 -0500 +++ wfdb-10.5.0/app/xform.c 2010-03-12 13:41:09.000000000 -0500 @@ -1,8 +1,8 @@ /* file: xform.c G. Moody 8 December 1983 - Last revised: 4 March 2009 + Last revised: 12 March 2010 ------------------------------------------------------------------------------- xform: Sampling frequency, amplitude, and format conversion for WFDB records -Copyright (C) 1983-2009 George B. Moody +Copyright (C) 1983-2010 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 @@ -393,10 +393,14 @@ " 310 3 10-bit amplitudes bit-packed in 15 LS bits of each of 2 words\n"); (void)fprintf(stderr, " 311 3 10-bit amplitudes bit-packed in 30 LS bits of 4 bytes\n"); + (void)fprintf(stderr, + " 24 24-bit two's complement amplitudes (LSB first)\n"); + (void)fprintf(stderr, + " 32 32-bit two's complement amplitudes (LSB first)\n"); do { format = dfin[0].fmt; (void)fprintf(stderr, - "Choose an output format (8/16/61/80/160/212/310/311) [%d]: ", + "Choose an output format (8/16/61/80/160/212/310/311/24/32) [%d]: ", format); (void)fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &format); @@ -465,13 +469,11 @@ } dfout[i].units = *units[i] ? units[i] : NULL; } - do { - (void)fprintf(stderr, " Signal %d gain (adu/%s) [%g]: ", - i, dfout[i].units ? dfout[i].units : "mV", - dfout[i].gain); - (void)fgets(answer, sizeof(answer), ttyin); - (void)sscanf(answer, "%lf", &dfout[i].gain); - } while (dfout[i].gain < 0.); + (void)fprintf(stderr, " Signal %d gain (adu/%s) [%g]: ", + i, dfout[i].units ? dfout[i].units : "mV", + dfout[i].gain); + (void)fgets(answer, sizeof(answer), ttyin); + sscanf(answer, "%lf", &dfout[i].gain); do { if (i > 0) dfout[i].adcres = dfout[i-1].adcres; switch (dfout[i].fmt) { @@ -486,17 +488,25 @@ if (dfout[i].adcres < 8 || dfout[i].adcres > 10) dfout[i].adcres = 10; break; + case 24: + if (dfout[i].adcres < 8 || dfout[i].adcres > 24) + dfout[i].adcres = 24; + break; + case 32: + if (dfout[i].adcres < 8 || dfout[i].adcres > 32) + dfout[i].adcres = 32; + break; default: if (dfout[i].adcres < 8 || dfout[i].adcres > 16) dfout[i].adcres = WFDB_DEFRES; break; } (void)fprintf(stderr, - " Signal %d ADC resolution in bits (8-16) [%d]: ", i, + " Signal %d ADC resolution in bits (8-32) [%d]: ", i, dfout[i].adcres); (void)fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &dfout[i].adcres); - } while (dfout[i].adcres < 8 || dfout[i].adcres > 16); + } while (dfout[i].adcres < 8 || dfout[i].adcres > 32); (void)fprintf(stderr, " Signal %d ADC zero level (adu) [%d]: ", i, dfout[i].adczero); (void)fgets(answer, sizeof(answer), ttyin); @@ -650,6 +660,12 @@ case 310: dfin[j].adcres = 10; break; + case 24: + dfin[j].adcres = 24; + break; + case 32: + dfin[j].adcres = 32; + break; default: dfin[j].adcres = WFDB_DEFRES; break; @@ -715,7 +731,7 @@ /* Determine the legal range of sample values for each output signal. */ for (i = 0; i < nosig; i++) { vmax[i] = dfout[i].adczero + (1 << (dfout[i].adcres-1)) - 1; - vmin[i] = dfout[i].adczero - (1 << (dfout[i].adcres-1)); + vmin[i] = dfout[i].adczero + (-1 << (dfout[i].adcres-1)) + 1; } /* If resampling is required, initialize the interpolation/decimation diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/checkpkg/expected/lcheck.log-NETFILES wfdb-10.5.0/checkpkg/expected/lcheck.log-NETFILES --- wfdb-10.4.25/checkpkg/expected/lcheck.log-NETFILES 2009-02-24 16:35:07.000000000 -0500 +++ wfdb-10.5.0/checkpkg/expected/lcheck.log-NETFILES 2010-02-26 17:28:23.000000000 -0500 @@ -6,7 +6,7 @@ [OK]: WFDB_MAXRNL = 20 [OK]: WFDB_MAXUSL = 20 [OK]: WFDB_MAXDSL = 60 -[OK]: Signal formats = {0, 8, 16, 61, 80, 160, 212, 310, 311} +[OK]: Signal formats = {0, 8, 16, 61, 80, 160, 212, 310, 311, 24, 32} [OK]: WFDB_DEFFREQ = 250 [OK]: WFDB_DEFGAIN = 200 [OK]: WFDB_DEFRES = 12 diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/checkpkg/expected/lcheck.log-no-NETFILES wfdb-10.5.0/checkpkg/expected/lcheck.log-no-NETFILES --- wfdb-10.4.25/checkpkg/expected/lcheck.log-no-NETFILES 2009-02-24 16:38:54.000000000 -0500 +++ wfdb-10.5.0/checkpkg/expected/lcheck.log-no-NETFILES 2010-02-26 17:28:20.000000000 -0500 @@ -6,7 +6,7 @@ [OK]: WFDB_MAXRNL = 20 [OK]: WFDB_MAXUSL = 20 [OK]: WFDB_MAXDSL = 60 -[OK]: Signal formats = {0, 8, 16, 61, 80, 160, 212, 310, 311} +[OK]: Signal formats = {0, 8, 16, 61, 80, 160, 212, 310, 311, 24, 32} [OK]: WFDB_DEFFREQ = 250 [OK]: WFDB_DEFGAIN = 200 [OK]: WFDB_DEFRES = 12 diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/checkpkg/expected/xform-2.out wfdb-10.5.0/checkpkg/expected/xform-2.out --- wfdb-10.4.25/checkpkg/expected/xform-2.out 2001-08-15 15:42:56.000000000 -0400 +++ wfdb-10.5.0/checkpkg/expected/xform-2.out 2010-03-12 10:55:36.000000000 -0500 @@ -10,5 +10,7 @@ 212 2 12-bit amplitudes bit-packed in 3 bytes 310 3 10-bit amplitudes bit-packed in 15 LS bits of each of 2 words 311 3 10-bit amplitudes bit-packed in 30 LS bits of 4 bytes -Choose an output format (8/16/61/80/160/212/310/311) [212]: Save all signals in one file? [y]: Signal 0 gain (adu/mV) [2456]: Signal 0 ADC resolution in bits (8-16) [12]: Signal 0 ADC zero level (adu) [0]: Signal 1 gain (adu/mmHg) [13.335]: Signal 1 ADC resolution in bits (8-16) [12]: Signal 1 ADC zero level (adu) [0]: Signal 2 gain (adu/mV) [1053]: Signal 2 ADC resolution in bits (8-16) [12]: Signal 2 ADC zero level (adu) [0]: Signal 3 gain (adu/mmHg) [39.8]: Signal 3 ADC resolution in bits (8-16) [12]: Signal 3 ADC zero level (adu) [0]: Checking input signals ... done + 24 24-bit two's complement amplitudes (LSB first) + 32 32-bit two's complement amplitudes (LSB first) +Choose an output format (8/16/61/80/160/212/310/311/24/32) [212]: Save all signals in one file? [y]: Signal 0 gain (adu/mV) [2456]: Signal 0 ADC resolution in bits (8-32) [12]: Signal 0 ADC zero level (adu) [0]: Signal 1 gain (adu/mmHg) [13.335]: Signal 1 ADC resolution in bits (8-32) [12]: Signal 1 ADC zero level (adu) [0]: Signal 2 gain (adu/mV) [1053]: Signal 2 ADC resolution in bits (8-32) [12]: Signal 2 ADC zero level (adu) [0]: Signal 3 gain (adu/mmHg) [39.8]: Signal 3 ADC resolution in bits (8-32) [12]: Signal 3 ADC zero level (adu) [0]: Checking input signals ... done . diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/convert/wfdb2mat.c wfdb-10.5.0/convert/wfdb2mat.c --- wfdb-10.4.25/convert/wfdb2mat.c 2009-03-25 09:18:17.000000000 -0400 +++ wfdb-10.5.0/convert/wfdb2mat.c 2010-03-16 11:37:26.000000000 -0400 @@ -1,8 +1,8 @@ /* file: wfdb2mat.c G. Moody 26 February 2009 - Last revised: 25 March 2009 + Last revised: 16 March 2010 ------------------------------------------------------------------------------- wfdb2mat: Convert (all or part of) a WFDB signal file to Matlab .mat format -Copyright (C) 2009 George B. Moody +Copyright (C) 2009-2010 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 @@ -46,9 +46,11 @@ This program writes version 4 MAT-file format output files, as documented in http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf -The samples are written as 16-bit signed integers in little-endian format -(type=30 below), or as 8-bit unsigned integers (type=50) for records that -contain only 8-bit unsigned samples. +The samples are written as 32-bit signed integers (mattype=20 below) in +little-endian format if the record contains any format 24 or format 32 signals, +as 8-bit unsigned integers (mattype=50) if the record contains only format 80 +signals, or as 16-bit signed integers in little-endian format (mattype=30) +otherwise. Although version 5 and newer versions of Matlab normally use a different (less compact and more complex) format, they can read these files without difficulty. @@ -73,17 +75,11 @@ #include #include -/* Dynamic memory allocation macros. */ -#define MEMERR(P, N, S) \ - { wfdb_error("%s: can't allocate (%ld*%ld) bytes for %s\n", \ - pname, (size_t)N, (size_t)S, #P); \ - exit(1); } -#define SFREE(P) { if (P) { free (P); P = 0; } } -#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } -#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } -#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } -#define SSTRCPY(P, Q) { if (Q) { \ - SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } +/* Output .mat file types (values of mattype), defined by the .mat format + specification, see above */ +#define MAT8 50 /* 8 bits per sample */ +#define MAT16 30 /* 16 bits per sample */ +#define MAT32 20 /* 32 bits per sample */ char *pname; @@ -93,8 +89,8 @@ { char *matname, *orec, *p, *q, *record = NULL, *search = NULL, *prog_name(); static char prolog[24]; - int highres = 0, i, isiglist, nisig, nosig = 0, pflag = 0, s, *sig = NULL, - stat = 0, type = 50, vflag = 0; + int highres = 0, i, isiglist, mattype, nisig, nosig = 0, pflag = 0, + s, *sig = NULL, stat = 0, vflag = 0, wfdbtype; WFDB_Frequency freq; WFDB_Sample *vi, *vo; WFDB_Siginfo *si, *so; @@ -258,16 +254,23 @@ for (p = matname + strlen(matname) - 5; p > matname && *p != '/'; p--) if (*p == '.') *p = '_'; - /* Determine if we can write 8-bit unsigned samples, or if 16 bits are + /* Determine if we can write 8-bit unsigned samples, or if 16 or 32 bits are needed per sample. */ + mattype = MAT8; + wfdbtype = 80; for (i = 0; i < nosig; i++) - if (si[sig[i]].fmt != 80) { type = 30; break; } + switch (si[sig[i]].fmt) { + case 24: + case 32: mattype = MAT32; wfdbtype = 32; break; + case 80: break; + default: if (mattype != MAT32) mattype = MAT16; wfdbtype = 16; break; + } for (i = 0; i < nosig; i++) { so[i] = si[sig[i]]; so[i].fname = matname; so[i].group = 0; so[i].spf = 1; - so[i].fmt = (type == 30) ? 16 : 80; + so[i].fmt = wfdbtype; if (so[i].units == NULL) SSTRCPY(so[i].units, "mV"); } @@ -279,8 +282,8 @@ /* Fill in the .mat file's prolog and write it. (Elements of prolog[] not set explicitly below are always zero.) */ - prolog[ 0] = type & 0xff; /* format */ - prolog[ 1] = (type >> 8) & 0xff; + prolog[ 0] = mattype & 0xff; /* format */ + prolog[ 1] = (mattype >> 8) & 0xff; prolog[ 4] = nosig & 0xff; /* number of rows */ prolog[ 5] = (nosig >> 8) & 0xff; prolog[ 6] = (nosig >> 16) & 0xff; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/doc/wag-src/signal.5 wfdb-10.5.0/doc/wag-src/signal.5 --- wfdb-10.4.25/doc/wag-src/signal.5 2005-09-02 22:11:36.000000000 -0400 +++ wfdb-10.5.0/doc/wag-src/signal.5 2010-03-01 15:30:37.000000000 -0500 @@ -1,4 +1,4 @@ -.TH SIGNAL 5 "2 September 2005" "WFDB software 10.3.18" "WFDB Applications Guide" +.TH SIGNAL 5 "1 March 2010" "WFDB software 10.5.0" "WFDB Applications Guide" .SH NAME signal \- WFDB signal file formats .SH DESCRIPTION @@ -29,6 +29,14 @@ Historically, the format used for MIT\-BIH and AHA database distribution 9-track tapes was format 16, with the addition of a logical EOF (octal 0100000) and null-padding after the logical EOF. +.SS Format 24 +.PP +Each sample is represented by a 24-bit two's complement amplitude stored +least significant byte first. +.SS Format 32 +.PP +Each sample is represented by a 32-bit two's complement amplitude stored +least significant byte first. .SS Format 61 .PP Each sample is represented by a 16-bit two's complement amplitude stored @@ -77,6 +85,18 @@ using the WFDB library to write a format 311 signal file). This process is repeated for each successive set of three samples. +.PP +If the format specifies a number of bits per sample that exceeds the number of +bits in a \fBWFDB_Sample\fR, the excess high bits are not read on input, and +they are replaced by zeroes on output. Currently, this can happen only when +using formats 24 or 32 on a 16-bit platform (unusual except for embedded +processors); in this case, the \fBWFDB_Sample\fR data type may be redefined as +\fBlong\fR (in \fIwfdb/wfdb.h\fR) before compiling the WFDB library and +applications, to enable full-precision processing of signals in all formats. +This is not done by default since it would increase memory and computational +requirements unnecessarily in embedded applications that do not require 24- or +32-bit precision. + .SH SEE ALSO \fBannot\fR(5), \fBheader\fR(5), \fBwfdbcal\fR(5) .br diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/doc/wpg-src/wpg0.tex wfdb-10.5.0/doc/wpg-src/wpg0.tex --- wfdb-10.4.25/doc/wpg-src/wpg0.tex 2010-01-21 17:51:02.000000000 -0500 +++ wfdb-10.5.0/doc/wpg-src/wpg0.tex 2010-03-16 21:35:45.000000000 -0400 @@ -510,7 +510,38 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. -@unnumberedsubsec Changes in version 10.4.25 (21 January 2009) +@unnumberedsubsec Changes in version 10.5.0 (16 March 2010) + +The WFDB library now supports signals with 24 and 32 bits of +precision, using new formats 24 and 32, and WFDB applications can read +BDF and BDF+ files (24-bit EDF and EDF+ variants). Note that these +formats, unlike all previously defined formats, require more than 16 +bits per sample value. If the WFDB software is compiled on a 16-bit +platform (unusual except for embedded processors), the excess high +bits of signals in these formats are not read on input, and they are +replaced by zeroes on output, unless the @code{WFDB_Sample} data type +has been redefined as @code{long} (in @file{wfdb.h}). This is not +done by default since it would increase memory and computational +requirements unnecessarily in embedded applications that do not +require 24- or 32-bit precision. + +Since support for extended precision samples cannot be introduced +without this limitation in backward compatibility for 16-bit +platforms, the minor version number of the library has been +incremented to 5. Most users will not be affected by this change, +however, apart from the new functionality it provides. + +Memory allocation macros that have been defined previously in +@file{wfdblib.h} have been moved to @file{wfdb.h} so they are +accessible to WFDB applications, including user-written applications. +For information about using these macros (MEMERR, SFREE, SUALLOC, +SALLOC, SREALLOC, and SSTRCPY), @pxref{Memory Allocation Macros}. + +A buffer overflow in the WFDB library's internal function @code{edfparse()} +(in @file{signal.c}) has been corrected, thanks to a bug report and patch +from Joonas Paalasmaa. + +@unnumberedsubsec Changes in version 10.4.25 (21 January 2010) In WFDB library versions 10.4.5 through 10.4.24, strtim("e") did not work properly when the open input record was an EDF file and high @@ -4027,7 +4058,7 @@ first introduced in WFDB library version 6.0.) @page -@node miscellaneous functions, , calibration, Functions +@node miscellaneous functions, memory allocation, calibration, Functions @section Miscellaneous WFDB Functions @menu @@ -5163,6 +5194,144 @@ @code{wfdbsetstart(}@var{s, bytes}@code{)}. (This function was first introduced in WFDB library version 10.4.15.) +@page +@node memory allocation, , miscellaneous functions, Functions +@section Memory Allocation Macros + +@menu +* MEMERR:: Handling a memory allocation error. +* SFREE:: Safely release allocated memory. +* SUALLOC:: Safely allocate memory using a new pointer. +* SALLOC:: Safely allocate memory, reusing a pointer. +* SREALLOC:: Safely expand a chunk of allocated memory. +* SSTRCPY:: Safely copy a string into a new buffer. + +@end menu + +@c @group +@node MEMERR, SFREE, memory allocation, memory allocation +@unnumberedsubsec MEMERR +@findex MEMERR (10.5.0) +@cindex insufficient memory +@cindex memory errors +@cindex allocation errors + +@example +MEMERR(@var{object_name}, size_t @var{n_elements}, size_t @var{element_size}) +@end example +@c @end group + +@noindent +This macro uses @code{wfdb_error} to send a short error message of the +form @code{WFDB: can't allocate (@var{n_elements}*@var{element_size}) +bytes for @var{object_name})}. Unless @code{wfdbmemerr(1)} has been +invoked previously, the process that invoked @code{MEMERR} exits immediately. + +@c @group +@node SFREE, SUALLOC, MEMERR, memory allocation +@unnumberedsubsec SFREE +@findex SFREE (10.5.0) +@cindex release allocated memory +@cindex freeing allocated memory +@cindex memory deallocation + +@example +SFREE(@var{object} *@var{pointer}) +@end example +@c @end group + +@noindent +This macro releases memory previously allocated to the @var{object} addressed +by the specified @var{pointer}, somewhat more safely than by invoking the +standard @code{free()} function. On completion, @var{pointer} is set to NULL. + +@code{SFREE} does nothing if @var{pointer} is initially NULL (unlike +@code{free()}, which may cause the process to crash). If @code{SFREE} receives +a non-NULL pointer, it passes that pointer to @code{free()}, which may cause a +crash if the pointer does not point to an allocated block of memory. + +@c @group +@node SUALLOC, SALLOC, SFREE, memory allocation +@unnumberedsubsec SUALLOC +@findex SUALLOC (10.5.0) +@cindex allocating memory +@cindex memory allocation + +@example +SUALLOC(@var{object_name}, size_t @var{n_elements}, size_t @var{element_size}) +@end example +@c @end group + +@noindent +This macro allocates memory sufficient for @var{n_elements} items of +@var{element_size} bytes each, and sets the pointer given by @var{object_name} +to point to the allocated memory. If there is not enough available memory, +@code{SUALLOC} invokes @code{MEMERR} (above). + +@code{SUALLOC} does not check to see if @var{object_name} already points to +allocated memory, which will lead to memory leaks if so. + +@c @group +@node SALLOC, SREALLOC, SUALLOC, memory allocation +@unnumberedsubsec SALLOC +@findex SALLOC (10.5.0) +@cindex allocating memory +@cindex memory allocation + +@example +SALLOC(@var{object_name}, size_t @var{n_elements}, size_t @var{element_size}) +@end example +@c @end group + +@noindent +This macro allocates memory sufficient for @var{n_elements} items of +@var{element_size} bytes each, and sets the pointer given by @var{object_name} +to point to the allocated memory. If there is not enough available memory, +@code{SALLOC} invokes @code{MEMERR} (above). + +If @var{object_name} is initially non-NULL, @code{SALLOC} frees it using +@code{SFREE} before allocating the requested memory. + +@c @group +@node SREALLOC, SSTRCPY, SALLOC, memory allocation +@unnumberedsubsec SREALLOC +@findex SREALLOC (10.5.0) +@cindex allocating memory +@cindex expanding allocated memory +@cindex memory allocation +@cindex reallocating memory + +@example +SREALLOC(@var{object_name}, size_t @var{n_elements}, size_t @var{element_size}) +@end example +@c @end group + +@noindent +This macro allocates memory sufficient for @var{n_elements} items of +@var{element_size} bytes each, and sets the pointer given by @var{object_name} +to point to the allocated memory. If there is not enough available memory, +@code{SREALLOC} invokes @code{MEMERR} (above). + +@code{SREALLOC} attempts to reuse the memory previously allocated to +@var{object_name} rather than releasing it and then making a new request. + +@c @group +@node SSTRCPY, , SREALLOC, memory allocation +@unnumberedsubsec SSTRCPY +@findex SSTRCPY (10.5.0) +@cindex allocating strings +@cindex string allocation + +@example +SSTRCPY(char *destination, char *source) +@end example +@c @end group + +@noindent +This macro copies the @var{source} string (including a trailing null character) +into newly-allocated memory, and it sets @var{destination} to point to the copy. +If @var{destination} is not NULL on entry, @code{SSTRCPY} uses @code{SFREE} +to release the previously allocated memory. @node Data Types, Annotation Codes, Functions, Top @chapter Data Types diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/doc/wug-src/wave/ppm/find-window.ppm.gz wfdb-10.5.0/doc/wug-src/wave/ppm/find-window.ppm.gz --- wfdb-10.4.25/doc/wug-src/wave/ppm/find-window.ppm.gz 2001-11-27 13:21:43.000000000 -0500 +++ wfdb-10.5.0/doc/wug-src/wave/ppm/find-window.ppm.gz 2010-02-12 18:10:32.000000000 -0500 @@ -1,5 +1,11 @@ -<find-window.ppm6FH qg]CIL],@$|;_~|q??{K1dCaqɁ5Á "2X@, C !@D  "Cd!2_2( Ȱ2_(Yo@_7Рgf R2Lsa3o}|4_v C񩼃ؾXuhZ6a'!/7“*ذbƢۃ E @d=CM>Aga/=w_ʗ* |t7=mil/--|?76r7Abv8Aħ<bӟx$2<2䑕!B_~v~mhaʚe82D?⼭p}B< 1)Tbd8r p(:7OB?P ۖ"cZ֎S~Ó"22M= -bӹ^ "~@iO) 2,T8i և aN f Rx/ 9pnއFDd "2X@, C !@D  "Cdu\dpOdx6:T \ No newline at end of file +uKfind-window.ppmo3^5U*ڪ$Z)(@(MHR h^&0% 4pc 69^}/~9`1@1CٙgwϷ{sߏZ>3lo/^AOhqUeՒ^[o?g_w|g|3ߪ EX8 *wݺ(Z?Cf*4vVSS C3ך]W`ηAit|xʽVhg(sNE Qwr75^o43y#}A:52w׷]g(DQAP?o:o|smPYsKx(ꕵJfhPeJU+~)36tcAPTyBWֽ^|iBƘkZc-skC g-}=JqKz~SA)ndFrr-4#{>A?3FAZ2l(}J@Lg$2007y ; g&X% . %5wt)qez=pO(rC@_7 Fho5iJ42ō%8ċ}L۟;`zasH= }՚=ҜvW6TNw:um7uozG'PYsK{oRCq~ ǂQf>x[:%TLXy>ϝVϋ#G!/+CuDoMlWbJ`s'B g-{)-={N =9y8N$#d[:%T~)/޹;sjz.+ޞ^}cwCAӁƁ31zcVZҭQ.^/aGvjXP\ ^d6NXQ2*ᬹe(-=}-Gf̼?OŹSA'F=5Nrp~ev^}p7ˋ BўaBG/d/\fbOX D[P`Bc(pѦh/'#H͚y2OfL[:%T{{HyI^"v B3 ׯ/P5${ndۙw #;g5n(-ޑmv'W#GSV斾r{RINX:%T5$/w{V̎[6{nT&y*"l/Btsv7q2^4OLYU~ZΚ[5)U`LR3@23NU6\P^ L!h]f1f[גIcD{F5BTodGy3Im_\ߵ|!VI]HJ8kn˶^V[֌ L$ЙQ^f?ld < }t,fm9<֜u5>>n^P9}r,~(l ɛIB/ݱZPYsKFWEA4t8Ƨ{-}?C g-} A:/+•g(ᬹ<ANzk} %57 IoZ^^ Wg(ᬹ4ANZ[zM{-zsΚ[o| H'ym[kњ %5t HLKap/I ,sKzף=sc@'(^GAN%7p){j( +U&ku҇PFd V綐5d]Lm5P-RrR8Ad` * G6+߸/K˜VѬF( Km; J[&fW9fbIZZ:At!, +%*U/qO+%(qaj.nKA=SRS =` /;jkIз +(wUl"Be-eمZI%FɖXl`~x^΀ +Ƌo-6UdDplU2'5HEqts)"ɕ;Nw[܅&xl 8U&* +#P:rcvQ椰Fx#7>(t3E1rtRK~Ae, OP` +^1ǀ` tX:h,Km6@` tX:h,OzY7]\?EPć Ks}n vT^D!UP,99OʄK/+w~ߌ<īlφ+ }̾|c҅ Ÿ]FBxը$C4sskew = 0; SSTRCPY(hsd[s]->info.fname, edf_fname); hsd[s]->info.group = hsd[s]->info.bsize = hsd[s]->info.cksum = 0; - hsd[s]->info.fmt = 16; + hsd[s]->info.fmt = format; hsd[s]->info.nsamp = nframes; - wfdb_fread(junk, 1, 16, ifile); /* signal type */ - junk[16] = ' '; - for (i = 16; i >= 0 && junk[i] == ' '; i--) - junk[i] = '\0'; - SSTRCPY(hsd[s]->info.desc, junk); + wfdb_fread(buf, 1, 16, ifile); /* signal type */ + buf[16] = ' '; + for (i = 16; i >= 0 && buf[i] == ' '; i--) + buf[i] = '\0'; + SSTRCPY(hsd[s]->info.desc, buf); } for (s = 0; s < nsig; s++) - wfdb_fread(junk, 1, 80, ifile); /* transducer type (ignored) */ + wfdb_fread(buf, 1, 80, ifile); /* transducer type (ignored) */ for (s = 0; s < nsig; s++) { wfdb_fread(buf, 1, 8, ifile); /* signal units */ @@ -727,7 +731,7 @@ } for (s = 0; s < nsig; s++) - wfdb_fread(junk, 1, 80, ifile); /* filtering information (ignored) */ + wfdb_fread(buf, 1, 80, ifile); /* filtering information (ignored) */ for (s = framelen = 0; s < nsig; s++) { int n; @@ -1291,6 +1295,7 @@ written and the signal group pointer). */ static int _l; /* macro temporary storage for low byte of word */ +static int _L; /* macro temporary storage for low 16 bits of int */ static int _n; /* macro temporary storage for byte count */ #define r8(G) ((G->bp < G->be) ? *(G->bp++) : \ @@ -1312,6 +1317,10 @@ #define w16(V,G) (w8((V), (G)), w8(((V) >> 8), (G))) #define r61(G) (_l = r8(G), ((int)((short)((r8(G) & 0xff) | (_l << 8))))) #define w61(V,G) (w8(((V) >> 8), (G)), w8((V), (G))) +#define r24(G) (_L = r16(G), ((int)((r8(G) << 16) | (_L & 0xffff)))) +#define w24(V,G) (w16((V), (G)), w8(((V) >> 16), (G))) +#define r32(G) (_L = r16(G), ((int)((r16(G) << 16) | (_L & 0xffff)))) +#define w32(V,G) (w16((V), (G)), w16(((V) >> 16), (G))) #else static int r16(struct igdata *g) @@ -1343,6 +1352,40 @@ w8((v >> 8), g); w8(v, g); } + +/* r24: read and return the next sample from a format 24 signal file */ +static int r24(struct igdata *g) +{ + int l, h; + + l = r16(g); + h = r8(g); + return ((int)((h << 16) | (l & 0xffff))); +} + +/* w24: write the next sample to a format 24 signal file */ +static void w24(WFDB_Sample v, struct ogdata *g) +{ + w16(v, g); + w8((v >> 16), g); +} + +/* r32: read and return the next sample from a format 32 signal file */ +static int r32(struct igdata *g) +{ + int l, h; + + l = r16(g); + h = r16(g); + return ((int)((h << 16) | (l & 0xffff))); +} + +/* w32: write the next sample to a format 32 signal file */ +static void w32(WFDB_Sample v, struct ogdata *g) +{ + w16(v, g); + w16((v >> 16), g); +} #endif #define r80(G) ((r8(G) & 0xff) - (1 << 7)) @@ -1459,7 +1502,7 @@ break; } } - + static int isgsetframe(WFDB_Group g, WFDB_Time t) { int i, trem = 0; @@ -1580,6 +1623,8 @@ return (0); } b = 4*nn; d = 3; break; + case 24: b = 3*nn; break; + case 32: b = 4*nn; break; } /* Seek to the beginning of the block which contains the desired sample. @@ -1685,35 +1730,64 @@ default: *vector = v = is->samp += r8(ig); break; case 16: /* 16-bit amplitudes */ - *vector = v = r16(ig); break; + *vector = v = r16(ig); + if (v == -1 << 15) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; + break; case 61: /* 16-bit amplitudes, bytes swapped */ - *vector = v = r61(ig); break; + *vector = v = r61(ig); + if (v == -1 << 15) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; + break; case 80: /* 8-bit offset binary amplitudes */ *vector = v = r80(ig); - if (v == -128) + if (v == 0) *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; else is->samp = *vector; break; case 160: /* 16-bit offset binary amplitudes */ - *vector = v = r160(ig); break; + *vector = v = r160(ig); + if (v == 0) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; + break; case 212: /* 2 12-bit amplitudes bit-packed in 3 bytes */ *vector = v = r212(ig); - if (v == -2048) + if (v == -1 << 11) *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; else is->samp = *vector; break; case 310: /* 3 10-bit amplitudes bit-packed in 4 bytes */ *vector = v = r310(ig); - if (v == -512) + if (v == -1 << 9) *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; else is->samp = *vector; break; case 311: /* 3 10-bit amplitudes bit-packed in 4 bytes */ *vector = v = r311(ig); - if (v == -512) + if (v == -1 << 9) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; + break; + case 24: /* 24-bit amplitudes */ + *vector = v = r24(ig); + if (v == -1 << 23) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; + break; + case 32: /* 32-bit amplitudes */ + *vector = v = r32(ig); + if (v == -1 << 31) *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; else is->samp = *vector; @@ -2420,22 +2494,27 @@ if (os->info.nsamp++ == (WFDB_Time)0L) os->info.initval = os->samp = *vector; for (c = 0; c < os->info.spf; c++, vector++) { - if (*vector == WFDB_INVALID_SAMPLE) /* use lowest possible value */ + /* Replace invalid samples with lowest possible value for format */ + if (*vector == WFDB_INVALID_SAMPLE) switch (os->info.fmt) { case 0: case 8: case 16: case 61: default: - break; + *vector = -1 << 15; break; case 80: case 160: *vector = 0; break; case 212: - *vector = -2048; break; + *vector = -1 << 11; break; case 310: case 311: - *vector = -512; break; + *vector = -1 << 9; break; + case 24: + *vector = -1 << 23; break; + case 32: + *vector = -1 << 31; break; } switch (os->info.fmt) { case 0: /* null signal (do not write) */ @@ -2462,6 +2541,10 @@ w310(*vector, og); os->samp = *vector; break; case 311: /* 3 10-bit amplitudes bit-packed in 4 bytes */ w311(*vector, og); os->samp = *vector; break; + case 24: /* 24-bit amplitudes */ + w24(*vector, og); os->samp = *vector; break; + case 32: /* 32-bit amplitudes */ + w32(*vector, og); os->samp = *vector; break; } if (wfdb_ferror(og->fp)) { wfdb_error("putvec: write error in signal %d\n", s); diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/lib/wfdb.h wfdb-10.5.0/lib/wfdb.h --- wfdb-10.4.25/lib/wfdb.h 2010-01-21 20:49:21.000000000 -0500 +++ wfdb-10.5.0/lib/wfdb.h 2010-03-16 21:43:47.000000000 -0400 @@ -1,10 +1,10 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 28 July 2009 wfdblib 10.4.22 + Last revised: 12 March 2010 wfdblib 10.5.0 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1983-2009 George B. Moody +Copyright (C) 1983-2010 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -32,8 +32,8 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 -#define WFDB_MINOR 4 -#define WFDB_RELEASE 25 +#define WFDB_MINOR 5 +#define WFDB_RELEASE 0 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 @@ -79,8 +79,14 @@ typedef unsigned int WFDB_Signal; /* signal number */ typedef unsigned int WFDB_Annotator;/* annotator number */ -#define WFDB_INVALID_SAMPLE (-32768) /* samples from getvec or getframe with - this value are not valid */ +/* getvec and getframe return a sample with a value of WFDB_INVALID_SAMPLE + when the amplitude of a signal is undefined (e.g., the input is clipped or + the signal is not available) and padding is disabled (see WFDB_GVPAD, below). + WFDB_INVALID_SAMPLE is the minimum value for a 16-bit WFDB_Sample. In + a format 24 or 32 signal, this value will be near mid-range, but it should + occur only rarely in such cases; if this is a concern, WFDB_INVALID_SAMPLE + can be redefined and the WFDB library can be recompiled. */ +#define WFDB_INVALID_SAMPLE (-32768) /* Array sizes Many older applications use the values of WFDB_MAXANN, WFDB_MAXSIG, and @@ -113,9 +119,11 @@ 212 2 12-bit amplitudes bit-packed in 3 bytes 310 3 10-bit amplitudes bit-packed in 4 bytes 311 3 10-bit amplitudes bit-packed in 4 bytes + 24 24-bit 2's complement amplitudes, low byte first + 32 32-bit 2's complement amplitudes, low byte first */ -#define WFDB_FMT_LIST {0, 8, 16, 61, 80, 160, 212, 310, 311} -#define WFDB_NFMTS 9 /* number of items in FMT_LIST */ +#define WFDB_FMT_LIST {0, 8, 16, 61, 80, 160, 212, 310, 311, 24, 32} +#define WFDB_NFMTS 11 /* number of items in WFDB_FMT_LIST */ /* Default signal specifications */ #define WFDB_DEFFREQ 250.0 /* default sampling frequency (Hz) */ @@ -187,6 +195,18 @@ typedef struct WFDB_anninfo WFDB_Anninfo; typedef struct WFDB_ann WFDB_Annotation; +/* Dynamic memory allocation macros. */ +#define MEMERR(P, N, S) \ + { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ + (size_t)N, (size_t)S, #P); \ + if (wfdb_me_fatal()) exit(1); } +#define SFREE(P) { if (P) { free (P); P = 0; } } +#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } +#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } +#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } +#define SSTRCPY(P, Q) { if (Q) { \ + SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } + /* Function types */ #ifndef _WINDOWS /* for everything *except* MS Windows applications */ typedef char *FSTRING; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/lib/wfdb.h0 wfdb-10.5.0/lib/wfdb.h0 --- wfdb-10.4.25/lib/wfdb.h0 2009-07-28 08:25:49.000000000 -0400 +++ wfdb-10.5.0/lib/wfdb.h0 2010-03-12 10:55:02.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 28 July 2009 wfdblib 10.4.22 + Last revised: 12 March 2010 wfdblib 10.5.0 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1983-2009 George B. Moody +Copyright (C) 1983-2010 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -79,8 +79,14 @@ typedef unsigned int WFDB_Signal; /* signal number */ typedef unsigned int WFDB_Annotator;/* annotator number */ -#define WFDB_INVALID_SAMPLE (-32768) /* samples from getvec or getframe with - this value are not valid */ +/* getvec and getframe return a sample with a value of WFDB_INVALID_SAMPLE + when the amplitude of a signal is undefined (e.g., the input is clipped or + the signal is not available) and padding is disabled (see WFDB_GVPAD, below). + WFDB_INVALID_SAMPLE is the minimum value for a 16-bit WFDB_Sample. In + a format 24 or 32 signal, this value will be near mid-range, but it should + occur only rarely in such cases; if this is a concern, WFDB_INVALID_SAMPLE + can be redefined and the WFDB library can be recompiled. */ +#define WFDB_INVALID_SAMPLE (-32768) /* Array sizes Many older applications use the values of WFDB_MAXANN, WFDB_MAXSIG, and @@ -113,9 +119,11 @@ 212 2 12-bit amplitudes bit-packed in 3 bytes 310 3 10-bit amplitudes bit-packed in 4 bytes 311 3 10-bit amplitudes bit-packed in 4 bytes + 24 24-bit 2's complement amplitudes, low byte first + 32 32-bit 2's complement amplitudes, low byte first */ -#define WFDB_FMT_LIST {0, 8, 16, 61, 80, 160, 212, 310, 311} -#define WFDB_NFMTS 9 /* number of items in FMT_LIST */ +#define WFDB_FMT_LIST {0, 8, 16, 61, 80, 160, 212, 310, 311, 24, 32} +#define WFDB_NFMTS 11 /* number of items in WFDB_FMT_LIST */ /* Default signal specifications */ #define WFDB_DEFFREQ 250.0 /* default sampling frequency (Hz) */ @@ -187,6 +195,18 @@ typedef struct WFDB_anninfo WFDB_Anninfo; typedef struct WFDB_ann WFDB_Annotation; +/* Dynamic memory allocation macros. */ +#define MEMERR(P, N, S) \ + { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ + (size_t)N, (size_t)S, #P); \ + if (wfdb_me_fatal()) exit(1); } +#define SFREE(P) { if (P) { free (P); P = 0; } } +#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } +#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } +#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } +#define SSTRCPY(P, Q) { if (Q) { \ + SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } + /* Function types */ #ifndef _WINDOWS /* for everything *except* MS Windows applications */ typedef char *FSTRING; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/lib/wfdblib.h wfdb-10.5.0/lib/wfdblib.h --- wfdb-10.4.25/lib/wfdblib.h 2010-01-21 20:49:39.000000000 -0500 +++ wfdb-10.5.0/lib/wfdblib.h 2010-03-16 21:37:13.000000000 -0400 @@ -1,10 +1,10 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 8 April 2008 wfdblib 10.4.6 + Last revised: 1 March 2010 wfdblib 10.5.0 External definitions for WFDB library private functions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2008 George B. Moody +Copyright (C) 1989-2010 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -200,18 +200,6 @@ #define FALSE 0 #endif -/* Dynamic memory allocation macros for the WFDB library. */ -#define MEMERR(P, N, S) \ - { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ - (size_t)N, (size_t)S, #P); \ - if (wfdb_me_fatal()) exit(1); } -#define SFREE(P) { if (P) { free (P); P = 0; } } -#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } -#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } -#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } -#define SSTRCPY(P, Q) { if (Q) { \ - SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } - /* Structures used by internal WFDB library functions only */ struct netfile { char *url; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/lib/wfdblib.h0 wfdb-10.5.0/lib/wfdblib.h0 --- wfdb-10.4.25/lib/wfdblib.h0 2008-08-12 17:28:38.000000000 -0400 +++ wfdb-10.5.0/lib/wfdblib.h0 2010-03-01 14:28:03.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 8 April 2008 wfdblib 10.4.6 + Last revised: 1 March 2010 wfdblib 10.5.0 External definitions for WFDB library private functions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2008 George B. Moody +Copyright (C) 1989-2010 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -200,18 +200,6 @@ #define FALSE 0 #endif -/* Dynamic memory allocation macros for the WFDB library. */ -#define MEMERR(P, N, S) \ - { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ - (size_t)N, (size_t)S, #P); \ - if (wfdb_me_fatal()) exit(1); } -#define SFREE(P) { if (P) { free (P); P = 0; } } -#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } -#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } -#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } -#define SSTRCPY(P, Q) { if (Q) { \ - SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } - /* Structures used by internal WFDB library functions only */ struct netfile { char *url; diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/NEWS wfdb-10.5.0/NEWS --- wfdb-10.4.25/NEWS 2010-01-21 21:19:00.000000000 -0500 +++ wfdb-10.5.0/NEWS 2010-03-16 22:11:30.000000000 -0400 @@ -1,3 +1,48 @@ +10.5.0 (16 March 2010): + The WFDB library now supports signals with 24 and 32 bits of precision, + using new formats 24 and 32, and WFDB applications 'wrsamp' and 'xform' + support user selection of 24- and 32-bit formats for output signal + files. 'wfdb2mat' automatically selects 32-bit .mat format when + exporting records that include format 24 or 32 signals. WFDB + applications can now read BDF and BDF+ files (24-bit EDF and EDF+ + variants). + + Note that these formats, unlike all previously supported formats, + require more than 16 bits per sample value. If the WFDB software is + compiled on a 16-bit platform (unusual except for embedded processors), + the excess high bits of signals in these formats are not read on input, + and they are replaced by zeroes on output, unless the WFDB_Sample data + type has been redefined as 'long' (in wfdb.h). This is not done by + default since it would increase memory and computational requirements + unnecessarily in embedded applications that do not require 24- or + 32-bit precision. + + Since support for extended precision samples cannot be introduced + without this limitation in backward compatibility for 16-bit platforms, + the minor version number of the WFDB library has been incremented to 5. + Most users will not be affected by this change, however, apart from the + new functionality it provides. + + Memory allocation macros that have been defined previously in wfdblib.h + have been moved to wfdb.h so they are accessible to WFDB applications, + including user-written applications. See the WFDB Programmer's Guide + for information about using these macros (MEMERR, SFREE, SUALLOC, + SALLOC, SREALLOC, and SSTRCPY). + + A buffer overflow in the WFDB library's internal function edfparse() + (in lib/signal.c) has been corrected, thanks to a bug report and patch + from Joonas Paalasmaa. + + In previous versions of 'rdsamp', the '-pe' and '-Pe' options did not + force output of elapsed times if the selected record had a defined + starting time. These options now work correctly in such cases. + + Some combinations of options caused the version of 'wrsamp' included + in version 10.4.25 to fail; this has now been corrected. + + WAVE's Find window now provides a means to search for the next valid + sample of a specified signal. + 10.4.25 (21 January 2010): WFDB application 'rdsamp' can now write CSV (comma-separated value) format output using its new '-c' option, and 'wrsamp' can read CSV diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/wave/mainpan.c wfdb-10.5.0/wave/mainpan.c --- wfdb-10.4.25/wave/mainpan.c 2009-02-15 13:00:31.000000000 -0500 +++ wfdb-10.5.0/wave/mainpan.c 2010-02-12 17:38:53.000000000 -0500 @@ -1,10 +1,10 @@ /* file: mainpan.c G. Moody 30 April 1990 - Last revised: 15 February 2009 + Last revised: 12 February 2010 Functions for the main control panel of WAVE ------------------------------------------------------------------------------- WAVE: Waveform analyzer, viewer, and editor -Copyright (C) 1990-2005 George B. Moody +Copyright (C) 1990-2010 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 @@ -45,12 +45,13 @@ /* Pulldown menus from "File", "Edit", and "Properties" menu buttons */ Menu file_menu, edit_menu, prop_menu; -Panel_item desc_item, /* Description field (from log file) */ - annot_item, /* "Annotator:" field */ - find_item, /* "Search for:" field */ - record_item, /* "Record:" field */ - time_item, /* "Start time:" field */ - time2_item, /* "End time:" field */ +Panel_item desc_item, /* Description field (from log file) */ + annot_item, /* "Annotator:" field */ + find_item, /* "Search for:" field */ + findsig_item, /* "Find signal:" field */ + record_item, /* "Record:" field */ + time_item, /* "Start time:" field */ + time2_item, /* "End time:" field */ wfdbpath_item, /* "WFDB path:" field */ wfdbcal_item, /* "Calibration file:" field */ psprint_item, /* "PostScript print command:" field */ @@ -504,7 +505,7 @@ find_item = xv_create(find_panel, PANEL_TEXT, PANEL_NEXT_ROW, -1, XV_HELP_DATA, "wave:find.search_for", - PANEL_LABEL_STRING, "Search for: ", + PANEL_LABEL_STRING, "Search for annotation: ", PANEL_VALUE_DISPLAY_LENGTH, 6, PANEL_NOTIFY_PROC, disp_proc, PANEL_CLIENT_DATA, (caddr_t) ']', @@ -515,6 +516,14 @@ XV_HELP_DATA, "wave:find.more_options", PANEL_NOTIFY_PROC, show_search_template, NULL); + findsig_item = xv_create(find_panel, PANEL_TEXT, + XV_HELP_DATA, "wave:find.search_for_signal", + PANEL_LABEL_STRING, "Find signal: ", + PANEL_VALUE_DISPLAY_LENGTH, 6, + PANEL_NOTIFY_PROC, disp_proc, + PANEL_CLIENT_DATA, (caddr_t) '}', + PANEL_VALUE, "", + 0); window_fit(find_panel); window_fit(find_frame); } @@ -754,10 +763,9 @@ display_start_time = 0L; cache_time = -1L; break; - case ']': /* Find next occurrence of specified annotation or signal. */ - case '[': /* Find previous occurrence of specified annotation. */ + case '}': /* Find next occurrence of specified signal. */ if (1) { - char *fp = (char *)xv_get(find_item, PANEL_VALUE); + char *fp = (char *)xv_get(findsig_item, PANEL_VALUE); if ((i = findsig(fp)) >= 0) { WFDB_Time tnext = tnextvec(i, display_start_time + nsamp); @@ -784,6 +792,9 @@ } } } + break; + case ']': /* Find next occurrence of specified annotation. */ + case '[': /* Find previous occurrence of specified annotation. */ if (annotator[0]) { char *fp = (char *)xv_get(find_item, PANEL_VALUE); static char auxstr[256]; @@ -942,4 +953,5 @@ char *s; { xv_set(find_item, PANEL_VALUE, s, NULL); + xv_set(findsig_item, PANEL_VALUE, s, NULL); } diff -Naur --exclude Makefile --exclude info wfdb-10.4.25/wave/sig.c wfdb-10.5.0/wave/sig.c --- wfdb-10.4.25/wave/sig.c 2009-06-12 15:02:13.000000000 -0400 +++ wfdb-10.5.0/wave/sig.c 2010-03-02 11:55:16.000000000 -0500 @@ -1,10 +1,10 @@ /* file: sig.c G. Moody 27 April 1990 - Last revised: 12 June 2009 + Last revised: 2 March 2010 Signal display functions for WAVE ------------------------------------------------------------------------------- WAVE: Waveform analyzer, viewer, and editor -Copyright (C) 1990-2009 George B. Moody +Copyright (C) 1990-2010 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 @@ -336,7 +336,7 @@ vmin[c] = vmax[c] = v0[c]; vvalid[c] = 0; if (v0[c] == WFDB_INVALID_SAMPLE) - lp->vlist[c][0].y = WFDB_INVALID_SAMPLE; + lp->vlist[c][0].y = -1 << 15; else lp->vlist[c][0].y = v0[c]*vscale[c]; } @@ -363,7 +363,7 @@ lp->vlist[c][x0].y = v0[c]*vscale[c]; } else - lp->vlist[c][x0].y = WFDB_INVALID_SAMPLE; + lp->vlist[c][x0].y = -1 << 15; } } } @@ -375,7 +375,7 @@ for (i = 1; i < nsamp && getvec(v) > 0; i++) for (c = 0; c < nsig; c++) { if (v[c] == WFDB_INVALID_SAMPLE) - lp->vlist[c][i].y = WFDB_INVALID_SAMPLE; + lp->vlist[c][i].y = -1 << 15; else lp->vlist[c][i].y = v[c]*vscale[c]; }