/* make a linked list of all sections containing ALLOCatable data */ static void read_sections(int fd, Elf_Ehdr *ehdr, char *shstrtab, struct elf_section **head) { int i; Elf_Shdr shdr; *head = NULL; /* scan through section headers */ for (i = 0; i < ehdr->e_shnum; i++) { struct elf_section *s; read_section_header(fd, ehdr, i, &shdr); if ((shdr.sh_flags & SHF_ALLOC) == 0 && shdr.sh_type != SHT_STRTAB && shdr.sh_type != SHT_SYMTAB && shdr.sh_type != SHT_DYNSYM) { /* skip non-ALLOC sections */ continue; } s = malloc(sizeof(*s)); if (s == NULL) errx(1, "failed to allocate %lu bytes", (u_long)sizeof(*s)); s->name = shstrtab + shdr.sh_name; s->type = shdr.sh_type; s->addr = (void *)shdr.sh_addr; s->offset = shdr.sh_offset; s->size = shdr.sh_size; s->align = shdr.sh_addralign; add_section(head, s); } }
/* read section header's string table */ static char * read_shstring_table(int fd, Elf_Ehdr *ehdr) { Elf_Shdr shdr; char *shstrtab; read_section_header(fd, ehdr, ehdr->e_shstrndx, &shdr); shstrtab = malloc(shdr.sh_size); if (shstrtab == NULL) errx(1, "failed to allocate %lu bytes", (u_long)shdr.sh_size); if (lseek(fd, shdr.sh_offset, SEEK_SET) < 0) err(1, "lseek"); if (read(fd, shstrtab, shdr.sh_size) != shdr.sh_size) err(1, "read"); return shstrtab; }
void UI_SCPECG2EDFwindow::SelectFileButton() { FILE *inputfile=NULL; int i, j, k, n, hdl, chns, sf, avm, blocks, *buf, encoding, compression, offset, abs_val_a[256], abs_val_b[256], var_tmp; unsigned short sh_tmp; long long filesize, ll_tmp, bits; char input_filename[MAX_PATH_LENGTH], txt_string[2048], edf_filename[MAX_PATH_LENGTH], scratchpad[MAX_PATH_LENGTH], *block, ch_tmp; union{ unsigned long long ll_int; unsigned int one[2]; unsigned short two[4]; unsigned char four[8]; } var; pushButton1->setEnabled(false); for(i=0; i<256; i++) { abs_val_a[i] = 0; abs_val_b[i] = 0; } strcpy(input_filename, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "SCP files (*.scp *.SCP)").toLocal8Bit().data()); if(!strcmp(input_filename, "")) { pushButton1->setEnabled(true); return; } get_directory_from_path(recent_opendir, input_filename, MAX_PATH_LENGTH); inputfile = fopeno(input_filename, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.\n", input_filename); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(true); return; } get_filename_from_path(scratchpad, input_filename, MAX_PATH_LENGTH); snprintf(txt_string, 2048, "Read file: %s", scratchpad); textEdit1->append(QString::fromLocal8Bit(txt_string)); fseeko(inputfile, 0LL, SEEK_END); filesize = ftello(inputfile); if(filesize<126) { textEdit1->append("Error, filesize is too small.\n"); fclose(inputfile); pushButton1->setEnabled(true); return; } ll_tmp = 0LL; fseeko(inputfile, 2LL, SEEK_SET); if(fread(&ll_tmp, 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (1)\n"); fclose(inputfile); pushButton1->setEnabled(true); return; } if(ll_tmp != filesize) { textEdit1->append("Error, filesize does not match with header.\n"); fclose(inputfile); pushButton1->setEnabled(true); return; } block = (char *)malloc(SPCECGBUFSIZE); if(block == NULL) { textEdit1->append("Malloc error (block 1)\n"); fclose(inputfile); pushButton1->setEnabled(true); return; } rewind(inputfile); if(fread(&sh_tmp, 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (2)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(check_crc(inputfile, 2LL, filesize - 2LL, sh_tmp, block)) { fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } memset(&sp, 0, sizeof(struct section_prop_struct[12])); if(read_section_header(0, inputfile, 6LL, block)) { fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(strncmp(sp[0].reserved, "SCPECG", 6)) { textEdit1->append("Error, reserved field of section header 0 does not contain string \"SCPECG\".\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } sp[0].file_offset = 6LL; // printf("\nsection ID is %i\n" // "section file offset is %lli\n" // "section CRC is 0x%04X\n" // "section length is %i\n" // "section version is %i\n" // "section protocol version is %i\n", // sp[0].section_id, // sp[0].file_offset, // (int)sp[0].crc, // sp[0].section_length, // sp[0].section_version, // sp[0].section_protocol_version); if(read_data_section_zero(inputfile, block, filesize)) { fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } fseeko(inputfile, sp[6].file_offset + 16LL, SEEK_SET); if(fread(block, 6, 1, inputfile) != 1) { textEdit1->append("A read-error occurred\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } avm = *((unsigned short *)block); sf = 1000000 / *((unsigned short *)(block + 2)); encoding = *((unsigned char *)(block + 4)); compression = *((unsigned char *)(block + 5)); if(compression != 0) { textEdit1->append("File contains bimodal compressed data which is not supported by this converter.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } fseeko(inputfile, sp[3].file_offset + 16LL, SEEK_SET); if(fread(scratchpad, 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (40)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } chns = *((unsigned char *)scratchpad); if(chns < 1) { textEdit1->append("Error, number of signals is less than one.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(chns > 256) { textEdit1->append("Error, number of signals is more than 256.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(scratchpad[1] & 1) { textEdit1->append("Reference beat subtraction used for compression which is not supported by this converter.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(!(scratchpad[1] & 4)) { textEdit1->append("Leads are not simultaneously recorded which is not supported by this converter. (1)\n "); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } // printf("chns is %u AVM is %u sf is %u encoding is %u compression is %u\n", // chns, avm, sf, encoding, compression); memset(&lp, 0, sizeof(struct lead_prop_struct[256])); fseeko(inputfile, sp[3].file_offset + 18LL, SEEK_SET); for(i=0; i<chns; i++) { if(fread(&(lp[i].start), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (30)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(fread(&(lp[i].end), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (31)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(fread(&(lp[i].label), 1, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (32)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } } // for(i=0; i<chns; i++) // { // printf("lp[i].start is %i lp[i].end is %i\n", lp[i].start, lp[i].end); // } if(chns > 1) { for(i=1; i<chns; i++) { if(lp[i].start != lp[0].start) { textEdit1->append("Error, leads are not simultaneously recorded. (2)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(lp[i].end != lp[0].end) { textEdit1->append("Error, leads are not simultaneously recorded. (3)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } } } for(i=0; i<chns; i++) { if(lp[i].start < 1) { textEdit1->append("Error, start sample number in section 3 is less than 1.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(lp[i].end <= lp[i].start) { textEdit1->append("Error (56) (lp[i].end <= lp[i].start)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } if(lp[i].start != 1) { textEdit1->append("Error (57) (lp[i].start != 1)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } lp[i].start--; if((lp[i].end - lp[i].start) < sf) { textEdit1->append("Error, recording length is less than one second.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } lp[i].samples = lp[i].end - lp[i].start; } fseeko(inputfile, sp[6].file_offset + 22LL, SEEK_SET); n = 0; for(i=0; i<chns; i++) { if(fread(block, 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (41)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } lp[i].bytes = *((unsigned short *)block); n += lp[i].bytes; // printf("lead samples is %i bytes is %i\n", lp[i].samples, lp[i].bytes); if(sp[2].present != 1) // huffmantable { if(lp[i].bytes < (lp[i].samples * 2)) { textEdit1->append("Error, lead samples is less than lead bytes.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } } } if(n > (sp[6].section_length - 22 - (chns * 2))) { textEdit1->append("Error, total databytes is more than section size.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } //////////////////////////////// Huffman tables //////////////////// if(sp[2].present == 1) // huffmantable { fseeko(inputfile, sp[2].file_offset + 16LL, SEEK_SET); if(fread(block, 13, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (50)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } ht.h_tables_cnt = *((unsigned short *)block); ht.code_structs_cnt = *((unsigned short *)(block + 2)); ht.prefix_bits = *((unsigned char *)(block + 4)); ht.total_bits = *((unsigned char *)(block + 5)); ht.table_mode_switch = *((unsigned char *)(block + 6)); ht.base_value = *((unsigned short *)(block + 7)); ht.base_code = *((unsigned int *)(block + 9)); // printf("ht.h_tables_cnt is %i ht.code_structs_cnt is %i ht.prefix_bits is %i ht.total_bits is %i\n", // ht.h_tables_cnt, ht.code_structs_cnt, ht.prefix_bits, ht.total_bits); if(ht.h_tables_cnt != 19999) { textEdit1->append("Aborted, this converter does not support customized Huffmantables.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } } //////////////////////////////// patient data //////////////////// memset(&pat_dat, 0, sizeof(struct patient_data_struct)); if(get_patient_data(inputfile)) { fclose(inputfile); free(block); pushButton1->setEnabled(true); return; } // printf("patient ID: %s\n" // "patient lastname: %s\n" // "patient firstname: %s\n" // "patient sex: %i\n" // "startdate year: %i\n" // "startdate month: %i\n" // "startdate day: %i\n" // "starttime hour: %i\n" // "starttime minute: %i\n" // "starttime second: %i\n" // "birthdate year: %i\n" // "birthdate month: %i\n" // "birthdate day: %i\n" // "device model: %s\n" // "language code: %u\n" // "manufacturer: %s\n", // pat_dat.pat_id, // pat_dat.last_name, // pat_dat.first_name, // pat_dat.sex, // pat_dat.startdate_year, // pat_dat.startdate_month, // pat_dat.startdate_day, // pat_dat.starttime_hour, // pat_dat.starttime_minute, // pat_dat.starttime_second, // pat_dat.birthdate_year, // pat_dat.birthdate_month, // pat_dat.birthdate_day, // pat_dat.device_model, // pat_dat.lang_code, // pat_dat.manufacturer); ////////////////////////// start conversion /////////////////////////////// free(block); buf = (int *)malloc(((lp[0].samples / sf) + 1) * chns * sf * sizeof(int)); if(buf == NULL) { textEdit1->append("Malloc error (buf)\n"); fclose(inputfile); pushButton1->setEnabled(true); return; } n = 0; for(i=0; i<chns; i++) { n += lp[i].bytes; } block = (char *)calloc(1, n + 64); if(block == NULL) { textEdit1->append("Malloc error (block 3)\n"); fclose(inputfile); free(buf); pushButton1->setEnabled(true); return; } fseeko(inputfile, sp[6].file_offset + 22LL + (chns * 2LL), SEEK_SET); // rhythm data if(fread(block, n, 1, inputfile) != 1) { textEdit1->append("A read-error occurred during conversion (70)\n"); fclose(inputfile); free(buf); free(block); pushButton1->setEnabled(true); return; } offset = 0; for(j=0; j<chns; j++) { if(j > 0) { offset += lp[j - 1].bytes; } bits = 0LL; for(i=0; i<lp[j].samples; i++) { if(sp[2].present == 1) // huffmantable present { if((bits / 8LL) > lp[j].bytes) { textEdit1->append("Error, (bits / 8) >= lp[j].bytes (71)\n"); fclose(inputfile); free(buf); free(block); pushButton1->setEnabled(true); return; } memcpy(&var, block + offset + ((int)(bits / 8LL)), 5); for(k=0; k<5; k++) { var.four[k] = reverse_bitorder(var.four[k]); } var.ll_int >>= (int)(bits % 8LL); if((var.four[0] & 1) == 0) // b00000001 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 0; bits++; } else if((var.four[0] & 7) == 1) // b00000111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 1; bits += 3LL; } else if((var.four[0] & 7) == 5) // b00000111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -1; bits += 3LL; } else if((var.four[0] & 15) == 3) // b00001111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 2; bits += 4LL; } else if((var.four[0] & 15) == 11) // b00001111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -2; bits += 4LL; } else if((var.four[0] & 31) == 7) // b00011111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 3; bits += 5LL; } else if((var.four[0] & 31) == 23) // b00011111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -3; bits += 5LL; } else if((var.four[0] & 63) == 15) // b00111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 4; bits += 6LL; } else if((var.four[0] & 63) == 47) // b00111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -4; bits += 6LL; } else if((var.four[0] & 127) == 31) // b01111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 5; bits += 7LL; } else if((var.four[0] & 127) == 95) // b01111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -5; bits += 7LL; } else if(var.four[0] == 63) // b11111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 6; bits += 8LL; } else if(var.four[0] == 191) // b11111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -6; bits += 8LL; } else if(var.four[0] == 127) // b11111111 { if((var.four[1] & 1) == 0) // b00000001 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 7; bits += 9LL; } else { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -7; bits += 9LL; } } else if(var.four[0] == 255) // b11111111 { if((var.four[1] & 3) == 0) // b00000011 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 8; bits += 10LL; } else if((var.four[1] & 3) == 2) // b00000011 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -8; bits += 10LL; } else if((var.four[1] & 3) == 1) // b00000011 { var.ll_int >>= 2; var.four[1] = reverse_bitorder(var.four[1]); buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = *((signed char *)&(var.four[1])); // 8-bit original bits += 18LL; } else if((var.four[1] & 3) == 3) // b00000011 { var.ll_int >>= 10; ch_tmp = reverse_bitorder(var.four[0]); var.four[0] = reverse_bitorder(var.four[1]); var.four[1] = ch_tmp; buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = *((signed short *)&(var.two[0])); // 16-bit original bits += 26LL; } } }