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