Beispiel #1
0
/* 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);
	}
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
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;
          }
        }
      }