📄 scp-decode.cpp
字号:
1, 1, 1, 0, 0, 0,
3, 3, 1, 1, 1, 4,
3, 3, 1, -1, 5, 5,
4, 4, 1, 2, 3, 12,
4, 4, 1, -2, 11, 13,
5, 5, 1, 3, 7, 28,
5, 5, 1, -3, 23, 29,
6, 6, 1, 4, 15, 60,
6, 6, 1, -4, 47, 61,
7, 7, 1, 5, 31, 124,
7, 7, 1, -5, 95, 125,
8, 8, 1, 6, 63, 252,
8, 8, 1, -6, 191, 253,
9, 9, 1, 7, 127, 508,
9, 9, 1, -7, 383, 509,
10, 10, 1, 8, 255, 1020,
10, 10, 1, -8, 767, 1021,
10, 18, 1, 0, 511, 1022,
10, 26, 1, 0, 1023, 1023,
*/
U_int_S i;
i= 0U; riga[i].bit_prefix= 1U; riga[i].bit_code= 1U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code= 0UL;
i= 1U; riga[i].bit_prefix= 3U; riga[i].bit_code= 3U; riga[i].TMS=1U; riga[i].base_value= 1; riga[i].base_code= 1UL;
i= 2U; riga[i].bit_prefix= 3U; riga[i].bit_code= 3U; riga[i].TMS=1U; riga[i].base_value=-1; riga[i].base_code= 5UL;
i= 3U; riga[i].bit_prefix= 4U; riga[i].bit_code= 4U; riga[i].TMS=1U; riga[i].base_value= 2; riga[i].base_code= 3UL;
i= 4U; riga[i].bit_prefix= 4U; riga[i].bit_code= 4U; riga[i].TMS=1U; riga[i].base_value=-2; riga[i].base_code= 11UL;
i= 5U; riga[i].bit_prefix= 5U; riga[i].bit_code= 5U; riga[i].TMS=1U; riga[i].base_value= 3; riga[i].base_code= 7UL;
i= 6U; riga[i].bit_prefix= 5U; riga[i].bit_code= 5U; riga[i].TMS=1U; riga[i].base_value=-3; riga[i].base_code= 23UL;
i= 7U; riga[i].bit_prefix= 6U; riga[i].bit_code= 6U; riga[i].TMS=1U; riga[i].base_value= 4; riga[i].base_code= 15UL;
i= 8U; riga[i].bit_prefix= 6U; riga[i].bit_code= 6U; riga[i].TMS=1U; riga[i].base_value=-4; riga[i].base_code= 47UL;
i= 9U; riga[i].bit_prefix= 7U; riga[i].bit_code= 7U; riga[i].TMS=1U; riga[i].base_value= 5; riga[i].base_code= 31UL;
i=10U; riga[i].bit_prefix= 7U; riga[i].bit_code= 7U; riga[i].TMS=1U; riga[i].base_value=-5; riga[i].base_code= 95UL;
i=11U; riga[i].bit_prefix= 8U; riga[i].bit_code= 8U; riga[i].TMS=1U; riga[i].base_value= 6; riga[i].base_code= 63UL;
i=12U; riga[i].bit_prefix= 8U; riga[i].bit_code= 8U; riga[i].TMS=1U; riga[i].base_value=-6; riga[i].base_code= 191UL;
i=13U; riga[i].bit_prefix= 9U; riga[i].bit_code= 9U; riga[i].TMS=1U; riga[i].base_value= 7; riga[i].base_code= 127UL;
i=14U; riga[i].bit_prefix= 9U; riga[i].bit_code= 9U; riga[i].TMS=1U; riga[i].base_value=-7; riga[i].base_code= 383UL;
i=15U; riga[i].bit_prefix=10U; riga[i].bit_code=10U; riga[i].TMS=1U; riga[i].base_value= 8; riga[i].base_code= 255UL;
i=16U; riga[i].bit_prefix=10U; riga[i].bit_code=10U; riga[i].TMS=1U; riga[i].base_value=-8; riga[i].base_code= 767UL;
i=17U; riga[i].bit_prefix=10U; riga[i].bit_code=18U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code= 511UL;
i=18U; riga[i].bit_prefix=10U; riga[i].bit_code=26U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code=1023UL;
}//end InitHuffman
//______________________________________________________________________________
// handle sections
U_int_M ReadCRC()
// read the CRC of the entire file or of a section and convert it to decimal.
{
U_int_M dim;
ReadByte(dim);
return dim;
}//end ReadCRC
bool Check_CRC(U_int_M CRC, U_int_L pos, U_int_L length)
/* CRC check starting from pos for Length
Remark: all computations are in byte.
A = new byte
B = temp byte
CRCHI = MSB of the CRC (16 bits)
CRCLO = LSB of the CRC
START:
for A=first_byte to last_byte in block do:
A = A xor CRCHI
CRCHI = A
shift A right 4 times {fulfill with zeroes}
A = A xor CRCHI {I J K L M N O P}
CRCHI = CRCLO {swap CRCHI, CRCLO}
CRCLO = A
rotate A left 4 times {M N O P I J K L}
B = A { temp save }
rotate A left once { N O P I J K L M }
A = A and $1F { 0 0 0 I J L L M }
CRCHI = A xor CRCHI
A = B and $F0 { M N O P 0 0 0 0 }
CRCHI = A xor CRCHI { CRCHI complete }
rotate B left once { N O P 0 0 0 0 M }
B = B and $E0 { N O P 0 0 0 0 0 }
CRCLO = B xor CRCLO { CRCLO complete }
end
Final check on the CRC is accomplished by adding or concatenating CRCHI and CRCLO at
the end of the data stream. Calculating the checksum of the resulting data stream shall result in
a zero CRC if the data was correctly received.
*/
{
U_int_L i;
U_int_S A, B;
U_int_S CRCLO, CRCHI;
CRCLO=0xFF;
CRCHI=0xFF;
fseek(in,pos-1,0U);
for(i=1;i<=length;i++)
{
A=getc(in);
A^=CRCHI;
A^=(A>>4);
CRCHI=CRCLO;
CRCLO=A;
A=(A<<4)|(A>>4U);
B=A;
A=(A<<1)|(A>>7U);
A&=0x1F;
CRCHI^=A;
A=B&0xF0;
CRCHI^=A;
B=(B<<1)|(B>>7U);
B&=0xE0;
CRCLO^=B; }//end for
CRCLO-=CRC%256UL;
CRCHI-=CRC/256UL;
if ((CRCLO==CRCHI) && (CRCLO==0))
return 1;
else
{
fprintf(stderr,"Cannot read the file: BAD CRC.");
exit(2);
}
}//end Check_CRC
U_int_L ID_section(U_int_L pos, int_S &version)
//read section Header
{
U_int_L dim;
U_int_M CRC;
CRC=ReadCRC();
Skip(2U);
ReadByte(dim);
if (CRC != 0xFFFF) Check_CRC(CRC,pos+2,dim-2); // by E.C. may 2004 CARDIOLINE 1.0
fseek(in,pos+7L,0);
ReadByte(version); // by E.C. may 2004 store the version number
Skip(7U);
return dim;
}//end ID_section
void sectionsOptional(pointer_section *section, DATA_DECODE &block1, DATA_RECORD &block2, DATA_INFO &block3)
//handles optional sections
{
U_int_S i=0, bimodal;
//initialization
block1.t_Huffman=NULL;
block1.flag_Huffman=NULL;
block1.data_lead=NULL;
block1.data_protected=NULL;
block1.data_subtraction=NULL;
block1.length_BdR0=NULL;
block1.samples_BdR0=NULL;
block1.Median=NULL;
block1.length_Res=NULL;
block1.samples_Res=NULL;
block1.Residual=NULL;
block1.Reconstructed=NULL;
block2.data_spike=NULL;
block2.type_BdR=NULL;
block2.data_BdR=NULL;
block2.data_additional=NULL;
block2.lead_block=NULL;
block3.text_dim=NULL;
block3.text_report=NULL;
block3.data_statement=NULL;
block3.text_statement=NULL;
//variables inizialization
block1.flag_lead.number=0;
block1.flag_lead.subtraction=0;
block1.flag_lead.all_simultaneously=0;
block1.flag_lead.number_simultaneously=0;
block1.flag_BdR0.length=0;
block1.flag_BdR0.fcM=0;
block1.flag_BdR0.AVM=0;
block1.flag_BdR0.STM=0;
block1.flag_BdR0.number_samples=0;
block1.flag_BdR0.encoding=0;
block1.flag_Res.AVM=0;
block1.flag_Res.STM=0;
block1.flag_Res.number=0;
block1.flag_Res.number_samples=0;
block1.flag_Res.encoding=0;
block1.flag_Res.bimodal=0;
block1.flag_Res.decimation_factor=0;
block2.data_global.number=0;
block2.data_global.number_QRS=0;
block2.data_global.number_spike=0;
block2.data_global.average_RR=0;
block2.data_global.average_PP=0;
block2.data_global.ventricular_rate=0;
block2.data_global.atrial_rate=0;
block2.data_global.QT_corrected=0;
block2.data_global.formula_type=0;
block2.data_global.number_tag=0;
block2.header_lead.number_lead=0;
block2.header_lead.number_lead_measurement=0;
while(i<_NUM_SECTION)
{
if(section[i].ID)
switch(section[i].ID)
{
case 2: if(section[i].length)
section_2(section[i],block1); //HUFFMAN
break;
case 3: if(section[i].length)
section_3(section[i],block1,block3.des.acquiring.protocol_revision_number); //lead
break;
case 4: if(section[i].length)
{
if((block3.des.acquiring.protocol_revision_number>10) && section[6].length) // by E.C. 27.02.2004 whole section to be included in {} !
{
fseek(in,section[6].index+22,0);
ReadByte(bimodal);
block1.flag_Res.bimodal=bimodal;
}
else
block1.flag_Res.bimodal=0;
section_4(section[i],block1,block3.des.analyzing.protocol_revision_number); // fiducial locations
}
break;
case 5: if(section[i].length)
section_5(section[i],block1,section[2].length); //type 0 median beat
break;
case 6: if(section[i].length)
section_6(section[i],block1,section[2].length); //rhythm compressed data
break;
case 7: if(section[i].length)
section_7(section[i],block2,block3.des.acquiring.protocol_revision_number); //global measurements
break;
case 8: if(section[i].length)
section_8(section[i],block3); //full text interpretative statements
break;
case 10:if(section[i].length)
section_10(section[i],block2,block3.des.acquiring.protocol_revision_number); //lead measurement block
break;
case 11:if(section[i].length) //universal ECG interpretative statements
// section_11(section[i],block3);
break;
}//end switch
++i;
}//end while
}//end sectionsOptional
//______________________________________________________________________________
// sections
//______________________________________________________________________________
//______________________________________________________________________________
// section 0
//______________________________________________________________________________
void section_0(pointer_section *info, int size_max)
// section 0
//build info_sections with ID, offset and length of each section
{
U_int_L pos, dim, ini;
U_int_M ind;
U_int_S i;
int_S version;
fseek(in,6L,0);
pos=ID_section(7L, version)+7L; //length + offset
_COUNT_BYTE=7L+16L;
for(i=0;i<_NUM_SECTION;i++)
{
info[i].ID=0;
info[i].length=0L;
info[i].index=0L;
}
while((_COUNT_BYTE+10)<=pos)
{
ReadByte(ind);
if(ind>11U)
Skip(8U);
else
{
ReadByte(dim);
if(dim)
{
ReadByte(ini);
if (ini<size_max) { // by E.C. may 2004 check overflow of file
info[ind].ID=ind;
info[ind].length=dim;
info[ind].index=ini;
}
}//end if dim
else
Skip(4U);
}//end else
}//end while
}//end section_0
//______________________________________________________________________________
// section 1
//______________________________________________________________________________
void Init_S1(DATA_INFO &inf)
{
inf.ana.last_name=STR_NULL;
inf.ana.first_name=STR_NULL;
inf.ana.ID=STR_NULL;
inf.ana.second_last_name=STR_NULL;
inf.ana.age.value=0;
inf.ana.age.unit=0;
inf.ana.date_birth=STR_NULL;
inf.ana.height.value=0;
inf.ana.height.unit=0;
inf.ana.weight.value=0;
inf.ana.weight.unit=0;
inf.ana.sex=0;
inf.ana.race=0;
inf.ana.systolic_pressure=0;
inf.ana.diastolic_pressure=0;
inf.cli.number_drug=0;
inf.cli.text_drug=STR_NULL;
inf.cli.number_diagnose=0;
inf.cli.text_diagnose=STR_NULL;
inf.cli.referring_physician=STR_NULL;
inf.cli.latest_confirming_physician=STR_NULL;
inf.cli.technician_description=STR_NULL;
inf.cli.number_text=0;
inf.cli.text_free_text=STR_NULL;
inf.cli.number_hystory=0;
inf.cli.number_free_hystory=0;
inf.cli.text_free_medical_hystory=STR_NULL;
inf.des.acquiring.institution_number=0;
inf.des.acquiring.department_number=0;
inf.des.acquiring.ID=0;
inf.des.acquiring.type=2;
inf.des.acquiring.manifacturer=0;
inf.des.acquiring.model_description=STR_NULL;
inf.des.acquiring.protocol_revision_number=0;
inf.des.acquiring.category=255;
inf.des.acquiring.language=255;
inf.des.acquiring.capability[0]=1;
inf.des.acquiring.capability[1]=2;
inf.des.acquiring.capability[2]=3;
inf.des.acquiring.capability[3]=4;
inf.des.acquiring.AC=0;
inf.des.acquiring.analysing_program_revision_number=STR_NULL;
inf.des.acquiring.serial_number_device=STR_NULL;
inf.des.acquiring.device_system_software=STR_NULL;
inf.des.acquiring.device_SCP_implementation_software=STR_NULL;
inf.des.acquiring.manifacturer_trade_name=STR_NULL;
inf.des.analyzing.institution_number=0;
inf.des.analyzing.department_number=0;
inf.des.analyzing.ID=0;
inf.des.analyzing.type=2;
inf.des.analyzing.manifacturer=0;
inf.des.analyzing.model_description=STR_NULL;
inf.des.analyzing.protocol_revision_number=0;
inf.des.analyzing.category=255;
inf.des.analyzing.language=255;
inf.des.analyzing.capability[0]=1;
inf.des.analyzing.capability[1]=2;
inf.des.analyzing.capability[2]=3;
inf.des.analyzing.capability[3]=4;
inf.des.analyzing.AC=0;
inf.des.analyzing.analysing_program_revision_number=STR_NULL;
inf.des.analyzing.serial_number_device=STR_NULL;
inf.des.analyzing.device_system_software=STR_NULL;
inf.des.analyzing.device_SCP_implementation_software=STR_NULL;
inf.des.analyzing.manifacturer_trade_name=STR_NULL;
inf.des.acquiring_institution=STR_NULL;
inf.des.analyzing_institution=STR_NULL;
inf.des.acquiring_department=STR_NULL;
inf.des.analyzing_department=STR_NULL;
inf.des.room=STR_NULL;
inf.des.stat_code=0;
inf.dev.date_acquisition=STR_NULL;
inf.dev.time_acquisition=STR_NULL;
inf.dev.baseline_filter=0;
inf.dev.lowpass_filter=0;
inf.dev.other_filter[0]=0;
inf.dev.other_filter[1]=0;
inf.dev.other_filter[2]=0;
inf.dev.other_filter[3]=0;
inf.dev.sequence_number=STR_NULL;
inf.dev.electrode_configuration.value=0;
inf.dev.electrode_configuration.unit=0;
inf.dev.TZ.offset=0;
inf.dev.TZ.index=0;
inf.dev.TZ.description=STR_NULL;
}
void section_1(pointer_section info_sections, DATA_INFO &inf)
// section 1
{
U_int_S tag;
U_int_L num=info_sections.length+_COUNT_BYTE;
U_int_M dim=0U;
int_S version;
_COUNT_BYTE=info_sections.index;
fseek(in,info_sections.index-1,0);
ID_section(info_sections.index, version);
Init_S1(inf);
do
{
ReadByte(tag);
switch(tag)
{
case 0:
section_1_0(inf.ana); break;
case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -