1 /*
2 *****************************************************************************
3 *
4 * Copyright (c) 2009 - 2021 Teunis van Beelen
5 * All rights reserved.
6 *
7 * Email: teuniz@protonmail.com
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in the
15 *       documentation and/or other materials provided with the distribution.
16 *     * Neither the name of the copyright holder nor the names of its
17 *       contributors may be used to endorse or promote products derived from
18 *       this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 *****************************************************************************
32 */
33 
34 /* compile with options "-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE" */
35 
36 #include "edflib.h"
37 
38 #define EDFLIB_VERSION  (120)
39 #define EDFLIB_MAXFILES  (64)
40 
41 #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__HAIKU__) || defined(__FreeBSD__)
42 
43 #define fopeno fopen
44 
45 #else
46 
47 #define fseeko fseeko64
48 #define ftello ftello64
49 #define fopeno fopen64
50 
51 #endif
52 
53 #ifdef _WIN32
54 
55 #ifndef __MINGW32__
56 /* needed for visual c */
57 #undef fseeko
58 #define fseeko _fseeki64
59 
60 #undef ftello
61 #define ftello _ftelli64
62 
63 #undef fopeno
64 #define fopeno fopen
65 
66 #endif
67 
68 #endif
69 
70 /* max size of annotationtext */
71 #define EDFLIB_WRITE_MAX_ANNOTATION_LEN  (40)
72 
73 /* bytes in datarecord for EDF annotations, must be an integer multiple of three and two */
74 #define EDFLIB_ANNOTATION_BYTES  (114)
75 
76 /* for writing only */
77 #define EDFLIB_MAX_ANNOTATION_CHANNELS  (64)
78 
79 #define EDFLIB_ANNOT_MEMBLOCKSZ  (1000)
80 
81 struct edfparamblock{
82         char   label[17];
83         char   transducer[81];
84         char   physdimension[9];
85         double phys_min;
86         double phys_max;
87         int    dig_min;
88         int    dig_max;
89         char   prefilter[81];
90         int    smp_per_record;
91         char   reserved[33];
92         double offset;
93         int    buf_offset;
94         double bitvalue;
95         int    annotation;
96         long long sample_pntr;
97       };
98 
99 struct edfhdrblock{
100         FILE      *file_hdl;
101         char      path[1024];
102         int       writemode;
103         char      version[32];
104         char      patient[81];
105         char      recording[81];
106         char      plus_patientcode[81];
107         char      plus_gender[16];
108         char      plus_birthdate[16];
109         char      plus_patient_name[81];
110         char      plus_patient_additional[81];
111         char      plus_startdate[16];
112         char      plus_admincode[81];
113         char      plus_technician[81];
114         char      plus_equipment[81];
115         char      plus_recording_additional[81];
116         long long l_starttime;
117         int       startdate_day;
118         int       startdate_month;
119         int       startdate_year;
120         int       starttime_second;
121         int       starttime_minute;
122         int       starttime_hour;
123         char      reserved[45];
124         int       hdrsize;
125         int       edfsignals;
126         long long datarecords;
127         int       recordsize;
128         int       annot_ch[EDFLIB_MAXSIGNALS];
129         int       nr_annot_chns;
130         int       mapped_signals[EDFLIB_MAXSIGNALS];
131         int       edf;
132         int       edfplus;
133         int       bdf;
134         int       bdfplus;
135         int       discontinuous;
136         int       signal_write_sequence_pos;
137         long long starttime_offset;
138         double    data_record_duration;
139         long long long_data_record_duration;
140         int       annots_in_file;
141         int       annotlist_sz;
142         int       total_annot_bytes;
143         int       eq_sf;
144         char      *wrbuf;
145         int       wrbufsize;
146         struct edfparamblock *edfparam;
147       };
148 
149 static struct edf_annotationblock{
150         long long onset;
151         char duration[16];
152         char annotation[EDFLIB_MAX_ANNOTATION_LEN + 1];
153        } *annotationslist[EDFLIB_MAXFILES];
154 
155 static struct edf_write_annotationblock{
156         long long onset;
157         long long duration;
158         char annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN + 1];
159        } *write_annotationslist[EDFLIB_MAXFILES];
160 
161 static int edf_files_open=0;
162 
163 static struct edfhdrblock *hdrlist[EDFLIB_MAXFILES];
164 
165 static struct edfhdrblock * edflib_check_edf_file(FILE *, int *);
166 static int edflib_is_integer_number(char *);
167 static int edflib_is_number(char *);
168 static long long edflib_get_long_duration(char *);
169 static int edflib_get_annotations(struct edfhdrblock *, int, int);
170 static int edflib_is_duration_number(char *);
171 static int edflib_is_onset_number(char *);
172 static long long edflib_get_long_time(char *);
173 static int edflib_write_edf_header(struct edfhdrblock *);
174 static void edflib_latin1_to_ascii(char *, int);
175 static void edflib_latin12utf8(char *, int);
176 static void edflib_remove_padding_trailing_spaces(char *);
177 static int edflib_atoi_nonlocalized(const char *);
178 static double edflib_atof_nonlocalized(const char *);
179 static int edflib_snprint_number_nonlocalized(char *, double, int);
180 /*
181 static int edflib_sprint_int_number_nonlocalized(char *, int, int, int);
182 */
183 static int edflib_snprint_ll_number_nonlocalized(char *, long long, int, int, int);
184 static int edflib_fprint_int_number_nonlocalized(FILE *, int, int, int);
185 static int edflib_fprint_ll_number_nonlocalized(FILE *, long long, int, int);
186 static int edflib_write_tal(struct edfhdrblock *, FILE *);
187 static int edflib_strlcpy(char *, const char *, int);
188 static int edflib_strlcat(char *, const char *, int);
189 
190 
edflib_is_file_used(const char * path)191 int edflib_is_file_used(const char *path)
192 {
193   int i;
194 
195   for(i=0; i<EDFLIB_MAXFILES; i++)
196   {
197     if(hdrlist[i]!=NULL)
198     {
199       if(!(strcmp(path, hdrlist[i]->path)))
200       {
201         return 1;
202       }
203     }
204   }
205 
206   return 0;
207 }
208 
209 
edflib_get_number_of_open_files()210 int edflib_get_number_of_open_files()
211 {
212   return edf_files_open;
213 }
214 
215 
edflib_get_handle(int file_number)216 int edflib_get_handle(int file_number)
217 {
218   int i, file_count=0;
219 
220   for(i=0; i<EDFLIB_MAXFILES; i++)
221   {
222     if(hdrlist[i]!=NULL)
223     {
224       if(file_count++ == file_number)
225       {
226         return i;
227       }
228     }
229   }
230 
231   return -1;
232 }
233 
234 
edfopen_file_readonly(const char * path,struct edf_hdr_struct * edfhdr,int read_annotations_mode)235 int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int read_annotations_mode)
236 {
237   int i, j,
238       channel,
239       edf_error;
240 
241   FILE *file;
242 
243   struct edfhdrblock *hdr;
244 
245 
246   if(read_annotations_mode<0)
247   {
248     edfhdr->filetype = EDFLIB_INVALID_READ_ANNOTS_VALUE;
249 
250     return -1;
251   }
252 
253   if(read_annotations_mode>2)
254   {
255     edfhdr->filetype = EDFLIB_INVALID_READ_ANNOTS_VALUE;
256 
257     return -1;
258   }
259 
260   memset(edfhdr, 0, sizeof(struct edf_hdr_struct));
261 
262   if(edf_files_open>=EDFLIB_MAXFILES)
263   {
264     edfhdr->filetype = EDFLIB_MAXFILES_REACHED;
265 
266     return -1;
267   }
268 
269   for(i=0; i<EDFLIB_MAXFILES; i++)
270   {
271     if(hdrlist[i]!=NULL)
272     {
273       if(!(strcmp(path, hdrlist[i]->path)))
274       {
275         edfhdr->filetype = EDFLIB_FILE_ALREADY_OPENED;
276 
277         return -1;
278       }
279     }
280   }
281 
282   file = fopeno(path, "rb");
283   if(file==NULL)
284   {
285     edfhdr->filetype = EDFLIB_NO_SUCH_FILE_OR_DIRECTORY;
286 
287     return -1;
288   }
289 
290   hdr = edflib_check_edf_file(file, &edf_error);
291   if(hdr==NULL)
292   {
293     edfhdr->filetype = edf_error;
294 
295     fclose(file);
296 
297     return -1;
298   }
299 
300   if(hdr->discontinuous)
301   {
302     edfhdr->filetype = EDFLIB_FILE_IS_DISCONTINUOUS;
303 
304     free(hdr->edfparam);
305     free(hdr);
306 
307     fclose(file);
308 
309     return -1;
310   }
311 
312   hdr->writemode = 0;
313 
314   for(i=0; i<EDFLIB_MAXFILES; i++)
315   {
316     if(hdrlist[i]==NULL)
317     {
318       hdrlist[i] = hdr;
319 
320       edfhdr->handle = i;
321 
322       break;
323     }
324   }
325 
326   if((hdr->edf)&&(!(hdr->edfplus)))
327   {
328     edfhdr->filetype = EDFLIB_FILETYPE_EDF;
329   }
330 
331   if(hdr->edfplus)
332   {
333     edfhdr->filetype = EDFLIB_FILETYPE_EDFPLUS;
334   }
335 
336   if((hdr->bdf)&&(!(hdr->bdfplus)))
337   {
338     edfhdr->filetype = EDFLIB_FILETYPE_BDF;
339   }
340 
341   if(hdr->bdfplus)
342   {
343     edfhdr->filetype = EDFLIB_FILETYPE_BDFPLUS;
344   }
345 
346   edfhdr->edfsignals = hdr->edfsignals - hdr->nr_annot_chns;
347   edfhdr->file_duration = hdr->long_data_record_duration * hdr->datarecords;
348   edfhdr->startdate_day = hdr->startdate_day;
349   edfhdr->startdate_month = hdr->startdate_month;
350   edfhdr->startdate_year = hdr->startdate_year;
351   edfhdr->starttime_hour = hdr->starttime_hour;
352   edfhdr->starttime_second = hdr->starttime_second;
353   edfhdr->starttime_minute = hdr->starttime_minute;
354   edfhdr->starttime_subsecond = hdr->starttime_offset;
355   edfhdr->datarecords_in_file = hdr->datarecords;
356   edfhdr->datarecord_duration = hdr->long_data_record_duration;
357 
358   annotationslist[edfhdr->handle] = NULL;
359 
360   hdr->annotlist_sz = 0;
361 
362   hdr->annots_in_file = 0;
363 
364   edfhdr->annotations_in_file = 0LL;
365 
366   if((!(hdr->edfplus))&&(!(hdr->bdfplus)))
367   {
368     edflib_strlcpy(edfhdr->patient, hdr->patient, 81);
369     edflib_strlcpy(edfhdr->recording, hdr->recording, 81);
370     edfhdr->patientcode[0] = 0;
371     edfhdr->gender[0] = 0;
372     edfhdr->birthdate[0] = 0;
373     edfhdr->patient_name[0] = 0;
374     edfhdr->patient_additional[0] = 0;
375     edfhdr->admincode[0] = 0;
376     edfhdr->technician[0] = 0;
377     edfhdr->equipment[0] = 0;
378     edfhdr->recording_additional[0] = 0;
379   }
380   else
381   {
382     edfhdr->patient[0] = 0;
383     edfhdr->recording[0] = 0;
384     edflib_strlcpy(edfhdr->patientcode, hdr->plus_patientcode, 81);
385     edflib_strlcpy(edfhdr->gender, hdr->plus_gender, 16);
386     edflib_strlcpy(edfhdr->birthdate, hdr->plus_birthdate, 16);
387     edflib_strlcpy(edfhdr->patient_name, hdr->plus_patient_name, 81);
388     edflib_strlcpy(edfhdr->patient_additional, hdr->plus_patient_additional, 81);
389     edflib_strlcpy(edfhdr->admincode, hdr->plus_admincode, 81);
390     edflib_strlcpy(edfhdr->technician, hdr->plus_technician, 81);
391     edflib_strlcpy(edfhdr->equipment, hdr->plus_equipment, 81);
392     edflib_strlcpy(edfhdr->recording_additional, hdr->plus_recording_additional, 81);
393 
394     if(edflib_get_annotations(hdr, edfhdr->handle, read_annotations_mode))
395     {
396       edfhdr->filetype = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
397 
398       fclose(file);
399 
400       free(hdr->edfparam);
401       hdr->edfparam = NULL;
402       free(hdr);
403       hdr = NULL;
404       hdrlist[edfhdr->handle] = NULL;
405       free(annotationslist[edfhdr->handle]);
406       annotationslist[edfhdr->handle] = NULL;
407 
408       return -1;
409     }
410 
411     edfhdr->starttime_subsecond = hdr->starttime_offset;
412 
413     edfhdr->annotations_in_file = hdr->annots_in_file;
414   }
415 
416   edflib_strlcpy(hdr->path, path, 1024);
417 
418   edf_files_open++;
419 
420   j = 0;
421 
422   for(i=0; i<hdr->edfsignals; i++)
423   {
424     if(!(hdr->edfparam[i].annotation))
425     {
426       hdr->mapped_signals[j++] = i;
427     }
428   }
429 
430   for(i=0; i<edfhdr->edfsignals; i++)
431   {
432     channel = hdr->mapped_signals[i];
433 
434     edflib_strlcpy(edfhdr->signalparam[i].label, hdr->edfparam[channel].label, 17);
435     edflib_strlcpy(edfhdr->signalparam[i].transducer, hdr->edfparam[channel].transducer, 81);
436     edflib_strlcpy(edfhdr->signalparam[i].physdimension, hdr->edfparam[channel].physdimension, 9);
437     edflib_strlcpy(edfhdr->signalparam[i].prefilter, hdr->edfparam[channel].prefilter, 81);
438     edfhdr->signalparam[i].smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords;
439     edfhdr->signalparam[i].phys_max = hdr->edfparam[channel].phys_max;
440     edfhdr->signalparam[i].phys_min = hdr->edfparam[channel].phys_min;
441     edfhdr->signalparam[i].dig_max = hdr->edfparam[channel].dig_max;
442     edfhdr->signalparam[i].dig_min = hdr->edfparam[channel].dig_min;
443     edfhdr->signalparam[i].smp_in_datarecord = hdr->edfparam[channel].smp_per_record;
444   }
445 
446   return 0;
447 }
448 
449 
edfclose_file(int handle)450 int edfclose_file(int handle)
451 {
452   struct edf_write_annotationblock *annot2;
453 
454   int i, j, k, n, p, err,
455       datrecsize,
456       nmemb;
457 
458   long long offset,
459             datarecords;
460 
461   char str[EDFLIB_ANNOTATION_BYTES * 2];
462 
463   struct edfhdrblock *hdr;
464 
465 
466   if(handle<0)
467   {
468     return -1;
469   }
470 
471   if(handle>=EDFLIB_MAXFILES)
472   {
473     return -1;
474   }
475 
476   if(hdrlist[handle]==NULL)
477   {
478     return -1;
479   }
480 
481   hdr = hdrlist[handle];
482 
483   if(hdr->writemode)
484   {
485     if(hdr->datarecords == 0LL)
486     {
487       err = edflib_write_edf_header(hdr);
488       if(err)
489       {
490         fclose(hdr->file_hdl);
491 
492         free(hdr->edfparam);
493 
494         free(hdr->wrbuf);
495 
496         free(hdr);
497 
498         hdrlist[handle] = NULL;
499 
500         free(write_annotationslist[handle]);
501 
502         write_annotationslist[handle] = NULL;
503 
504         edf_files_open--;
505 
506         return err;
507       }
508 
509       for(k=0; k<hdr->annots_in_file; k++)
510       {
511         annot2 = write_annotationslist[handle] + k;
512 
513         p = edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1);
514 
515         if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
516         {
517           fputc('.', hdr->file_hdl);
518           p++;
519           p += edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0);
520         }
521         fputc(20, hdr->file_hdl);
522         fputc(20, hdr->file_hdl);
523         p += 2;
524         for(; p<hdr->total_annot_bytes; p++)
525         {
526           fputc(0, hdr->file_hdl);
527         }
528 
529         hdr->datarecords++;
530       }
531     }
532 
533     if(hdr->datarecords<100000000LL)
534     {
535       fseeko(hdr->file_hdl, 236LL, SEEK_SET);
536       p = edflib_fprint_int_number_nonlocalized(hdr->file_hdl, (int)(hdr->datarecords), 0, 0);
537       if(p < 2)
538       {
539         fputc(' ', hdr->file_hdl);
540       }
541     }
542 
543     datarecords = 0LL;
544 
545     offset = (long long)((hdr->edfsignals + hdr->nr_annot_chns + 1) * 256);
546 
547     datrecsize = hdr->total_annot_bytes;
548 
549     for(i=0; i<hdr->edfsignals; i++)
550     {
551       if(hdr->edf)
552       {
553         offset += (long long)(hdr->edfparam[i].smp_per_record * 2);
554 
555         datrecsize += (hdr->edfparam[i].smp_per_record * 2);
556       }
557       else
558       {
559         offset += (long long)(hdr->edfparam[i].smp_per_record * 3);
560 
561         datrecsize += (hdr->edfparam[i].smp_per_record * 3);
562       }
563     }
564 
565     j = 0;
566 
567     for(k=0; k<hdr->annots_in_file; k++)
568     {
569       annot2 = write_annotationslist[handle] + k;
570 
571       annot2->onset += hdr->starttime_offset / 1000LL;
572 
573       p = 0;
574 
575       if(j==0)  // first annotation signal
576       {
577         if(fseeko(hdr->file_hdl, offset, SEEK_SET))
578         {
579           break;
580         }
581 
582         p += edflib_snprint_ll_number_nonlocalized(str, (datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * 2);
583 
584         if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
585         {
586           str[p++] = '.';
587           n = edflib_snprint_ll_number_nonlocalized(str + p, (datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
588           p += n;
589         }
590         str[p++] = 20;
591         str[p++] = 20;
592         str[p++] =  0;
593       }
594 
595       n = edflib_snprint_ll_number_nonlocalized(str + p, annot2->onset / 10000LL, 0, 1, (EDFLIB_ANNOTATION_BYTES * 2) - p);
596       p += n;
597       if(annot2->onset % 10000LL)
598       {
599         str[p++] = '.';
600         n = edflib_snprint_ll_number_nonlocalized(str + p, annot2->onset % 10000LL, 4, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
601         p += n;
602       }
603       if(annot2->duration>=0LL)
604       {
605         str[p++] = 21;
606         n = edflib_snprint_ll_number_nonlocalized(str + p, annot2->duration / 10000LL, 0, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
607         p += n;
608         if(annot2->duration % 10000LL)
609         {
610           str[p++] = '.';
611           n = edflib_snprint_ll_number_nonlocalized(str + p, annot2->duration % 10000LL, 4, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
612           p += n;
613         }
614       }
615       str[p++] = 20;
616       for(i=0; i<EDFLIB_WRITE_MAX_ANNOTATION_LEN; i++)
617       {
618         if(annot2->annotation[i]==0)
619         {
620           break;
621         }
622 
623         str[p++] = annot2->annotation[i];
624       }
625       str[p++] = 20;
626 
627       for(; p<EDFLIB_ANNOTATION_BYTES; p++)
628       {
629         str[p] = 0;
630       }
631 
632       nmemb = fwrite(str, EDFLIB_ANNOTATION_BYTES, 1, hdr->file_hdl);
633 
634       if(nmemb != 1)
635       {
636         break;
637       }
638 
639       j++;
640 
641       if(j >= hdr->nr_annot_chns)
642       {
643         j = 0;
644 
645         offset += datrecsize;
646 
647         datarecords++;
648 
649         if(datarecords>=hdr->datarecords)
650         {
651           break;
652         }
653       }
654     }
655 
656     free(write_annotationslist[handle]);
657   }
658   else
659   {
660     free(annotationslist[handle]);
661   }
662 
663   fclose(hdr->file_hdl);
664 
665   free(hdr->edfparam);
666 
667   free(hdr->wrbuf);
668 
669   free(hdr);
670 
671   hdrlist[handle] = NULL;
672 
673   edf_files_open--;
674 
675   return 0;
676 }
677 
678 
edfseek(int handle,int edfsignal,long long offset,int whence)679 long long edfseek(int handle, int edfsignal, long long offset, int whence)
680 {
681   long long smp_in_file;
682 
683   int channel;
684 
685 
686   if(handle<0)
687   {
688     return -1;
689   }
690 
691   if(handle>=EDFLIB_MAXFILES)
692   {
693     return -1;
694   }
695 
696   if(hdrlist[handle]==NULL)
697   {
698     return -1;
699   }
700 
701   if(edfsignal<0)
702   {
703     return -1;
704   }
705 
706   if(hdrlist[handle]->writemode)
707   {
708     return -1;
709   }
710 
711   if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns))
712   {
713     return -1;
714   }
715 
716   channel = hdrlist[handle]->mapped_signals[edfsignal];
717 
718   smp_in_file = hdrlist[handle]->edfparam[channel].smp_per_record * hdrlist[handle]->datarecords;
719 
720   if(whence==EDFSEEK_SET)
721   {
722     hdrlist[handle]->edfparam[channel].sample_pntr = offset;
723   }
724 
725   if(whence==EDFSEEK_CUR)
726   {
727     hdrlist[handle]->edfparam[channel].sample_pntr += offset;
728   }
729 
730   if(whence==EDFSEEK_END)
731   {
732     hdrlist[handle]->edfparam[channel].sample_pntr =
733       (hdrlist[handle]->edfparam[channel].smp_per_record * hdrlist[handle]->datarecords) + offset;
734   }
735 
736   if(hdrlist[handle]->edfparam[channel].sample_pntr > smp_in_file)
737   {
738     hdrlist[handle]->edfparam[channel].sample_pntr = smp_in_file;
739   }
740 
741   if(hdrlist[handle]->edfparam[channel].sample_pntr < 0LL)
742   {
743     hdrlist[handle]->edfparam[channel].sample_pntr = 0LL;
744   }
745 
746   return hdrlist[handle]->edfparam[channel].sample_pntr;
747 }
748 
749 
edftell(int handle,int edfsignal)750 long long edftell(int handle, int edfsignal)
751 {
752   int channel;
753 
754 
755   if(handle<0)
756   {
757     return -1;
758   }
759 
760   if(handle>=EDFLIB_MAXFILES)
761   {
762     return -1;
763   }
764 
765   if(hdrlist[handle]==NULL)
766   {
767     return -1;
768   }
769 
770   if(edfsignal<0)
771   {
772     return -1;
773   }
774 
775   if(hdrlist[handle]->writemode)
776   {
777     return -1;
778   }
779 
780   if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns))
781   {
782     return -1;
783   }
784 
785   channel = hdrlist[handle]->mapped_signals[edfsignal];
786 
787   return hdrlist[handle]->edfparam[channel].sample_pntr;
788 }
789 
790 
edfrewind(int handle,int edfsignal)791 void edfrewind(int handle, int edfsignal)
792 {
793   int channel;
794 
795 
796   if(handle<0)
797   {
798     return;
799   }
800 
801   if(handle>=EDFLIB_MAXFILES)
802   {
803     return;
804   }
805 
806   if(hdrlist[handle]==NULL)
807   {
808     return;
809   }
810 
811   if(edfsignal<0)
812   {
813     return;
814   }
815 
816   if(hdrlist[handle]->writemode)
817   {
818     return;
819   }
820 
821   if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns))
822   {
823     return;
824   }
825 
826   channel = hdrlist[handle]->mapped_signals[edfsignal];
827 
828   hdrlist[handle]->edfparam[channel].sample_pntr = 0LL;
829 }
830 
831 
edfread_physical_samples(int handle,int edfsignal,int n,double * buf)832 int edfread_physical_samples(int handle, int edfsignal, int n, double *buf)
833 {
834   int bytes_per_smpl=2,
835       tmp,
836       i,
837       channel;
838 
839   double phys_bitvalue,
840          phys_offset;
841 
842   long long smp_in_file,
843             offset,
844             sample_pntr,
845             smp_per_record,
846             jump;
847 
848   struct edfhdrblock *hdr;
849 
850   union {
851           unsigned int one;
852           signed int one_signed;
853           unsigned short two[2];
854           signed short two_signed[2];
855           unsigned char four[4];
856         } var;
857 
858   FILE *file;
859 
860 
861   if(handle<0)
862   {
863     return -1;
864   }
865 
866   if(handle>=EDFLIB_MAXFILES)
867   {
868     return -1;
869   }
870 
871   if(hdrlist[handle]==NULL)
872   {
873     return -1;
874   }
875 
876   if(edfsignal<0)
877   {
878     return -1;
879   }
880 
881   if(hdrlist[handle]->writemode)
882   {
883     return -1;
884   }
885 
886   if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns))
887   {
888     return -1;
889   }
890 
891   channel = hdrlist[handle]->mapped_signals[edfsignal];
892 
893   if(n<0LL)
894   {
895     return -1;
896   }
897 
898   if(n==0LL)
899   {
900     return 0LL;
901   }
902 
903   hdr = hdrlist[handle];
904 
905   if(hdr->edf)
906   {
907     bytes_per_smpl = 2;
908   }
909 
910   if(hdr->bdf)
911   {
912     bytes_per_smpl = 3;
913   }
914 
915   smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords;
916 
917   if((hdr->edfparam[channel].sample_pntr + n) > smp_in_file)
918   {
919     n = smp_in_file - hdr->edfparam[channel].sample_pntr;
920 
921     if(n==0)
922     {
923       return 0LL;
924     }
925 
926     if(n<0)
927     {
928       return -1;
929     }
930   }
931 
932   file = hdr->file_hdl;
933 
934   offset = hdr->hdrsize;
935   offset += (hdr->edfparam[channel].sample_pntr / hdr->edfparam[channel].smp_per_record) * hdr->recordsize;
936   offset += hdr->edfparam[channel].buf_offset;
937   offset += ((hdr->edfparam[channel].sample_pntr % hdr->edfparam[channel].smp_per_record) * bytes_per_smpl);
938 
939   fseeko(file, offset, SEEK_SET);
940 
941   sample_pntr = hdr->edfparam[channel].sample_pntr;
942 
943   smp_per_record = hdr->edfparam[channel].smp_per_record;
944 
945   jump = hdr->recordsize - (smp_per_record * bytes_per_smpl);
946 
947   phys_bitvalue = hdr->edfparam[channel].bitvalue;
948 
949   phys_offset = hdr->edfparam[channel].offset;
950 
951   if(hdr->edf)
952   {
953     for(i=0; i<n; i++)
954     {
955       if(!(sample_pntr%smp_per_record))
956       {
957         if(i)
958         {
959           fseeko(file, jump, SEEK_CUR);
960         }
961       }
962 
963       var.four[0] = fgetc(file);
964       tmp = fgetc(file);
965       if(tmp==EOF)
966       {
967         return -1;
968       }
969       var.four[1] = tmp;
970 
971       if(var.two_signed[0] > hdr->edfparam[channel].dig_max)
972       {
973         var.two_signed[0] = hdr->edfparam[channel].dig_max;
974       }
975       else if(var.two_signed[0] < hdr->edfparam[channel].dig_min)
976         {
977           var.two_signed[0] = hdr->edfparam[channel].dig_min;
978         }
979 
980       buf[i] = phys_bitvalue * (phys_offset + (double)var.two_signed[0]);
981 
982       sample_pntr++;
983     }
984   }
985 
986   if(hdr->bdf)
987   {
988     for(i=0; i<n; i++)
989     {
990       if(!(sample_pntr%smp_per_record))
991       {
992         if(i)
993         {
994           fseeko(file, jump, SEEK_CUR);
995         }
996       }
997 
998       var.four[0] = fgetc(file);
999       var.four[1] = fgetc(file);
1000       tmp = fgetc(file);
1001       if(tmp==EOF)
1002       {
1003         return -1;
1004       }
1005       var.four[2] = tmp;
1006 
1007       if(var.four[2]&0x80)
1008       {
1009         var.four[3] = 0xff;
1010       }
1011       else
1012       {
1013         var.four[3] = 0x00;
1014       }
1015 
1016       if(var.one_signed > hdr->edfparam[channel].dig_max)
1017       {
1018         var.one_signed = hdr->edfparam[channel].dig_max;
1019       }
1020       else if(var.one_signed < hdr->edfparam[channel].dig_min)
1021         {
1022           var.one_signed = hdr->edfparam[channel].dig_min;
1023         }
1024 
1025       buf[i] = phys_bitvalue * (phys_offset + (double)var.one_signed);
1026 
1027       sample_pntr++;
1028     }
1029   }
1030 
1031   hdr->edfparam[channel].sample_pntr = sample_pntr;
1032 
1033   return n;
1034 }
1035 
1036 
edfread_digital_samples(int handle,int edfsignal,int n,int * buf)1037 int edfread_digital_samples(int handle, int edfsignal, int n, int *buf)
1038 {
1039   int bytes_per_smpl=2,
1040       tmp,
1041       i,
1042       channel;
1043 
1044   long long smp_in_file,
1045             offset,
1046             sample_pntr,
1047             smp_per_record,
1048             jump;
1049 
1050   struct edfhdrblock *hdr;
1051 
1052   union {
1053           unsigned int one;
1054           signed int one_signed;
1055           unsigned short two[2];
1056           signed short two_signed[2];
1057           unsigned char four[4];
1058         } var;
1059 
1060   FILE *file;
1061 
1062 
1063   if(handle<0)
1064   {
1065     return -1;
1066   }
1067 
1068   if(handle>=EDFLIB_MAXFILES)
1069   {
1070     return -1;
1071   }
1072 
1073   if(hdrlist[handle]==NULL)
1074   {
1075     return -1;
1076   }
1077 
1078   if(edfsignal<0)
1079   {
1080     return -1;
1081   }
1082 
1083   if(hdrlist[handle]->writemode)
1084   {
1085     return -1;
1086   }
1087 
1088   if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns))
1089   {
1090     return -1;
1091   }
1092 
1093   channel = hdrlist[handle]->mapped_signals[edfsignal];
1094 
1095   if(n<0LL)
1096   {
1097     return -1;
1098   }
1099 
1100   if(n==0LL)
1101   {
1102     return 0LL;
1103   }
1104 
1105   hdr = hdrlist[handle];
1106 
1107   if(hdr->edf)
1108   {
1109     bytes_per_smpl = 2;
1110   }
1111 
1112   if(hdr->bdf)
1113   {
1114     bytes_per_smpl = 3;
1115   }
1116 
1117   smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords;
1118 
1119   if((hdr->edfparam[channel].sample_pntr + n) > smp_in_file)
1120   {
1121     n = smp_in_file - hdr->edfparam[channel].sample_pntr;
1122 
1123     if(n==0)
1124     {
1125       return 0LL;
1126     }
1127 
1128     if(n<0)
1129     {
1130       return -1;
1131     }
1132   }
1133 
1134   file = hdr->file_hdl;
1135 
1136   offset = hdr->hdrsize;
1137   offset += (hdr->edfparam[channel].sample_pntr / hdr->edfparam[channel].smp_per_record) * hdr->recordsize;
1138   offset += hdr->edfparam[channel].buf_offset;
1139   offset += ((hdr->edfparam[channel].sample_pntr % hdr->edfparam[channel].smp_per_record) * bytes_per_smpl);
1140 
1141   fseeko(file, offset, SEEK_SET);
1142 
1143   sample_pntr = hdr->edfparam[channel].sample_pntr;
1144 
1145   smp_per_record = hdr->edfparam[channel].smp_per_record;
1146 
1147   jump = hdr->recordsize - (smp_per_record * bytes_per_smpl);
1148 
1149   if(hdr->edf)
1150   {
1151     for(i=0; i<n; i++)
1152     {
1153       if(!(sample_pntr%smp_per_record))
1154       {
1155         if(i)
1156         {
1157           fseeko(file, jump, SEEK_CUR);
1158         }
1159       }
1160 
1161       var.four[0] = fgetc(file);
1162       tmp = fgetc(file);
1163       if(tmp==EOF)
1164       {
1165         return -1;
1166       }
1167       var.four[1] = tmp;
1168 
1169       if(var.two_signed[0] > hdr->edfparam[channel].dig_max)
1170       {
1171         var.two_signed[0] = hdr->edfparam[channel].dig_max;
1172       }
1173       else if(var.two_signed[0] < hdr->edfparam[channel].dig_min)
1174         {
1175           var.two_signed[0] = hdr->edfparam[channel].dig_min;
1176         }
1177 
1178       buf[i] = var.two_signed[0];
1179 
1180       sample_pntr++;
1181     }
1182   }
1183 
1184   if(hdr->bdf)
1185   {
1186     for(i=0; i<n; i++)
1187     {
1188       if(!(sample_pntr%smp_per_record))
1189       {
1190         if(i)
1191         {
1192           fseeko(file, jump, SEEK_CUR);
1193         }
1194       }
1195 
1196       var.four[0] = fgetc(file);
1197       var.four[1] = fgetc(file);
1198       tmp = fgetc(file);
1199       if(tmp==EOF)
1200       {
1201         return -1;
1202       }
1203       var.four[2] = tmp;
1204 
1205       if(var.four[2]&0x80)
1206       {
1207         var.four[3] = 0xff;
1208       }
1209       else
1210       {
1211         var.four[3] = 0x00;
1212       }
1213 
1214       if(var.one_signed > hdr->edfparam[channel].dig_max)
1215       {
1216         var.one_signed = hdr->edfparam[channel].dig_max;
1217       }
1218       else if(var.one_signed < hdr->edfparam[channel].dig_min)
1219         {
1220           var.one_signed = hdr->edfparam[channel].dig_min;
1221         }
1222 
1223       buf[i] = var.one_signed;
1224 
1225       sample_pntr++;
1226     }
1227   }
1228 
1229   hdr->edfparam[channel].sample_pntr = sample_pntr;
1230 
1231   return n;
1232 }
1233 
1234 
edf_get_annotation(int handle,int n,struct edf_annotation_struct * annot)1235 int edf_get_annotation(int handle, int n, struct edf_annotation_struct *annot)
1236 {
1237   memset(annot, 0, sizeof(struct edf_annotation_struct));
1238 
1239   if(handle<0)
1240   {
1241     return -1;
1242   }
1243 
1244   if(handle>=EDFLIB_MAXFILES)
1245   {
1246     return -1;
1247   }
1248 
1249   if(hdrlist[handle]==NULL)
1250   {
1251     return -1;
1252   }
1253 
1254   if(hdrlist[handle]->writemode)
1255   {
1256     return -1;
1257   }
1258 
1259   if(n<0)
1260   {
1261     return -1;
1262   }
1263 
1264   if(n>=hdrlist[handle]->annots_in_file)
1265   {
1266     return -1;
1267   }
1268 
1269   annot->onset = (annotationslist[handle] + n)->onset;
1270   edflib_strlcpy(annot->duration, (annotationslist[handle] + n)->duration, 16);
1271   edflib_strlcpy(annot->annotation, (annotationslist[handle] + n)->annotation, EDFLIB_MAX_ANNOTATION_LEN + 1);
1272 
1273   return 0;
1274 }
1275 
1276 
edflib_check_edf_file(FILE * inputfile,int * edf_error)1277 static struct edfhdrblock * edflib_check_edf_file(FILE *inputfile, int *edf_error)
1278 {
1279   int i, j, p, r=0, n,
1280       dotposition,
1281       error;
1282 
1283   char *edf_hdr,
1284        scratchpad[128],
1285        scratchpad2[64];
1286 
1287   struct edfhdrblock *edfhdr;
1288 
1289 /***************** check header ******************************/
1290 
1291   edf_hdr = (char *)calloc(1, 256);
1292   if(edf_hdr==NULL)
1293   {
1294     *edf_error = EDFLIB_MALLOC_ERROR;
1295     return NULL;
1296   }
1297 
1298   edfhdr = (struct edfhdrblock *)calloc(1, sizeof(struct edfhdrblock));
1299   if(edfhdr==NULL)
1300   {
1301     free(edf_hdr);
1302     *edf_error = EDFLIB_MALLOC_ERROR;
1303     return NULL;
1304   }
1305 
1306   rewind(inputfile);
1307   if(fread(edf_hdr, 256, 1, inputfile)!=1)
1308   {
1309     *edf_error = EDFLIB_FILE_READ_ERROR;
1310     free(edf_hdr);
1311     free(edfhdr);
1312     return NULL;
1313   }
1314 
1315 /**************************** VERSION ***************************************/
1316 
1317   strncpy(scratchpad, edf_hdr, 8);
1318   scratchpad[8] = 0;
1319 
1320   if(((signed char *)scratchpad)[0]==-1)   /* BDF-file */
1321   {
1322     for(i=1; i<8; i++)
1323     {
1324       if((scratchpad[i]<32)||(scratchpad[i]>126))
1325       {
1326         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1327         free(edf_hdr);
1328         free(edfhdr);
1329         return NULL;
1330       }
1331     }
1332 
1333     if(strcmp(scratchpad + 1, "BIOSEMI"))
1334     {
1335       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1336       free(edf_hdr);
1337       free(edfhdr);
1338       return NULL;
1339     }
1340 
1341     edfhdr->bdf = 1;
1342   }
1343   else    /* EDF-file */
1344   {
1345     for(i=0; i<8; i++)
1346     {
1347       if((scratchpad[i]<32)||(scratchpad[i]>126))
1348       {
1349         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1350         free(edf_hdr);
1351         free(edfhdr);
1352         return NULL;
1353       }
1354     }
1355 
1356     if(strcmp(scratchpad, "0       "))
1357     {
1358       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1359       free(edf_hdr);
1360       free(edfhdr);
1361       return NULL;
1362     }
1363 
1364     edfhdr->edf = 1;
1365   }
1366 
1367   strncpy(edfhdr->version, edf_hdr, 8);
1368   edfhdr->version[8] = 0;
1369   if(edfhdr->bdf)  edfhdr->version[0] = '.';
1370 
1371 /********************* PATIENTNAME *********************************************/
1372 
1373   strncpy(scratchpad, edf_hdr + 8, 80);
1374   scratchpad[80] = 0;
1375   for(i=0; i<80; i++)
1376   {
1377     if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126))
1378     {
1379       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1380       free(edf_hdr);
1381       free(edfhdr);
1382       return NULL;
1383     }
1384   }
1385 
1386   strncpy(edfhdr->patient, edf_hdr + 8, 80);
1387   edfhdr->patient[80] = 0;
1388 
1389 /********************* RECORDING *********************************************/
1390 
1391   strncpy(scratchpad, edf_hdr + 88, 80);
1392   scratchpad[80] = 0;
1393   for(i=0; i<80; i++)
1394   {
1395     if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126))
1396     {
1397       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1398       free(edf_hdr);
1399       free(edfhdr);
1400       return NULL;
1401     }
1402   }
1403 
1404   strncpy(edfhdr->recording, edf_hdr + 88, 80);
1405   edfhdr->recording[80] = 0;
1406 
1407 /********************* STARTDATE *********************************************/
1408 
1409   strncpy(scratchpad, edf_hdr + 168, 8);
1410   scratchpad[8] = 0;
1411   for(i=0; i<8; i++)
1412   {
1413     if((scratchpad[i]<32)||(scratchpad[i]>126))
1414     {
1415       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1416       free(edf_hdr);
1417       free(edfhdr);
1418       return NULL;
1419     }
1420   }
1421 
1422   error = 0;
1423 
1424   if((edf_hdr[170]!='.')||(edf_hdr[173]!='.'))  error = 1;
1425   if((edf_hdr[168]<48)||(edf_hdr[168]>57))      error = 1;
1426   if((edf_hdr[169]<48)||(edf_hdr[169]>57))      error = 1;
1427   if((edf_hdr[171]<48)||(edf_hdr[171]>57))      error = 1;
1428   if((edf_hdr[172]<48)||(edf_hdr[172]>57))      error = 1;
1429   if((edf_hdr[174]<48)||(edf_hdr[174]>57))      error = 1;
1430   if((edf_hdr[175]<48)||(edf_hdr[175]>57))      error = 1;
1431   strncpy(scratchpad, edf_hdr + 168, 8);
1432 
1433   if(error)
1434   {
1435     scratchpad[8] = 0;
1436     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1437     free(edf_hdr);
1438     free(edfhdr);
1439     return NULL;
1440   }
1441 
1442   scratchpad[2] = 0;
1443   scratchpad[5] = 0;
1444   scratchpad[8] = 0;
1445 
1446   if((edflib_atof_nonlocalized(scratchpad)<1)||(edflib_atof_nonlocalized(scratchpad)>31))
1447   {
1448     strncpy(scratchpad, edf_hdr + 168, 8);
1449     scratchpad[8] = 0;
1450     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1451     free(edf_hdr);
1452     free(edfhdr);
1453     return NULL;
1454   }
1455 
1456   if((edflib_atof_nonlocalized(scratchpad+3)<1)||(edflib_atof_nonlocalized(scratchpad+3)>12))
1457   {
1458     strncpy(scratchpad, edf_hdr + 168, 8);
1459     scratchpad[8] = 0;
1460     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1461     free(edf_hdr);
1462     free(edfhdr);
1463     return NULL;
1464   }
1465 
1466   edfhdr->startdate_day = edflib_atof_nonlocalized(scratchpad);
1467   edfhdr->startdate_month = edflib_atof_nonlocalized(scratchpad + 3);
1468   edfhdr->startdate_year = edflib_atof_nonlocalized(scratchpad + 6);
1469   if(edfhdr->startdate_year>84)
1470   {
1471     edfhdr->startdate_year += 1900;
1472   }
1473   else
1474   {
1475     edfhdr->startdate_year += 2000;
1476   }
1477 
1478 /********************* STARTTIME *********************************************/
1479 
1480   strncpy(scratchpad, edf_hdr + 176, 8);
1481   scratchpad[8] = 0;
1482   for(i=0; i<8; i++)
1483   {
1484     if((scratchpad[i]<32)||(scratchpad[i]>126))
1485     {
1486       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1487       free(edf_hdr);
1488       free(edfhdr);
1489       return NULL;
1490     }
1491   }
1492 
1493   error = 0;
1494 
1495   if((edf_hdr[178]!='.')||(edf_hdr[181]!='.'))  error = 1;
1496   if((edf_hdr[176]<48)||(edf_hdr[176]>57))      error = 1;
1497   if((edf_hdr[177]<48)||(edf_hdr[177]>57))      error = 1;
1498   if((edf_hdr[179]<48)||(edf_hdr[179]>57))      error = 1;
1499   if((edf_hdr[180]<48)||(edf_hdr[180]>57))      error = 1;
1500   if((edf_hdr[182]<48)||(edf_hdr[182]>57))      error = 1;
1501   if((edf_hdr[183]<48)||(edf_hdr[183]>57))      error = 1;
1502 
1503   strncpy(scratchpad, edf_hdr + 176, 8);
1504 
1505   if(error)
1506   {
1507     strncpy(scratchpad, edf_hdr + 176, 8);
1508     scratchpad[8] = 0;
1509     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1510     free(edf_hdr);
1511     free(edfhdr);
1512     return NULL;
1513   }
1514 
1515   scratchpad[2] = 0;
1516   scratchpad[5] = 0;
1517   scratchpad[8] = 0;
1518 
1519   if(edflib_atof_nonlocalized(scratchpad)>23)
1520   {
1521     strncpy(scratchpad, edf_hdr + 176, 8);
1522     scratchpad[8] = 0;
1523     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1524     free(edf_hdr);
1525     free(edfhdr);
1526     return NULL;
1527   }
1528 
1529   if(edflib_atof_nonlocalized(scratchpad+3)>59)
1530   {
1531     strncpy(scratchpad, edf_hdr + 176, 8);
1532     scratchpad[8] = 0;
1533     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1534     free(edf_hdr);
1535     free(edfhdr);
1536     return NULL;
1537   }
1538 
1539   if(edflib_atof_nonlocalized(scratchpad+6)>59)
1540   {
1541     strncpy(scratchpad, edf_hdr + 176, 8);
1542     scratchpad[8] = 0;
1543     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1544     free(edf_hdr);
1545     free(edfhdr);
1546     return NULL;
1547   }
1548 
1549   edfhdr->starttime_hour = edflib_atof_nonlocalized(scratchpad);
1550   edfhdr->starttime_minute = edflib_atof_nonlocalized(scratchpad + 3);
1551   edfhdr->starttime_second = edflib_atof_nonlocalized(scratchpad + 6);
1552 
1553   edfhdr->l_starttime = 3600 * edflib_atof_nonlocalized(scratchpad);
1554   edfhdr->l_starttime += 60 * edflib_atof_nonlocalized(scratchpad + 3);
1555   edfhdr->l_starttime += edflib_atof_nonlocalized(scratchpad + 6);
1556 
1557   edfhdr->l_starttime *= EDFLIB_TIME_DIMENSION;
1558 
1559 /***************** NUMBER OF SIGNALS IN HEADER *******************************/
1560 
1561   strncpy(scratchpad, edf_hdr + 252, 4);
1562   scratchpad[4] = 0;
1563   for(i=0; i<4; i++)
1564   {
1565     if((scratchpad[i]<32)||(scratchpad[i]>126))
1566     {
1567       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1568       free(edf_hdr);
1569       free(edfhdr);
1570       return NULL;
1571     }
1572   }
1573 
1574   if(edflib_is_integer_number(scratchpad))
1575   {
1576     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1577     free(edf_hdr);
1578     free(edfhdr);
1579     return NULL;
1580   }
1581   edfhdr->edfsignals = edflib_atof_nonlocalized(scratchpad);
1582   if(edfhdr->edfsignals<1)
1583   {
1584     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1585     free(edf_hdr);
1586     free(edfhdr);
1587     return NULL;
1588   }
1589 
1590   if(edfhdr->edfsignals>EDFLIB_MAXSIGNALS)
1591   {
1592     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1593     free(edf_hdr);
1594     free(edfhdr);
1595     return NULL;
1596   }
1597 
1598 /***************** NUMBER OF BYTES IN HEADER *******************************/
1599 
1600   strncpy(scratchpad, edf_hdr + 184, 8);
1601   scratchpad[8] = 0;
1602 
1603   for(i=0; i<8; i++)
1604   {
1605     if((scratchpad[i]<32)||(scratchpad[i]>126))
1606     {
1607       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1608       free(edf_hdr);
1609       free(edfhdr);
1610       return NULL;
1611     }
1612   }
1613 
1614   if(edflib_is_integer_number(scratchpad))
1615   {
1616     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1617     free(edf_hdr);
1618     free(edfhdr);
1619     return NULL;
1620   }
1621 
1622   n  = edflib_atof_nonlocalized(scratchpad);
1623   if((edfhdr->edfsignals * 256 + 256)!=n)
1624   {
1625     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1626     free(edf_hdr);
1627     free(edfhdr);
1628     return NULL;
1629   }
1630 
1631 /********************* RESERVED FIELD *************************************/
1632 
1633   edfhdr->edfplus = 0;
1634   edfhdr->discontinuous = 0;
1635   strncpy(scratchpad, edf_hdr + 192, 44);
1636   scratchpad[44] = 0;
1637 
1638   for(i=0; i<44; i++)
1639   {
1640     if((scratchpad[i]<32)||(scratchpad[i]>126))
1641     {
1642       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1643       free(edf_hdr);
1644       free(edfhdr);
1645       return NULL;
1646     }
1647   }
1648 
1649   if(edfhdr->edf)
1650   {
1651     if(!strncmp(scratchpad, "EDF+C", 5))
1652     {
1653       edfhdr->edfplus = 1;
1654     }
1655 
1656     if(!strncmp(scratchpad, "EDF+D", 5))
1657     {
1658       edfhdr->edfplus = 1;
1659       edfhdr->discontinuous = 1;
1660     }
1661   }
1662 
1663   if(edfhdr->bdf)
1664   {
1665     if(!strncmp(scratchpad, "BDF+C", 5))
1666     {
1667       edfhdr->bdfplus = 1;
1668     }
1669 
1670     if(!strncmp(scratchpad, "BDF+D", 5))
1671     {
1672       edfhdr->bdfplus = 1;
1673       edfhdr->discontinuous = 1;
1674     }
1675   }
1676 
1677   strncpy(edfhdr->reserved, edf_hdr + 192, 44);
1678   edfhdr->reserved[44] = 0;
1679 
1680 /********************* NUMBER OF DATARECORDS *************************************/
1681 
1682   strncpy(scratchpad, edf_hdr + 236, 8);
1683   scratchpad[8] = 0;
1684 
1685   for(i=0; i<8; i++)
1686   {
1687     if((scratchpad[i]<32)||(scratchpad[i]>126))
1688     {
1689       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1690       free(edf_hdr);
1691       free(edfhdr);
1692       return NULL;
1693     }
1694   }
1695 
1696   if(edflib_is_integer_number(scratchpad))
1697   {
1698     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1699     free(edf_hdr);
1700     free(edfhdr);
1701     return NULL;
1702   }
1703 
1704   edfhdr->datarecords = edflib_atof_nonlocalized(scratchpad);
1705   if(edfhdr->datarecords<1)
1706   {
1707     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1708     free(edf_hdr);
1709     free(edfhdr);
1710     return NULL;
1711   }
1712 
1713 /********************* DATARECORD DURATION *************************************/
1714 
1715   strncpy(scratchpad, edf_hdr + 244, 8);
1716   scratchpad[8] = 0;
1717 
1718   for(i=0; i<8; i++)
1719   {
1720     if((scratchpad[i]<32)||(scratchpad[i]>126))
1721     {
1722       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1723       free(edf_hdr);
1724       free(edfhdr);
1725       return NULL;
1726     }
1727   }
1728 
1729   if(edflib_is_number(scratchpad))
1730   {
1731     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1732     free(edf_hdr);
1733     free(edfhdr);
1734     return NULL;
1735   }
1736 
1737   edfhdr->data_record_duration = edflib_atof_nonlocalized(scratchpad);
1738   if(edfhdr->data_record_duration < -0.000001)
1739   {
1740     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1741     free(edf_hdr);
1742     free(edfhdr);
1743     return NULL;
1744   }
1745 
1746   edfhdr->long_data_record_duration = edflib_get_long_duration(scratchpad);
1747 
1748   free(edf_hdr);
1749 
1750 /********************* START WITH THE SIGNALS IN THE HEADER *********************/
1751 
1752   edf_hdr = (char *)calloc(1, (edfhdr->edfsignals + 1) * 256);
1753   if(edf_hdr==NULL)
1754   {
1755     *edf_error = EDFLIB_MALLOC_ERROR;
1756     free(edfhdr);
1757     return NULL;
1758   }
1759 
1760   rewind(inputfile);
1761   if(fread(edf_hdr, (edfhdr->edfsignals + 1) * 256, 1, inputfile)!=1)
1762   {
1763     *edf_error = EDFLIB_FILE_READ_ERROR;
1764     free(edf_hdr);
1765     free(edfhdr);
1766     return NULL;
1767   }
1768 
1769   edfhdr->edfparam = (struct edfparamblock *)calloc(1, sizeof(struct edfparamblock) * edfhdr->edfsignals);
1770   if(edfhdr->edfparam==NULL)
1771   {
1772     *edf_error = EDFLIB_MALLOC_ERROR;
1773     free(edf_hdr);
1774     free(edfhdr);
1775     return NULL;
1776   }
1777 
1778 /**************************** LABELS *************************************/
1779 
1780   edfhdr->nr_annot_chns = 0;
1781   for(i=0; i<edfhdr->edfsignals; i++)
1782   {
1783     strncpy(scratchpad, edf_hdr + 256 + (i * 16), 16);
1784     for(j=0; j<16; j++)
1785     {
1786       if((scratchpad[j]<32)||(scratchpad[j]>126))
1787       {
1788         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1789         free(edf_hdr);
1790         free(edfhdr->edfparam);
1791         free(edfhdr);
1792         return NULL;
1793       }
1794     }
1795     if(edfhdr->edfplus)
1796     {
1797       if(!strncmp(scratchpad, "EDF Annotations ", 16))
1798       {
1799         edfhdr->annot_ch[edfhdr->nr_annot_chns] = i;
1800         edfhdr->nr_annot_chns++;
1801         edfhdr->edfparam[i].annotation = 1;
1802       }
1803     }
1804     if(edfhdr->bdfplus)
1805     {
1806       if(!strncmp(scratchpad, "BDF Annotations ", 16))
1807       {
1808         edfhdr->annot_ch[edfhdr->nr_annot_chns] = i;
1809         edfhdr->nr_annot_chns++;
1810         edfhdr->edfparam[i].annotation = 1;
1811       }
1812     }
1813     strncpy(edfhdr->edfparam[i].label, edf_hdr + 256 + (i * 16), 16);
1814     edfhdr->edfparam[i].label[16] = 0;
1815   }
1816   if(edfhdr->edfplus&&(!edfhdr->nr_annot_chns))
1817   {
1818     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1819     free(edf_hdr);
1820     free(edfhdr->edfparam);
1821     free(edfhdr);
1822     return NULL;
1823   }
1824   if(edfhdr->bdfplus&&(!edfhdr->nr_annot_chns))
1825   {
1826     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1827     free(edf_hdr);
1828     free(edfhdr->edfparam);
1829     free(edfhdr);
1830     return NULL;
1831   }
1832   if((edfhdr->edfsignals!=edfhdr->nr_annot_chns)||((!edfhdr->edfplus)&&(!edfhdr->bdfplus)))
1833   {
1834     if(edfhdr->data_record_duration<0.0000001)
1835     {
1836       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1837       free(edf_hdr);
1838       free(edfhdr->edfparam);
1839       free(edfhdr);
1840       return NULL;
1841     }
1842   }
1843 
1844 /**************************** TRANSDUCER TYPES *************************************/
1845 
1846   for(i=0; i<edfhdr->edfsignals; i++)
1847   {
1848     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80);
1849     for(j=0; j<80; j++)
1850     {
1851       if((scratchpad[j]<32)||(scratchpad[j]>126))
1852       {
1853         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1854         free(edf_hdr);
1855         free(edfhdr->edfparam);
1856         free(edfhdr);
1857         return NULL;
1858       }
1859     }
1860     strncpy(edfhdr->edfparam[i].transducer, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80);
1861     edfhdr->edfparam[i].transducer[80] = 0;
1862 
1863     if((edfhdr->edfplus) || (edfhdr->bdfplus))
1864     {
1865       if(edfhdr->edfparam[i].annotation)
1866       {
1867         for(j=0; j<80; j++)
1868         {
1869           if(edfhdr->edfparam[i].transducer[j]!=' ')
1870           {
1871             *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1872             free(edf_hdr);
1873             free(edfhdr->edfparam);
1874             free(edfhdr);
1875             return NULL;
1876           }
1877         }
1878       }
1879     }
1880   }
1881 
1882 /**************************** PHYSICAL DIMENSIONS *************************************/
1883 
1884   for(i=0; i<edfhdr->edfsignals; i++)
1885   {
1886     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8);
1887     for(j=0; j<8; j++)
1888     {
1889       if((scratchpad[j]<32)||(scratchpad[j]>126))
1890       {
1891         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1892         free(edf_hdr);
1893         free(edfhdr->edfparam);
1894         free(edfhdr);
1895         return NULL;
1896       }
1897     }
1898     strncpy(edfhdr->edfparam[i].physdimension, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8);
1899     edfhdr->edfparam[i].physdimension[8] = 0;
1900   }
1901 
1902 /**************************** PHYSICAL MINIMUMS *************************************/
1903 
1904   for(i=0; i<edfhdr->edfsignals; i++)
1905   {
1906     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 104) + (i * 8), 8);
1907     scratchpad[8] = 0;
1908 
1909     for(j=0; j<8; j++)
1910     {
1911       if((scratchpad[j]<32)||(scratchpad[j]>126))
1912       {
1913         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1914         free(edf_hdr);
1915         free(edfhdr->edfparam);
1916         free(edfhdr);
1917         return NULL;
1918       }
1919     }
1920 
1921     if(edflib_is_number(scratchpad))
1922     {
1923       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1924       free(edf_hdr);
1925       free(edfhdr->edfparam);
1926       free(edfhdr);
1927       return NULL;
1928     }
1929 
1930     edfhdr->edfparam[i].phys_min = edflib_atof_nonlocalized(scratchpad);
1931   }
1932 
1933 /**************************** PHYSICAL MAXIMUMS *************************************/
1934 
1935   for(i=0; i<edfhdr->edfsignals; i++)
1936   {
1937     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 112) + (i * 8), 8);
1938     scratchpad[8] = 0;
1939 
1940     for(j=0; j<8; j++)
1941     {
1942       if((scratchpad[j]<32)||(scratchpad[j]>126))
1943       {
1944         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1945         free(edf_hdr);
1946         free(edfhdr->edfparam);
1947         free(edfhdr);
1948         return NULL;
1949       }
1950     }
1951 
1952     if(edflib_is_number(scratchpad))
1953     {
1954       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1955       free(edf_hdr);
1956       free(edfhdr->edfparam);
1957       free(edfhdr);
1958       return NULL;
1959     }
1960 
1961     edfhdr->edfparam[i].phys_max = edflib_atof_nonlocalized(scratchpad);
1962     if(edfhdr->edfparam[i].phys_max==edfhdr->edfparam[i].phys_min)
1963     {
1964       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1965       free(edf_hdr);
1966       free(edfhdr->edfparam);
1967       free(edfhdr);
1968       return NULL;
1969     }
1970   }
1971 
1972 /**************************** DIGITAL MINIMUMS *************************************/
1973 
1974   for(i=0; i<edfhdr->edfsignals; i++)
1975   {
1976     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 120) + (i * 8), 8);
1977     scratchpad[8] = 0;
1978 
1979     for(j=0; j<8; j++)
1980     {
1981       if((scratchpad[j]<32)||(scratchpad[j]>126))
1982       {
1983         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1984         free(edf_hdr);
1985         free(edfhdr->edfparam);
1986         free(edfhdr);
1987         return NULL;
1988       }
1989     }
1990 
1991     if(edflib_is_integer_number(scratchpad))
1992     {
1993       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
1994       free(edf_hdr);
1995       free(edfhdr->edfparam);
1996       free(edfhdr);
1997       return NULL;
1998     }
1999 
2000     n = edflib_atof_nonlocalized(scratchpad);
2001     if(edfhdr->edfplus)
2002     {
2003       if(edfhdr->edfparam[i].annotation)
2004       {
2005         if(n!=-32768)
2006         {
2007           *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2008           free(edf_hdr);
2009           free(edfhdr->edfparam);
2010           free(edfhdr);
2011           return NULL;
2012         }
2013       }
2014     }
2015     if(edfhdr->bdfplus)
2016     {
2017       if(edfhdr->edfparam[i].annotation)
2018       {
2019         if(n!=-8388608)
2020         {
2021           *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2022           free(edf_hdr);
2023           free(edfhdr->edfparam);
2024           free(edfhdr);
2025           return NULL;
2026         }
2027       }
2028     }
2029     if(edfhdr->edf)
2030     {
2031       if((n>32767)||(n<-32768))
2032       {
2033         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2034         free(edf_hdr);
2035         free(edfhdr->edfparam);
2036         free(edfhdr);
2037         return NULL;
2038       }
2039     }
2040     if(edfhdr->bdf)
2041     {
2042       if((n>8388607)||(n<-8388608))
2043       {
2044         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2045         free(edf_hdr);
2046         free(edfhdr->edfparam);
2047         free(edfhdr);
2048         return NULL;
2049       }
2050     }
2051     edfhdr->edfparam[i].dig_min = n;
2052   }
2053 
2054 /**************************** DIGITAL MAXIMUMS *************************************/
2055 
2056   for(i=0; i<edfhdr->edfsignals; i++)
2057   {
2058     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 128) + (i * 8), 8);
2059     scratchpad[8] = 0;
2060 
2061     for(j=0; j<8; j++)
2062     {
2063       if((scratchpad[j]<32)||(scratchpad[j]>126))
2064       {
2065         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2066         free(edf_hdr);
2067         free(edfhdr->edfparam);
2068         free(edfhdr);
2069         return NULL;
2070       }
2071     }
2072 
2073     if(edflib_is_integer_number(scratchpad))
2074     {
2075       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2076       free(edf_hdr);
2077       free(edfhdr->edfparam);
2078       free(edfhdr);
2079       return NULL;
2080     }
2081 
2082     n = edflib_atof_nonlocalized(scratchpad);
2083     if(edfhdr->edfplus)
2084     {
2085       if(edfhdr->edfparam[i].annotation)
2086       {
2087         if(n!=32767)
2088         {
2089           *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2090           free(edf_hdr);
2091           free(edfhdr->edfparam);
2092           free(edfhdr);
2093           return NULL;
2094         }
2095       }
2096     }
2097     if(edfhdr->bdfplus)
2098     {
2099       if(edfhdr->edfparam[i].annotation)
2100       {
2101         if(n!=8388607)
2102         {
2103           *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2104           free(edf_hdr);
2105           free(edfhdr->edfparam);
2106           free(edfhdr);
2107           return NULL;
2108         }
2109       }
2110     }
2111     if(edfhdr->edf)
2112     {
2113       if((n>32767)||(n<-32768))
2114       {
2115         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2116         free(edf_hdr);
2117         free(edfhdr->edfparam);
2118         free(edfhdr);
2119         return NULL;
2120       }
2121     }
2122     else
2123     {
2124       if((n>8388607)||(n<-8388608))
2125       {
2126         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2127         free(edf_hdr);
2128         free(edfhdr->edfparam);
2129         free(edfhdr);
2130         return NULL;
2131       }
2132     }
2133     edfhdr->edfparam[i].dig_max = n;
2134     if(edfhdr->edfparam[i].dig_max<(edfhdr->edfparam[i].dig_min + 1))
2135     {
2136       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2137       free(edf_hdr);
2138       free(edfhdr->edfparam);
2139       free(edfhdr);
2140       return NULL;
2141     }
2142   }
2143 
2144 /**************************** PREFILTER FIELDS *************************************/
2145 
2146   for(i=0; i<edfhdr->edfsignals; i++)
2147   {
2148     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80);
2149     for(j=0; j<80; j++)
2150     {
2151       if((scratchpad[j]<32)||(scratchpad[j]>126))
2152       {
2153         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2154         free(edf_hdr);
2155         free(edfhdr->edfparam);
2156         free(edfhdr);
2157         return NULL;
2158       }
2159     }
2160     strncpy(edfhdr->edfparam[i].prefilter, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80);
2161     edfhdr->edfparam[i].prefilter[80] = 0;
2162 
2163     if((edfhdr->edfplus) || (edfhdr->bdfplus))
2164     {
2165       if(edfhdr->edfparam[i].annotation)
2166       {
2167         for(j=0; j<80; j++)
2168         {
2169           if(edfhdr->edfparam[i].prefilter[j]!=' ')
2170           {
2171             *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2172             free(edf_hdr);
2173             free(edfhdr->edfparam);
2174             free(edfhdr);
2175             return NULL;
2176           }
2177         }
2178       }
2179     }
2180   }
2181 
2182 /*********************** NR OF SAMPLES IN EACH DATARECORD ********************/
2183 
2184   edfhdr->recordsize = 0;
2185 
2186   for(i=0; i<edfhdr->edfsignals; i++)
2187   {
2188     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 216) + (i * 8), 8);
2189     scratchpad[8] = 0;
2190 
2191     for(j=0; j<8; j++)
2192     {
2193       if((scratchpad[j]<32)||(scratchpad[j]>126))
2194       {
2195         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2196         free(edf_hdr);
2197         free(edfhdr->edfparam);
2198         free(edfhdr);
2199         return NULL;
2200       }
2201     }
2202 
2203     if(edflib_is_integer_number(scratchpad))
2204     {
2205       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2206       free(edf_hdr);
2207       free(edfhdr->edfparam);
2208       free(edfhdr);
2209       return NULL;
2210     }
2211 
2212     n = edflib_atof_nonlocalized(scratchpad);
2213     if(n<1)
2214     {
2215       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2216       free(edf_hdr);
2217       free(edfhdr->edfparam);
2218       free(edfhdr);
2219       return NULL;
2220     }
2221     edfhdr->edfparam[i].smp_per_record = n;
2222     edfhdr->recordsize += n;
2223   }
2224 
2225   if(edfhdr->bdf)
2226   {
2227     edfhdr->recordsize *= 3;
2228 
2229     if(edfhdr->recordsize > (15 * 1024 * 1024))
2230     {
2231       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2232       free(edf_hdr);
2233       free(edfhdr->edfparam);
2234       free(edfhdr);
2235       return NULL;
2236     }
2237   }
2238   else
2239   {
2240     edfhdr->recordsize *= 2;
2241 
2242     if(edfhdr->recordsize > (10 * 1024 * 1024))
2243     {
2244       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2245       free(edf_hdr);
2246       free(edfhdr->edfparam);
2247       free(edfhdr);
2248       return NULL;
2249     }
2250   }
2251 
2252 /**************************** RESERVED FIELDS *************************************/
2253 
2254   for(i=0; i<edfhdr->edfsignals; i++)
2255   {
2256     strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32);
2257     for(j=0; j<32; j++)
2258     {
2259       if((scratchpad[j]<32)||(scratchpad[j]>126))
2260       {
2261         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2262         free(edf_hdr);
2263         free(edfhdr->edfparam);
2264         free(edfhdr);
2265         return NULL;
2266       }
2267     }
2268     strncpy(edfhdr->edfparam[i].reserved, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32);
2269     edfhdr->edfparam[i].reserved[32] = 0;
2270   }
2271 
2272 /********************* EDF+ PATIENTNAME *********************************************/
2273 
2274   if(edfhdr->edfplus || edfhdr->bdfplus)
2275   {
2276     error = 0;
2277     dotposition = 0;
2278     strncpy(scratchpad, edf_hdr + 8, 80);
2279     scratchpad[80] = 0;
2280     for(i=0; i<80; i++)
2281     {
2282       if(scratchpad[i]==' ')
2283       {
2284         dotposition = i;
2285         break;
2286       }
2287     }
2288     dotposition++;
2289     if((dotposition>73)||(dotposition<2))  error = 1;
2290     if(scratchpad[dotposition + 2]!='X')
2291     {
2292       if(dotposition>65)  error = 1;
2293     }
2294     if((scratchpad[dotposition]!='M')&&(scratchpad[dotposition]!='F')&&(scratchpad[dotposition]!='X'))  error = 1;
2295     dotposition++;
2296     if(scratchpad[dotposition]!=' ')  error = 1;
2297     if(scratchpad[dotposition + 1]=='X')
2298     {
2299       if(scratchpad[dotposition + 2]!=' ')  error = 1;
2300       if(scratchpad[dotposition + 3]==' ')  error = 1;
2301     }
2302     else
2303     {
2304       if(scratchpad[dotposition + 12]!=' ')  error = 1;
2305       if(scratchpad[dotposition + 13]==' ')  error = 1;
2306       dotposition++;
2307       strncpy(scratchpad2, scratchpad + dotposition, 11);
2308       scratchpad2[11] = 0;
2309       if((scratchpad2[2]!='-')||(scratchpad2[6]!='-'))  error = 1;
2310       scratchpad2[2] = 0;
2311       scratchpad2[6] = 0;
2312       if((scratchpad2[0]<48)||(scratchpad2[0]>57))  error = 1;
2313       if((scratchpad2[1]<48)||(scratchpad2[1]>57))  error = 1;
2314       if((scratchpad2[7]<48)||(scratchpad2[7]>57))  error = 1;
2315       if((scratchpad2[8]<48)||(scratchpad2[8]>57))  error = 1;
2316       if((scratchpad2[9]<48)||(scratchpad2[9]>57))  error = 1;
2317       if((scratchpad2[10]<48)||(scratchpad2[10]>57))  error = 1;
2318       if((edflib_atof_nonlocalized(scratchpad2)<1)||(edflib_atof_nonlocalized(scratchpad2)>31))  error = 1;
2319       if(strcmp(scratchpad2 + 3, "JAN"))
2320         if(strcmp(scratchpad2 + 3, "FEB"))
2321           if(strcmp(scratchpad2 + 3, "MAR"))
2322             if(strcmp(scratchpad2 + 3, "APR"))
2323               if(strcmp(scratchpad2 + 3, "MAY"))
2324                 if(strcmp(scratchpad2 + 3, "JUN"))
2325                   if(strcmp(scratchpad2 + 3, "JUL"))
2326                     if(strcmp(scratchpad2 + 3, "AUG"))
2327                       if(strcmp(scratchpad2 + 3, "SEP"))
2328                         if(strcmp(scratchpad2 + 3, "OCT"))
2329                           if(strcmp(scratchpad2 + 3, "NOV"))
2330                             if(strcmp(scratchpad2 + 3, "DEC"))
2331                               error = 1;
2332     }
2333 
2334     if(error)
2335     {
2336       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2337       free(edf_hdr);
2338       free(edfhdr->edfparam);
2339       free(edfhdr);
2340       return NULL;
2341     }
2342 
2343     p = 0;
2344     if(edfhdr->patient[p]=='X')
2345     {
2346       edfhdr->plus_patientcode[0] = 0;
2347       p += 2;
2348     }
2349     else
2350     {
2351       for(i=0; i<(80-p); i++)
2352       {
2353         if(edfhdr->patient[i+p]==' ')
2354         {
2355           break;
2356         }
2357         edfhdr->plus_patientcode[i] = edfhdr->patient[i+p];
2358         if(edfhdr->plus_patientcode[i]=='_')  edfhdr->plus_patientcode[i] = ' ';
2359       }
2360       edfhdr->plus_patientcode[i] = 0;
2361       p += i + 1;
2362     }
2363 
2364     if(edfhdr->patient[p]=='M')
2365     {
2366       edflib_strlcpy(edfhdr->plus_gender, "Male", 16);
2367     }
2368     if(edfhdr->patient[p]=='F')
2369     {
2370       edflib_strlcpy(edfhdr->plus_gender, "Female", 16);
2371     }
2372     if(edfhdr->patient[p]=='X')
2373     {
2374       edfhdr->plus_gender[0] = 0;
2375     }
2376     for(i=0; i<(80-p);i++)
2377     {
2378       if(edfhdr->patient[i+p]==' ')
2379       {
2380         break;
2381       }
2382     }
2383     p += i + 1;
2384 
2385     if(edfhdr->patient[p]=='X')
2386     {
2387       edfhdr->plus_birthdate[0] = 0;
2388       p += 2;
2389     }
2390     else
2391     {
2392       for(i=0; i<(80-p); i++)
2393       {
2394         if(edfhdr->patient[i+p]==' ')
2395         {
2396           break;
2397         }
2398         edfhdr->plus_birthdate[i] = edfhdr->patient[i+p];
2399       }
2400       edfhdr->plus_birthdate[2] = ' ';
2401       edfhdr->plus_birthdate[3] += 32;
2402       edfhdr->plus_birthdate[4] += 32;
2403       edfhdr->plus_birthdate[5] += 32;
2404       edfhdr->plus_birthdate[6] = ' ';
2405       edfhdr->plus_birthdate[11] = 0;
2406       p += i + 1;
2407     }
2408 
2409     for(i=0; i<(80-p);i++)
2410     {
2411       if(edfhdr->patient[i+p]==' ')
2412       {
2413         break;
2414       }
2415       edfhdr->plus_patient_name[i] = edfhdr->patient[i+p];
2416       if(edfhdr->plus_patient_name[i]=='_')  edfhdr->plus_patient_name[i] = ' ';
2417     }
2418     edfhdr->plus_patient_name[i] = 0;
2419     p += i + 1;
2420 
2421     for(i=0; i<(80-p);i++)
2422     {
2423       edfhdr->plus_patient_additional[i] = edfhdr->patient[i+p];
2424     }
2425     edfhdr->plus_patient_additional[i] = 0;
2426     p += i + 1;
2427   }
2428 
2429 /********************* EDF+ RECORDINGFIELD *********************************************/
2430 
2431   if(edfhdr->edfplus || edfhdr->bdfplus)
2432   {
2433     error = 0;
2434     strncpy(scratchpad, edf_hdr + 88, 80);
2435     scratchpad[80] = 0;
2436     if(strncmp(scratchpad, "Startdate ", 10))  error = 1;
2437     if(scratchpad[10]=='X')
2438     {
2439       if(scratchpad[11]!=' ')  error = 1;
2440       if(scratchpad[12]==' ')  error = 1;
2441       p = 12;
2442     }
2443     else
2444     {
2445       if(scratchpad[21]!=' ')  error = 1;
2446       if(scratchpad[22]==' ')  error = 1;
2447       p = 22;
2448       strncpy(scratchpad2, scratchpad + 10, 11);
2449       scratchpad2[11] = 0;
2450       if((scratchpad2[2]!='-')||(scratchpad2[6]!='-'))  error = 1;
2451       scratchpad2[2] = 0;
2452       scratchpad2[6] = 0;
2453       if((scratchpad2[0]<48)||(scratchpad2[0]>57))  error = 1;
2454       if((scratchpad2[1]<48)||(scratchpad2[1]>57))  error = 1;
2455       if((scratchpad2[7]<48)||(scratchpad2[7]>57))  error = 1;
2456       if((scratchpad2[8]<48)||(scratchpad2[8]>57))  error = 1;
2457       if((scratchpad2[9]<48)||(scratchpad2[9]>57))  error = 1;
2458       if((scratchpad2[10]<48)||(scratchpad2[10]>57))  error = 1;
2459       if((edflib_atof_nonlocalized(scratchpad2)<1)||(edflib_atof_nonlocalized(scratchpad2)>31))  error = 1;
2460       r = 0;
2461       if(!strcmp(scratchpad2 + 3, "JAN"))  r = 1;
2462         else if(!strcmp(scratchpad2 + 3, "FEB"))  r = 2;
2463           else if(!strcmp(scratchpad2 + 3, "MAR"))  r = 3;
2464             else if(!strcmp(scratchpad2 + 3, "APR"))  r = 4;
2465               else if(!strcmp(scratchpad2 + 3, "MAY"))  r = 5;
2466                 else if(!strcmp(scratchpad2 + 3, "JUN"))  r = 6;
2467                   else if(!strcmp(scratchpad2 + 3, "JUL"))  r = 7;
2468                     else if(!strcmp(scratchpad2 + 3, "AUG"))  r = 8;
2469                       else if(!strcmp(scratchpad2 + 3, "SEP"))  r = 9;
2470                         else if(!strcmp(scratchpad2 + 3, "OCT"))  r = 10;
2471                           else if(!strcmp(scratchpad2 + 3, "NOV"))  r = 11;
2472                             else if(!strcmp(scratchpad2 + 3, "DEC"))  r = 12;
2473                               else error = 1;
2474     }
2475 
2476     n = 0;
2477     for(i=p; i<80; i++)
2478     {
2479       if(i>78)
2480       {
2481         error = 1;
2482         break;
2483       }
2484       if(scratchpad[i]==' ')
2485       {
2486         n++;
2487         if(scratchpad[i + 1]==' ')
2488         {
2489           error = 1;
2490           break;
2491         }
2492       }
2493       if(n>1)  break;
2494     }
2495 
2496     if(error)
2497     {
2498       *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2499       free(edf_hdr);
2500       free(edfhdr->edfparam);
2501       free(edfhdr);
2502       return NULL;
2503     }
2504 
2505     if(edf_hdr[98]!='X')
2506     {
2507       error = 0;
2508 
2509       strncpy(scratchpad, edf_hdr + 168, 8);
2510       scratchpad[2] = 0;
2511       scratchpad[5] = 0;
2512       scratchpad[8] = 0;
2513 
2514       if(edflib_atof_nonlocalized(scratchpad)!=edflib_atof_nonlocalized(scratchpad2))  error = 1;
2515       if(edflib_atof_nonlocalized(scratchpad+3)!=r)  error = 1;
2516       if(edflib_atof_nonlocalized(scratchpad+6)!=edflib_atof_nonlocalized(scratchpad2+9))  error = 1;
2517       if(error)
2518       {
2519         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2520         free(edf_hdr);
2521         free(edfhdr->edfparam);
2522         free(edfhdr);
2523         return NULL;
2524       }
2525 
2526       if(edfhdr->startdate_year != edflib_atof_nonlocalized(scratchpad2 + 7))
2527       {
2528         *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2529         free(edf_hdr);
2530         free(edfhdr->edfparam);
2531         free(edfhdr);
2532         return NULL;
2533       }
2534     }
2535 
2536     p = 10;
2537     for(i=0; i<(80-p); i++)
2538     {
2539       if(edfhdr->recording[i+p]==' ')
2540       {
2541         break;
2542       }
2543       edfhdr->plus_startdate[i] = edfhdr->recording[i+p];
2544     }
2545     edfhdr->plus_startdate[2] = ' ';
2546     edfhdr->plus_startdate[3] += 32;
2547     edfhdr->plus_startdate[4] += 32;
2548     edfhdr->plus_startdate[5] += 32;
2549     edfhdr->plus_startdate[6] = ' ';
2550     edfhdr->plus_startdate[11] = 0;
2551     p += i + 1;
2552 
2553     if(edfhdr->recording[p]=='X')
2554     {
2555       edfhdr->plus_admincode[0] = 0;
2556       p += 2;
2557     }
2558     else
2559     {
2560       for(i=0; i<(80-p); i++)
2561       {
2562         if(edfhdr->recording[i+p]==' ')
2563         {
2564           break;
2565         }
2566         edfhdr->plus_admincode[i] = edfhdr->recording[i+p];
2567         if(edfhdr->plus_admincode[i]=='_')  edfhdr->plus_admincode[i] = ' ';
2568       }
2569       edfhdr->plus_admincode[i] = 0;
2570       p += i + 1;
2571     }
2572 
2573     if(edfhdr->recording[p]=='X')
2574     {
2575       edfhdr->plus_technician[0] = 0;
2576       p += 2;
2577     }
2578     else
2579     {
2580       for(i=0; i<(80-p); i++)
2581       {
2582         if(edfhdr->recording[i+p]==' ')
2583         {
2584           break;
2585         }
2586         edfhdr->plus_technician[i] = edfhdr->recording[i+p];
2587         if(edfhdr->plus_technician[i]=='_')  edfhdr->plus_technician[i] = ' ';
2588       }
2589       edfhdr->plus_technician[i] = 0;
2590       p += i + 1;
2591     }
2592 
2593     if(edfhdr->recording[p]=='X')
2594     {
2595       edfhdr->plus_equipment[0] = 0;
2596       p += 2;
2597     }
2598     else
2599     {
2600       for(i=0; i<(80-p); i++)
2601       {
2602         if(edfhdr->recording[i+p]==' ')
2603         {
2604           break;
2605         }
2606         edfhdr->plus_equipment[i] = edfhdr->recording[i+p];
2607         if(edfhdr->plus_equipment[i]=='_')  edfhdr->plus_equipment[i] = ' ';
2608       }
2609       edfhdr->plus_equipment[i] = 0;
2610       p += i + 1;
2611     }
2612 
2613     for(i=0; i<(80-p);i++)
2614     {
2615       edfhdr->plus_recording_additional[i] = edfhdr->recording[i+p];
2616     }
2617     edfhdr->plus_recording_additional[i] = 0;
2618     p += i + 1;
2619   }
2620 
2621 /********************* FILESIZE *********************************************/
2622 
2623   edfhdr->hdrsize = edfhdr->edfsignals * 256 + 256;
2624 
2625   fseeko(inputfile, 0LL, SEEK_END);
2626   if(ftello(inputfile)!=(edfhdr->recordsize * edfhdr->datarecords + edfhdr->hdrsize))
2627   {
2628     *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
2629     free(edf_hdr);
2630     free(edfhdr->edfparam);
2631     free(edfhdr);
2632     return NULL;
2633   }
2634 
2635   n = 0;
2636 
2637   for(i=0; i<edfhdr->edfsignals; i++)
2638   {
2639     edfhdr->edfparam[i].buf_offset = n;
2640     if(edfhdr->bdf)  n += edfhdr->edfparam[i].smp_per_record * 3;
2641     else  n += edfhdr->edfparam[i].smp_per_record * 2;
2642 
2643     edfhdr->edfparam[i].bitvalue = (edfhdr->edfparam[i].phys_max - edfhdr->edfparam[i].phys_min) / (edfhdr->edfparam[i].dig_max - edfhdr->edfparam[i].dig_min);
2644     edfhdr->edfparam[i].offset = edfhdr->edfparam[i].phys_max / edfhdr->edfparam[i].bitvalue - edfhdr->edfparam[i].dig_max;
2645   }
2646 
2647   edfhdr->file_hdl = inputfile;
2648 
2649   free(edf_hdr);
2650 
2651   return edfhdr;
2652 }
2653 
2654 
2655 
2656 
edflib_is_integer_number(char * str)2657 static int edflib_is_integer_number(char *str)
2658 {
2659   int i=0, l, hasspace = 0, hassign=0, digit=0;
2660 
2661   l = strlen(str);
2662 
2663   if(!l)  return 1;
2664 
2665   if((str[0]=='+')||(str[0]=='-'))
2666   {
2667     hassign++;
2668     i++;
2669   }
2670 
2671   for(; i<l; i++)
2672   {
2673     if(str[i]==' ')
2674     {
2675       if(!digit)
2676       {
2677         return 1;
2678       }
2679       hasspace++;
2680     }
2681     else
2682     {
2683       if((str[i]<48)||(str[i]>57))
2684       {
2685         return 1;
2686       }
2687       else
2688       {
2689         if(hasspace)
2690         {
2691           return 1;
2692         }
2693         digit++;
2694       }
2695     }
2696   }
2697 
2698   if(digit)  return 0;
2699   else  return 1;
2700 }
2701 
2702 
2703 
edflib_is_number(char * str)2704 static int edflib_is_number(char *str)
2705 {
2706   int i=0, l, hasspace = 0, hassign=0, digit=0, hasdot=0, hasexp=0;
2707 
2708   l = strlen(str);
2709 
2710   if(!l)  return 1;
2711 
2712   if((str[0]=='+')||(str[0]=='-'))
2713   {
2714     hassign++;
2715     i++;
2716   }
2717 
2718   for(; i<l; i++)
2719   {
2720     if((str[i]=='e')||(str[i]=='E'))
2721     {
2722       if((!digit)||hasexp)
2723       {
2724         return 1;
2725       }
2726       hasexp++;
2727       hassign = 0;
2728       digit = 0;
2729 
2730       break;
2731     }
2732 
2733     if(str[i]==' ')
2734     {
2735       if(!digit)
2736       {
2737         return 1;
2738       }
2739       hasspace++;
2740     }
2741     else
2742     {
2743       if(((str[i]<48)||(str[i]>57))&&str[i]!='.')
2744       {
2745         return 1;
2746       }
2747       else
2748       {
2749         if(hasspace)
2750         {
2751           return 1;
2752         }
2753         if(str[i]=='.')
2754         {
2755           if(hasdot)  return 1;
2756           hasdot++;
2757         }
2758         else
2759         {
2760           digit++;
2761         }
2762       }
2763     }
2764   }
2765 
2766   if(hasexp)
2767   {
2768     if(++i==l)
2769     {
2770       return 1;
2771     }
2772 
2773     if((str[i]=='+')||(str[i]=='-'))
2774     {
2775       hassign++;
2776       i++;
2777     }
2778 
2779     for(; i<l; i++)
2780     {
2781       if(str[i]==' ')
2782       {
2783         if(!digit)
2784         {
2785           return 1;
2786         }
2787         hasspace++;
2788       }
2789       else
2790       {
2791         if((str[i]<48)||(str[i]>57))
2792         {
2793           return 1;
2794         }
2795         else
2796         {
2797           if(hasspace)
2798           {
2799             return 1;
2800           }
2801 
2802           digit++;
2803         }
2804       }
2805     }
2806   }
2807 
2808   if(digit)  return 0;
2809   else  return 1;
2810 }
2811 
2812 
edflib_get_long_duration(char * str)2813 static long long edflib_get_long_duration(char *str)
2814 {
2815   int i, len=8, hasdot=0, dotposition=0;
2816 
2817   long long value=0, radix;
2818 
2819   if((str[0] == '+') || (str[0] == '-'))
2820   {
2821     for(i=0; i<7; i++)
2822     {
2823       str[i] = str[i+1];
2824     }
2825 
2826     str[7] = ' ';
2827   }
2828 
2829   for(i=0; i<8; i++)
2830   {
2831     if(str[i]==' ')
2832     {
2833       len = i;
2834       break;
2835     }
2836   }
2837 
2838   for(i=0; i<len; i++)
2839   {
2840     if(str[i]=='.')
2841     {
2842       hasdot = 1;
2843       dotposition = i;
2844       break;
2845     }
2846   }
2847 
2848   if(hasdot)
2849   {
2850     radix = EDFLIB_TIME_DIMENSION;
2851 
2852     for(i=dotposition-1; i>=0; i--)
2853     {
2854         value += ((long long)(str[i] - 48)) * radix;
2855         radix *= 10;
2856     }
2857 
2858     radix = EDFLIB_TIME_DIMENSION / 10;
2859 
2860     for(i=dotposition+1; i<len; i++)
2861     {
2862         value += ((long long)(str[i] - 48)) * radix;
2863         radix /= 10;
2864     }
2865   }
2866   else
2867   {
2868     radix = EDFLIB_TIME_DIMENSION;
2869 
2870     for(i=len-1; i>=0; i--)
2871     {
2872         value += ((long long)(str[i] - 48)) * radix;
2873         radix *= 10;
2874     }
2875   }
2876 
2877   return value;
2878 }
2879 
2880 
edflib_version(void)2881 int edflib_version(void)
2882 {
2883   return EDFLIB_VERSION;
2884 }
2885 
2886 
edflib_get_annotations(struct edfhdrblock * edfhdr,int hdl,int read_annotations_mode)2887 static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_annotations_mode)
2888 {
2889   int i, j, k, p, r=0, n,
2890       edfsignals,
2891       datarecords,
2892       recordsize,
2893       discontinuous,
2894       *annot_ch,
2895       nr_annot_chns,
2896       max,
2897       onset,
2898       duration,
2899       duration_start,
2900       zero,
2901       max_tal_ln,
2902       error,
2903       annots_in_record,
2904       annots_in_tal,
2905       samplesize=2;
2906 
2907   char *scratchpad,
2908        *cnv_buf,
2909        *time_in_txt,
2910        *duration_in_txt;
2911 
2912 
2913   long long data_record_duration,
2914             elapsedtime,
2915             time_tmp=0;
2916 
2917   FILE *inputfile;
2918 
2919   struct edfparamblock *edfparam;
2920 
2921   struct edf_annotationblock *new_annotation=NULL,
2922                              *malloc_list;
2923 
2924   inputfile = edfhdr->file_hdl;
2925   edfsignals = edfhdr->edfsignals;
2926   recordsize = edfhdr->recordsize;
2927   edfparam = edfhdr->edfparam;
2928   nr_annot_chns = edfhdr->nr_annot_chns;
2929   datarecords = edfhdr->datarecords;
2930   data_record_duration = edfhdr->long_data_record_duration;
2931   discontinuous = edfhdr->discontinuous;
2932   annot_ch = edfhdr->annot_ch;
2933 
2934   if(edfhdr->edfplus)
2935   {
2936     samplesize = 2;
2937   }
2938   if(edfhdr->bdfplus)
2939   {
2940     samplesize = 3;
2941   }
2942 
2943   cnv_buf = (char *)calloc(1, recordsize);
2944   if(cnv_buf==NULL)
2945   {
2946     return 1;
2947   }
2948 
2949   max_tal_ln = 0;
2950 
2951   for(i=0; i<nr_annot_chns; i++)
2952   {
2953     if(max_tal_ln<edfparam[annot_ch[i]].smp_per_record * samplesize)  max_tal_ln = edfparam[annot_ch[i]].smp_per_record * samplesize;
2954   }
2955 
2956   if(max_tal_ln<128)  max_tal_ln = 128;
2957 
2958   scratchpad = (char *)calloc(1, max_tal_ln + 3);
2959   if(scratchpad==NULL)
2960   {
2961     free(cnv_buf);
2962     return 1;
2963   }
2964 
2965   time_in_txt = (char *)calloc(1, max_tal_ln + 3);
2966   if(time_in_txt==NULL)
2967   {
2968     free(cnv_buf);
2969     free(scratchpad);
2970     return 1;
2971   }
2972 
2973   duration_in_txt = (char *)calloc(1, max_tal_ln + 3);
2974   if(duration_in_txt==NULL)
2975   {
2976     free(cnv_buf);
2977     free(scratchpad);
2978     free(time_in_txt);
2979     return 1;
2980   }
2981 
2982   if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET))
2983   {
2984     free(cnv_buf);
2985     free(scratchpad);
2986     free(time_in_txt);
2987     free(duration_in_txt);
2988     return 2;
2989   }
2990 
2991   elapsedtime = 0;
2992 
2993   for(i=0; i<datarecords; i++)
2994   {
2995     if(fread(cnv_buf, recordsize, 1, inputfile)!=1)
2996     {
2997       free(cnv_buf);
2998       free(scratchpad);
2999       free(time_in_txt);
3000       free(duration_in_txt);
3001       return 2;
3002     }
3003 
3004 
3005 /************** process annotationsignals (if any) **************/
3006 
3007     error = 0;
3008 
3009     for(r=0; r<nr_annot_chns; r++)
3010     {
3011       n = 0;
3012       zero = 0;
3013       onset = 0;
3014       duration = 0;
3015       duration_start = 0;
3016       scratchpad[0] = 0;
3017       annots_in_tal = 0;
3018       annots_in_record = 0;
3019 
3020       p = edfparam[annot_ch[r]].buf_offset;
3021       max = edfparam[annot_ch[r]].smp_per_record * samplesize;
3022 
3023 /************** process one annotation signal ****************/
3024 
3025       if(cnv_buf[p + max - 1]!=0)
3026       {
3027         error = 5;
3028         goto END;
3029       }
3030 
3031       if(!r)  /* if it's the first annotation signal, then check */
3032       {       /* the timekeeping annotation */
3033         error = 1;
3034 
3035         for(k=0; k<(max-2); k++)
3036         {
3037           scratchpad[k] = cnv_buf[p + k];
3038 
3039           if(scratchpad[k]==20)
3040           {
3041             if(cnv_buf[p + k + 1]!=20)
3042             {
3043               error = 6;
3044               goto END;
3045             }
3046             scratchpad[k] = 0;
3047             if(edflib_is_onset_number(scratchpad))
3048             {
3049               error = 36;
3050               goto END;
3051             }
3052             else
3053             {
3054               time_tmp = edflib_get_long_time(scratchpad);
3055               if(i)
3056               {
3057                 if(discontinuous)
3058                 {
3059                   if((time_tmp-elapsedtime)<data_record_duration)
3060                   {
3061                     error = 4;
3062                     goto END;
3063                   }
3064                 }
3065                 else
3066                 {
3067                   if((time_tmp-elapsedtime)!=data_record_duration)
3068                   {
3069                     error = 3;
3070                     goto END;
3071                   }
3072                 }
3073               }
3074               else
3075               {
3076                 if((time_tmp>=EDFLIB_TIME_DIMENSION) || (time_tmp<0LL))
3077                 {
3078                   error = 2;
3079                   goto END;
3080                 }
3081                 else
3082                 {
3083                   edfhdr->starttime_offset = time_tmp;
3084                   if(read_annotations_mode==EDFLIB_DO_NOT_READ_ANNOTATIONS)
3085                   {
3086                     error = 0;
3087                     goto END_OUT;
3088                   }
3089                 }
3090               }
3091               elapsedtime = time_tmp;
3092               error = 0;
3093               break;
3094             }
3095           }
3096         }
3097       }
3098 
3099       for(k=0; k<max; k++)
3100       {
3101         scratchpad[n] = cnv_buf[p + k];
3102 
3103         if(!scratchpad[n])
3104         {
3105           if(!zero)
3106           {
3107             if(k)
3108             {
3109               if(cnv_buf[p + k - 1]!=20)
3110               {
3111                 error = 33;
3112                 goto END;
3113               }
3114             }
3115             n = 0;
3116             onset = 0;
3117             duration = 0;
3118             duration_start = 0;
3119             scratchpad[0] = 0;
3120             annots_in_tal = 0;
3121           }
3122           zero++;
3123           continue;
3124         }
3125         if(zero>1)
3126         {
3127           error = 34;
3128           goto END;
3129         }
3130         zero = 0;
3131 
3132         if((scratchpad[n]==20)||(scratchpad[n]==21))
3133         {
3134           if(scratchpad[n]==21)
3135           {
3136             if(duration||duration_start||onset||annots_in_tal)
3137             {               /* it's not allowed to have multiple duration fields */
3138               error = 35;   /* in one TAL or to have a duration field which is   */
3139               goto END;     /* not immediately behind the onsetfield             */
3140             }
3141             duration_start = 1;
3142           }
3143 
3144           if((scratchpad[n]==20)&&onset&&(!duration_start))
3145           {
3146             if(r||annots_in_record)
3147             {
3148               if(n >= 0)
3149               {
3150                 if(edfhdr->annots_in_file >= edfhdr->annotlist_sz)
3151                 {
3152                   malloc_list = (struct edf_annotationblock *)realloc(annotationslist[hdl],
3153                                                                       sizeof(struct edf_annotationblock) * (edfhdr->annotlist_sz + EDFLIB_ANNOT_MEMBLOCKSZ));
3154                   if(malloc_list==NULL)
3155                   {
3156                     free(cnv_buf);
3157                     free(scratchpad);
3158                     free(time_in_txt);
3159                     free(duration_in_txt);
3160                     return -1;
3161                   }
3162 
3163                   annotationslist[hdl] = malloc_list;
3164 
3165                   edfhdr->annotlist_sz += EDFLIB_ANNOT_MEMBLOCKSZ;
3166                 }
3167 
3168                 new_annotation = annotationslist[hdl] + edfhdr->annots_in_file;
3169 
3170                 new_annotation->annotation[0] = 0;
3171 
3172                 if(duration)  edflib_strlcpy(new_annotation->duration, duration_in_txt, 16);
3173                 else  new_annotation->duration[0] = 0;
3174 
3175                 for(j=0; j<n; j++)
3176                 {
3177                   if(j==EDFLIB_MAX_ANNOTATION_LEN)  break;
3178                   new_annotation->annotation[j] = scratchpad[j];
3179                 }
3180                 new_annotation->annotation[j] = 0;
3181 
3182                 new_annotation->onset = edflib_get_long_time(time_in_txt);
3183 
3184                 new_annotation->onset -= edfhdr->starttime_offset;
3185 
3186                 edfhdr->annots_in_file++;
3187 
3188                 if(read_annotations_mode==EDFLIB_READ_ANNOTATIONS)
3189                 {
3190                   if(!(strncmp(new_annotation->annotation, "Recording ends", 14)))
3191                   {
3192                     if(nr_annot_chns==1)
3193                     {
3194                       goto END;
3195                     }
3196                   }
3197                 }
3198               }
3199             }
3200 
3201             annots_in_tal++;
3202             annots_in_record++;
3203             n = 0;
3204             continue;
3205           }
3206 
3207           if(!onset)
3208           {
3209             scratchpad[n] = 0;
3210             if(edflib_is_onset_number(scratchpad))
3211             {
3212               error = 36;
3213               goto END;
3214             }
3215             onset = 1;
3216             n = 0;
3217             edflib_strlcpy(time_in_txt, scratchpad, max_tal_ln + 3);
3218             continue;
3219           }
3220 
3221           if(duration_start)
3222           {
3223             scratchpad[n] = 0;
3224             if(edflib_is_duration_number(scratchpad))
3225             {
3226               error = 37;
3227               goto END;
3228             }
3229 
3230             for(j=0; j<n; j++)
3231             {
3232               if(j==15)  break;
3233               duration_in_txt[j] = scratchpad[j];
3234               if((duration_in_txt[j]<32)||(duration_in_txt[j]>126))
3235               {
3236                 duration_in_txt[j] = '.';
3237               }
3238             }
3239             duration_in_txt[j] = 0;
3240 
3241             duration = 1;
3242             duration_start = 0;
3243             n = 0;
3244             continue;
3245           }
3246         }
3247 
3248         n++;
3249       }
3250 
3251  END:
3252 
3253 /****************** end ************************/
3254 
3255       if(error)
3256       {
3257         free(cnv_buf);
3258         free(scratchpad);
3259         free(time_in_txt);
3260         free(duration_in_txt);
3261         return 9;
3262       }
3263     }
3264   }
3265 
3266  END_OUT:
3267 
3268   free(cnv_buf);
3269   free(scratchpad);
3270   free(time_in_txt);
3271   free(duration_in_txt);
3272 
3273   return 0;
3274 }
3275 
3276 
edflib_is_duration_number(char * str)3277 static int edflib_is_duration_number(char *str)
3278 {
3279   int i, l, hasdot = 0;
3280 
3281   l = strlen(str);
3282 
3283   if(!l)  return 1;
3284 
3285   if((str[0] == '.')||(str[l-1] == '.'))  return 1;
3286 
3287   for(i=0; i<l; i++)
3288   {
3289     if(str[i]=='.')
3290     {
3291       if(hasdot)  return 1;
3292       hasdot++;
3293     }
3294     else
3295     {
3296       if((str[i]<48)||(str[i]>57))  return 1;
3297     }
3298   }
3299 
3300   return 0;
3301 }
3302 
3303 
3304 
edflib_is_onset_number(char * str)3305 static int edflib_is_onset_number(char *str)
3306 {
3307   int i, l, hasdot = 0;
3308 
3309   l = strlen(str);
3310 
3311   if(l<2)  return 1;
3312 
3313   if((str[0]!='+')&&(str[0]!='-'))  return 1;
3314 
3315   if((str[1] == '.')||(str[l-1] == '.'))  return 1;
3316 
3317   for(i=1; i<l; i++)
3318   {
3319     if(str[i]=='.')
3320     {
3321       if(hasdot)  return 1;
3322       hasdot++;
3323     }
3324     else
3325     {
3326       if((str[i]<48)||(str[i]>57))  return 1;
3327     }
3328   }
3329 
3330   return 0;
3331 }
3332 
3333 
3334 
edflib_get_long_time(char * str)3335 static long long edflib_get_long_time(char *str)
3336 {
3337   int i, len, hasdot=0, dotposition=0, neg=0;
3338 
3339   long long value=0, radix;
3340 
3341   if(str[0] == '+')
3342   {
3343     str++;
3344   }
3345   else if(str[0] == '-')
3346     {
3347       neg = 1;
3348       str++;
3349     }
3350 
3351   len = strlen(str);
3352 
3353   for(i=0; i<len; i++)
3354   {
3355     if(str[i]=='.')
3356     {
3357       hasdot = 1;
3358       dotposition = i;
3359       break;
3360     }
3361   }
3362 
3363   if(hasdot)
3364   {
3365     radix = EDFLIB_TIME_DIMENSION;
3366 
3367     for(i=dotposition-1; i>=0; i--)
3368     {
3369         value += ((long long)(str[i] - 48)) * radix;
3370         radix *= 10;
3371     }
3372 
3373     radix = EDFLIB_TIME_DIMENSION / 10;
3374 
3375     for(i=dotposition+1; i<len; i++)
3376     {
3377         value += ((long long)(str[i] - 48)) * radix;
3378         radix /= 10;
3379     }
3380   }
3381   else
3382   {
3383     radix = EDFLIB_TIME_DIMENSION;
3384 
3385     for(i=len-1; i>=0; i--)
3386     {
3387         value += ((long long)(str[i] - 48)) * radix;
3388         radix *= 10;
3389     }
3390   }
3391 
3392   if(neg)  value = -value;
3393 
3394   return value;
3395 }
3396 
3397 
edflib_latin1_to_ascii(char * str,int len)3398 static void edflib_latin1_to_ascii(char *str, int len)
3399 {
3400   /* ISO 8859-1 except for characters 0x80 to 0x9f which are taken from the extension CP-1252 */
3401 
3402   int i, value;
3403 
3404   const char conv_table[]=".E.,F\".++^.S<E.Z..`\'\"\".--~.s>e.zY.i....|....<...-....\'u.....>...?AAAAAAECEEEEIIIIDNOOOOOxOUUUUYtsaaaaaaeceeeeiiiidnooooo:0uuuuyty";
3405 
3406   for(i=0; i<len; i++)
3407   {
3408     value = *((unsigned char *)(str + i));
3409 
3410     if((value>31)&&(value<127))
3411     {
3412       continue;
3413     }
3414 
3415     if(value < 32)
3416     {
3417       str[i] = '.';
3418 
3419       continue;
3420     }
3421 
3422     str[i] = conv_table[value - 127];
3423   }
3424 }
3425 
3426 
edflib_latin12utf8(char * latin1_str,int len)3427 static void edflib_latin12utf8(char *latin1_str, int len)
3428 {
3429   int i, j;
3430 
3431   unsigned char *str, tmp_str[512];
3432 
3433 
3434   str = (unsigned char *)latin1_str;
3435 
3436   j = 0;
3437 
3438   for(i=0; i<len; i++)
3439   {
3440     if(str[i]==0)
3441     {
3442       tmp_str[j] = 0;
3443 
3444       break;
3445     }
3446 
3447     tmp_str[j] = str[i];
3448 
3449     if(str[i]<32) tmp_str[j] = '.';
3450 
3451     if((str[i]>126)&&(str[i]<160))  tmp_str[j] = '.';
3452 
3453     if(str[i]>159)
3454     {
3455       if((len-j)<2)
3456       {
3457         tmp_str[j] = ' ';
3458       }
3459       else
3460       {
3461         tmp_str[j] = 192 + (str[i]>>6);
3462         j++;
3463         tmp_str[j] = 128 + (str[i]&63);
3464       }
3465     }
3466 
3467     j++;
3468 
3469     if(j>=len)  break;
3470   }
3471 
3472   for(i=0; i<len; i++)
3473   {
3474     str[i] = tmp_str[i];
3475   }
3476 }
3477 
3478 
edfopen_file_writeonly_with_params(const char * path,int filetype,int number_of_signals,int samplefrequency,double phys_max_min,const char * phys_dim)3479 int edfopen_file_writeonly_with_params(const char *path, int filetype, int number_of_signals, int samplefrequency, double phys_max_min, const char *phys_dim)
3480 {
3481   int i, handle;
3482 
3483   char str[32]="";
3484 
3485   handle = edfopen_file_writeonly(path, filetype, number_of_signals);
3486   if(handle < 0)
3487   {
3488     return handle;
3489   }
3490 
3491   for(i=0; i<number_of_signals; i++)
3492   {
3493     if(edf_set_samplefrequency(handle, i, samplefrequency))
3494     {
3495       edfclose_file(handle);
3496       return -1;
3497     }
3498 
3499     if(edf_set_physical_maximum(handle, i, phys_max_min))
3500     {
3501       edfclose_file(handle);
3502       return -1;
3503     }
3504 
3505     if(edf_set_physical_minimum(handle, i, -phys_max_min))
3506     {
3507       edfclose_file(handle);
3508       return -1;
3509     }
3510 
3511     if(edf_set_physical_dimension(handle, i, phys_dim))
3512     {
3513       edfclose_file(handle);
3514       return -1;
3515     }
3516 
3517     snprintf(str, 32, "chan. %i", i + 1);
3518 
3519     if(edf_set_label(handle, i, str))
3520     {
3521       edfclose_file(handle);
3522       return -1;
3523     }
3524 
3525     if(filetype == EDFLIB_FILETYPE_BDFPLUS)
3526     {
3527       if(edf_set_digital_maximum(handle, i, 8388607))
3528       {
3529         edfclose_file(handle);
3530         return -1;
3531       }
3532 
3533       if(edf_set_digital_minimum(handle, i, -8388608))
3534       {
3535         edfclose_file(handle);
3536         return -1;
3537       }
3538     }
3539     else
3540     {
3541       if(edf_set_digital_maximum(handle, i, 32767))
3542       {
3543         edfclose_file(handle);
3544         return -1;
3545       }
3546 
3547       if(edf_set_digital_minimum(handle, i, -32768))
3548       {
3549         edfclose_file(handle);
3550         return -1;
3551       }
3552     }
3553   }
3554 
3555   return handle;
3556 }
3557 
3558 
edfopen_file_writeonly(const char * path,int filetype,int number_of_signals)3559 int edfopen_file_writeonly(const char *path, int filetype, int number_of_signals)
3560 {
3561   int i, handle;
3562 
3563   FILE *file;
3564 
3565   struct edfhdrblock *hdr;
3566 
3567 
3568   if((filetype!=EDFLIB_FILETYPE_EDFPLUS)&&(filetype!=EDFLIB_FILETYPE_BDFPLUS))
3569   {
3570     return EDFLIB_FILETYPE_ERROR;
3571   }
3572 
3573   if(edf_files_open>=EDFLIB_MAXFILES)
3574   {
3575     return EDFLIB_MAXFILES_REACHED;
3576   }
3577 
3578   for(i=0; i<EDFLIB_MAXFILES; i++)
3579   {
3580     if(hdrlist[i]!=NULL)
3581     {
3582       if(!(strcmp(path, hdrlist[i]->path)))
3583       {
3584         return EDFLIB_FILE_ALREADY_OPENED;
3585       }
3586     }
3587   }
3588 
3589   if(number_of_signals<0)
3590   {
3591     return EDFLIB_NUMBER_OF_SIGNALS_INVALID;
3592   }
3593 
3594   if(number_of_signals>EDFLIB_MAXSIGNALS)
3595   {
3596     return EDFLIB_NUMBER_OF_SIGNALS_INVALID;
3597   }
3598 
3599   hdr = (struct edfhdrblock *)calloc(1, sizeof(struct edfhdrblock));
3600   if(hdr==NULL)
3601   {
3602     return EDFLIB_MALLOC_ERROR;
3603   }
3604 
3605   hdr->edfparam = (struct edfparamblock *)calloc(1, sizeof(struct edfparamblock) * number_of_signals);
3606   if(hdr->edfparam==NULL)
3607   {
3608     free(hdr);
3609 
3610     return EDFLIB_MALLOC_ERROR;
3611   }
3612 
3613   hdr->writemode = 1;
3614 
3615   hdr->edfsignals = number_of_signals;
3616 
3617   handle = -1;
3618 
3619   for(i=0; i<EDFLIB_MAXFILES; i++)
3620   {
3621     if(hdrlist[i]==NULL)
3622     {
3623       hdrlist[i] = hdr;
3624 
3625       handle = i;
3626 
3627       break;
3628     }
3629   }
3630 
3631   if(handle<0)
3632   {
3633     free(hdr->edfparam);
3634 
3635     free(hdr);
3636 
3637     return EDFLIB_MAXFILES_REACHED;
3638   }
3639 
3640   write_annotationslist[handle] = NULL;
3641 
3642   hdr->annotlist_sz = 0;
3643 
3644   hdr->annots_in_file = 0;
3645 
3646   file = fopeno(path, "wb");
3647   if(file==NULL)
3648   {
3649     free(hdr->edfparam);
3650     hdr->edfparam = NULL;
3651     free(hdr);
3652     hdr = NULL;
3653     hdrlist[handle] = NULL;
3654 
3655     return EDFLIB_NO_SUCH_FILE_OR_DIRECTORY;
3656   }
3657 
3658   hdr->file_hdl = file;
3659 
3660   edflib_strlcpy(hdr->path, path, 1024);
3661 
3662   edf_files_open++;
3663 
3664   if(filetype==EDFLIB_FILETYPE_EDFPLUS)
3665   {
3666     hdr->edf = 1;
3667     hdr->edfplus = 1;
3668   }
3669 
3670   if(filetype==EDFLIB_FILETYPE_BDFPLUS)
3671   {
3672     hdr->bdf = 1;
3673     hdr->bdfplus = 1;
3674   }
3675 
3676   hdr->long_data_record_duration = EDFLIB_TIME_DIMENSION;
3677 
3678   hdr->data_record_duration = 1.0;
3679 
3680   hdr->nr_annot_chns = 1;
3681 
3682   return handle;
3683 }
3684 
3685 
edf_set_samplefrequency(int handle,int edfsignal,int samplefrequency)3686 int edf_set_samplefrequency(int handle, int edfsignal, int samplefrequency)
3687 {
3688   if(handle<0)
3689   {
3690     return -1;
3691   }
3692 
3693   if(handle>=EDFLIB_MAXFILES)
3694   {
3695     return -1;
3696   }
3697 
3698   if(hdrlist[handle]==NULL)
3699   {
3700     return -1;
3701   }
3702 
3703   if(!(hdrlist[handle]->writemode))
3704   {
3705     return -1;
3706   }
3707 
3708   if(edfsignal<0)
3709   {
3710     return -1;
3711   }
3712 
3713   if(edfsignal>=hdrlist[handle]->edfsignals)
3714   {
3715     return -1;
3716   }
3717 
3718   if(samplefrequency<1)
3719   {
3720     return -1;
3721   }
3722 
3723   if(hdrlist[handle]->datarecords)
3724   {
3725     return -1;
3726   }
3727 
3728   hdrlist[handle]->edfparam[edfsignal].smp_per_record = samplefrequency;
3729 
3730   return 0;
3731 }
3732 
3733 
edf_set_number_of_annotation_signals(int handle,int annot_signals)3734 int edf_set_number_of_annotation_signals(int handle, int annot_signals)
3735 {
3736   if(handle<0)
3737   {
3738     return -1;
3739   }
3740 
3741   if(handle>=EDFLIB_MAXFILES)
3742   {
3743     return -1;
3744   }
3745 
3746   if(hdrlist[handle]==NULL)
3747   {
3748     return -1;
3749   }
3750 
3751   if(!(hdrlist[handle]->writemode))
3752   {
3753     return -1;
3754   }
3755 
3756   if(hdrlist[handle]->datarecords)
3757   {
3758     return -1;
3759   }
3760 
3761   if((annot_signals < 1) || (annot_signals > EDFLIB_MAX_ANNOTATION_CHANNELS))
3762   {
3763     return -1;
3764   }
3765 
3766   hdrlist[handle]->nr_annot_chns = annot_signals;
3767 
3768   return 0;
3769 }
3770 
3771 
edf_set_datarecord_duration(int handle,int duration)3772 int edf_set_datarecord_duration(int handle, int duration)
3773 {
3774   if(handle<0)
3775   {
3776     return -1;
3777   }
3778 
3779   if(handle>=EDFLIB_MAXFILES)
3780   {
3781     return -1;
3782   }
3783 
3784   if(hdrlist[handle]==NULL)
3785   {
3786     return -1;
3787   }
3788 
3789   if(!(hdrlist[handle]->writemode))
3790   {
3791     return -1;
3792   }
3793 
3794   if(hdrlist[handle]->datarecords)
3795   {
3796     return -1;
3797   }
3798 
3799   if((duration < 100) || (duration > 6000000))
3800   {
3801     return -1;
3802   }
3803 
3804   hdrlist[handle]->long_data_record_duration = (long long)duration * 100LL;
3805 
3806   if(hdrlist[handle]->long_data_record_duration < (EDFLIB_TIME_DIMENSION * 10LL))
3807   {
3808     hdrlist[handle]->long_data_record_duration /= 10LL;
3809 
3810     hdrlist[handle]->long_data_record_duration *= 10LL;
3811   }
3812   else
3813   {
3814     hdrlist[handle]->long_data_record_duration /= 100LL;
3815 
3816     hdrlist[handle]->long_data_record_duration *= 100LL;
3817   }
3818 
3819   hdrlist[handle]->data_record_duration = ((double)(hdrlist[handle]->long_data_record_duration)) / EDFLIB_TIME_DIMENSION;
3820 
3821   return 0;
3822 }
3823 
3824 
edf_set_micro_datarecord_duration(int handle,int duration)3825 int edf_set_micro_datarecord_duration(int handle, int duration)
3826 {
3827   if(handle<0)
3828   {
3829     return -1;
3830   }
3831 
3832   if(handle>=EDFLIB_MAXFILES)
3833   {
3834     return -1;
3835   }
3836 
3837   if(hdrlist[handle]==NULL)
3838   {
3839     return -1;
3840   }
3841 
3842   if(!(hdrlist[handle]->writemode))
3843   {
3844     return -1;
3845   }
3846 
3847   if(hdrlist[handle]->datarecords)
3848   {
3849     return -1;
3850   }
3851 
3852   if((duration < 1) || (duration > 9999))
3853   {
3854     return -1;
3855   }
3856 
3857   hdrlist[handle]->long_data_record_duration = (long long)duration * 10LL;
3858 
3859   hdrlist[handle]->data_record_duration = ((double)(hdrlist[handle]->long_data_record_duration)) / EDFLIB_TIME_DIMENSION;
3860 
3861   return 0;
3862 }
3863 
3864 
edf_set_subsecond_starttime(int handle,int subsecond)3865 int edf_set_subsecond_starttime(int handle, int subsecond)
3866 {
3867   if(handle<0)
3868   {
3869     return -1;
3870   }
3871 
3872   if(handle>=EDFLIB_MAXFILES)
3873   {
3874     return -1;
3875   }
3876 
3877   if(hdrlist[handle]==NULL)
3878   {
3879     return -1;
3880   }
3881 
3882   if(!(hdrlist[handle]->writemode))
3883   {
3884     return -1;
3885   }
3886 
3887   if(hdrlist[handle]->datarecords)
3888   {
3889     return -1;
3890   }
3891 
3892   if((subsecond < 0) || (subsecond > 9999999))
3893   {
3894     return -1;
3895   }
3896 
3897   hdrlist[handle]->starttime_offset = (long long)subsecond;
3898 
3899   return 0;
3900 }
3901 
3902 
edfwrite_digital_short_samples(int handle,short * buf)3903 int edfwrite_digital_short_samples(int handle, short *buf)
3904 {
3905   int  i,
3906        error,
3907        sf,
3908        digmax,
3909        digmin,
3910        edfsignal,
3911        value;
3912 
3913   FILE *file;
3914 
3915   struct edfhdrblock *hdr;
3916 
3917 
3918   if(handle<0)
3919   {
3920     return -1;
3921   }
3922 
3923   if(handle>=EDFLIB_MAXFILES)
3924   {
3925     return -1;
3926   }
3927 
3928   if(hdrlist[handle]==NULL)
3929   {
3930     return -1;
3931   }
3932 
3933   if(!(hdrlist[handle]->writemode))
3934   {
3935     return -1;
3936   }
3937 
3938   if(hdrlist[handle]->edfsignals == 0)
3939   {
3940     return -1;
3941   }
3942 
3943   if(hdrlist[handle]->bdf == 1)
3944   {
3945     return -1;
3946   }
3947 
3948   hdr = hdrlist[handle];
3949 
3950   file = hdr->file_hdl;
3951 
3952   edfsignal = hdr->signal_write_sequence_pos;
3953 
3954   if(!hdr->datarecords)
3955   {
3956     if(!edfsignal)
3957     {
3958       error = edflib_write_edf_header(hdr);
3959 
3960       if(error)
3961       {
3962         return error;
3963       }
3964     }
3965   }
3966 
3967   sf = hdr->edfparam[edfsignal].smp_per_record;
3968 
3969   digmax = hdr->edfparam[edfsignal].dig_max;
3970 
3971   digmin = hdr->edfparam[edfsignal].dig_min;
3972 
3973   if(hdr->edf)
3974   {
3975     if((digmax != 32767) || (digmin != -32768))
3976     {
3977       for(i=0; i<sf; i++)
3978       {
3979         if(buf[i]>digmax)
3980         {
3981           buf[i] = digmax;
3982         }
3983 
3984         if(buf[i]<digmin)
3985         {
3986           buf[i] = digmin;
3987         }
3988       }
3989     }
3990 
3991     if(fwrite(buf, sf * 2, 1, file) != 1)
3992     {
3993       return -1;
3994     }
3995   }
3996   else  // BDF
3997   {
3998     if(hdr->wrbufsize < (sf * 3))
3999     {
4000       free(hdr->wrbuf);
4001 
4002       hdr->wrbufsize = 0;
4003 
4004       hdr->wrbuf = (char *)malloc(sf * 3);
4005 
4006       if(hdr->wrbuf == NULL)
4007       {
4008         return -1;
4009       }
4010 
4011       hdr->wrbufsize = sf * 3;
4012     }
4013 
4014     for(i=0; i<sf; i++)
4015     {
4016       value = buf[i];
4017 
4018       if(value>digmax)
4019       {
4020         value = digmax;
4021       }
4022 
4023       if(value<digmin)
4024       {
4025         value = digmin;
4026       }
4027 
4028       hdr->wrbuf[i * 3] = value & 0xff;
4029 
4030       hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4031 
4032       hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4033     }
4034 
4035     if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4036     {
4037       return -1;
4038     }
4039   }
4040 
4041   hdr->signal_write_sequence_pos++;
4042 
4043   if(hdr->signal_write_sequence_pos == hdr->edfsignals)
4044   {
4045     hdr->signal_write_sequence_pos = 0;
4046 
4047     if(edflib_write_tal(hdr, file))
4048     {
4049       return -1;
4050     }
4051 
4052     hdr->datarecords++;
4053 
4054     fflush(file);
4055   }
4056 
4057   return 0;
4058 }
4059 
4060 
edfwrite_digital_samples(int handle,int * buf)4061 int edfwrite_digital_samples(int handle, int *buf)
4062 {
4063   int  i,
4064        error,
4065        sf,
4066        digmax,
4067        digmin,
4068        edfsignal,
4069        value;
4070 
4071   FILE *file;
4072 
4073   struct edfhdrblock *hdr;
4074 
4075 
4076   if(handle<0)
4077   {
4078     return -1;
4079   }
4080 
4081   if(handle>=EDFLIB_MAXFILES)
4082   {
4083     return -1;
4084   }
4085 
4086   if(hdrlist[handle]==NULL)
4087   {
4088     return -1;
4089   }
4090 
4091   if(!(hdrlist[handle]->writemode))
4092   {
4093     return -1;
4094   }
4095 
4096   if(hdrlist[handle]->edfsignals == 0)
4097   {
4098     return -1;
4099   }
4100 
4101   hdr = hdrlist[handle];
4102 
4103   file = hdr->file_hdl;
4104 
4105   edfsignal = hdr->signal_write_sequence_pos;
4106 
4107   if(!hdr->datarecords)
4108   {
4109     if(!edfsignal)
4110     {
4111       error = edflib_write_edf_header(hdr);
4112 
4113       if(error)
4114       {
4115         return error;
4116       }
4117     }
4118   }
4119 
4120   sf = hdr->edfparam[edfsignal].smp_per_record;
4121 
4122   digmax = hdr->edfparam[edfsignal].dig_max;
4123 
4124   digmin = hdr->edfparam[edfsignal].dig_min;
4125 
4126   if(hdr->edf)
4127   {
4128     if(hdr->wrbufsize < (sf * 2))
4129     {
4130       free(hdr->wrbuf);
4131 
4132       hdr->wrbufsize = 0;
4133 
4134       hdr->wrbuf = (char *)malloc(sf * 2);
4135 
4136       if(hdr->wrbuf == NULL)
4137       {
4138         return -1;
4139       }
4140 
4141       hdr->wrbufsize = sf * 2;
4142     }
4143 
4144     for(i=0; i<sf; i++)
4145     {
4146       value = buf[i];
4147 
4148       if(value>digmax)
4149       {
4150         value = digmax;
4151       }
4152 
4153       if(value<digmin)
4154       {
4155         value = digmin;
4156       }
4157 
4158       hdr->wrbuf[i * 2] = value & 0xff;
4159 
4160       hdr->wrbuf[i * 2 + 1] = (value >> 8) & 0xff;
4161     }
4162 
4163     if(fwrite(hdr->wrbuf, sf * 2, 1, file) != 1)
4164     {
4165       return -1;
4166     }
4167   }
4168   else  // BDF
4169   {
4170     if(hdr->wrbufsize < (sf * 3))
4171     {
4172       free(hdr->wrbuf);
4173 
4174       hdr->wrbufsize = 0;
4175 
4176       hdr->wrbuf = (char *)malloc(sf * 3);
4177 
4178       if(hdr->wrbuf == NULL)
4179       {
4180         return -1;
4181       }
4182 
4183       hdr->wrbufsize = sf * 3;
4184     }
4185 
4186     for(i=0; i<sf; i++)
4187     {
4188       value = buf[i];
4189 
4190       if(value>digmax)
4191       {
4192         value = digmax;
4193       }
4194 
4195       if(value<digmin)
4196       {
4197         value = digmin;
4198       }
4199 
4200       hdr->wrbuf[i * 3] = value & 0xff;
4201 
4202       hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4203 
4204       hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4205     }
4206 
4207     if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4208     {
4209       return -1;
4210     }
4211   }
4212 
4213   hdr->signal_write_sequence_pos++;
4214 
4215   if(hdr->signal_write_sequence_pos == hdr->edfsignals)
4216   {
4217     hdr->signal_write_sequence_pos = 0;
4218 
4219     if(edflib_write_tal(hdr, file))
4220     {
4221       return -1;
4222     }
4223 
4224     hdr->datarecords++;
4225 
4226     fflush(file);
4227   }
4228 
4229   return 0;
4230 }
4231 
4232 
edf_blockwrite_digital_samples(int handle,int * buf)4233 int edf_blockwrite_digital_samples(int handle, int *buf)
4234 {
4235   int  i, j,
4236        error,
4237        sf,
4238        digmax,
4239        digmin,
4240        edfsignals,
4241        buf_offset,
4242        value;
4243 
4244   FILE *file;
4245 
4246   struct edfhdrblock *hdr;
4247 
4248 
4249   if(handle<0)
4250   {
4251     return -1;
4252   }
4253 
4254   if(handle>=EDFLIB_MAXFILES)
4255   {
4256     return -1;
4257   }
4258 
4259   if(hdrlist[handle]==NULL)
4260   {
4261     return -1;
4262   }
4263 
4264   if(!(hdrlist[handle]->writemode))
4265   {
4266     return -1;
4267   }
4268 
4269   if(hdrlist[handle]->signal_write_sequence_pos)
4270   {
4271     return -1;
4272   }
4273 
4274   if(hdrlist[handle]->edfsignals == 0)
4275   {
4276     return -1;
4277   }
4278 
4279   hdr = hdrlist[handle];
4280 
4281   file = hdr->file_hdl;
4282 
4283   edfsignals = hdr->edfsignals;
4284 
4285   if(!hdr->datarecords)
4286   {
4287     error = edflib_write_edf_header(hdr);
4288 
4289     if(error)
4290     {
4291       return error;
4292     }
4293   }
4294 
4295   buf_offset = 0;
4296 
4297   for(j=0; j<edfsignals; j++)
4298   {
4299     sf = hdr->edfparam[j].smp_per_record;
4300 
4301     digmax = hdr->edfparam[j].dig_max;
4302 
4303     digmin = hdr->edfparam[j].dig_min;
4304 
4305     if(hdr->edf)
4306     {
4307       if(hdr->wrbufsize < (sf * 2))
4308       {
4309         free(hdr->wrbuf);
4310 
4311         hdr->wrbufsize = 0;
4312 
4313         hdr->wrbuf = (char *)malloc(sf * 2);
4314 
4315         if(hdr->wrbuf == NULL)
4316         {
4317           return -1;
4318         }
4319 
4320         hdr->wrbufsize = sf * 2;
4321       }
4322 
4323       for(i=0; i<sf; i++)
4324       {
4325         value = buf[i + buf_offset];
4326 
4327         if(value>digmax)
4328         {
4329           value = digmax;
4330         }
4331 
4332         if(value<digmin)
4333         {
4334           value = digmin;
4335         }
4336 
4337         hdr->wrbuf[i * 2] = value & 0xff;
4338 
4339         hdr->wrbuf[i * 2 + 1] = (value >> 8) & 0xff;
4340       }
4341 
4342       if(fwrite(hdr->wrbuf, sf * 2, 1, file) != 1)
4343       {
4344         return -1;
4345       }
4346     }
4347     else  // BDF
4348     {
4349       if(hdr->wrbufsize < (sf * 3))
4350       {
4351         free(hdr->wrbuf);
4352 
4353         hdr->wrbufsize = 0;
4354 
4355         hdr->wrbuf = (char *)malloc(sf * 3);
4356 
4357         if(hdr->wrbuf == NULL)
4358         {
4359           return -1;
4360         }
4361 
4362         hdr->wrbufsize = sf * 3;
4363       }
4364 
4365       for(i=0; i<sf; i++)
4366       {
4367         value = buf[i + buf_offset];
4368 
4369         if(value>digmax)
4370         {
4371           value = digmax;
4372         }
4373 
4374         if(value<digmin)
4375         {
4376           value = digmin;
4377         }
4378 
4379         hdr->wrbuf[i * 3] = value & 0xff;
4380 
4381         hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4382 
4383         hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4384       }
4385 
4386       if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4387       {
4388         return -1;
4389       }
4390     }
4391 
4392     buf_offset += sf;
4393   }
4394 
4395   if(edflib_write_tal(hdr, file))
4396   {
4397     return -1;
4398   }
4399 
4400   hdr->datarecords++;
4401 
4402   fflush(file);
4403 
4404   return 0;
4405 }
4406 
4407 
edf_blockwrite_digital_short_samples(int handle,short * buf)4408 int edf_blockwrite_digital_short_samples(int handle, short *buf)
4409 {
4410   int  i, j,
4411        error,
4412        sf,
4413        digmax,
4414        digmin,
4415        edfsignals,
4416        buf_offset,
4417        value;
4418 
4419   FILE *file;
4420 
4421   struct edfhdrblock *hdr;
4422 
4423 
4424   if(handle<0)
4425   {
4426     return -1;
4427   }
4428 
4429   if(handle>=EDFLIB_MAXFILES)
4430   {
4431     return -1;
4432   }
4433 
4434   if(hdrlist[handle]==NULL)
4435   {
4436     return -1;
4437   }
4438 
4439   if(!(hdrlist[handle]->writemode))
4440   {
4441     return -1;
4442   }
4443 
4444   if(hdrlist[handle]->signal_write_sequence_pos)
4445   {
4446     return -1;
4447   }
4448 
4449   if(hdrlist[handle]->edfsignals == 0)
4450   {
4451     return -1;
4452   }
4453 
4454   if(hdrlist[handle]->bdf == 1)
4455   {
4456     return -1;
4457   }
4458 
4459   hdr = hdrlist[handle];
4460 
4461   file = hdr->file_hdl;
4462 
4463   edfsignals = hdr->edfsignals;
4464 
4465   if(!hdr->datarecords)
4466   {
4467     error = edflib_write_edf_header(hdr);
4468 
4469     if(error)
4470     {
4471       return error;
4472     }
4473   }
4474 
4475   buf_offset = 0;
4476 
4477   for(j=0; j<edfsignals; j++)
4478   {
4479     sf = hdr->edfparam[j].smp_per_record;
4480 
4481     digmax = hdr->edfparam[j].dig_max;
4482 
4483     digmin = hdr->edfparam[j].dig_min;
4484 
4485     if(hdr->edf)
4486     {
4487       if((digmax != 32767) || (digmin != -32768))
4488       {
4489         for(i=0; i<sf; i++)
4490         {
4491           if(buf[i + buf_offset] > digmax)
4492           {
4493             buf[i + buf_offset] = digmax;
4494           }
4495 
4496           if(buf[i + buf_offset] < digmin)
4497           {
4498             buf[i + buf_offset] = digmin;
4499           }
4500         }
4501       }
4502 
4503       if(fwrite(buf + buf_offset, sf * 2, 1, file) != 1)
4504       {
4505         return -1;
4506       }
4507     }
4508     else  // BDF
4509     {
4510       if(hdr->wrbufsize < (sf * 3))
4511       {
4512         free(hdr->wrbuf);
4513 
4514         hdr->wrbufsize = 0;
4515 
4516         hdr->wrbuf = (char *)malloc(sf * 3);
4517 
4518         if(hdr->wrbuf == NULL)
4519         {
4520           return -1;
4521         }
4522 
4523         hdr->wrbufsize = sf * 3;
4524       }
4525 
4526       for(i=0; i<sf; i++)
4527       {
4528         value = buf[i + buf_offset];
4529 
4530         if(value>digmax)
4531         {
4532           value = digmax;
4533         }
4534 
4535         if(value<digmin)
4536         {
4537           value = digmin;
4538         }
4539 
4540         hdr->wrbuf[i * 3] = value & 0xff;
4541 
4542         hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4543 
4544         hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4545       }
4546 
4547       if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4548       {
4549         return -1;
4550       }
4551     }
4552 
4553     buf_offset += sf;
4554   }
4555 
4556   if(edflib_write_tal(hdr, file))
4557   {
4558     return -1;
4559   }
4560 
4561   hdr->datarecords++;
4562 
4563   fflush(file);
4564 
4565   return 0;
4566 }
4567 
4568 
edf_blockwrite_digital_3byte_samples(int handle,void * buf)4569 int edf_blockwrite_digital_3byte_samples(int handle, void *buf)
4570 {
4571   int  j,
4572        error,
4573        edfsignals,
4574        total_samples=0;
4575 
4576   FILE *file;
4577 
4578   struct edfhdrblock *hdr;
4579 
4580 
4581   if(handle<0)
4582   {
4583     return -1;
4584   }
4585 
4586   if(handle>=EDFLIB_MAXFILES)
4587   {
4588     return -1;
4589   }
4590 
4591   if(hdrlist[handle]==NULL)
4592   {
4593     return -1;
4594   }
4595 
4596   if(!(hdrlist[handle]->writemode))
4597   {
4598     return -1;
4599   }
4600 
4601   if(hdrlist[handle]->signal_write_sequence_pos)
4602   {
4603     return -1;
4604   }
4605 
4606   if(hdrlist[handle]->edfsignals == 0)
4607   {
4608     return -1;
4609   }
4610 
4611   if(hdrlist[handle]->bdf != 1)
4612   {
4613     return -1;
4614   }
4615 
4616   hdr = hdrlist[handle];
4617 
4618   file = hdr->file_hdl;
4619 
4620   edfsignals = hdr->edfsignals;
4621 
4622   if(!hdr->datarecords)
4623   {
4624     error = edflib_write_edf_header(hdr);
4625 
4626     if(error)
4627     {
4628       return error;
4629     }
4630   }
4631 
4632   for(j=0; j<edfsignals; j++)
4633   {
4634     total_samples += hdr->edfparam[j].smp_per_record;
4635   }
4636 
4637   if(fwrite(buf, total_samples * 3, 1, file) != 1)
4638   {
4639     return -1;
4640   }
4641 
4642   if(edflib_write_tal(hdr, file))
4643   {
4644     return -1;
4645   }
4646 
4647   hdr->datarecords++;
4648 
4649   fflush(file);
4650 
4651   return 0;
4652 }
4653 
4654 
edfwrite_physical_samples(int handle,double * buf)4655 int edfwrite_physical_samples(int handle, double *buf)
4656 {
4657   int  i,
4658        error,
4659        sf,
4660        digmax,
4661        digmin,
4662        value,
4663        edfsignal;
4664 
4665   double bitvalue,
4666          phys_offset;
4667 
4668   FILE *file;
4669 
4670   struct edfhdrblock *hdr;
4671 
4672 
4673   if(handle<0)
4674   {
4675     return -1;
4676   }
4677 
4678   if(handle>=EDFLIB_MAXFILES)
4679   {
4680     return -1;
4681   }
4682 
4683   if(hdrlist[handle]==NULL)
4684   {
4685     return -1;
4686   }
4687 
4688   if(!(hdrlist[handle]->writemode))
4689   {
4690     return -1;
4691   }
4692 
4693   if(hdrlist[handle]->edfsignals == 0)
4694   {
4695     return -1;
4696   }
4697 
4698   hdr = hdrlist[handle];
4699 
4700   file = hdr->file_hdl;
4701 
4702   edfsignal = hdr->signal_write_sequence_pos;
4703 
4704   if(!hdr->datarecords)
4705   {
4706     if(!edfsignal)
4707     {
4708       error = edflib_write_edf_header(hdr);
4709 
4710       if(error)
4711       {
4712         return error;
4713       }
4714     }
4715   }
4716 
4717   sf = hdr->edfparam[edfsignal].smp_per_record;
4718 
4719   digmax = hdr->edfparam[edfsignal].dig_max;
4720 
4721   digmin = hdr->edfparam[edfsignal].dig_min;
4722 
4723   bitvalue = hdr->edfparam[edfsignal].bitvalue;
4724 
4725   phys_offset = hdr->edfparam[edfsignal].offset;
4726 
4727   if(hdr->edf)
4728   {
4729     if(hdr->wrbufsize < (sf * 2))
4730     {
4731       free(hdr->wrbuf);
4732 
4733       hdr->wrbufsize = 0;
4734 
4735       hdr->wrbuf = (char *)malloc(sf * 2);
4736 
4737       if(hdr->wrbuf == NULL)
4738       {
4739         return -1;
4740       }
4741 
4742       hdr->wrbufsize = sf * 2;
4743     }
4744 
4745     for(i=0; i<sf; i++)
4746     {
4747       value = (buf[i] / bitvalue) - phys_offset;
4748 
4749       if(value>digmax)
4750       {
4751         value = digmax;
4752       }
4753 
4754       if(value<digmin)
4755       {
4756         value = digmin;
4757       }
4758 
4759       hdr->wrbuf[i * 2] = value & 0xff;
4760 
4761       hdr->wrbuf[i * 2 + 1] = (value >> 8) & 0xff;
4762     }
4763 
4764     if(fwrite(hdr->wrbuf, sf * 2, 1, file) != 1)
4765     {
4766       return -1;
4767     }
4768   }
4769   else  // BDF
4770   {
4771     if(hdr->wrbufsize < (sf * 3))
4772     {
4773       free(hdr->wrbuf);
4774 
4775       hdr->wrbufsize = 0;
4776 
4777       hdr->wrbuf = (char *)malloc(sf * 3);
4778 
4779       if(hdr->wrbuf == NULL)
4780       {
4781         return -1;
4782       }
4783 
4784       hdr->wrbufsize = sf * 3;
4785     }
4786 
4787     for(i=0; i<sf; i++)
4788     {
4789       value = (buf[i] / bitvalue) - phys_offset;
4790 
4791       if(value>digmax)
4792       {
4793         value = digmax;
4794       }
4795 
4796       if(value<digmin)
4797       {
4798         value = digmin;
4799       }
4800 
4801       hdr->wrbuf[i * 3] = value & 0xff;
4802 
4803       hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4804 
4805       hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4806     }
4807 
4808     if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4809     {
4810       return -1;
4811     }
4812   }
4813 
4814   hdr->signal_write_sequence_pos++;
4815 
4816   if(hdr->signal_write_sequence_pos == hdr->edfsignals)
4817   {
4818     hdr->signal_write_sequence_pos = 0;
4819 
4820     if(edflib_write_tal(hdr, file))
4821     {
4822       return -1;
4823     }
4824 
4825     hdr->datarecords++;
4826 
4827     fflush(file);
4828   }
4829 
4830   return 0;
4831 }
4832 
4833 
edf_blockwrite_physical_samples(int handle,double * buf)4834 int edf_blockwrite_physical_samples(int handle, double *buf)
4835 {
4836   int  i, j,
4837        error,
4838        sf,
4839        digmax,
4840        digmin,
4841        edfsignals,
4842        buf_offset,
4843        value;
4844 
4845   double bitvalue,
4846          phys_offset;
4847 
4848   FILE *file;
4849 
4850   struct edfhdrblock *hdr;
4851 
4852 
4853   if(handle<0)
4854   {
4855     return -1;
4856   }
4857 
4858   if(handle>=EDFLIB_MAXFILES)
4859   {
4860     return -1;
4861   }
4862 
4863   if(hdrlist[handle]==NULL)
4864   {
4865     return -1;
4866   }
4867 
4868   if(!(hdrlist[handle]->writemode))
4869   {
4870     return -1;
4871   }
4872 
4873   if(hdrlist[handle]->signal_write_sequence_pos)
4874   {
4875     return -1;
4876   }
4877 
4878   if(hdrlist[handle]->edfsignals == 0)
4879   {
4880     return -1;
4881   }
4882 
4883   hdr = hdrlist[handle];
4884 
4885   file = hdr->file_hdl;
4886 
4887   edfsignals = hdr->edfsignals;
4888 
4889   if(!hdr->datarecords)
4890   {
4891     error = edflib_write_edf_header(hdr);
4892 
4893     if(error)
4894     {
4895       return error;
4896     }
4897   }
4898 
4899   buf_offset = 0;
4900 
4901   for(j=0; j<edfsignals; j++)
4902   {
4903     sf = hdr->edfparam[j].smp_per_record;
4904 
4905     digmax = hdr->edfparam[j].dig_max;
4906 
4907     digmin = hdr->edfparam[j].dig_min;
4908 
4909     bitvalue = hdr->edfparam[j].bitvalue;
4910 
4911     phys_offset = hdr->edfparam[j].offset;
4912 
4913     if(hdr->edf)
4914     {
4915       if(hdr->wrbufsize < (sf * 2))
4916       {
4917         free(hdr->wrbuf);
4918 
4919         hdr->wrbufsize = 0;
4920 
4921         hdr->wrbuf = (char *)malloc(sf * 2);
4922 
4923         if(hdr->wrbuf == NULL)
4924         {
4925           return -1;
4926         }
4927 
4928         hdr->wrbufsize = sf * 2;
4929       }
4930 
4931       for(i=0; i<sf; i++)
4932       {
4933         value = (buf[i + buf_offset] / bitvalue) - phys_offset;
4934 
4935         if(value>digmax)
4936         {
4937           value = digmax;
4938         }
4939 
4940         if(value<digmin)
4941         {
4942           value = digmin;
4943         }
4944 
4945         hdr->wrbuf[i * 2] = value & 0xff;
4946 
4947         hdr->wrbuf[i * 2 + 1] = (value >> 8) & 0xff;
4948       }
4949 
4950       if(fwrite(hdr->wrbuf, sf * 2, 1, file) != 1)
4951       {
4952         return -1;
4953       }
4954     }
4955     else  // BDF
4956     {
4957       if(hdr->wrbufsize < (sf * 3))
4958       {
4959         free(hdr->wrbuf);
4960 
4961         hdr->wrbufsize = 0;
4962 
4963         hdr->wrbuf = (char *)malloc(sf * 3);
4964 
4965         if(hdr->wrbuf == NULL)
4966         {
4967           return -1;
4968         }
4969 
4970         hdr->wrbufsize = sf * 3;
4971       }
4972 
4973       for(i=0; i<sf; i++)
4974       {
4975         value = (buf[i + buf_offset] / bitvalue) - phys_offset;
4976 
4977         if(value>digmax)
4978         {
4979           value = digmax;
4980         }
4981 
4982         if(value<digmin)
4983         {
4984           value = digmin;
4985         }
4986 
4987         hdr->wrbuf[i * 3] = value & 0xff;
4988 
4989         hdr->wrbuf[i * 3 + 1] = (value >> 8) & 0xff;
4990 
4991         hdr->wrbuf[i * 3 + 2] = (value >> 16) & 0xff;
4992       }
4993 
4994       if(fwrite(hdr->wrbuf, sf * 3, 1, file) != 1)
4995       {
4996         return -1;
4997       }
4998     }
4999 
5000     buf_offset += sf;
5001   }
5002 
5003   if(edflib_write_tal(hdr, file))
5004   {
5005     return -1;
5006   }
5007 
5008   hdr->datarecords++;
5009 
5010   fflush(file);
5011 
5012   return 0;
5013 }
5014 
5015 
edflib_write_edf_header(struct edfhdrblock * hdr)5016 static int edflib_write_edf_header(struct edfhdrblock *hdr)
5017 {
5018   int i, j, p, q,
5019       len,
5020       rest,
5021       edfsignals;
5022 
5023   char str[128];
5024 
5025   struct tm *date_time;
5026 
5027   time_t elapsed_time;
5028 
5029   FILE *file;
5030 
5031 
5032   file = hdr->file_hdl;
5033 
5034   edfsignals = hdr->edfsignals;
5035 
5036   if(edfsignals<0)
5037   {
5038     return EDFLIB_NO_SIGNALS;
5039   }
5040 
5041   if(edfsignals>EDFLIB_MAXSIGNALS)
5042   {
5043     return EDFLIB_TOO_MANY_SIGNALS;
5044   }
5045 
5046   hdr->eq_sf = 1;
5047 
5048   hdr->recordsize = 0;
5049 
5050   hdr->total_annot_bytes = EDFLIB_ANNOTATION_BYTES * hdr->nr_annot_chns;
5051 
5052   for(i=0; i<edfsignals; i++)
5053   {
5054     if(hdr->edfparam[i].smp_per_record<1)
5055     {
5056       return EDFLIB_NO_SAMPLES_IN_RECORD;
5057     }
5058 
5059     if(hdr->edfparam[i].dig_max==hdr->edfparam[i].dig_min)
5060     {
5061       return EDFLIB_DIGMIN_IS_DIGMAX;
5062     }
5063 
5064     if(hdr->edfparam[i].dig_max<hdr->edfparam[i].dig_min)
5065     {
5066       return EDFLIB_DIGMAX_LOWER_THAN_DIGMIN;
5067     }
5068 
5069     if(hdr->edfparam[i].phys_max==hdr->edfparam[i].phys_min)
5070     {
5071       return EDFLIB_PHYSMIN_IS_PHYSMAX;
5072     }
5073 
5074     hdr->recordsize += hdr->edfparam[i].smp_per_record;
5075 
5076     if(i > 0)
5077     {
5078       if(hdr->edfparam[i].smp_per_record != hdr->edfparam[i-1].smp_per_record)
5079       {
5080         hdr->eq_sf = 0;
5081       }
5082     }
5083   }
5084 
5085   if(hdr->edf)
5086   {
5087     hdr->recordsize *= 2;
5088 
5089     hdr->recordsize += hdr->total_annot_bytes;
5090 
5091     if(hdr->recordsize > (10 * 1024 * 1024))  /* datarecord size should not exceed 10MB for EDF */
5092     {
5093       return EDFLIB_DATARECORD_SIZE_TOO_BIG;
5094     }  /* if your application gets hit by this limitation, lower the value for the datarecord duration */
5095        /* using the function edf_set_datarecord_duration() */
5096   }
5097   else
5098   {
5099     hdr->recordsize *= 3;
5100 
5101     hdr->recordsize += hdr->total_annot_bytes;
5102 
5103     if(hdr->recordsize > (15 * 1024 * 1024))  /* datarecord size should not exceed 15MB for BDF */
5104     {
5105       return EDFLIB_DATARECORD_SIZE_TOO_BIG;
5106     }  /* if your application gets hit by this limitation, lower the value for the datarecord duration */
5107        /* using the function edf_set_datarecord_duration() */
5108   }
5109 
5110   for(i=0; i<edfsignals; i++)
5111   {
5112     hdr->edfparam[i].bitvalue = (hdr->edfparam[i].phys_max - hdr->edfparam[i].phys_min) / (hdr->edfparam[i].dig_max - hdr->edfparam[i].dig_min);
5113     hdr->edfparam[i].offset = hdr->edfparam[i].phys_max / hdr->edfparam[i].bitvalue - hdr->edfparam[i].dig_max;
5114   }
5115 
5116   rewind(file);
5117 
5118   if(hdr->edf)
5119   {
5120     fprintf(file, "0       ");
5121   }
5122   else
5123   {
5124     fputc(255, file);
5125     fprintf(file, "BIOSEMI");
5126   }
5127 
5128   p = 0;
5129 
5130   if(hdr->plus_birthdate[0]==0)
5131   {
5132     rest = 72;
5133   }
5134   else
5135   {
5136     rest = 62;
5137   }
5138 
5139   len = strlen(hdr->plus_patientcode);
5140   if(len && rest)
5141   {
5142     if(len>rest)
5143     {
5144       len = rest;
5145       rest = 0;
5146     }
5147     else
5148     {
5149       rest -= len;
5150     }
5151     edflib_strlcpy(str, hdr->plus_patientcode, 128);
5152     edflib_latin1_to_ascii(str, len);
5153     str[len] = 0;
5154     for(i=0; i<len; i++)
5155     {
5156       if(str[i]==' ')
5157       {
5158         str[i] = '_';
5159       }
5160     }
5161     p += fprintf(file, "%s ", str);
5162   }
5163   else
5164   {
5165     p += fprintf(file, "X ");
5166   }
5167 
5168   if(hdr->plus_gender[0]=='M')
5169   {
5170     fputc('M', file);
5171   }
5172   else
5173   {
5174     if(hdr->plus_gender[0]=='F')
5175     {
5176       fputc('F', file);
5177     }
5178     else
5179     {
5180       fputc('X', file);
5181     }
5182   }
5183   fputc(' ', file);
5184   p +=2;
5185 
5186   if(hdr->plus_birthdate[0]==0)
5187   {
5188     fputc('X', file);
5189     fputc(' ', file);
5190 
5191     p +=2;
5192   }
5193   else
5194   {
5195     fputc(hdr->plus_birthdate[0], file);
5196     fputc(hdr->plus_birthdate[1], file);
5197     fputc('-', file);
5198     q = edflib_atof_nonlocalized(&(hdr->plus_birthdate[3]));
5199     switch(q)
5200     {
5201       case  1: fprintf(file, "JAN");  break;
5202       case  2: fprintf(file, "FEB");  break;
5203       case  3: fprintf(file, "MAR");  break;
5204       case  4: fprintf(file, "APR");  break;
5205       case  5: fprintf(file, "MAY");  break;
5206       case  6: fprintf(file, "JUN");  break;
5207       case  7: fprintf(file, "JUL");  break;
5208       case  8: fprintf(file, "AUG");  break;
5209       case  9: fprintf(file, "SEP");  break;
5210       case 10: fprintf(file, "OCT");  break;
5211       case 11: fprintf(file, "NOV");  break;
5212       case 12: fprintf(file, "DEC");  break;
5213     }
5214     fputc('-', file);
5215     fputc(hdr->plus_birthdate[6], file);
5216     fputc(hdr->plus_birthdate[7], file);
5217     fputc(hdr->plus_birthdate[8], file);
5218     fputc(hdr->plus_birthdate[9], file);
5219     fputc(' ', file);
5220 
5221     p += 12;
5222   }
5223 
5224   len = strlen(hdr->plus_patient_name);
5225   if(len && rest)
5226   {
5227     if(len>rest)
5228     {
5229       len = rest;
5230       rest = 0;
5231     }
5232     else
5233     {
5234       rest -= len;
5235     }
5236     edflib_strlcpy(str, hdr->plus_patient_name, 128);
5237     edflib_latin1_to_ascii(str, len);
5238     str[len] = 0;
5239     for(i=0; i<len; i++)
5240     {
5241       if(str[i]==' ')
5242       {
5243         str[i] = '_';
5244       }
5245     }
5246     p += fprintf(file, "%s", str);
5247   }
5248   else
5249   {
5250     fputc('X', file);
5251 
5252     p++;
5253   }
5254 
5255   if(rest)
5256   {
5257     fputc(' ', file);
5258 
5259     p++;
5260 
5261     rest--;
5262   }
5263 
5264   len = strlen(hdr->plus_patient_additional);
5265   if(len && rest)
5266   {
5267     if(len>rest)
5268     {
5269       len = rest;
5270     }
5271     edflib_strlcpy(str, hdr->plus_patient_additional, 128);
5272     edflib_latin1_to_ascii(str, len);
5273     str[len] = 0;
5274     p += fprintf(file, "%s", str);
5275   }
5276 
5277   for(; p<80; p++)
5278   {
5279     fputc(' ', file);
5280   }
5281 
5282   if(!hdr->startdate_year)
5283   {
5284     elapsed_time = time(NULL);
5285     date_time = localtime(&elapsed_time);
5286 
5287     hdr->startdate_year = date_time->tm_year + 1900;
5288     hdr->startdate_month = date_time->tm_mon + 1;
5289     hdr->startdate_day = date_time->tm_mday;
5290     hdr->starttime_hour = date_time->tm_hour;
5291     hdr->starttime_minute = date_time->tm_min;
5292     hdr->starttime_second = date_time->tm_sec % 60;
5293   }
5294 
5295   p = 0;
5296 
5297   p += fprintf(file, "Startdate %02u-", hdr->startdate_day);
5298   switch(hdr->startdate_month)
5299   {
5300     case  1 : fprintf(file, "JAN");  break;
5301     case  2 : fprintf(file, "FEB");  break;
5302     case  3 : fprintf(file, "MAR");  break;
5303     case  4 : fprintf(file, "APR");  break;
5304     case  5 : fprintf(file, "MAY");  break;
5305     case  6 : fprintf(file, "JUN");  break;
5306     case  7 : fprintf(file, "JUL");  break;
5307     case  8 : fprintf(file, "AUG");  break;
5308     case  9 : fprintf(file, "SEP");  break;
5309     case 10 : fprintf(file, "OCT");  break;
5310     case 11 : fprintf(file, "NOV");  break;
5311     case 12 : fprintf(file, "DEC");  break;
5312   }
5313   p += 3;
5314   fputc('-', file);
5315   p++;
5316   p += edflib_fprint_int_number_nonlocalized(file, hdr->startdate_year, 4, 0);
5317   fputc(' ', file);
5318   p++;
5319 
5320   rest = 42;
5321 
5322   len = strlen(hdr->plus_admincode);
5323   if(len && rest)
5324   {
5325     if(len>rest)
5326     {
5327       len = rest;
5328       rest = 0;
5329     }
5330     else
5331     {
5332       rest -= len;
5333     }
5334     edflib_strlcpy(str, hdr->plus_admincode, 128);
5335     edflib_latin1_to_ascii(str, len);
5336     str[len] = 0;
5337     for(i=0; i<len; i++)
5338     {
5339       if(str[i]==' ')
5340       {
5341         str[i] = '_';
5342       }
5343     }
5344     p += fprintf(file, "%s", str);
5345   }
5346   else
5347   {
5348     p += fprintf(file, "X");
5349   }
5350 
5351   if(rest)
5352   {
5353     fputc(' ', file);
5354 
5355     p++;
5356 
5357     rest--;
5358   }
5359 
5360   len = strlen(hdr->plus_technician);
5361   if(len && rest)
5362   {
5363     if(len>rest)
5364     {
5365       len = rest;
5366       rest = 0;
5367     }
5368     else
5369     {
5370       rest -= len;
5371     }
5372     edflib_strlcpy(str, hdr->plus_technician, 128);
5373     edflib_latin1_to_ascii(str, len);
5374     str[len] = 0;
5375     for(i=0; i<len; i++)
5376     {
5377       if(str[i]==' ')
5378       {
5379         str[i] = '_';
5380       }
5381     }
5382     p += fprintf(file, "%s", str);
5383   }
5384   else
5385   {
5386     p += fprintf(file, "X");
5387   }
5388 
5389   if(rest)
5390   {
5391     fputc(' ', file);
5392 
5393     p++;
5394 
5395     rest--;
5396   }
5397 
5398   len = strlen(hdr->plus_equipment);
5399   if(len && rest)
5400   {
5401     if(len>rest)
5402     {
5403       len = rest;
5404       rest = 0;
5405     }
5406     else
5407     {
5408       rest -= len;
5409     }
5410     edflib_strlcpy(str, hdr->plus_equipment, 128);
5411     edflib_latin1_to_ascii(str, len);
5412     str[len] = 0;
5413     for(i=0; i<len; i++)
5414     {
5415       if(str[i]==' ')
5416       {
5417         str[i] = '_';
5418       }
5419     }
5420     p += fprintf(file, "%s", str);
5421   }
5422   else
5423   {
5424     p += fprintf(file, "X");
5425   }
5426 
5427   if(rest)
5428   {
5429     fputc(' ', file);
5430 
5431     p++;
5432 
5433     rest--;
5434   }
5435 
5436   len = strlen(hdr->plus_recording_additional);
5437   if(len && rest)
5438   {
5439     if(len>rest)
5440     {
5441       len = rest;
5442     }
5443     edflib_strlcpy(str, hdr->plus_recording_additional, 128);
5444     edflib_latin1_to_ascii(str, len);
5445     str[len] = 0;
5446     p += fprintf(file, "%s", str);
5447   }
5448 
5449   for(; p<80; p++)
5450   {
5451     fputc(' ', file);
5452   }
5453 
5454   fprintf(file, "%02u.%02u.%02u", hdr->startdate_day, hdr->startdate_month, (hdr->startdate_year % 100));
5455   fprintf(file, "%02u.%02u.%02u", hdr->starttime_hour, hdr->starttime_minute, hdr->starttime_second);
5456   p = edflib_fprint_int_number_nonlocalized(file, (edfsignals + hdr->nr_annot_chns + 1) * 256, 0, 0);
5457   for(; p<8; p++)
5458   {
5459     fputc(' ', file);
5460   }
5461   if(hdr->edf)
5462   {
5463     fprintf(file, "EDF+C");
5464   }
5465   else
5466   {
5467     fprintf(file, "BDF+C");
5468   }
5469   for(i=0; i<39; i++)
5470   {
5471     fputc(' ', file);
5472   }
5473   fprintf(file, "-1      ");
5474   if(hdr->long_data_record_duration == EDFLIB_TIME_DIMENSION)
5475   {
5476     fprintf(file, "1       ");
5477   }
5478   else
5479   {
5480     edflib_snprint_number_nonlocalized(str, hdr->data_record_duration, 128);
5481     edflib_strlcat(str, "        ", 128);
5482     str[8] = 0;
5483     fprintf(file, "%s", str);
5484   }
5485   p = edflib_fprint_int_number_nonlocalized(file, edfsignals + hdr->nr_annot_chns, 0, 0);
5486   for(; p<4; p++)
5487   {
5488     fputc(' ', file);
5489   }
5490 
5491   for(i=0; i<edfsignals; i++)
5492   {
5493     len = strlen(hdr->edfparam[i].label);
5494     edflib_latin1_to_ascii(hdr->edfparam[i].label, len);
5495     for(j=0; j<len; j++)
5496     {
5497       fputc(hdr->edfparam[i].label[j], file);
5498     }
5499     for(; j<16; j++)
5500     {
5501       fputc(' ', file);
5502     }
5503   }
5504   for(j=0; j<hdr->nr_annot_chns; j++)
5505   {
5506     if(hdr->edf)
5507     {
5508       fprintf(file, "EDF Annotations ");
5509     }
5510     else
5511     {
5512       fprintf(file, "BDF Annotations ");
5513     }
5514   }
5515   for(i=0; i<edfsignals; i++)
5516   {
5517     len = strlen(hdr->edfparam[i].transducer);
5518     edflib_latin1_to_ascii(hdr->edfparam[i].transducer, len);
5519     for(j=0; j<len; j++)
5520     {
5521       fputc(hdr->edfparam[i].transducer[j], file);
5522     }
5523     for(; j<80; j++)
5524     {
5525       fputc(' ', file);
5526     }
5527   }
5528   for(j=0; j<hdr->nr_annot_chns; j++)
5529   {
5530     for(i=0; i<80; i++)
5531     {
5532       fputc(' ', file);
5533     }
5534   }
5535   for(i=0; i<edfsignals; i++)
5536   {
5537     len = strlen(hdr->edfparam[i].physdimension);
5538     edflib_latin1_to_ascii(hdr->edfparam[i].physdimension, len);
5539     for(j=0; j<len; j++)
5540     {
5541       fputc(hdr->edfparam[i].physdimension[j], file);
5542     }
5543     for(; j<8; j++)
5544     {
5545       fputc(' ', file);
5546     }
5547   }
5548   for(j=0; j<hdr->nr_annot_chns; j++)
5549   {
5550     fprintf(file, "        ");
5551   }
5552   for(i=0; i<edfsignals; i++)
5553   {
5554     p = edflib_snprint_number_nonlocalized(str, hdr->edfparam[i].phys_min, 128);
5555     for(; p<8; p++)
5556     {
5557       str[p] = ' ';
5558     }
5559     str[8] = 0;
5560     fprintf(file, "%s", str);
5561   }
5562   for(j=0; j<hdr->nr_annot_chns; j++)
5563   {
5564     fprintf(file, "-1      ");
5565   }
5566   for(i=0; i<edfsignals; i++)
5567   {
5568     p = edflib_snprint_number_nonlocalized(str, hdr->edfparam[i].phys_max, 128);
5569     for(; p<8; p++)
5570     {
5571       str[p] = ' ';
5572     }
5573     str[8] = 0;
5574     fprintf(file, "%s", str);
5575   }
5576   for(j=0; j<hdr->nr_annot_chns; j++)
5577   {
5578     fprintf(file, "1       ");
5579   }
5580   for(i=0; i<edfsignals; i++)
5581   {
5582     p = edflib_fprint_int_number_nonlocalized(file, hdr->edfparam[i].dig_min, 0, 0);
5583     for(; p<8; p++)
5584     {
5585       fputc(' ', file);
5586     }
5587   }
5588   for(j=0; j<hdr->nr_annot_chns; j++)
5589   {
5590     if(hdr->edf)
5591     {
5592       fprintf(file, "-32768  ");
5593     }
5594     else
5595     {
5596       fprintf(file, "-8388608");
5597     }
5598   }
5599   for(i=0; i<edfsignals; i++)
5600   {
5601     p = edflib_fprint_int_number_nonlocalized(file, hdr->edfparam[i].dig_max, 0, 0);
5602     for(; p<8; p++)
5603     {
5604       fputc(' ', file);
5605     }
5606   }
5607   for(j=0; j<hdr->nr_annot_chns; j++)
5608   {
5609     if(hdr->edf)
5610     {
5611       fprintf(file, "32767   ");
5612     }
5613     else
5614     {
5615       fprintf(file, "8388607 ");
5616     }
5617   }
5618   for(i=0; i<edfsignals; i++)
5619   {
5620     len = strlen(hdr->edfparam[i].prefilter);
5621     edflib_latin1_to_ascii(hdr->edfparam[i].prefilter, len);
5622     for(j=0; j<len; j++)
5623     {
5624       fputc(hdr->edfparam[i].prefilter[j], file);
5625     }
5626     for(; j<80; j++)
5627     {
5628       fputc(' ', file);
5629     }
5630   }
5631   for(i=0; i<hdr->nr_annot_chns; i++)
5632   {
5633     for(j=0; j<80; j++)
5634     {
5635       fputc(' ', file);
5636     }
5637   }
5638   for(i=0; i<edfsignals; i++)
5639   {
5640     p = edflib_fprint_int_number_nonlocalized(file, hdr->edfparam[i].smp_per_record, 0, 0);
5641     for(; p<8; p++)
5642     {
5643       fputc(' ', file);
5644     }
5645   }
5646   for(j=0; j<hdr->nr_annot_chns; j++)
5647   {
5648     if(hdr->edf)
5649     {
5650       p = edflib_fprint_int_number_nonlocalized(file, EDFLIB_ANNOTATION_BYTES / 2, 0, 0);
5651       for(; p<8; p++)
5652       {
5653         fputc(' ', file);
5654       }
5655     }
5656     else
5657     {
5658       p = edflib_fprint_int_number_nonlocalized(file, EDFLIB_ANNOTATION_BYTES / 3, 0, 0);
5659       for(; p<8; p++)
5660       {
5661         fputc(' ', file);
5662       }
5663     }
5664   }
5665   for(i=0; i<(edfsignals * 32); i++)
5666   {
5667     fputc(' ', file);
5668   }
5669   for(i=0; i<(hdr->nr_annot_chns * 32); i++)
5670   {
5671     fputc(' ', file);
5672   }
5673 
5674   return 0;
5675 }
5676 
5677 
edf_set_label(int handle,int edfsignal,const char * label)5678 int edf_set_label(int handle, int edfsignal, const char *label)
5679 {
5680   if(handle<0)
5681   {
5682     return -1;
5683   }
5684 
5685   if(handle>=EDFLIB_MAXFILES)
5686   {
5687     return -1;
5688   }
5689 
5690   if(hdrlist[handle]==NULL)
5691   {
5692     return -1;
5693   }
5694 
5695   if(!(hdrlist[handle]->writemode))
5696   {
5697     return -1;
5698   }
5699 
5700   if(edfsignal<0)
5701   {
5702     return -1;
5703   }
5704 
5705   if(edfsignal>=hdrlist[handle]->edfsignals)
5706   {
5707     return -1;
5708   }
5709 
5710   if(hdrlist[handle]->datarecords)
5711   {
5712     return -1;
5713   }
5714 
5715   strncpy(hdrlist[handle]->edfparam[edfsignal].label, label, 16);
5716 
5717   hdrlist[handle]->edfparam[edfsignal].label[16] = 0;
5718 
5719   edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].label);
5720 
5721   return 0;
5722 }
5723 
5724 
edf_set_physical_dimension(int handle,int edfsignal,const char * phys_dim)5725 int edf_set_physical_dimension(int handle, int edfsignal, const char *phys_dim)
5726 {
5727   if(handle<0)
5728   {
5729     return -1;
5730   }
5731 
5732   if(handle>=EDFLIB_MAXFILES)
5733   {
5734     return -1;
5735   }
5736 
5737   if(hdrlist[handle]==NULL)
5738   {
5739     return -1;
5740   }
5741 
5742   if(!(hdrlist[handle]->writemode))
5743   {
5744     return -1;
5745   }
5746 
5747   if(edfsignal<0)
5748   {
5749     return -1;
5750   }
5751 
5752   if(edfsignal>=hdrlist[handle]->edfsignals)
5753   {
5754     return -1;
5755   }
5756 
5757   if(hdrlist[handle]->datarecords)
5758   {
5759     return -1;
5760   }
5761 
5762   strncpy(hdrlist[handle]->edfparam[edfsignal].physdimension, phys_dim, 8);
5763 
5764   hdrlist[handle]->edfparam[edfsignal].physdimension[8] = 0;
5765 
5766   edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].physdimension);
5767 
5768   return 0;
5769 }
5770 
5771 
edf_set_physical_maximum(int handle,int edfsignal,double phys_max)5772 int edf_set_physical_maximum(int handle, int edfsignal, double phys_max)
5773 {
5774   if(handle<0)
5775   {
5776     return -1;
5777   }
5778 
5779   if(handle>=EDFLIB_MAXFILES)
5780   {
5781     return -1;
5782   }
5783 
5784   if(hdrlist[handle]==NULL)
5785   {
5786     return -1;
5787   }
5788 
5789   if(!(hdrlist[handle]->writemode))
5790   {
5791     return -1;
5792   }
5793 
5794   if(edfsignal<0)
5795   {
5796     return -1;
5797   }
5798 
5799   if(edfsignal>=hdrlist[handle]->edfsignals)
5800   {
5801     return -1;
5802   }
5803 
5804   if(hdrlist[handle]->datarecords)
5805   {
5806     return -1;
5807   }
5808 
5809   hdrlist[handle]->edfparam[edfsignal].phys_max = phys_max;
5810 
5811   return 0;
5812 }
5813 
5814 
edf_set_physical_minimum(int handle,int edfsignal,double phys_min)5815 int edf_set_physical_minimum(int handle, int edfsignal, double phys_min)
5816 {
5817   if(handle<0)
5818   {
5819     return -1;
5820   }
5821 
5822   if(handle>=EDFLIB_MAXFILES)
5823   {
5824     return -1;
5825   }
5826 
5827   if(hdrlist[handle]==NULL)
5828   {
5829     return -1;
5830   }
5831 
5832   if(!(hdrlist[handle]->writemode))
5833   {
5834     return -1;
5835   }
5836 
5837   if(edfsignal<0)
5838   {
5839     return -1;
5840   }
5841 
5842   if(edfsignal>=hdrlist[handle]->edfsignals)
5843   {
5844     return -1;
5845   }
5846 
5847   if(hdrlist[handle]->datarecords)
5848   {
5849     return -1;
5850   }
5851 
5852   hdrlist[handle]->edfparam[edfsignal].phys_min = phys_min;
5853 
5854   return 0;
5855 }
5856 
5857 
edf_set_digital_maximum(int handle,int edfsignal,int dig_max)5858 int edf_set_digital_maximum(int handle, int edfsignal, int dig_max)
5859 {
5860   if(handle<0)
5861   {
5862     return -1;
5863   }
5864 
5865   if(handle>=EDFLIB_MAXFILES)
5866   {
5867     return -1;
5868   }
5869 
5870   if(hdrlist[handle]==NULL)
5871   {
5872     return -1;
5873   }
5874 
5875   if(!(hdrlist[handle]->writemode))
5876   {
5877     return -1;
5878   }
5879 
5880   if(edfsignal<0)
5881   {
5882     return -1;
5883   }
5884 
5885   if(edfsignal>=hdrlist[handle]->edfsignals)
5886   {
5887     return -1;
5888   }
5889 
5890   if(hdrlist[handle]->edf)
5891   {
5892     if(dig_max > 32767)
5893     {
5894       return -1;
5895     }
5896   }
5897   else
5898   {
5899     if(dig_max > 8388607)
5900     {
5901       return -1;
5902     }
5903   }
5904 
5905   if(hdrlist[handle]->datarecords)
5906   {
5907     return -1;
5908   }
5909 
5910   hdrlist[handle]->edfparam[edfsignal].dig_max = dig_max;
5911 
5912   return 0;
5913 }
5914 
5915 
edf_set_digital_minimum(int handle,int edfsignal,int dig_min)5916 int edf_set_digital_minimum(int handle, int edfsignal, int dig_min)
5917 {
5918   if(handle<0)
5919   {
5920     return -1;
5921   }
5922 
5923   if(handle>=EDFLIB_MAXFILES)
5924   {
5925     return -1;
5926   }
5927 
5928   if(hdrlist[handle]==NULL)
5929   {
5930     return -1;
5931   }
5932 
5933   if(!(hdrlist[handle]->writemode))
5934   {
5935     return -1;
5936   }
5937 
5938   if(edfsignal<0)
5939   {
5940     return -1;
5941   }
5942 
5943   if(edfsignal>=hdrlist[handle]->edfsignals)
5944   {
5945     return -1;
5946   }
5947 
5948   if(hdrlist[handle]->edf)
5949   {
5950     if(dig_min < (-32768))
5951     {
5952       return -1;
5953     }
5954   }
5955   else
5956   {
5957     if(dig_min < (-8388608))
5958     {
5959       return -1;
5960     }
5961   }
5962 
5963   if(hdrlist[handle]->datarecords)
5964   {
5965     return -1;
5966   }
5967 
5968   hdrlist[handle]->edfparam[edfsignal].dig_min = dig_min;
5969 
5970   return 0;
5971 }
5972 
5973 
edf_set_patientname(int handle,const char * patientname)5974 int edf_set_patientname(int handle, const char *patientname)
5975 {
5976   if(handle<0)
5977   {
5978     return -1;
5979   }
5980 
5981   if(handle>=EDFLIB_MAXFILES)
5982   {
5983     return -1;
5984   }
5985 
5986   if(hdrlist[handle]==NULL)
5987   {
5988     return -1;
5989   }
5990 
5991   if(!(hdrlist[handle]->writemode))
5992   {
5993     return -1;
5994   }
5995 
5996   if(hdrlist[handle]->datarecords)
5997   {
5998     return -1;
5999   }
6000 
6001   strncpy(hdrlist[handle]->plus_patient_name, patientname, 80);
6002 
6003   hdrlist[handle]->plus_patient_name[80] = 0;
6004 
6005   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patient_name);
6006 
6007   return 0;
6008 }
6009 
6010 
edf_set_patientcode(int handle,const char * patientcode)6011 int edf_set_patientcode(int handle, const char *patientcode)
6012 {
6013   if(handle<0)
6014   {
6015     return -1;
6016   }
6017 
6018   if(handle>=EDFLIB_MAXFILES)
6019   {
6020     return -1;
6021   }
6022 
6023   if(hdrlist[handle]==NULL)
6024   {
6025     return -1;
6026   }
6027 
6028   if(!(hdrlist[handle]->writemode))
6029   {
6030     return -1;
6031   }
6032 
6033   if(hdrlist[handle]->datarecords)
6034   {
6035     return -1;
6036   }
6037 
6038   strncpy(hdrlist[handle]->plus_patientcode, patientcode, 80);
6039 
6040   hdrlist[handle]->plus_patientcode[80] = 0;
6041 
6042   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patientcode);
6043 
6044   return 0;
6045 }
6046 
6047 
edf_set_gender(int handle,int gender)6048 int edf_set_gender(int handle, int gender)
6049 {
6050   if(handle<0)
6051   {
6052     return -1;
6053   }
6054 
6055   if(handle>=EDFLIB_MAXFILES)
6056   {
6057     return -1;
6058   }
6059 
6060   if(hdrlist[handle]==NULL)
6061   {
6062     return -1;
6063   }
6064 
6065   if(!(hdrlist[handle]->writemode))
6066   {
6067     return -1;
6068   }
6069 
6070   if(hdrlist[handle]->datarecords)
6071   {
6072     return -1;
6073   }
6074 
6075   if((gender<0)||(gender>1))
6076   {
6077     return -1;
6078   }
6079 
6080   if(gender)
6081   {
6082     hdrlist[handle]->plus_gender[0] = 'M';
6083   }
6084   else
6085   {
6086     hdrlist[handle]->plus_gender[0] = 'F';
6087   }
6088 
6089   hdrlist[handle]->plus_gender[1] = 0;
6090 
6091   return 0;
6092 }
6093 
6094 
edf_set_birthdate(int handle,int birthdate_year,int birthdate_month,int birthdate_day)6095 int edf_set_birthdate(int handle, int birthdate_year, int birthdate_month, int birthdate_day)
6096 {
6097   if(handle<0)
6098   {
6099     return -1;
6100   }
6101 
6102   if(handle>=EDFLIB_MAXFILES)
6103   {
6104     return -1;
6105   }
6106 
6107   if(hdrlist[handle]==NULL)
6108   {
6109     return -1;
6110   }
6111 
6112   if(!(hdrlist[handle]->writemode))
6113   {
6114     return -1;
6115   }
6116 
6117   if(hdrlist[handle]->datarecords)
6118   {
6119     return -1;
6120   }
6121 
6122   if((birthdate_year<1800) || (birthdate_year>3000) ||
6123      (birthdate_month<1)   || (birthdate_month>12)  ||
6124      (birthdate_day<1)     || (birthdate_day>31))
6125   {
6126     return -1;
6127   }
6128 
6129   sprintf(hdrlist[handle]->plus_birthdate, "%02i.%02i.%02i%02i", birthdate_day, birthdate_month, birthdate_year / 100, birthdate_year % 100);
6130 
6131   hdrlist[handle]->plus_birthdate[10] = 0;
6132 
6133   return 0;
6134 }
6135 
6136 
edf_set_patient_additional(int handle,const char * patient_additional)6137 int edf_set_patient_additional(int handle, const char *patient_additional)
6138 {
6139   if(handle<0)
6140   {
6141     return -1;
6142   }
6143 
6144   if(handle>=EDFLIB_MAXFILES)
6145   {
6146     return -1;
6147   }
6148 
6149   if(hdrlist[handle]==NULL)
6150   {
6151     return -1;
6152   }
6153 
6154   if(!(hdrlist[handle]->writemode))
6155   {
6156     return -1;
6157   }
6158 
6159   if(hdrlist[handle]->datarecords)
6160   {
6161     return -1;
6162   }
6163 
6164   strncpy(hdrlist[handle]->plus_patient_additional, patient_additional, 80);
6165 
6166   hdrlist[handle]->plus_patient_additional[80] = 0;
6167 
6168   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patient_additional);
6169 
6170   return 0;
6171 }
6172 
6173 
edf_set_admincode(int handle,const char * admincode)6174 int edf_set_admincode(int handle, const char *admincode)
6175 {
6176   if(handle<0)
6177   {
6178     return -1;
6179   }
6180 
6181   if(handle>=EDFLIB_MAXFILES)
6182   {
6183     return -1;
6184   }
6185 
6186   if(hdrlist[handle]==NULL)
6187   {
6188     return -1;
6189   }
6190 
6191   if(!(hdrlist[handle]->writemode))
6192   {
6193     return -1;
6194   }
6195 
6196   if(hdrlist[handle]->datarecords)
6197   {
6198     return -1;
6199   }
6200 
6201   strncpy(hdrlist[handle]->plus_admincode, admincode, 80);
6202 
6203   hdrlist[handle]->plus_admincode[80] = 0;
6204 
6205   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_admincode);
6206 
6207   return 0;
6208 }
6209 
6210 
edf_set_technician(int handle,const char * technician)6211 int edf_set_technician(int handle, const char *technician)
6212 {
6213   if(handle<0)
6214   {
6215     return -1;
6216   }
6217 
6218   if(handle>=EDFLIB_MAXFILES)
6219   {
6220     return -1;
6221   }
6222 
6223   if(hdrlist[handle]==NULL)
6224   {
6225     return -1;
6226   }
6227 
6228   if(!(hdrlist[handle]->writemode))
6229   {
6230     return -1;
6231   }
6232 
6233   if(hdrlist[handle]->datarecords)
6234   {
6235     return -1;
6236   }
6237 
6238   strncpy(hdrlist[handle]->plus_technician, technician, 80);
6239 
6240   hdrlist[handle]->plus_technician[80] = 0;
6241 
6242   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_technician);
6243 
6244   return 0;
6245 }
6246 
6247 
edf_set_equipment(int handle,const char * equipment)6248 int edf_set_equipment(int handle, const char *equipment)
6249 {
6250   if(handle<0)
6251   {
6252     return -1;
6253   }
6254 
6255   if(handle>=EDFLIB_MAXFILES)
6256   {
6257     return -1;
6258   }
6259 
6260   if(hdrlist[handle]==NULL)
6261   {
6262     return -1;
6263   }
6264 
6265   if(!(hdrlist[handle]->writemode))
6266   {
6267     return -1;
6268   }
6269 
6270   if(hdrlist[handle]->datarecords)
6271   {
6272     return -1;
6273   }
6274 
6275   strncpy(hdrlist[handle]->plus_equipment, equipment, 80);
6276 
6277   hdrlist[handle]->plus_equipment[80] = 0;
6278 
6279   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_equipment);
6280 
6281   return 0;
6282 }
6283 
6284 
edf_set_recording_additional(int handle,const char * recording_additional)6285 int edf_set_recording_additional(int handle, const char *recording_additional)
6286 {
6287   if(handle<0)
6288   {
6289     return -1;
6290   }
6291 
6292   if(handle>=EDFLIB_MAXFILES)
6293   {
6294     return -1;
6295   }
6296 
6297   if(hdrlist[handle]==NULL)
6298   {
6299     return -1;
6300   }
6301 
6302   if(!(hdrlist[handle]->writemode))
6303   {
6304     return -1;
6305   }
6306 
6307   if(hdrlist[handle]->datarecords)
6308   {
6309     return -1;
6310   }
6311 
6312   strncpy(hdrlist[handle]->plus_recording_additional, recording_additional, 80);
6313 
6314   hdrlist[handle]->plus_recording_additional[80] = 0;
6315 
6316   edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_recording_additional);
6317 
6318   return 0;
6319 }
6320 
6321 
edf_set_startdatetime(int handle,int startdate_year,int startdate_month,int startdate_day,int starttime_hour,int starttime_minute,int starttime_second)6322 int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, int startdate_day,
6323                                       int starttime_hour, int starttime_minute, int starttime_second)
6324 {
6325   if(handle<0)
6326   {
6327     return -1;
6328   }
6329 
6330   if(handle>=EDFLIB_MAXFILES)
6331   {
6332     return -1;
6333   }
6334 
6335   if(hdrlist[handle]==NULL)
6336   {
6337     return -1;
6338   }
6339 
6340   if(!(hdrlist[handle]->writemode))
6341   {
6342     return -1;
6343   }
6344 
6345   if(hdrlist[handle]->datarecords)
6346   {
6347     return -1;
6348   }
6349 
6350   if((startdate_year<1985) || (startdate_year>2084) ||
6351      (startdate_month<1)   || (startdate_month>12)  ||
6352      (startdate_day<1)     || (startdate_day>31)    ||
6353      (starttime_hour<0)    || (starttime_hour>23)   ||
6354      (starttime_minute<0)  || (starttime_minute>59) ||
6355      (starttime_second<0)  || (starttime_second>59))
6356   {
6357     return -1;
6358   }
6359 
6360   hdrlist[handle]->startdate_year = startdate_year;
6361   hdrlist[handle]->startdate_month = startdate_month;
6362   hdrlist[handle]->startdate_day = startdate_day;
6363   hdrlist[handle]->starttime_hour = starttime_hour;
6364   hdrlist[handle]->starttime_minute = starttime_minute;
6365   hdrlist[handle]->starttime_second = starttime_second;
6366 
6367   return 0;
6368 }
6369 
6370 
edfwrite_annotation_utf8(int handle,long long onset,long long duration,const char * description)6371 int edfwrite_annotation_utf8(int handle, long long onset, long long duration, const char *description)
6372 {
6373   int i;
6374 
6375   struct edf_write_annotationblock *list_annot, *malloc_list;
6376 
6377 
6378   if(handle<0)
6379   {
6380     return -1;
6381   }
6382 
6383   if(handle>=EDFLIB_MAXFILES)
6384   {
6385     return -1;
6386   }
6387 
6388   if(hdrlist[handle]==NULL)
6389   {
6390     return -1;
6391   }
6392 
6393   if(!(hdrlist[handle]->writemode))
6394   {
6395     return -1;
6396   }
6397 
6398   if(onset<0LL)
6399   {
6400     return -1;
6401   }
6402 
6403   if(hdrlist[handle]->annots_in_file >= hdrlist[handle]->annotlist_sz)
6404   {
6405     malloc_list = (struct edf_write_annotationblock *)realloc(write_annotationslist[handle],
6406                                                               sizeof(struct edf_write_annotationblock) * (hdrlist[handle]->annotlist_sz + EDFLIB_ANNOT_MEMBLOCKSZ));
6407     if(malloc_list==NULL)
6408     {
6409       return -1;
6410     }
6411 
6412     write_annotationslist[handle] = malloc_list;
6413 
6414     hdrlist[handle]->annotlist_sz += EDFLIB_ANNOT_MEMBLOCKSZ;
6415   }
6416 
6417   list_annot = write_annotationslist[handle] + hdrlist[handle]->annots_in_file;
6418 
6419   list_annot->onset = onset;
6420   list_annot->duration = duration;
6421   strncpy(list_annot->annotation, description, EDFLIB_WRITE_MAX_ANNOTATION_LEN);
6422   list_annot->annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0;
6423 
6424   for(i=0; ; i++)
6425   {
6426     if(list_annot->annotation[i] == 0)
6427     {
6428       break;
6429     }
6430 
6431     if(((unsigned char *)(list_annot->annotation))[i] < 32)
6432     {
6433       list_annot->annotation[i] = '.';
6434     }
6435   }
6436 
6437   hdrlist[handle]->annots_in_file++;
6438 
6439   return 0;
6440 }
6441 
6442 
edfwrite_annotation_latin1(int handle,long long onset,long long duration,const char * description)6443 int edfwrite_annotation_latin1(int handle, long long onset, long long duration, const char *description)
6444 {
6445   struct edf_write_annotationblock *list_annot, *malloc_list;
6446 
6447   char str[EDFLIB_WRITE_MAX_ANNOTATION_LEN + 1];
6448 
6449 
6450   if(handle<0)
6451   {
6452     return -1;
6453   }
6454 
6455   if(handle>=EDFLIB_MAXFILES)
6456   {
6457     return -1;
6458   }
6459 
6460   if(hdrlist[handle]==NULL)
6461   {
6462     return -1;
6463   }
6464 
6465   if(!(hdrlist[handle]->writemode))
6466   {
6467     return -1;
6468   }
6469 
6470   if(onset<0LL)
6471   {
6472     return -1;
6473   }
6474 
6475   if(hdrlist[handle]->annots_in_file >= hdrlist[handle]->annotlist_sz)
6476   {
6477     malloc_list = (struct edf_write_annotationblock *)realloc(write_annotationslist[handle],
6478                                                               sizeof(struct edf_write_annotationblock) * (hdrlist[handle]->annotlist_sz + EDFLIB_ANNOT_MEMBLOCKSZ));
6479     if(malloc_list==NULL)
6480     {
6481       return -1;
6482     }
6483 
6484     write_annotationslist[handle] = malloc_list;
6485 
6486     hdrlist[handle]->annotlist_sz += EDFLIB_ANNOT_MEMBLOCKSZ;
6487   }
6488 
6489   list_annot = write_annotationslist[handle] + hdrlist[handle]->annots_in_file;
6490 
6491   list_annot->onset = onset;
6492   list_annot->duration = duration;
6493   strncpy(str, description, EDFLIB_WRITE_MAX_ANNOTATION_LEN);
6494   str[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0;
6495   edflib_latin12utf8(str, strlen(str));
6496   strncpy(list_annot->annotation, str, EDFLIB_WRITE_MAX_ANNOTATION_LEN);
6497   list_annot->annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0;
6498 
6499   hdrlist[handle]->annots_in_file++;
6500 
6501   return 0;
6502 }
6503 
6504 
edflib_remove_padding_trailing_spaces(char * str)6505 static void edflib_remove_padding_trailing_spaces(char *str)
6506 {
6507   int i;
6508 
6509   while(str[0]==' ')
6510   {
6511     for(i=0; ; i++)
6512     {
6513       if(str[i]==0)
6514       {
6515         break;
6516       }
6517 
6518       str[i] = str[i+1];
6519     }
6520   }
6521 
6522   for(i = strlen(str); i>0; i--)
6523   {
6524     if(str[i-1]==' ')
6525     {
6526       str[i-1] = 0;
6527     }
6528     else
6529     {
6530       break;
6531     }
6532   }
6533 }
6534 
6535 
edf_set_prefilter(int handle,int edfsignal,const char * prefilter)6536 int edf_set_prefilter(int handle, int edfsignal, const char *prefilter)
6537 {
6538   if(handle<0)
6539   {
6540     return -1;
6541   }
6542 
6543   if(handle>=EDFLIB_MAXFILES)
6544   {
6545     return -1;
6546   }
6547 
6548   if(hdrlist[handle]==NULL)
6549   {
6550     return -1;
6551   }
6552 
6553   if(!(hdrlist[handle]->writemode))
6554   {
6555     return -1;
6556   }
6557 
6558   if(edfsignal<0)
6559   {
6560     return -1;
6561   }
6562 
6563   if(edfsignal>=hdrlist[handle]->edfsignals)
6564   {
6565     return -1;
6566   }
6567 
6568   if(hdrlist[handle]->datarecords)
6569   {
6570     return -1;
6571   }
6572 
6573   strncpy(hdrlist[handle]->edfparam[edfsignal].prefilter, prefilter, 80);
6574 
6575   hdrlist[handle]->edfparam[edfsignal].prefilter[80] = 0;
6576 
6577   edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].prefilter);
6578 
6579   return 0;
6580 }
6581 
6582 
edf_set_transducer(int handle,int edfsignal,const char * transducer)6583 int edf_set_transducer(int handle, int edfsignal, const char *transducer)
6584 {
6585   if(handle<0)
6586   {
6587     return -1;
6588   }
6589 
6590   if(handle>=EDFLIB_MAXFILES)
6591   {
6592     return -1;
6593   }
6594 
6595   if(hdrlist[handle]==NULL)
6596   {
6597     return -1;
6598   }
6599 
6600   if(!(hdrlist[handle]->writemode))
6601   {
6602     return -1;
6603   }
6604 
6605   if(edfsignal<0)
6606   {
6607     return -1;
6608   }
6609 
6610   if(edfsignal>=hdrlist[handle]->edfsignals)
6611   {
6612     return -1;
6613   }
6614 
6615   if(hdrlist[handle]->datarecords)
6616   {
6617     return -1;
6618   }
6619 
6620   strncpy(hdrlist[handle]->edfparam[edfsignal].transducer, transducer, 80);
6621 
6622   hdrlist[handle]->edfparam[edfsignal].transducer[80] = 0;
6623 
6624   edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].transducer);
6625 
6626   return 0;
6627 }
6628 
6629 
6630 /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */
6631 /* if sign is zero, only negative numbers will have the sign '-' character */
6632 /* if sign is one, the sign '+' or '-' character will always be printed */
6633 /* returns the amount of characters printed */
edflib_fprint_int_number_nonlocalized(FILE * file,int q,int minimum,int sign)6634 static int edflib_fprint_int_number_nonlocalized(FILE *file, int q, int minimum, int sign)
6635 {
6636   int flag=0, z, i, j=0, base = 1000000000;
6637 
6638   if(minimum < 0)
6639   {
6640     minimum = 0;
6641   }
6642 
6643   if(minimum > 9)
6644   {
6645     flag = 1;
6646   }
6647 
6648   if(q < 0)
6649   {
6650     fputc('-', file);
6651 
6652     j++;
6653 
6654     base = -base;
6655   }
6656   else
6657   {
6658     if(sign)
6659     {
6660       fputc('+', file);
6661 
6662       j++;
6663     }
6664   }
6665 
6666   for(i=10; i; i--)
6667   {
6668     if(minimum == i)
6669     {
6670       flag = 1;
6671     }
6672 
6673     z = q / base;
6674 
6675     q %= base;
6676 
6677     if(z || flag)
6678     {
6679       fputc('0' + z, file);
6680 
6681       j++;
6682 
6683       flag = 1;
6684     }
6685 
6686     base /= 10;
6687   }
6688 
6689   if(!flag)
6690   {
6691     fputc('0', file);
6692 
6693     j++;
6694   }
6695 
6696   return j;
6697 }
6698 
6699 
6700 /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */
6701 /* if sign is zero, only negative numbers will have the sign '-' character */
6702 /* if sign is one, the sign '+' or '-' character will always be printed */
6703 /* returns the amount of characters printed */
edflib_fprint_ll_number_nonlocalized(FILE * file,long long q,int minimum,int sign)6704 static int edflib_fprint_ll_number_nonlocalized(FILE *file, long long q, int minimum, int sign)
6705 {
6706   int flag=0, z, i, j=0;
6707 
6708   long long base = 1000000000000000000LL;
6709 
6710   if(minimum < 0)
6711   {
6712     minimum = 0;
6713   }
6714 
6715   if(minimum > 18)
6716   {
6717     flag = 1;
6718   }
6719 
6720   if(q < 0LL)
6721   {
6722     fputc('-', file);
6723 
6724     j++;
6725 
6726     base = -base;
6727   }
6728   else
6729   {
6730     if(sign)
6731     {
6732       fputc('+', file);
6733 
6734       j++;
6735     }
6736   }
6737 
6738   for(i=19; i; i--)
6739   {
6740     if(minimum == i)
6741     {
6742       flag = 1;
6743     }
6744 
6745     z = q / base;
6746 
6747     q %= base;
6748 
6749     if(z || flag)
6750     {
6751       fputc('0' + z, file);
6752 
6753       j++;
6754 
6755       flag = 1;
6756     }
6757 
6758     base /= 10LL;
6759   }
6760 
6761   if(!flag)
6762   {
6763     fputc('0', file);
6764 
6765     j++;
6766   }
6767 
6768   return j;
6769 }
6770 
6771 
6772 /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */
6773 /* if sign is zero, only negative numbers will have the sign '-' character */
6774 /* if sign is one, the sign '+' or '-' character will always be printed */
6775 /* returns the amount of characters printed */
6776 /*
6777 static int edflib_sprint_int_number_nonlocalized(char *str, int q, int minimum, int sign)
6778 {
6779   int flag=0, z, i, j=0, base = 1000000000;
6780 
6781   if(minimum < 0)
6782   {
6783     minimum = 0;
6784   }
6785 
6786   if(minimum > 9)
6787   {
6788     flag = 1;
6789   }
6790 
6791   if(q < 0)
6792   {
6793     str[j++] = '-';
6794 
6795     q = -q;
6796   }
6797   else
6798   {
6799     if(sign)
6800     {
6801       str[j++] = '+';
6802     }
6803   }
6804 
6805   for(i=10; i; i--)
6806   {
6807     if(minimum == i)
6808     {
6809       flag = 1;
6810     }
6811 
6812     z = q / base;
6813 
6814     q %= base;
6815 
6816     if(z || flag)
6817     {
6818       str[j++] = '0' + z;
6819 
6820       flag = 1;
6821     }
6822 
6823     base /= 10;
6824   }
6825 
6826   if(!flag)
6827   {
6828     str[j++] = '0';
6829   }
6830 
6831   str[j] = 0;
6832 
6833   return j;
6834 }
6835 */
6836 
6837 /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */
6838 /* if sign is zero, only negative numbers will have the sign '-' character */
6839 /* if sign is one, the sign '+' or '-' character will always be printed */
6840 /* returns the amount of characters printed */
edflib_snprint_ll_number_nonlocalized(char * dest,long long q,int minimum,int sign,int sz)6841 static int edflib_snprint_ll_number_nonlocalized(char *dest, long long q, int minimum, int sign, int sz)
6842 {
6843   int flag=0, z, i, j=0;
6844 
6845   long long base = 1000000000000000000LL;
6846 
6847   if(sz < 1)
6848   {
6849     return 0;
6850   }
6851 
6852   if(minimum < 0)
6853   {
6854     minimum = 0;
6855   }
6856 
6857   if(minimum > 18)
6858   {
6859     flag = 1;
6860   }
6861 
6862   if(q < 0LL)
6863   {
6864     dest[j++] = '-';
6865 
6866     base = -base;
6867   }
6868   else
6869   {
6870     if(sign)
6871     {
6872       dest[j++] = '+';
6873     }
6874   }
6875 
6876   if(j == sz)
6877   {
6878     dest[--j] = 0;
6879 
6880     return j;
6881   }
6882 
6883   for(i=19; i; i--)
6884   {
6885     if(minimum == i)
6886     {
6887       flag = 1;
6888     }
6889 
6890     z = q / base;
6891 
6892     q %= base;
6893 
6894     if(z || flag)
6895     {
6896       dest[j++] = '0' + z;
6897 
6898       if(j == sz)
6899       {
6900         dest[--j] = 0;
6901 
6902         return j;
6903       }
6904 
6905       flag = 1;
6906     }
6907 
6908     base /= 10LL;
6909   }
6910 
6911   if(!flag)
6912   {
6913     dest[j++] = '0';
6914   }
6915 
6916   if(j == sz)
6917   {
6918     dest[--j] = 0;
6919 
6920     return j;
6921   }
6922 
6923   dest[j] = 0;
6924 
6925   return j;
6926 }
6927 
6928 
edflib_snprint_number_nonlocalized(char * dest,double val,int sz)6929 static int edflib_snprint_number_nonlocalized(char *dest, double val, int sz)
6930 {
6931   int flag=0, z, i, j=0, q, base = 1000000000;
6932 
6933   double var;
6934 
6935   if(sz < 1)  return 0;
6936 
6937   q = (int)val;
6938 
6939   var = val - q;
6940 
6941   if(val < 0.0)
6942   {
6943     dest[j++] = '-';
6944 
6945     if(q < 0)
6946     {
6947       base = -base;
6948     }
6949   }
6950 
6951   if(j == sz)
6952   {
6953     dest[--j] = 0;
6954 
6955     return j;
6956   }
6957 
6958   for(i=10; i; i--)
6959   {
6960     z = q / base;
6961 
6962     q %= base;
6963 
6964     if(z || flag)
6965     {
6966       dest[j++] = '0' + z;
6967 
6968       if(j == sz)
6969       {
6970         dest[--j] = 0;
6971 
6972         return j;
6973       }
6974 
6975       flag = 1;
6976     }
6977 
6978     base /= 10;
6979   }
6980 
6981   if(!flag)
6982   {
6983     dest[j++] = '0';
6984   }
6985 
6986   if(j == sz)
6987   {
6988     dest[--j] = 0;
6989 
6990     return j;
6991   }
6992 
6993   base = 100000000;
6994 
6995   var *= (base * 10);
6996 
6997   q = (int)var;
6998 
6999   if(q < 0)
7000   {
7001     base = -base;
7002   }
7003 
7004   if(!q)
7005   {
7006     dest[j] = 0;
7007 
7008     return j;
7009   }
7010 
7011   dest[j++] = '.';
7012 
7013   if(j == sz)
7014   {
7015     dest[--j] = 0;
7016 
7017     return j;
7018   }
7019 
7020   for(i=9; i; i--)
7021   {
7022     z = q / base;
7023 
7024     q %= base;
7025 
7026     dest[j++] = '0' + z;
7027 
7028     if(j == sz)
7029     {
7030       dest[--j] = 0;
7031 
7032       return j;
7033     }
7034 
7035     base /= 10;
7036   }
7037 
7038   dest[j] = 0;
7039 
7040   j--;
7041 
7042   for(; j>0; j--)
7043   {
7044     if(dest[j] == '0')
7045     {
7046       dest[j] = 0;
7047     }
7048     else
7049     {
7050       j++;
7051 
7052       break;
7053     }
7054   }
7055 
7056   return j;
7057 }
7058 
7059 
edflib_atof_nonlocalized(const char * str)7060 static double edflib_atof_nonlocalized(const char *str)
7061 {
7062   int i=0, j, dot_pos=-1, decimals=0, sign=1, exp_pos=-1, exp_sign=1, exp_val=0;
7063 
7064   double value, value2=0.0;
7065 
7066 
7067   value = edflib_atoi_nonlocalized(str);
7068 
7069   while(str[i] == ' ')
7070   {
7071     i++;
7072   }
7073 
7074   if((str[i] == '+') || (str[i] == '-'))
7075   {
7076     if(str[i] == '-')
7077     {
7078       sign = -1;
7079     }
7080 
7081     i++;
7082   }
7083 
7084   for(; ; i++)
7085   {
7086     if(str[i] == 0)
7087     {
7088       break;
7089     }
7090 
7091     if((str[i] == 'e') || (str[i] == 'E'))
7092     {
7093       exp_pos = i;
7094 
7095       break;
7096     }
7097 
7098     if(((str[i] < '0') || (str[i] > '9')) && (str[i] != '.'))
7099     {
7100       break;
7101     }
7102 
7103     if(dot_pos >= 0)
7104     {
7105       if((str[i] >= '0') && (str[i] <= '9'))
7106       {
7107         decimals++;
7108       }
7109       else
7110       {
7111         break;
7112       }
7113     }
7114 
7115     if(str[i] == '.')
7116     {
7117       if(dot_pos < 0)
7118       {
7119         dot_pos = i;
7120       }
7121     }
7122   }
7123 
7124   if(decimals)
7125   {
7126     value2 = edflib_atoi_nonlocalized(str + dot_pos + 1) * sign;
7127 
7128     i = 1;
7129 
7130     while(decimals--)
7131     {
7132       i *= 10;
7133     }
7134 
7135     value2 /= i;
7136 
7137     value += value2;
7138   }
7139 
7140   if(exp_pos > 0)
7141   {
7142     i = exp_pos + 1;
7143 
7144     if(str[i])
7145     {
7146       if(str[i] == '+')
7147       {
7148         i++;
7149       }
7150       else if(str[i] == '-')
7151         {
7152           exp_sign = -1;
7153 
7154           i++;
7155         }
7156 
7157       if(str[i])
7158       {
7159         exp_val = edflib_atoi_nonlocalized(str + i);
7160 
7161         if(exp_val > 0)
7162         {
7163           for(j=0; j<exp_val; j++)
7164           {
7165             if(exp_sign > 0)
7166             {
7167               value *= 10;
7168             }
7169             else
7170             {
7171               value /= 10;
7172             }
7173           }
7174         }
7175       }
7176     }
7177   }
7178 
7179   return value;
7180 }
7181 
7182 
edflib_atoi_nonlocalized(const char * str)7183 static int edflib_atoi_nonlocalized(const char *str)
7184 {
7185   int i=0, value=0, sign=1;
7186 
7187   while(str[i] == ' ')
7188   {
7189     i++;
7190   }
7191 
7192   if((str[i] == '+') || (str[i] == '-'))
7193   {
7194     if(str[i] == '-')
7195     {
7196       sign = -1;
7197     }
7198 
7199     i++;
7200   }
7201 
7202   for( ; ; i++)
7203   {
7204     if(str[i] == 0)
7205     {
7206       break;
7207     }
7208 
7209     if((str[i] < '0') || (str[i] > '9'))
7210     {
7211       break;
7212     }
7213 
7214     value *= 10;
7215 
7216     value += ((str[i] - '0') * sign);
7217   }
7218 
7219   return value;
7220 }
7221 
7222 
edflib_write_tal(struct edfhdrblock * hdr,FILE * file)7223 static int edflib_write_tal(struct edfhdrblock *hdr, FILE *file)
7224 {
7225   int p;
7226 
7227   char str[EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1)];
7228 
7229   p = edflib_snprint_ll_number_nonlocalized(str, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1));
7230   if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
7231   {
7232     str[p++] = '.';
7233     p += edflib_snprint_ll_number_nonlocalized(str + p, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1)) - p);
7234   }
7235   str[p++] = 20;
7236   str[p++] = 20;
7237   for(; p<hdr->total_annot_bytes; p++)
7238   {
7239     str[p] = 0;
7240   }
7241 
7242   if(fwrite(str, hdr->total_annot_bytes, 1, file) != 1)
7243   {
7244     return -1;
7245   }
7246 
7247   return 0;
7248 }
7249 
7250 
edflib_strlcpy(char * dst,const char * src,int sz)7251 static int edflib_strlcpy(char *dst, const char *src, int sz)
7252 {
7253   int srclen;
7254 
7255   sz--;
7256 
7257   srclen = strlen(src);
7258 
7259   if(srclen > sz)  srclen = sz;
7260 
7261   memcpy(dst, src, srclen);
7262 
7263   dst[srclen] = 0;
7264 
7265   return srclen;
7266 }
7267 
7268 
edflib_strlcat(char * dst,const char * src,int sz)7269 static int edflib_strlcat(char *dst, const char *src, int sz)
7270 {
7271   int srclen,
7272       dstlen;
7273 
7274   dstlen = strlen(dst);
7275 
7276   sz -= dstlen + 1;
7277 
7278   if(!sz)  return dstlen;
7279 
7280   srclen = strlen(src);
7281 
7282   if(srclen > sz)  srclen = sz;
7283 
7284   memcpy(dst + dstlen, src, srclen);
7285 
7286   dst[dstlen + srclen] = 0;
7287 
7288   return (dstlen + srclen);
7289 }
7290 
7291 
7292 
7293 
7294 
7295 
7296 
7297 
7298 
7299 
7300 
7301 
7302 
7303 
7304 
7305 
7306 
7307 
7308 
7309 
7310 
7311 
7312 
7313 
7314 
7315 
7316 
7317