📄 sopen_scp_write.c
字号:
/* $Id: sopen_scp_write.c,v 1.32 2008/03/14 08:30:43 schloegl Exp $ Copyright (C) 2005,2006,2007 Alois Schloegl <a.schloegl@ieee.org> This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "../biosig-dev.h"int sopen_SCP_write(HDRTYPE* hdr) { /* this function is a stub or placeholder and need to be defined in order to be useful. It will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h"*/ uint8_t* ptr; // pointer to memory mapping of the file layout uint8_t* PtrCurSect; // point to current section int curSect; uint32_t len; uint16_t crc; uint32_t i; uint32_t sectionStart; time_t T0; tm* T0_tm; double AVM, avm; aECG_TYPE* aECG; if ((fabs(hdr->VERSION - 1.3)<0.01) && (fabs(hdr->VERSION-2.0)<0.01)) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Version %f not supported\n",hdr->VERSION); uint8_t VERSION = 20; // (uint8_t)round(hdr->VERSION*10); // implemented version number if (hdr->aECG==NULL) { fprintf(stderr,"Warning SOPEN_SCP_WRITE: No aECG info defined\n"); hdr->aECG = malloc(sizeof(aECG_TYPE)); aECG = (aECG_TYPE*)hdr->aECG; aECG->diastolicBloodPressure=0.0; aECG->systolicBloodPressure=0.0; aECG->MedicationDrugs="/0"; aECG->ReferringPhysician="/0"; aECG->LatestConfirmingPhysician="/0"; aECG->Diagnosis="/0"; aECG->EmergencyLevel=0; hdr->ID.Technician = "nobody"; } else aECG = (aECG_TYPE*)hdr->aECG;//fprintf(stdout,"SCP-Write: IIb %s\n",hdr->aECG->ReferringPhysician); /* predefined values */ aECG->Section1.Tag14.INST_NUMBER = 0; // tag 14, byte 1-2 aECG->Section1.Tag14.DEPT_NUMBER = 0; // tag 14, byte 3-4 aECG->Section1.Tag14.DEVICE_ID = 0; // tag 14, byte 5-6 aECG->Section1.Tag14.DEVICE_TYPE = 0; // tag 14, byte 7: 0: Cart, 1: System (or Host) aECG->Section1.Tag14.MANUF_CODE = 255; // tag 14, byte 8 (MANUF_CODE has to be 255) aECG->Section1.Tag14.MOD_DESC = "Cart1"; // tag 14, byte 9 (MOD_DESC has to be "Cart1") aECG->Section1.Tag14.VERSION = VERSION; // tag 14, byte 15 (VERSION * 10) aECG->Section1.Tag14.PROT_COMP_LEVEL = 0xA0; // tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) aECG->Section1.Tag14.LANG_SUPP_CODE = 0x00; // tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) aECG->Section1.Tag14.ECG_CAP_DEV = 0xD0; // tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) aECG->Section1.Tag14.MAINS_FREQ = 0; // tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) aECG->Section1.Tag14.ANAL_PROG_REV_NUM = ""; aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV = ""; aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID = ""; aECG->Section1.Tag14.ACQ_DEV_SCP_SW = "OpenECG XML-SCP 1.00"; // tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") aECG->Section1.Tag14.ACQ_DEV_MANUF = "Manufacturer"; // tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") aECG->Section5.Length = 0; aECG->Section6.Length = 0; /* */ aECG->FLAG.HUFFMAN = 0; aECG->FLAG.REF_BEAT= 0; aECG->FLAG.DIFF = 0; aECG->FLAG.BIMODAL = 0; ptr = (uint8_t*)hdr->AS.Header; int NSections = 12; // initialize section 0 sectionStart = 6+16+NSections*10; ptr = (uint8_t*)realloc(ptr,sectionStart); memset(ptr,0,sectionStart); uint32_t curSectLen = 0; // current section length for (curSect=NSections-1; curSect>=0; curSect--) { curSectLen = 0; // current section length //ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); // fprintf(stdout,"Section %i %x\n",curSect,ptr); if (curSect==0) // SECTION 0 { hdr->HeadLen = sectionStart; // length of all other blocks together ptr = (uint8_t*)realloc(ptr,hdr->HeadLen); // total file length curSectLen = 16; // current section length sectionStart = 6; memcpy(ptr+16,"SCPECG",6); // reserved curSectLen += NSections*10; } else if (curSect==1) // SECTION 1 { ptr = (uint8_t*)realloc(ptr,sectionStart+10000); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Tag 0 (max len = 64) if (!hdr->FLAG.ANONYMOUS && (hdr->Patient.Name != NULL)) { *(ptr+sectionStart+curSectLen) = 0; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; } // Tag 1 (max len = 64) Firstname /* *(ptr+sectionStart+curSectLen) = 1; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; */ // Tag 2 (max len = 64) Patient ID // if (hdr->Patient.Id != NULL) { if (strlen(hdr->Patient.Id)>0) { *(ptr+sectionStart+curSectLen) = 2; // tag len = strlen(hdr->Patient.Id) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Id,len); // field curSectLen += len+3; } // fprintf(stdout,"Section %i Len %i %x\n",curSect,curSectLen,sectionStart); // Tag 3 (max len = 64) Second Last Name /* *(ptr+sectionStart+curSectLen) = 3; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy(ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; */ // Tag 5 (len = 4) if ((hdr->Patient.Birthday) > 0) { T0 = gdf_time2t_time(hdr->Patient.Birthday); T0_tm = gmtime(&T0); *(ptr+sectionStart+curSectLen) = 5; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(4); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(T0_tm->tm_year+1900);// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1); // month *(ptr+sectionStart+curSectLen+6) = (uint8_t)(T0_tm->tm_mday); // day curSectLen += 7; } // Tag 6 (len = 3) Height if (hdr->Patient.Height>0.0) { *(ptr+sectionStart+curSectLen) = 6; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(hdr->Patient.Height); // value *(ptr+sectionStart+curSectLen+5) = 1; // cm curSectLen += 6; } // Tag 7 (len = 3) Weight if (hdr->Patient.Weight>0.0) { *(ptr+sectionStart+curSectLen) = 7; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(hdr->Patient.Weight); // value *(ptr+sectionStart+curSectLen+5) = 1; // kg curSectLen += 6; } // Tag 8 (len = 1) if (hdr->Patient.Sex != 0) { *(ptr+sectionStart+curSectLen) = 8; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = hdr->Patient.Sex; // value curSectLen += 4; } // Tag 11 (len = 2) if (aECG->diastolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 11; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)aECG->diastolicBloodPressure); // value curSectLen += 5; }; // Tag 12 (len = 2) if (aECG->systolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 12; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)aECG->systolicBloodPressure); // value curSectLen += 5; }; // Tag 13 (max len = 80) aECG->Diagnosis=""; len = strlen(aECG->Diagnosis); if (len>0) { *(ptr+sectionStart+curSectLen) = 13; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->Diagnosis,len); curSectLen += 3+len; }; // Tag 14 (max len = 2 + 2 + 2 + 1 + 1 + 6 + 1 + 1 + 1 + 1 + 1 + 16 + 1 + 25 + 25 + 25 + 25 + 25) // Total = 161 (max value) *(ptr+sectionStart+curSectLen) = 14; // tag //len = 41; // minimum length //*(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length memset(ptr+sectionStart+curSectLen+3,0,41); // dummy value curSectLen += 3; *(uint16_t*)(ptr+sectionStart+curSectLen) = aECG->Section1.Tag14.INST_NUMBER; *(uint16_t*)(ptr+sectionStart+curSectLen+2) = aECG->Section1.Tag14.DEPT_NUMBER; *(uint16_t*)(ptr+sectionStart+curSectLen+4) = aECG->Section1.Tag14.DEVICE_ID; *(ptr+sectionStart+curSectLen+ 6) = aECG->Section1.Tag14.DEVICE_TYPE; *(ptr+sectionStart+curSectLen+ 7) = aECG->Section1.Tag14.MANUF_CODE; // tag 14, byte 7 (MANUF_CODE has to be 255) strncpy((char*)(ptr+sectionStart+curSectLen+8), aECG->Section1.Tag14.MOD_DESC, 6); // tag 14, byte 7 (MOD_DESC has to be "Cart1") *(ptr+sectionStart+curSectLen+14) = VERSION; // tag 14, byte 14 (VERSION has to be 20) *(ptr+sectionStart+curSectLen+14) = aECG->Section1.Tag14.VERSION; *(ptr+sectionStart+curSectLen+15) = aECG->Section1.Tag14.PROT_COMP_LEVEL; // tag 14, byte 15 (PROT_COMP_LEVEL has to be 0xA0 => level II) *(ptr+sectionStart+curSectLen+16) = aECG->Section1.Tag14.LANG_SUPP_CODE; // tag 14, byte 16 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) *(ptr+sectionStart+curSectLen+17) = aECG->Section1.Tag14.ECG_CAP_DEV; // tag 14, byte 17 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) *(ptr+sectionStart+curSectLen+18) = aECG->Section1.Tag14.MAINS_FREQ; // tag 14, byte 18 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) *(ptr+sectionStart+curSectLen+35) = strlen(aECG->Section1.Tag14.ANAL_PROG_REV_NUM)+1; // tag 14, byte 34 => length of ANAL_PROG_REV_NUM + 1 = 1 uint16_t len1 = 36; char* tmp; tmp = aECG->Section1.Tag14.ANAL_PROG_REV_NUM; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -