1 /*
2
3 % Copyright (C) 2005-2020 Alois Schloegl <alois.schloegl@gmail.com>
4 % This file is part of the "BioSig for C/C++" repository
5 % (biosig4c++) at http://biosig.sf.net/
6
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 3
11 of the License, or (at your option) any later version.
12
13
14 */
15
16 /*
17 Internal definitions (external API is defined in biosig.h)
18 */
19
20 /****************************************************************************/
21 /** **/
22 /** CONSTANTS and Global variables **/
23 /** **/
24 /****************************************************************************/
25
26 #ifndef __BIOSIG_INTERNAL_H__
27 #define __BIOSIG_INTERNAL_H__
28
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <string.h>
32 #if defined(__MINGW32__)
33 #include <sys/param.h>
34 #endif
35 #include <time.h>
36 #include "physicalunits.h"
37
38 #include <sys/endian.h>
39 #include <machine/endian.h> // for betoh16, etc.
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 #ifdef NDEBUG
46 #define VERBOSE_LEVEL 0 // turn off debugging information, but its only used without NDEBUG
47 #else
48 extern int VERBOSE_LEVEL; // used for debugging, variable is always defined
49 #endif
50
51
52 /*
53 Including ZLIB enables reading gzipped files (they are decompressed on-the-fly)
54 The output files can be zipped, too.
55 */
56
57 #ifdef HAVE_ZLIB
58 #include <zlib.h>
59 #ifndef ZLIB_H
60 #if defined(__MINGW64__)
61 #include "win64/zlib/zlib.h"
62 #elif defined(__MINGW32__)
63 #include "win32/zlib/include/zlib.h"
64 #endif
65 #endif
66 #endif
67
68 #ifdef HAVE_CHOLMOD
69 #ifdef __APPLE__
70 #include <cholmod.h>
71 #else
72 #include <suitesparse/cholmod.h>
73 #endif
74 #endif
75
76 #ifdef HAVE_HDF5
77 #include <hdf5.h>
78 #endif
79 #ifdef WITH_NIFTI
80 #include <nifti1.h>
81 #endif
82
83
84 #ifdef WITH_GSL
85 #include <gsl/gsl_matrix_double.h>
86 #endif
87
88 #ifdef __WIN32__
89 #define FILESEP '\\'
90 char *getlogin (void);
91 #else
92 #define FILESEP '/'
93 #endif
94
95
96 /* test whether HDR.CHANNEL[].{bi,bi8} can be replaced, reduction of header size by about 3%
97 currently this is not working, because FAMOS seems to need it.
98 //#define NO_BI
99 */
100
101 /* External API definitions - this was part of old biosig.h */
102 // #include "biosig.h"
103
104 /****************************************************************************/
105 /** **/
106 /** DEFINITIONS, TYPEDEFS AND MACROS **/
107 /** **/
108 /****************************************************************************/
109
110 #define BIOSIG_VERSION_MAJOR 3
111 #define BIOSIG_VERSION_MINOR 0
112 #define BIOSIG_PATCHLEVEL 1
113 // for backward compatibility
114 #define BIOSIG_VERSION_STEPPING BIOSIG_PATCHLEVEL
115 #define BIOSIG_VERSION (BIOSIG_VERSION_MAJOR * 10000 + BIOSIG_VERSION_MINOR * 100 + BIOSIG_PATCHLEVEL)
116 // biosigCHECK_VERSION returns true if BIOSIG_VERSION is at least a.b.c
117 #define biosigCHECK_VERSION(a,b,c) (BIOSIG_VERSION >= ( 10000*(a) + 100*(b) + (c) ) )
118
119 #if defined(_MSC_VER) && (_MSC_VER < 1600)
120 #if defined(_WIN64)
121 typedef __int64 ssize_t;
122 typedef unsigned __int64 size_t;
123 #else
124 typedef __int32 ssize_t;
125 typedef unsigned __int32 size_t;
126 #endif
127 typedef unsigned __int64 uint64_t;
128 typedef __int64 int64_t;
129 typedef unsigned __int32 uint32_t;
130 typedef __int32 int32_t;
131 typedef __int16 int16_t;
132 typedef unsigned __int8 uint8_t;
133 typedef __int8 int8_t;
134 #else
135 #include <inttypes.h>
136 #endif
137
138 #include "gdftime.h"
139
140 /*
141 * pack structures to fulfil following requirements:
142 * (1) Matlab v7.3+ requires 8 byte alignment
143 * (2) in order to use mingw-compiled libbiosig with MS' VisualStudio,
144 * the structurs must be packed in a MS compatible way.
145 */
146 #pragma pack(push, 8)
147
148 //* this is probably redundant to the #pragma pack(8) statement, its here to do it the gnu way, too. */
149 #ifdef __GNUC__
150 #define ATT_ALI __attribute__ ((aligned (8)))
151 #define ATT_DEPREC __attribute__ ((deprecated))
152 #else
153 #define ATT_ALI
154 #define ATT_DEPREC
155 #endif
156
157 #if defined(_MINGW32__) || defined(__CYGWIN__)
158 #pragma ms_struct on
159 #define ATT_MSSTRUCT __attribute__ ((ms_struct))
160 #else
161 #define ATT_MSSTRUCT
162 #endif
163
164 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
165 biosig_data_type data type of internal data format
166 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
167 typedef double biosig_data_type;
168
169
170 /****************************************************************************/
171 /** **/
172 /** CONSTANTS and Global variables **/
173 /** **/
174 /****************************************************************************/
175
176
177 /* for error handling */
178 enum B4C_ERROR {
179 B4C_NO_ERROR=0,
180 B4C_FORMAT_UNKNOWN,
181 B4C_FORMAT_UNSUPPORTED,
182 B4C_CANNOT_OPEN_FILE,
183 B4C_CANNOT_WRITE_FILE,
184 B4C_CANNOT_APPEND_FILE,
185 B4C_INSUFFICIENT_MEMORY,
186 B4C_ENDIAN_PROBLEM,
187 B4C_CRC_ERROR,
188 B4C_DATATYPE_UNSUPPORTED,
189 B4C_SCLOSE_FAILED,
190 B4C_DECOMPRESSION_FAILED,
191 B4C_MEMORY_ALLOCATION_FAILED,
192 B4C_RAWDATA_COLLAPSING_FAILED,
193 B4C_REREF_FAILED,
194 B4C_INCOMPLETE_FILE,
195 B4C_UNSPECIFIC_ERROR,
196 B4C_CHAR_ENCODING_UNSUPPORTED
197 };
198
199 #ifdef BIN
200 #undef BIN // needed for biosig4perl
201 #endif
202 #ifdef EVENT
203 #undef EVENT // defined by MS VC++
204 #endif
205
206 /* list of file formats */
207 enum FileFormat {
208 noFile, unknown,
209 ABF, ABF2, ACQ, ACR_NEMA, AIFC, AIFF, AINF, alpha, ARFF,
210 ASCII_IBI, ASCII, AU, ASF, ATES, ATF, AVI, AXG, Axona,
211 BCI2000, BDF, BESA, BIN, BKR, BLSC, BMP, BNI, BSCS,
212 BrainVision, BrainVisionVAmp, BrainVisionMarker, BZ2,
213 CDF, CFS, CFWB, CNT, CTF, DICOM, DEMG,
214 EBS, EDF, EEG1100, EEProbe, EEProbe2, EEProbeAvr, EGI,
215 EGIS, ELF, EMBLA, EMSA, ePrime, ET_MEG, ETG4000, EVENT, EXIF,
216 FAMOS, FEF, FIFF, FITS, FLAC, GDF, GDF1,
217 GIF, GTF, GZIP, HDF, HL7aECG, HEKA,
218 IBW, ISHNE, ITX, JPEG, JSON, Lexicor,
219 Matlab, MFER, MIDI, MIT, MM, MSI, MSVCLIB, MS_LNK, MX,
220 native, NeuroLoggerHEX, NetCDF, NEURON, NEV, NEX1, NIFTI, NUMPY,
221 OGG, OpenXDF,
222 PBMA, PBMN, PDF, PDP, Persyst, PGMA, PGMB,
223 PLEXON, PNG, PNM, POLY5, PPMA, PPMB, PS,
224 RDF, RIFF,
225 SASXPT, SCP_ECG, SIGIF, Sigma, SMA, SMR, SND, SQLite,
226 SPSS, STATA, SVG, SXI, SYNERGY,
227 TDMS, TIFF, TMS32, TMSiLOG, TRC, UNIPRO, VRML, VTK,
228 WAV, WCP, WG1, WinEEG, WMF, XML, XPM,
229 Z, ZIP, ZIP2, RHD2000, RHS2000, IntanCLP,
230 EBNEURO, SigViewerEventsCSV, XDF,
231 EAS, EZ3, ARC,
232 LastPlaceHolder, invalid=0xffff
233 };
234
235
236 /****************************************************************************/
237 /** **/
238 /** DEFINITIONS, TYPEDEFS AND MACROS **/
239 /** **/
240 /****************************************************************************/
241
242
243
244 typedef int64_t nrec_t; /* type for number of records */
245
246 /****************************************************************************/
247 /** **/
248 /** TYPEDEFS AND STRUCTURES **/
249 /** **/
250 /****************************************************************************/
251
252 /*
253 This structure defines the header for each channel (variable header)
254 */
255 // TODO: change fixed length strings to dynamically allocated strings
256 #define MAX_LENGTH_LABEL 80 // TMS: 40, AXG: 79
257 #define MAX_LENGTH_TRANSDUCER 80
258 #if (BIOSIG_VERSION < 10600)
259 #define MAX_LENGTH_PHYSDIM 20 // DEPRECATED - DO NOT USE
260 #else
261 #undef MAX_LENGTH_PHYSDIM
262 #endif
263 #define MAX_LENGTH_PID 80 // length of Patient ID: MFER<65, GDF<67, EDF/BDF<81, etc.
264 #define MAX_LENGTH_RID 80 // length of Recording ID: EDF,GDF,BDF<80, HL7 ?
265 #define MAX_LENGTH_NAME 132 // max length of personal name: MFER<=128, EBS<=33*4
266 #define MAX_LENGTH_MANUF 128 // max length of manufacturer field: MFER<128
267 #define MAX_LENGTH_TECHNICIAN 128 // max length of manufacturer field: SCP<41
268
269 typedef struct CHANNEL_STRUCT {
270 double PhysMin ATT_ALI; /* physical minimum */
271 double PhysMax ATT_ALI; /* physical maximum */
272 double DigMin ATT_ALI; /* digital minimum */
273 double DigMax ATT_ALI; /* digital maximum */
274 double Cal ATT_ALI; /* gain factor */
275 double Off ATT_ALI; /* bias */
276
277 char Label[MAX_LENGTH_LABEL+1] ATT_ALI; /* Label of channel */
278 char OnOff ATT_ALI; /* 0: channel is off, not consider for data output; 1: channel is turned on; 2: channel containing time axis */
279 uint16_t LeadIdCode ATT_ALI; /* Lead identification code */
280 char Transducer[MAX_LENGTH_TRANSDUCER+1] ATT_ALI; /* transducer e.g. EEG: Ag-AgCl electrodes */
281 #ifdef MAX_LENGTH_PHYSDIM
282 char PhysDim[MAX_LENGTH_PHYSDIM+1] ATT_ALI ATT_DEPREC; /* DONOT USE - use PhysDim3(PhysDimCode) instead */
283 #endif
284 uint16_t PhysDimCode ATT_ALI; /* code for physical dimension - PhysDim3(PhysDimCode) returns corresponding string */
285
286 float TOffset ATT_ALI; /* time delay of sampling */
287 float LowPass ATT_ALI; /* lowpass filter */
288 float HighPass ATT_ALI; /* high pass */
289 float Notch ATT_ALI; /* notch filter */
290 float XYZ[3] ATT_ALI; /* sensor position */
291
292 union {
293 /* context specific channel information */
294 float Impedance ATT_ALI; /* Electrode Impedance in Ohm, defined only if PhysDim = _Volt */
295 float fZ ATT_ALI; /* ICG probe frequency, defined only if PhysDim = _Ohm */
296 } ATT_ALI;
297
298 /* this part should not be used by application programs */
299 uint8_t* bufptr ATT_ALI; /* pointer to buffer: NRec<=1 and bi,bi8 not used */
300 uint32_t SPR ATT_ALI; /* samples per record (block) */
301 uint32_t bi ATT_ALI; /* start byte (byte index) of channel within data block */
302 uint32_t bi8 ATT_ALI; /* start bit (bit index) of channel within data block */
303 uint16_t GDFTYP ATT_ALI; /* data type */
304 } CHANNEL_TYPE ATT_ALI ATT_MSSTRUCT;
305
306
307 /*
308 This structure defines the general (fixed) header
309 */
310 typedef struct HDR_STRUCT {
311
312 char* FileName ATT_ALI; /* FileName - dynamically allocated, local copy of file name */
313
314 union {
315 // workaround for transition to cleaner fieldnames
316 float VERSION; /* GDF version number */
317 float Version; /* GDF version number */
318 } ATT_ALI;
319
320 union {
321 // workaround for transition to cleaner fieldnames
322 enum FileFormat TYPE; /* type of file format */
323 enum FileFormat Type; /* type of file format */
324 } ATT_ALI;
325
326 struct {
327 size_t size[2] ATT_ALI; /* size {rows, columns} of data block */
328 biosig_data_type* block ATT_ALI; /* data block */
329 } data ATT_ALI;
330
331 uint8_t IPaddr[16] ATT_ALI; /* IP address of recording device (if applicable) */
332 double SampleRate ATT_ALI; /* Sampling rate */
333 nrec_t NRec ATT_ALI; /* number of records/blocks -1 indicates length is unknown. */
334 gdf_time T0 ATT_ALI; /* starttime of recording */
335 uint32_t HeadLen ATT_ALI; /* length of header in bytes */
336 uint32_t SPR ATT_ALI; /* samples per block (when different sampling rates are used, this is the LCM(CHANNEL[..].SPR) */
337 uint32_t LOC[4] ATT_ALI; /* location of recording according to RFC1876 */
338 uint16_t NS ATT_ALI; /* number of channels */
339 int16_t tzmin ATT_ALI; /* time zone : minutes east of UTC */
340
341 #ifdef CHOLMOD_H
342 cholmod_sparse *Calib ATT_ALI; /* re-referencing matrix */
343 #else
344 void *Calib ATT_ALI; /* re-referencing matrix */
345 #endif
346 CHANNEL_TYPE *rerefCHANNEL ATT_ALI;
347
348 /* Patient specific information */
349 struct {
350 gdf_time Birthday; /* Birthday of Patient */
351 // Age; // the age is HDR.T0 - HDR.Patient.Birthday, even if T0 and Birthday are not known
352 uint16_t Headsize[3]; /* circumference, nasion-inion, left-right mastoid in millimeter; */
353
354 /* Patient Name:
355 * can consist of up to three components, separated by the unit separator ascii(31), 0x1f, containing in that order
356 Last name, first name, second last name (see also SCP-ECG specification EN1064, Section 1, tag 0, 1, and 3)
357 * for privacy protection this field is by default not supported, support can be turned on with FLAG.ANONYMOUS
358 */
359 char Name[MAX_LENGTH_NAME+1];
360
361 char Id[MAX_LENGTH_PID+1]; /* patient identification, identification code as used in hospital */
362 uint8_t Weight; /* weight in kilograms [kg] 0:unkown, 255: overflow */
363 uint8_t Height; /* height in centimeter [cm] 0:unkown, 255: overflow */
364 // BMI; // the body-mass index = weight[kg]/height[m]^2
365 /* Patient classification */
366 int8_t Sex; /* 0:Unknown, 1: Male, 2: Female */
367 int8_t Handedness; /* 0:Unknown, 1: Right, 2: Left, 3: Equal */
368 int8_t Smoking; /* 0:Unknown, 1: NO, 2: YES */
369 int8_t AlcoholAbuse; /* 0:Unknown, 1: NO, 2: YES */
370 int8_t DrugAbuse; /* 0:Unknown, 1: NO, 2: YES */
371 int8_t Medication; /* 0:Unknown, 1: NO, 2: YES */
372 struct {
373 int8_t Visual; /* 0:Unknown, 1: NO, 2: YES, 3: Corrected */
374 int8_t Heart; /* 0:Unknown, 1: NO, 2: YES, 3: Pacemaker */
375 } Impairment;
376 } Patient ATT_ALI;
377
378 struct {
379 char Recording[MAX_LENGTH_RID+1]; /* HL7, EDF, GDF, BDF replaces HDR.AS.RID */
380 char* Technician;
381 char* Hospital; /* recording institution */
382 uint64_t Equipment; /* identifies this software */
383 struct {
384 /* see
385 SCP: section1, tag14,
386 MFER: tag23: "Manufacturer^model^version number^serial number"
387 */
388 const char* Name;
389 const char* Model;
390 const char* Version;
391 const char* SerialNumber;
392 char _field[MAX_LENGTH_MANUF+1]; /* buffer */
393 } Manufacturer;
394 } ID ATT_ALI;
395
396 /* position of electrodes; see also HDR.CHANNEL[k].XYZ */
397 struct {
398 float REF[3]; /* XYZ position of reference electrode */
399 float GND[3]; /* XYZ position of ground electrode */
400 } ELEC ATT_ALI;
401
402 /* EVENTTABLE */
403 struct {
404 double SampleRate ATT_ALI; /* for converting POS and DUR into seconds */
405 uint16_t *TYP ATT_ALI; /* defined at http://biosig.svn.sourceforge.net/viewvc/biosig/trunk/biosig/doc/eventcodes.txt */
406 uint32_t *POS ATT_ALI; /* starting position [in samples] using a 0-based indexing */
407 uint32_t *DUR ATT_ALI; /* duration [in samples] */
408 uint16_t *CHN ATT_ALI; /* channel number; 0: all channels */
409 #if (BIOSIG_VERSION >= 10500)
410 gdf_time *TimeStamp ATT_ALI; /* store time stamps */
411 #endif
412 const char* *CodeDesc ATT_ALI; /* describtion of "free text"/"user specific" events (encoded with TYP=0..255 */
413 uint32_t N ATT_ALI; /* number of events */
414 uint16_t LenCodeDesc ATT_ALI; /* length of CodeDesc Table */
415 } EVENT ATT_ALI;
416
417 struct { /* flags */
418 char OVERFLOWDETECTION; /* overflow & saturation detection 0: OFF, !=0 ON */
419 char UCAL; /* UnCalibration 0: scaling !=0: NO scaling - raw data return */
420 char ANONYMOUS; /* 1: anonymous mode, no personal names are processed */
421 char ROW_BASED_CHANNELS; /* 0: column-based data [default]; 1: row-based data */
422 char TARGETSEGMENT; /* in multi-segment files (like Nihon-Khoden, EEG1100), it is used to select a segment */
423 } FLAG ATT_ALI;
424
425 CHANNEL_TYPE *CHANNEL ATT_ALI;
426 // moving CHANNEL after the next struct (HDR.FILE) gives problems at AMD64 MEX-file.
427 // perhaps some alignment problem.
428
429 struct { /* File specific data */
430 #ifdef ZLIB_H
431 gzFile gzFID;
432 #else
433 void* gzFID;
434 #endif
435 #ifdef _BZLIB_H
436 // BZFILE* bzFID;
437 #endif
438 FILE* FID; /* file handle */
439 size_t size; /* size of file - experimental: only partly supported */
440 size_t POS; /* current reading/writing position [in blocks] */
441 //size_t POS2; // current reading/writing position [in samples] */
442 int Des; /* file descriptor */
443 int DES; /* descriptor for streams */
444 uint8_t OPEN; /* 0: closed, 1:read, 2: write */
445 uint8_t LittleEndian; /* 1 if file is LittleEndian data format and 0 for big endian data format*/
446 uint8_t COMPRESSION; /* 0: no compression 9: best compression */
447 } FILE ATT_ALI;
448
449 /* internal variables (not public) */
450 struct {
451 const char* B4C_ERRMSG; /* error message */
452 // char PID[MAX_LENGTH_PID+1]; // use HDR.Patient.Id instead
453 // char* RID; // recording identification
454 uint32_t bpb; /* total bytes per block */
455 uint32_t bpb8; /* total bits per block */
456
457 uint8_t* Header;
458 uint8_t* rawEventData;
459 uint8_t* rawdata; /* raw data block */
460 size_t first; /* first block loaded in buffer - this is equivalent to hdr->FILE.POS */
461 size_t length; /* number of block(s) loaded in buffer */
462 uint8_t* auxBUF; /* auxillary buffer - used for storing EVENT.CodeDesc, MIT FMT infor, alpha:rawdata header */
463 union {
464 char* bci2000; /* application specific free text field */
465 char* fpulse;
466 char* stimfit;
467 };
468 uint32_t SegSel[5]; /* segment selection in a hirachical data formats, e.g. sweeps in HEKA/PatchMaster format */
469 enum B4C_ERROR B4C_ERRNUM; /* error code */
470 char flag_collapsed_rawdata; /* 0 if rawdata contain obsolete channels, too. */
471 } AS ATT_ALI;
472
473 void *aECG; /* used as an pointer to (non-standard) auxilary information - mostly used for hacks */
474 uint64_t viewtime; /* used by edfbrowser */
475
476 #if (BIOSIG_VERSION >= 10500)
477 struct {
478 /*
479 This part contains Section 7-11 of the SCP-ECG format
480 without its 16 byte "Section ID header".
481 These sections are also stored in GDF Header 3 (tag 9-13)
482 It is mostly used for SCP<->GDF conversion.
483
484 The pointers points into hdr->AS.Header,
485 so do not dynamically re-allocate the pointers.
486 */
487 const uint8_t* Section7;
488 const uint8_t* Section8;
489 const uint8_t* Section9;
490 const uint8_t* Section10;
491 const uint8_t* Section11;
492 uint32_t Section7Length;
493 uint32_t Section8Length;
494 uint32_t Section9Length;
495 uint32_t Section10Length;
496 uint32_t Section11Length;
497 } SCP;
498 #endif
499
500 } HDRTYPE ATT_MSSTRUCT;
501
502 /*
503 This structure defines codes and groups of the event table
504 */
505
506 // Desription of event codes
507 struct etd_t {
508 uint16_t typ; // used in HDR.EVENT.TYP
509 uint16_t groupid; // defines the group id as used in EventCodeGroups below
510 const char* desc; // name/description of event code // const decrease signifitiantly number of warning
511 } ATT_MSSTRUCT;
512 // Groups of event codes
513 struct event_groups_t {
514 uint16_t groupid;
515 const char* GroupDescription; // const decrease signifitiantly number of warning
516 } ATT_MSSTRUCT;
517 struct FileFormatStringTable_t {
518 enum FileFormat fmt;
519 const char* FileTypeString;
520 } ATT_MSSTRUCT;
521 struct NomenclatureAnnotatedECG_t {
522 uint16_t part;
523 uint16_t code10;
524 uint32_t cf_code10;
525 const char *refid;
526 } ATT_MSSTRUCT;
527
528 extern const struct etd_t ETD [] __attribute__ ((visibility ("default") ));
529 extern const struct event_groups_t EventCodeGroups [] __attribute__ ((visibility ("default") ));
530 extern const struct FileFormatStringTable_t FileFormatStringTable [];
531
532 typedef struct {
533 const char *free_text_event_limiter;
534 } biosig_options_type;
535
536 HDRTYPE* sopen_extended(const char* FileName, const char* MODE, HDRTYPE* hdr, biosig_options_type* options) __attribute__ ((visibility ("default") ));
537
538 /* reset structure packing to default settings */
539 #pragma pack(pop)
540 #if defined(_MINGW32__) || defined(__CYGWIN__)
541 #pragma ms_struct reset
542 #endif
543
544
545
546
547 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
548
549 #if 0
550
551 #elif defined(__linux__)
552 # include <endian.h>
553 # include <byteswap.h>
554
555 #elif defined(__FreeBSD__)
556 # include <machine/endian.h>
557
558 #elif defined(__GLIBC__) // for Hurd
559 # include <endian.h>
560 # include <byteswap.h>
561
562 #elif defined(__CYGWIN__)
563 # include <endian.h>
564 # include <byteswap.h>
565
566 #elif defined(__WIN32__) || defined(_WIN32)
567 # include <stdlib.h>
568 # define __BIG_ENDIAN 4321
569 # define __LITTLE_ENDIAN 1234
570 # define __BYTE_ORDER __LITTLE_ENDIAN
571 # define bswap_16(x) __builtin_bswap16(x)
572 # define bswap_32(x) __builtin_bswap32(x)
573 # define bswap_64(x) __builtin_bswap64(x)
574
575 # include <winsock2.h>
576 # if defined(__MINGW32__)
577 # include <sys/param.h>
578 # endif
579 # if BYTE_ORDER == LITTLE_ENDIAN
580 # define htobe16(x) htons(x)
581 # define htole16(x) (x)
582 # define be16toh(x) ntohs(x)
583 # define le16toh(x) (x)
584
585 # define htobe32(x) htonl(x)
586 # define htole32(x) (x)
587 # define be32toh(x) ntohl(x)
588 # define le32toh(x) (x)
589
590 # define htole64(x) (x)
591 # if defined(__MINGW32__)
592 # define htobe64(x) __builtin_bswap64(x)
593 # define be64toh(x) __builtin_bswap64(x)
594 # else
595 # define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) | (unsigned int)ntohl(((int)(x >> 32))))
596 # define htonll(x) ntohll(x)
597 # define htobe64(x) htonll(x)
598 # define be64toh(x) ntohll(x)
599 # endif
600 # define le64toh(x) (x)
601
602 # elif BYTE_ORDER == BIG_ENDIAN
603 /* that would be xbox 360 */
604 # define htobe16(x) (x)
605 # define htole16(x) __builtin_bswap16(x)
606 # define be16toh(x) (x)
607 # define le16toh(x) __builtin_bswap16(x)
608
609 # define htobe32(x) (x)
610 # define htole32(x) __builtin_bswap32(x)
611 # define be32toh(x) (x)
612 # define le32toh(x) __builtin_bswap32(x)
613
614 # define htobe64(x) (x)
615 # define htole64(x) __builtin_bswap64(x)
616 # define be64toh(x) (x)
617 # define le64toh(x) __builtin_bswap64(x)
618
619 # else
620 # error byte order not supported
621 # endif
622
623 #elif defined(__NetBSD__)
624 # include <sys/bswap.h>
625 # define __BIG_ENDIAN _BIG_ENDIAN
626 # define __LITTLE_ENDIAN _LITTLE_ENDIAN
627 # define __BYTE_ORDER _BYTE_ORDER
628 # define bswap_16(x) bswap16(x)
629 # define bswap_32(x) bswap32(x)
630 # define bswap_64(x) bswap64(x)
631
632 #elif defined(__APPLE__)
633 # define __BIG_ENDIAN 4321
634 # define __LITTLE_ENDIAN 1234
635 #if (defined(__LITTLE_ENDIAN__) && (__LITTLE_ENDIAN__ == 1))
636 #define __BYTE_ORDER __LITTLE_ENDIAN
637 #else
638 #define __BYTE_ORDER __BIG_ENDIAN
639 #endif
640
641 # include <libkern/OSByteOrder.h>
642 # define bswap_16 OSSwapInt16
643 # define bswap_32 OSSwapInt32
644 # define bswap_64 OSSwapInt64
645
646 # define htobe16(x) OSSwapHostToBigInt16(x)
647 # define htole16(x) OSSwapHostToLittleInt16(x)
648 # define be16toh(x) OSSwapBigToHostInt16(x)
649 # define le16toh(x) OSSwapLittleToHostInt16(x)
650
651 # define htobe32(x) OSSwapHostToBigInt32(x)
652 # define htole32(x) OSSwapHostToLittleInt32(x)
653 # define be32toh(x) OSSwapBigToHostInt32(x)
654 # define le32toh(x) OSSwapLittleToHostInt32(x)
655
656 # define htobe64(x) OSSwapHostToBigInt64(x)
657 # define htole64(x) OSSwapHostToLittleInt64(x)
658 # define be64toh(x) OSSwapBigToHostInt64(x)
659 # define le64toh(x) OSSwapLittleToHostInt64(x)
660
661 #elif defined(__OpenBSD__)
662 # include <sys/endian.h>
663 # define bswap_16 __swap16
664 # define bswap_32 __swap32
665 # define bswap_64 __swap64
666
667 #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
668 # include <sys/endian.h>
669 # define be16toh(x) betoh16(x)
670 # define le16toh(x) letoh16(x)
671 # define be32toh(x) betoh32(x)
672 # define le32toh(x) letoh32(x)
673 # define be64toh(x) betoh64(x)
674 # define le64toh(x) letoh64(x)
675
676 #elif (defined(BSD) && (BSD >= 199103)) && !defined(__GLIBC__)
677 # include <machine/endian.h>
678 # define __BIG_ENDIAN _BIG_ENDIAN
679 # define __LITTLE_ENDIAN _LITTLE_ENDIAN
680 # define __BYTE_ORDER _BYTE_ORDER
681 # define bswap_16(x) __bswap16(x)
682 # define bswap_32(x) __bswap32(x)
683 # define bswap_64(x) __bswap64(x)
684
685 #elif defined(__GNUC__)
686 /* use byteswap macros from the host system, hopefully optimized ones ;-) */
687 # include <endian.h>
688 # include <byteswap.h>
689 # define bswap_16(x) __bswap_16 (x)
690 # define bswap_32(x) __bswap_32 (x)
691 # define bswap_64(x) __bswap_64 (x)
692
693 #elif defined(__sparc__)
694 # define __BIG_ENDIAN 4321
695 # define __LITTLE_ENDIAN 1234
696 # define __BYTE_ORDER __BIG_ENDIAN
697
698 #else
699 # error Unknown platform
700 #endif
701
702 #if defined(__sparc__)
703
704 # ifndef bswap_16
705 # define bswap_16(x) \
706 ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
707 # endif
708
709 # ifndef bswap_32
710 # define bswap_32(x) \
711 ((((x) & 0xff000000) >> 24) \
712 | (((x) & 0x00ff0000) >> 8) \
713 | (((x) & 0x0000ff00) << 8) \
714 | (((x) & 0x000000ff) << 24))
715
716 # endif
717
718 # ifndef bswap_64
719 # define bswap_64(x) \
720 ((((x) & 0xff00000000000000ull) >> 56) \
721 | (((x) & 0x00ff000000000000ull) >> 40) \
722 | (((x) & 0x0000ff0000000000ull) >> 24) \
723 | (((x) & 0x000000ff00000000ull) >> 8) \
724 | (((x) & 0x00000000ff000000ull) << 8) \
725 | (((x) & 0x0000000000ff0000ull) << 24) \
726 | (((x) & 0x000000000000ff00ull) << 40) \
727 | (((x) & 0x00000000000000ffull) << 56))
728 # endif
729
730 #endif
731
732
733 #if !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
734 #error ENDIANITY is not known
735 #endif
736
leu16p(const void * i)737 static inline uint16_t leu16p(const void* i) {
738 uint16_t a;
739 memcpy(&a, i, sizeof(a));
740 return (le16toh(a));
741 }
lei16p(const void * i)742 static inline int16_t lei16p(const void* i) {
743 uint16_t a;
744 memcpy(&a, i, sizeof(a));
745 return ((int16_t)le16toh(a));
746 }
leu32p(const void * i)747 static inline uint32_t leu32p(const void* i) {
748 uint32_t a;
749 memcpy(&a, i, sizeof(a));
750 return (le32toh(a));
751 }
lei32p(const void * i)752 static inline int32_t lei32p(const void* i) {
753 uint32_t a;
754 memcpy(&a, i, sizeof(a));
755 return ((int32_t)le32toh(a));
756 }
leu64p(const void * i)757 static inline uint64_t leu64p(const void* i) {
758 uint64_t a;
759 memcpy(&a, i, sizeof(a));
760 return (le64toh(a));
761 }
lei64p(const void * i)762 static inline int64_t lei64p(const void* i) {
763 uint64_t a;
764 memcpy(&a, i, sizeof(a));
765 return ((int64_t)le64toh(a));
766 }
767
beu16p(const void * i)768 static inline uint16_t beu16p(const void* i) {
769 uint16_t a;
770 memcpy(&a, i, sizeof(a));
771 return ((int16_t)be16toh(a));
772 }
bei16p(const void * i)773 static inline int16_t bei16p(const void* i) {
774 uint16_t a;
775 memcpy(&a, i, sizeof(a));
776 return ((int16_t)be16toh(a));
777 }
beu32p(const void * i)778 static inline uint32_t beu32p(const void* i) {
779 uint32_t a;
780 memcpy(&a, i, sizeof(a));
781 return (be32toh(a));
782 }
bei32p(const void * i)783 static inline int32_t bei32p(const void* i) {
784 uint32_t a;
785 memcpy(&a, i, sizeof(a));
786 return ((int32_t)be32toh(a));
787 }
beu64p(const void * i)788 static inline uint64_t beu64p(const void* i) {
789 uint64_t a;
790 memcpy(&a, i, sizeof(a));
791 return ((int64_t)be64toh(a));
792 }
bei64p(const void * i)793 static inline int64_t bei64p(const void* i) {
794 uint64_t a;
795 memcpy(&a, i, sizeof(a));
796 return ((int64_t)be64toh(a));
797 }
798
leu16a(uint16_t i,void * r)799 static inline void leu16a(uint16_t i, void* r) {
800 i = htole16(i);
801 memcpy(r, &i, sizeof(i));
802 }
lei16a(int16_t i,void * r)803 static inline void lei16a( int16_t i, void* r) {
804 i = htole16(i);
805 memcpy(r, &i, sizeof(i));
806 }
leu32a(uint32_t i,void * r)807 static inline void leu32a(uint32_t i, void* r) {
808 i = htole32(i);
809 memcpy(r, &i, sizeof(i));
810 }
lei32a(int32_t i,void * r)811 static inline void lei32a( int32_t i, void* r) {
812 i = htole32(i);
813 memcpy(r, &i, sizeof(i));
814 }
leu64a(uint64_t i,void * r)815 static inline void leu64a(uint64_t i, void* r) {
816 i = htole64(i);
817 memcpy(r, &i, sizeof(i));
818 }
lei64a(int64_t i,void * r)819 static inline void lei64a( int64_t i, void* r) {
820 i = htole64(i);
821 memcpy(r, &i, sizeof(i));
822 }
823
beu16a(uint16_t i,void * r)824 static inline void beu16a(uint16_t i, void* r) {
825 i = htobe16(i);
826 memcpy(r, &i, sizeof(i));
827 };
bei16a(int16_t i,void * r)828 static inline void bei16a( int16_t i, void* r) {
829 i = htobe16(i);
830 memcpy(r, &i, sizeof(i));
831 }
beu32a(uint32_t i,void * r)832 static inline void beu32a(uint32_t i, void* r) {
833 i = htobe32(i);
834 memcpy(r, &i, sizeof(i));
835 }
bei32a(int32_t i,void * r)836 static inline void bei32a( int32_t i, void* r) {
837 i = htobe32(i);
838 memcpy(r, &i, sizeof(i));
839 }
beu64a(uint64_t i,void * r)840 static inline void beu64a(uint64_t i, void* r) {
841 i = htobe64(i);
842 memcpy(r, &i, sizeof(i));
843 }
bei64a(int64_t i,void * r)844 static inline void bei64a( int64_t i, void* r) {
845 i = htobe64(i);
846 memcpy(r, &i, sizeof(i));
847 }
848
lef32p(const void * i)849 static inline float lef32p(const void* i) {
850 // decode little endian float pointer
851 uint32_t o;
852 union {
853 uint32_t i;
854 float r;
855 } c;
856 memcpy(&o,i,4);
857 c.i = le32toh(o);
858 return(c.r);
859 }
lef64p(const void * i)860 static inline double lef64p(const void* i) {
861 // decode little endian double pointer
862 uint64_t o=0;
863 union {
864 uint64_t i;
865 double r;
866 } c;
867 memcpy(&o,i,8);
868 c.i = le64toh(o);
869 return(c.r);
870 }
bef32p(const void * i)871 static inline float bef32p(const void* i) {
872 // decode little endian float pointer
873 uint32_t o;
874 union {
875 uint32_t i;
876 float r;
877 } c;
878 memcpy(&o,i,4);
879 c.i = be32toh(o);
880 return(c.r);
881 }
bef64p(const void * i)882 static inline double bef64p(const void* i) {
883 // decode little endian double pointer
884 uint64_t o=0;
885 union {
886 uint64_t i;
887 double r;
888 } c;
889 memcpy(&o,i,8);
890 c.i = be64toh(o);
891 return(c.r);
892 }
893
lef32a(float i,void * r)894 static inline void lef32a( float i, void* r) {
895 uint32_t i32;
896 memcpy(&i32, &i, sizeof(i));
897 i32 = le32toh(i32);
898 memcpy(r, &i32, sizeof(i32));
899 }
lef64a(double i,void * r)900 static inline void lef64a( double i, void* r) {
901 uint64_t i64;
902 memcpy(&i64, &i, sizeof(i));
903 i64 = le64toh(i64);
904 memcpy(r, &i64, sizeof(i64));
905 }
bef32a(float i,void * r)906 static inline void bef32a( float i, void* r) {
907 uint32_t i32;
908 memcpy(&i32, &i, sizeof(i));
909 i32 = be32toh(i32);
910 memcpy(r, &i32, sizeof(i32));
911 }
bef64a(double i,void * r)912 static inline void bef64a( double i, void* r) {
913 uint64_t i64;
914 memcpy(&i64, &i, sizeof(i));
915 i64 = be64toh(i64);
916 memcpy(r, &i64, sizeof(i64));
917 }
918
919 #ifndef NAN
920 # define NAN (0.0/0.0) /* used for encoding of missing values */
921 #endif
922 #ifndef INFINITY
923 # define INFINITY (1.0/0.0) /* positive infinity */
924 #endif
925 #ifndef isfinite
926 # define isfinite(a) (-INFINITY < (a) && (a) < INFINITY)
927 #endif
928
929 /*
930 The macro IS_SET() can be used to test for defines in
931 if (IS_SET(...)) {
932 }
933 as well as in
934 #if (IS_SET(...))
935 #endif
936 http://www.thepowerbase.com/2012/04/latest-release-of-linux-contains-code-developed-via-google-plus/
937 */
938 #define macrotest_1 ,
939 #define IS_SET(macro) is_set_(macro)
940 #define is_set_(value) is_set__(macrotest_##value)
941 #define is_set__(comma) is_set___(comma 1, 0)
942 #define is_set___(_, v, ...) v
943
944
945 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
946 global constants and variables
947 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
948
949
950 /****************************************************************************/
951 /** **/
952 /** TYPEDEFS AND STRUCTURES **/
953 /** **/
954 /****************************************************************************/
955
956
957 /*
958 This structure defines the fields used for "VitalFEF"
959 */
960 typedef struct asn1 {
961 void *pduType;
962 void *SAS;
963 } ASN1_t;
964
965 /*
966 This structure defines the fields used for "Annotated ECG"
967 */
968 typedef struct aecg {
969 char* test; /* test field for annotated ECG */
970
971 float diastolicBloodPressure; /* in mmHg */
972 float systolicBloodPressure; /* in mmHg */
973 char* MedicationDrugs;
974 char* ReferringPhysician;
975 char* LatestConfirmingPhysician;
976 char* Diagnosis;
977 uint8_t EmergencyLevel; /* 0: routine 1-10: increased emergency level */
978
979 float HeartRate;
980 float P_wave[2]; /* start and end */
981 float QRS_wave[2]; /* start and end */
982 float T_wave[2]; /* start and end */
983 float P_QRS_T_axes[3];
984
985 /***** SCP only fields *****/
986 struct {
987 uint8_t HUFFMAN;
988 uint8_t REF_BEAT;
989 uint8_t DIFF;
990 uint8_t BIMODAL;
991 } FLAG;
992 struct {
993 //uint8_t tag14[41],tag15[41];
994 struct {
995 uint16_t INST_NUMBER; /* tag 14, byte 1-2 */
996 uint16_t DEPT_NUMBER; /* tag 14, byte 3-4 */
997 uint16_t DEVICE_ID; /* tag 14, byte 5-6 */
998 uint8_t DeviceType; /* tag 14, byte 7: 0: Cart, 1: System (or Host) */
999 uint8_t MANUF_CODE; /* tag 14, byte 8 (MANUF_CODE has to be 255) */
1000 char* MOD_DESC; /* tag 14, byte 9 (MOD_DESC has to be "Cart1") */
1001 uint8_t VERSION; /* tag 14, byte 15 (VERSION has to be 20) */
1002 uint8_t PROT_COMP_LEVEL; /* tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) */
1003 uint8_t LANG_SUPP_CODE; /* tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) */
1004 uint8_t ECG_CAP_DEV; /* tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) */
1005 uint8_t MAINS_FREQ; /* tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) */
1006 char reserved[22]; /* char[35-19] reserved; */
1007 char* ANAL_PROG_REV_NUM;
1008 char* SERIAL_NUMBER_ACQ_DEV;
1009 char* ACQ_DEV_SYS_SW_ID;
1010 char* ACQ_DEV_SCP_SW; /* tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") */
1011 char* ACQ_DEV_MANUF; /* tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") */
1012 } Tag14, Tag15;
1013 } Section1;
1014 struct {
1015 size_t StartPtr;
1016 size_t Length;
1017 } Section5;
1018 struct {
1019 size_t StartPtr;
1020 size_t Length;
1021 } Section6;
1022 struct {
1023 char Confirmed; // 0: original report (not overread); 1:Confirmed report; 2: Overread report (not confirmed)
1024 struct tm t;
1025 uint8_t NumberOfStatements;
1026 char **Statements;
1027 } Section8;
1028 struct {
1029 char* StartPtr;
1030 size_t Length;
1031 } Section9;
1032 struct {
1033 size_t StartPtr;
1034 size_t Length;
1035 } Section10;
1036 struct {
1037 char Confirmed; // 0: original report (not overread); 1:Confirmed report; 2: Overread report (not confirmed)
1038 struct tm t;
1039 uint8_t NumberOfStatements;
1040 char **Statements;
1041 } Section11;
1042 struct {
1043 size_t StartPtr;
1044 size_t Length;
1045 } Section12;
1046
1047 } aECG_TYPE;
1048
1049 /****************************************************************************/
1050 /** **/
1051 /** INTERNAL FUNCTIONS **/
1052 /** **/
1053 /****************************************************************************/
1054
1055 #pragma GCC visibility push(default)
1056
1057 /*
1058 file access wrapper: use ZLIB (if available) or STDIO
1059 */
1060
1061 HDRTYPE* ifopen(HDRTYPE* hdr, const char* mode );
1062 int ifclose(HDRTYPE* hdr);
1063 int ifeof(HDRTYPE* hdr);
1064 int ifflush(HDRTYPE* hdr);
1065 size_t ifread(void* buf, size_t size, size_t nmemb, HDRTYPE* hdr);
1066 size_t ifwrite(void* buf, size_t size, size_t nmemb, HDRTYPE* hdr);
1067 int ifprintf(HDRTYPE* hdr, const char *format, va_list arg);
1068 int ifputc(int c, HDRTYPE* hdr);
1069 int ifgetc(HDRTYPE* hdr);
1070 char* ifgets(char *str, int n, HDRTYPE* hdr);
1071 int ifseek(HDRTYPE* hdr, ssize_t offset, int whence );
1072 ssize_t iftell(HDRTYPE* hdr);
1073 int ifgetpos(HDRTYPE* hdr, size_t *pos);
1074 int iferror(HDRTYPE* hdr);
1075
1076
1077 /*
1078 various utility functions
1079 */
1080
1081 uint32_t gcd(uint32_t A, uint32_t B);
1082 uint32_t lcm(uint32_t A, uint32_t B);
1083
1084 #pragma GCC visibility pop
1085
1086 extern const uint16_t GDFTYP_BITS[] __attribute__ ((visibility ("default") )) ;
1087 extern const char *LEAD_ID_TABLE[];
1088
1089 uint16_t CRCEvaluate(uint8_t* datablock, uint32_t datalength);
1090 int16_t CRCCheck(uint8_t* datablock, uint32_t datalength);
1091
1092 #if (BIOSIG_VERSION < 10700)
1093 // this deprecated since Aug 2013, v1.5.7
1094 #ifndef _WIN32
1095 ATT_DEPREC int strcmpi(const char* str1, const char* str2); // use strcasecmp() instead
1096 #endif
1097 ATT_DEPREC int strncmpi(const char* str1, const char* str2, size_t n); // use strncasecmp() instead
1098 #endif
1099
1100
1101 int month_string2int(const char *s);
1102
1103
1104 int u32cmp(const void *a, const void *b);
1105
1106 void biosigERROR(HDRTYPE *hdr, enum B4C_ERROR errnum, const char *errmsg) __attribute__ ((visibility ("default") ));
1107 /*
1108 sets the local and the (deprecated) global error variables B4C_ERRNUM and B4C_ERRMSG
1109 the global error variables are kept for backwards compatibility.
1110 */
1111
1112
1113 /*
1114 some important functions used internally,
1115 the interface for these functios is a bit clumsy and are
1116 therefore not exported to standard user applications.
1117 */
1118
1119 void struct2gdfbin(HDRTYPE *hdr) __attribute__ ((visibility ("default") ));
1120 int gdfbin2struct(HDRTYPE *hdr) __attribute__ ((visibility ("default") ));
1121 /* struct2gdfbin and gdfbin2struct
1122 convert between the streamed header information (as in a GDF file or
1123 on a network connection) and the header structure HDRTYPE
1124 Specifically, the fixed header, the variable hadder and the optional
1125 header information (header 1,2 and 3). This incluedes the
1126 description of the user-specified events (TYP=1..255), but not the
1127 event table itself.
1128 ------------------------------------------------------------------------*/
1129
1130 size_t hdrEVT2rawEVT(HDRTYPE *hdr) __attribute__ ((visibility ("default") ));
1131 void rawEVT2hdrEVT(HDRTYPE *hdr, size_t length_rawEventTable) __attribute__ ((visibility ("default") ));
1132 /* rawEVT2hdrEVT and hdrEVT2rawEVT
1133 convert between streamed event table and the structure
1134 HDRTYPE.EVENT.
1135 ------------------------------------------------------------------------*/
1136
1137 int NumberOfChannels(HDRTYPE *hdr) __attribute__ ((visibility ("default") ));
1138 /*
1139 returns the number of channels returned by SREAD.
1140 This might be different than the number of data channels in the file
1141 because of status,event and annotation channels, and because some
1142 rereferencing is applied
1143 ------------------------------------------------------------------------*/
1144
1145
1146 size_t reallocEventTable(HDRTYPE *hdr, size_t EventN);
1147 /*
1148 allocate, and resize memory of event table
1149 ------------------------------------------------------------------------*/
1150
1151 void FreeGlobalEventCodeTable();
1152 /*
1153 free memory allocated for global event code
1154 ------------------------------------------------------------------------*/
1155
1156 size_t sread_raw(size_t START, size_t LEN, HDRTYPE* hdr, char flag, void *buf, size_t bufsize) __attribute__ ((visibility ("default") ));
1157 /* sread_raw:
1158 LEN data segments are read from file associated with hdr, starting from
1159 segment START.
1160
1161 If buf==NULL, a sufficient amount of memory is (re-)allocated in
1162 hdr->AS.rawdata and the data is copied into hdr->AS.rawdata, and LEN*hdr->AS.bpb bytes
1163 are read and stored.
1164
1165 If buf points to some memory location of size bufsize, the data is stored
1166 in buf, no reallocation of memory is possible, and only the
1167 minimum(bufsize, LEN*hdr->AS.bpb) is stored.
1168
1169 No Overflowdetection or calibration is applied.
1170
1171 The number of successfully read data blocks is returned, this can be smaller
1172 than LEN at the end of the file, of when bufsize is not large enough.
1173
1174 The data can be "cached", this means
1175 that more than the requested number of blocks is available in hdr->AS.rawdata.
1176 hdr->AS.first and hdr->AS.length contain the number of the first
1177 block and the number of blocks, respectively.
1178 --------------------------------------------------------------- */
1179
1180 size_t bpb8_collapsed_rawdata(HDRTYPE *hdr) __attribute__ ((visibility ("default") ));
1181 /* bpb8_collapsed_rawdata
1182 computes the bits per block when rawdata is collapsed
1183 --------------------------------------------------------------- */
1184
1185 HDRTYPE* getfiletype(HDRTYPE* hdr);
1186 /* identify file format from header information
1187 input:
1188 hdr->AS.Header contains header of hdr->HeadLen bytes
1189 hdr->TYPE must be unknown, otherwise no FileFormat evaluation is performed
1190 output:
1191 hdr->TYPE file format
1192 hdr->VERSION is defined for some selected formats e.g. ACQ, EDF, BDF, GDF
1193 --------------------------------------------------------------- */
1194
1195 const char* GetFileTypeString(enum FileFormat FMT) __attribute__ ((visibility ("default") ));
1196 /* returns a string with file format
1197 --------------------------------------------------------------- */
1198
1199 enum FileFormat GetFileTypeFromString(const char *) __attribute__ ((visibility ("default") ));
1200 /* returns file format from string
1201 --------------------------------------------------------------- */
1202
1203
1204 #ifdef __cplusplus
1205 }
1206 #endif
1207
1208 /****************************************************************************/
1209 /** **/
1210 /** EOF **/
1211 /** **/
1212 /****************************************************************************/
1213
1214 #endif /* BIOSIG_INTERNAL_H */
1215