예제 #1
0
/*!
 * Write ECAT 6.3 matrix data to a specified file position.
 *   Data does not need to be allocated for full blocks.
 *   Data must be represented in current machines byte order, and it is
 *   always saved in big endian byte order.
 *   Give also nr of pixels and byte size of one pixel.
 *
 * @param fp target file pointer
 * @param strtblk starting image block [>=1]
 * @param data pointer to data that is written
 * @param pxlNr number of items to be written [>=1]
 * @param pxlSize size of one data item in bytes [>=1]
 * @return 0 if ok, 1 invalid input, 2 failed to find starting block, 
 * 3 failed to write data
 */
int ecat63WriteMatdata(FILE *fp, int strtblk, char *data, int pxlNr, int pxlSize) {
  unsigned char buf[MatBLKSIZE];
  char *dptr;
  int i, blkNr, dataSize, byteNr;

  if(ECAT63_TEST) printf("ecat63WriteMatdata(fp, %d, data, %d, %d)\n", strtblk, pxlNr, pxlSize);
  if(fp==NULL || strtblk<1 || data==NULL || pxlNr<1 || pxlSize<1) return(1);
  memset(buf, 0, MatBLKSIZE);
  dataSize=pxlNr*pxlSize; if(dataSize<1) return(1);
  /* block nr taken by all pixels */
  blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
  if(ECAT63_TEST>1) printf("    blkNr=%d\n", blkNr);
  /* Search the place for writing */
  fseek(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(strtblk-1)*MatBLKSIZE) return(2);
  /* Save blocks one at a time */
  for(i=0, dptr=data; i<blkNr && dataSize>0; i++) {
    byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
    memcpy(buf, dptr, byteNr);
    /* Change matrix byte order in big endian platforms */
    if(!little_endian()) {
      if(pxlSize==2) swabip(buf, byteNr);
      else if(pxlSize==4) swawbip(buf, byteNr);
    }
    /* Write block */
    if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
    /* Prepare for the next block */
    dptr+=byteNr;
    dataSize-=byteNr;
  } /* next block */
  return(0);
}
예제 #2
0
/*!
 * Write ECAT 6.3 image header
 *
 * @param fp target file pointer
 * @param block block number [>= 3]
 * @param h Ecat 6.3 image header
 * @return 0, if ok, 1 invalid input, 2 failed to find block, 
 * 3 failed to write block
 */
int ecat63WriteImageheader(FILE *fp, int block, ECAT63_imageheader *h) {
  char buf[MatBLKSIZE];
  int i, little, tovax;


  if(ECAT63_TEST) printf("ecat63WriteImageheader(fp, %d, ih)\n", block);
  little=little_endian();
  /* Clear buf */
  memset(buf, 0, MatBLKSIZE);
  /* Check arguments */
  if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
  if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
    tovax=1; else tovax=0;

  /* Copy short ints to buf */
  memcpy(buf+126, &h->data_type, 2); memcpy(buf+128, &h->num_dimensions, 2);
  memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
  memcpy(buf+176, &h->image_min, 2); memcpy(buf+178, &h->image_max, 2);
  memcpy(buf+200, &h->slice_location, 2); memcpy(buf+202, &h->recon_start_hour, 2);
  memcpy(buf+204, &h->recon_start_min, 2); memcpy(buf+206, &h->recon_start_sec, 2);
  memcpy(buf+236, &h->filter_code, 2); memcpy(buf+376, &h->processing_code, 2);
  memcpy(buf+380, &h->quant_units, 2); memcpy(buf+382, &h->recon_start_day, 2);
  memcpy(buf+384, &h->recon_start_month, 2); memcpy(buf+386, &h->recon_start_year, 2);
  memcpy(buf+460, h->fill2, 52);
  /* big to little endian if necessary */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats to buf */
  ecat63wFloat(&h->x_origin, buf+160, tovax, little);
  ecat63wFloat(&h->y_origin, buf+164, tovax, little);
  ecat63wFloat(&h->recon_scale, buf+168, tovax, little);
  ecat63wFloat(&h->quant_scale, buf+172, tovax, little);
  ecat63wFloat(&h->pixel_size, buf+184, tovax, little);
  ecat63wFloat(&h->slice_width, buf+188, tovax, little);
  ecat63wFloat(&h->image_rotation, buf+296, tovax, little);
  ecat63wFloat(&h->plane_eff_corr_fctr, buf+300, tovax, little);
  ecat63wFloat(&h->decay_corr_fctr, buf+304, tovax, little);
  ecat63wFloat(&h->loss_corr_fctr, buf+308, tovax, little);
  ecat63wFloat(&h->intrinsic_tilt, buf+312, tovax, little);
  ecat63wFloat(&h->ecat_calibration_fctr, buf+388, tovax, little);
  ecat63wFloat(&h->well_counter_cal_fctr, buf+392, tovax, little);
  for(i=0; i<6; i++) ecat63wFloat(&h->filter_params[i], buf+396+4*i, tovax, little);

  /* Copy ints to buf */
  ecat63wInt(&h->frame_duration, buf+192, tovax, little);
  ecat63wInt(&h->frame_start_time, buf+196, tovax, little);
  ecat63wInt(&h->scan_matrix_num, buf+238, tovax, little);
  ecat63wInt(&h->norm_matrix_num, buf+242, tovax, little);
  ecat63wInt(&h->atten_cor_mat_num, buf+246, tovax, little);

  /* Copy chars */
  memcpy(buf+0, h->fill1, 126); memcpy(buf+420, h->annotation, 40);

  /* Write subheader */
  fseek(fp, (block-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(block-1)*MatBLKSIZE) return(2);
  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);

  return(0);
}
예제 #3
0
/*!
 * Read ECAT 6.3 matrix data and convert byte order if necessary
 *  Remember to allocate memory for full blocks!
 *  There are differences here when compared to ecat7.c
 *
 * @param fp file pointer from where data is read
 * @param strtblk starting block [>= 1]
 * @param blkNr number of block to be read [>= 0]
 * @param data pointer to block where data is read
 * @param dtype data type code
 * @return 0 if ok, 1 invalid input, 2 failed to read data,
 * 9 failed to find starting block from file,
 */
int ecat63ReadMatdata(FILE *fp, int strtblk, int blkNr, char *data, int dtype) {
  int i, n, little, err=0;
  char *cptr;
  float f;


  if(ECAT63_TEST) printf("ecat63ReadMatdata(fp, %d, %d, data, %d)\n", strtblk, blkNr, dtype);
  /* Check the arguments */
  if(blkNr<=0 || strtblk<1 || data==NULL) return(1);
  /* Seek the first data block */
  fseek(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET);
  if(ftell(fp)!=(strtblk-1)*MatBLKSIZE) return(9);
  /* Read the data blocks */
  if(fread(data, MatBLKSIZE, blkNr, fp) < blkNr) return(2);
  /* Translate data if necessary */
  little=little_endian();
  switch(dtype) {
    case BYTE_TYPE: /* byte format...no translation necessary */
      break;
    case VAX_I2:    /* byte conversion necessary on big endian platform */
      if(!little) {cptr=data; swabip(cptr, blkNr*MatBLKSIZE);}
      break;
    case VAX_I4:
      for(i=0, cptr=data; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
        n=ecat63rInt(cptr, 1, little); memcpy(cptr, &n, 4);
      }
      break;
    case VAX_R4:
      for(i=0, cptr=data; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
        f=ecat63rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
      }
      break;
    case IEEE_R4:   /* IEEE float ; byte conversion necessary on big end platforms */
    case SUN_I4:    /* SUN int ; byte conversion necessary on big end platforms */
      if(!little) swawbip(data, blkNr*MatBLKSIZE);
      break;
    case SUN_I2:    /* SUN short ; byte conversion necessary on big end platforms */
      if(!little) swabip(data, blkNr*MatBLKSIZE);
      break;
    default:  /* if something else, for now think it as an error */
      err=2;
      break;
  }
  return(err);
}
예제 #4
0
/*!
 * Read ECAT 6.3 attenuation header
 *
 * @param fp file pointer
 * @param blk block number [2..number of blocks]
 * @param h Ecat 6.3 attenuation header
 * @return 0 if ok, 1 failed to find block, 3 failed to read block, 
 * 4 invalid data type, 5 invalid scale factor
 */
int ecat63ReadAttnheader(FILE *fp, int blk, ECAT63_attnheader *h) {
  unsigned char buf[MatBLKSIZE];
  int little; /* 1 if current platform is little endian (i386), else 0 */
  int vaxdata=1; /* 1 if data is in VAX format, else 0 */

  if(ECAT63_TEST) printf("ecat63ReadAttnheader(fp, %d, ah)\n", blk);
  if(fp==NULL || blk<2 || h==NULL) return(1);
  little=little_endian();
  /* Seek the subheader block */
  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
  /* Read the subheader block */
  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);

  /* Copy short ints */
  /* in big endian platform, change byte order temporarily */
  if(!little) swabip(buf, MatBLKSIZE);
  memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
  /*printf("data_type=%d\n", h->data_type);*/
  memcpy(&h->attenuation_type, buf+128, 2);
  memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
  /* Change back the byte order */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats */
  h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
  h->x_origin=ecat63rFloat(buf+186, vaxdata, little);
  h->y_origin=ecat63rFloat(buf+190, vaxdata, little);
  h->x_radius=ecat63rFloat(buf+194, vaxdata, little);
  h->y_radius=ecat63rFloat(buf+198, vaxdata, little);
  h->tilt_angle=ecat63rFloat(buf+202, vaxdata, little);
  h->attenuation_coeff=ecat63rFloat(buf+206, vaxdata, little);
  h->sample_distance=ecat63rFloat(buf+210, vaxdata, little);

  /* Check that most important contents are ok */
  if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
    if(ECAT63_TEST) printf("Invalid data types; probable conversion error.\n");
    return(4);
  }
  if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
    if(ECAT63_TEST) printf("Invalid scale factor; probable conversion error.\n");
    return(5);
  }

  return(0);
}
예제 #5
0
/*!
 * Write ECAT 6.3 scan header
 * 
 * @param fp target file pointer
 * @param block block number [>=3]
 * @param h Ecat 6.3 scan header
 * @return 0 if ok, 1 invalid input, 2 failed to find block,
 * 3 failed to write block
 */
int ecat63WriteScanheader(FILE *fp, int block, ECAT63_scanheader *h) {
  unsigned char buf[MatBLKSIZE];
  int i, little, tovax;


  if(ECAT63_TEST) printf("ecat63WriteScanheader(fp, %d, ih)\n", block);
  little=little_endian();
  /* Clear buf */
  memset(buf, 0, MatBLKSIZE);
  /* Check arguments */
  if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
  if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
    tovax=1; else tovax=0;

  /* Copy short ints to buf */
  memcpy(buf+126, &h->data_type, 2);
  memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
  memcpy(buf+136, &h->smoothing, 2); memcpy(buf+138, &h->processing_code, 2);
  memcpy(buf+170, &h->frame_duration_sec, 2);
  memcpy(buf+192, &h->scan_min, 2); memcpy(buf+194, &h->scan_max, 2);
  memcpy(buf+468, h->fill2, 44);
  /* big to little endian if necessary */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats to buf */
  ecat63wFloat(&h->sample_distance, buf+146, tovax, little);
  ecat63wFloat(&h->isotope_halflife, buf+166, tovax, little);
  ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
  for(i=0; i<16; i++) {
    ecat63wFloat(&h->cor_singles[i], buf+316+4*i, tovax, little);
    ecat63wFloat(&h->uncor_singles[i], buf+380+4*i, tovax, little);
  }
  ecat63wFloat(&h->tot_avg_cor, buf+444, tovax, little);
  ecat63wFloat(&h->tot_avg_uncor, buf+448, tovax, little);
  ecat63wFloat(&h->loss_correction_fctr, buf+464, tovax, little);

  /* Copy ints to buf */
  ecat63wInt(&h->gate_duration, buf+172, tovax, little);
  ecat63wInt(&h->r_wave_offset, buf+176, tovax, little);
  ecat63wInt(&h->prompts, buf+196, tovax, little);
  ecat63wInt(&h->delayed, buf+200, tovax, little);
  ecat63wInt(&h->multiples, buf+204, tovax, little);
  ecat63wInt(&h->net_trues, buf+208, tovax, little);
  ecat63wInt(&h->total_coin_rate, buf+452, tovax, little);
  ecat63wInt(&h->frame_start_time, buf+456, tovax, little);
  ecat63wInt(&h->frame_duration, buf+460, tovax, little);

  /* Copy chars */
  memcpy(buf+0, h->fill1, 126);

  /* Write subheader */
  fseek(fp, (block-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(block-1)*MatBLKSIZE) return(2);
  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);

  return(0);
}/*****************************************************************************/
예제 #6
0
/*!
 * Read ECAT 6.3 normalization header
 *
 * @param fp file pointer
 * @param blk block number [2..number of blocks]
 * @param h Ecat 6.3 normalization header
 * @return 0 if ok, 1 invalid input, 2 failed to find block, 
 * 3 failed to read block, 4 invalid data type, 5 invalid scale factor
 */
int ecat63ReadNormheader(FILE *fp, int blk, ECAT63_normheader *h) {
  unsigned char buf[MatBLKSIZE];
  int little; /* 1 if current platform is little endian (i386), else 0 */
  int vaxdata=1; /* 1 if data is in VAX format, else 0 */

  if(ECAT63_TEST) printf("ecat63ReadNormheader(fp, %d, nh)\n", blk);
  if(fp==NULL || blk<2 || h==NULL) return(1);
  little=little_endian();
  /* Seek the subheader block */
  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
  /* Read the subheader block */
  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);

  /* Copy short ints */
  /* in big endian platform, change byte order temporarily */
  if(!little) swabip(buf, MatBLKSIZE);
  memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
  /*printf("data_type=%d\n", h->data_type);*/
  memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
  memcpy(&h->norm_hour, buf+186, 2); memcpy(&h->norm_minute, buf+188, 2);
  memcpy(&h->norm_second, buf+190, 2); memcpy(&h->norm_day, buf+192, 2);
  memcpy(&h->norm_month, buf+194, 2); memcpy(&h->norm_year, buf+196, 2);
  /* Change back the byte order */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats */
  h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
  h->fov_source_width=ecat63rFloat(buf+198, vaxdata, little);

  /* Check that most important contents are ok */
  if(h->data_type<BYTE_TYPE && h->data_type>SUN_I4) {
    if(ECAT63_TEST) printf("Invalid data types; probable conversion error.\n");
    return(4);
  }
  if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
    if(ECAT63_TEST) printf("Invalid scale factor; probable conversion error.\n");
    return(5);
  }

  return(0);
}
예제 #7
0
/*!
 * Reading ECAT 6.3 floats
 *
 * @param bufi pointer to 32-bit long data block
 * @param isvax 1 for VAX format
 * @param islittle 1 for little endian
 * @return read float value
 */
float ecat63rFloat(void *bufi, int isvax, int islittle) {
  union {unsigned int ul; float f;} t;

  memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
  if(isvax) { /* if input is in VAX format */
    /* Swap words on i386 and bytes on SUN */
    if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
    t.ul-=(2L<<23); /* subtract 2 from exp */
  } else { /* input is in i386 format */
    if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
  }
  return(t.f);
}
예제 #8
0
/*!
 * Writing ECAT 6.3 floats
 *
 * @param bufi pointer to 4-byte long input (float data)
 * @param bufo pointer to 4-byte long output
 * @param tovax 1 for VAX format
 * @param islittle 1 for little endian
 */
void ecat63wFloat(float *bufi, void *bufo, int tovax, int islittle) {
  unsigned int ul;

  memcpy(&ul, bufi, 4); if(ul==0) {memcpy(bufo, bufi, 4); return;}
  if(tovax) { /* If VAX format is needed */
    ul+=(2L<<23); /* increase exp by 2 */
    /* Swap words on i386 and bytes on SUN */
    if(islittle) swawip(&ul, 4); else swabip(&ul, 4);
  } else {
    if(!islittle) swawbip(&ul, 4); /* Switch words and bytes on SUN */
  }
  memcpy(bufo, &ul, 4);
}
예제 #9
0
/*!
 * Write ECAT 6.3 normalization header
 *
 * @param fp target file pointer
 * @param block block number [>=3]
 * @param h Ecat 6.3 normalization header
 * @return 0 if ok, 1 invalid input, 2 failed to find block,
 * 3 failed to write block
 */
int ecat63WriteNormheader(FILE *fp, int block, ECAT63_normheader *h)
{
  unsigned char buf[MatBLKSIZE];
  int little, tovax;

  if(ECAT63_TEST) printf("ecat63WriteNormheader(fp, %d, nh)\n", block);
  little=little_endian();
  /* Clear buf */
  memset(buf, 0, MatBLKSIZE);
  /* Check arguments */
  if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
  if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
    tovax=1; else tovax=0;

  /* Copy short ints to buf */
  memcpy(buf+126, &h->data_type, 2);
  memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
  memcpy(buf+372, &h->norm_hour, 2);
  memcpy(buf+376, &h->norm_minute, 2);
  memcpy(buf+380, &h->norm_second, 2);
  memcpy(buf+384, &h->norm_day, 2);
  memcpy(buf+388, &h->norm_month, 2);
  memcpy(buf+392, &h->norm_year, 2);
  /* big to little endian if necessary */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats to buf */
  ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
  ecat63wFloat(&h->fov_source_width, buf+198, tovax, little);

  /* Write subheader */
  fseek(fp, (block-1)*MatBLKSIZE, SEEK_SET);
  if(ftell(fp)!=(block-1)*MatBLKSIZE) return(2);
  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);

  return(0);
}
예제 #10
0
/*!
 * Write ECAT 6.3 attenuation header
 *
 * @param fp target file pointer
 * @param block block number [>=3]
 * @param h Ecat 6.3 attenuation header
 * @return 0 if ok, 1 invalid input, 2 failed to find block, 
 * 3 failed to write block
 */
int ecat63WriteAttnheader(FILE *fp, int block, ECAT63_attnheader *h) {
  unsigned char buf[MatBLKSIZE];
  int little, tovax;

  if(ECAT63_TEST) printf("ecat63WriteAttnheader(fp, %d, ah)\n", block);
  little=little_endian();
  /* Clear buf */
  memset(buf, 0, MatBLKSIZE);
  /* Check arguments */
  if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
  if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
    tovax=1; else tovax=0;

  /* Copy short ints to buf */
  memcpy(buf+126, &h->data_type, 2); memcpy(buf+128, &h->attenuation_type, 2);
  memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
  /* big to little endian if necessary */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats to buf */
  ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
  ecat63wFloat(&h->x_origin, buf+186, tovax, little);
  ecat63wFloat(&h->y_origin, buf+190, tovax, little);
  ecat63wFloat(&h->x_radius, buf+194, tovax, little);
  ecat63wFloat(&h->y_radius, buf+198, tovax, little);
  ecat63wFloat(&h->tilt_angle, buf+202, tovax, little);
  ecat63wFloat(&h->attenuation_coeff, buf+206, tovax, little);
  ecat63wFloat(&h->sample_distance, buf+210, tovax, little);

  /* Write subheader */
  fseek(fp, (block-1)*MatBLKSIZE, SEEK_SET);
  if(ftell(fp)!=(block-1)*MatBLKSIZE) return(2);
  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);

  return(0);
}
예제 #11
0
int anaReadHeader(const char *filename, ANALYZE_DSR *h)
{
    unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
    unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
    unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
    int little; /* 1 if current platform is little endian (i386), else 0 */
    FILE *fp;
    int ret, nr, s1, s2, same_order;

    if(ANALYZE_TEST) printf("anaReadHeader(%s, *dsr)\n", filename);

    /* Check arguments */
    if(strlen(filename)<1 || h==NULL)
    {
        printf("could not open file : %s, or the ANALYZE_DSR is not allocated", filename);
        return 1;
    }
    little = little_endian();

    /* Open file */
    fp=fopen(filename, "rb");
    if(fp==NULL)
    {
        printf("could not open file : %s", filename);
        return 2;
    }


    /* Get file size */
    nr=0; while((ret=fgetc(fp))!=EOF) nr++; rewind(fp);
    if(nr<1)
    {
        fclose(fp);
        return(3);
    }

    /* Read Analyze header key */
   if(fread(buf1, ANALYZE_HEADER_KEY_SIZE, 1, fp)<1) return(3);
   /* Read Analyze header image dimension */
   if(fread(buf2, ANALYZE_HEADER_IMGDIM_SIZE, 1, fp)<1) return(3);
   /* Read Analyze header image data history */
   memset(buf3, 0, sizeof(data_history));
   ret=fread(buf3, ANALYZE_HEADER_HISTORY_SIZE, 1, fp);
   if(ANALYZE_TEST>1 && ret<1) printf(" complete data_history not found.\n");

    /* Close file */
    fclose(fp);


    /* Compare file size from header contents to the calculated value */
    /* to determine whether Analyze file is in little or big endian */
    memcpy(&s1, buf1+0, 4);
    s2=s1;
    swawbip(&s2, 4);
    if( abs(s1 - nr) < abs(s2 - nr))
    {
        same_order=1;
    }

    else
    {
        same_order=0;
    }

    if(ANALYZE_TEST>1) printf("same byte order: %d (s1=%d s2=%d nr=%d)\n",
        same_order, s1, s2, nr);
    if(same_order) h->little=little;
    else {if(little) h->little=0; else h->little=1;}

    /* Set key header structure contents */
    if(!same_order) swawbip(buf1+0, 4); memcpy(&h->hk.sizeof_hdr, buf1+0, 4);
    memcpy(h->hk.data_type, buf1+4, 10);
    memcpy(h->hk.db_name, buf1+14, 18);
    if(!same_order) swawbip(buf1+32, 4); memcpy(&h->hk.extents, buf1+32, 4);
    if(!same_order) swabip(buf1+36, 2); memcpy(&h->hk.session_error, buf1+36, 2);
    memcpy(&h->hk.regular, buf1+38, 1);
    memcpy(&h->hk.hkey_un0, buf1+39, 1);

    /* Set image dimension header structure contents */
    if(!same_order) swabip(buf2+0, 16); memcpy(h->dime.dim, buf2+0, 16);
    if(!same_order) swabip(buf2+16, 2); memcpy(&h->dime.unused8, buf2+16, 2);
    if(!same_order) swabip(buf2+18, 2); memcpy(&h->dime.unused9, buf2+18, 2);
    if(!same_order) swabip(buf2+20, 2); memcpy(&h->dime.unused10, buf2+20, 2);
    if(!same_order) swabip(buf2+22, 2); memcpy(&h->dime.unused11, buf2+22, 2);
    if(!same_order) swabip(buf2+24, 2); memcpy(&h->dime.unused12, buf2+24, 2);
    if(!same_order) swabip(buf2+26, 2); memcpy(&h->dime.unused13, buf2+26, 2);
    if(!same_order) swabip(buf2+28, 2); memcpy(&h->dime.unused14, buf2+28, 2);
    if(!same_order) swabip(buf2+30, 2); memcpy(&h->dime.datatype, buf2+30, 2);
    if(!same_order) swabip(buf2+32, 2); memcpy(&h->dime.bitpix, buf2+32, 2);
    if(!same_order) swabip(buf2+34, 2); memcpy(&h->dime.dim_un0, buf2+34, 2);
    if(!same_order) swawbip(buf2+36, 32); memcpy(h->dime.pixdim, buf2+36, 32);
    if(!same_order) swawbip(buf2+68, 4); memcpy(&h->dime.vox_offset, buf2+68, 4);
    if(!same_order) swawbip(buf2+72, 4); memcpy(&h->dime.funused1, buf2+72, 4);
    if(!same_order) swawbip(buf2+76, 4); memcpy(&h->dime.funused2, buf2+76, 4);
    if(!same_order) swawbip(buf2+80, 4); memcpy(&h->dime.funused3, buf2+80, 4);
    if(!same_order) swawbip(buf2+84, 4); memcpy(&h->dime.cal_max, buf2+84, 4);
    if(!same_order) swawbip(buf2+88, 4); memcpy(&h->dime.cal_min, buf2+88, 4);
    if(!same_order) swawbip(buf2+92, 4); memcpy(&h->dime.compressed, buf2+92, 4);
    if(!same_order) swawbip(buf2+96, 4); memcpy(&h->dime.verified, buf2+96, 4);
    if(!same_order) swawbip(buf2+100, 4); memcpy(&h->dime.glmax, buf2+100, 4);
    if(!same_order) swawbip(buf2+104, 4); memcpy(&h->dime.glmin, buf2+104, 4);

    /* Set data history header structure contents */
    memcpy(h->hist.descrip, buf3+0, 80);
    memcpy(h->hist.aux_file, buf3+80, 24);
    memcpy(&h->hist.orient, buf3+104, 1);
    memcpy(h->hist.originator, buf3+105, 10);
    memcpy(h->hist.generated, buf3+115, 10);
    memcpy(h->hist.scannum, buf3+125, 10);
    memcpy(h->hist.patient_id, buf3+135, 10);
    memcpy(h->hist.exp_date, buf3+145, 10);
    memcpy(h->hist.exp_time, buf3+155, 10);
    memcpy(h->hist.hist_un0, buf3+165, 3);
    if(!same_order) swawbip(buf3+168, 4); memcpy(&h->hist.views, buf3+168, 4);
    if(!same_order) swawbip(buf3+172, 4); memcpy(&h->hist.vols_added, buf3+172, 4);
    if(!same_order) swawbip(buf3+176, 4); memcpy(&h->hist.start_field, buf3+176,4);
    if(!same_order) swawbip(buf3+180, 4); memcpy(&h->hist.field_skip, buf3+180, 4);
    if(!same_order) swawbip(buf3+184, 4); memcpy(&h->hist.omax, buf3+184, 4);
    if(!same_order) swawbip(buf3+188, 4); memcpy(&h->hist.omin, buf3+188, 4);
    if(!same_order) swawbip(buf3+192, 4); memcpy(&h->hist.smax, buf3+192, 4);
    if(!same_order) swawbip(buf3+196, 4); memcpy(&h->hist.smin, buf3+196, 4);

    /* Check header contents */
    if(h->hk.extents!=16384 && h->hk.extents!=0) {
        if(ANALYZE_TEST>1) printf("hk.extents := %d\n", h->hk.extents);
        return(11);
    }
    if(h->hk.regular!='r') {
        if(ANALYZE_TEST>1) printf("hk.regular := %c\n", h->hk.regular);
        return(12);
    }

    return(0);
}
예제 #12
0
int anaWriteHeader(
    const char *filename,
    const ANALYZE_DSR *h
) {
    unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
    unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
    unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
    FILE *fp;
    int same_order, little;


    if(ANALYZE_TEST) printf("anaWriteHeader(%s, *dsr)\n", filename);

    /* Check arguments */
    if(strlen(filename)<1 || h==NULL) return(1);
    little=little_endian();
    if(little==h->little) same_order=1; else same_order=0;

    /* Copy header contents into buffers */
    /* Header key */
    memset(buf1, 0, ANALYZE_HEADER_KEY_SIZE);
    memcpy(buf1+0, &h->hk.sizeof_hdr, 4); if(!same_order) swawbip(buf1+0, 4);
    memcpy(buf1+4, &h->hk.data_type, 10);
    memcpy(buf1+14, &h->hk.db_name, 18);
    memcpy(buf1+32, &h->hk.extents, 4); if(!same_order) swawbip(buf1+32, 4);
    memcpy(buf1+36, &h->hk.session_error, 2); if(!same_order) swabip(buf1+36, 2);
    memcpy(buf1+38, &h->hk.regular, 1);
    memcpy(buf1+39, &h->hk.hkey_un0, 1);
    /* Image dimension */
    memset(buf2, 0, ANALYZE_HEADER_IMGDIM_SIZE);
    memcpy(buf2+0, h->dime.dim, 16); if(!same_order) swabip(buf2+0, 16);
    memcpy(buf2+16, &h->dime.unused8, 2); if(!same_order) swabip(buf2+16, 2);
    memcpy(buf2+18, &h->dime.unused9, 2); if(!same_order) swabip(buf2+18, 2);
    memcpy(buf2+20, &h->dime.unused10, 2); if(!same_order) swabip(buf2+20, 2);
    memcpy(buf2+22, &h->dime.unused11, 2); if(!same_order) swabip(buf2+22, 2);
    memcpy(buf2+24, &h->dime.unused12, 2); if(!same_order) swabip(buf2+24, 2);
    memcpy(buf2+26, &h->dime.unused13, 2); if(!same_order) swabip(buf2+26, 2);
    memcpy(buf2+28, &h->dime.unused14, 2); if(!same_order) swabip(buf2+28, 2);
    memcpy(buf2+30, &h->dime.datatype, 2); if(!same_order) swabip(buf2+30, 2);
    memcpy(buf2+32, &h->dime.bitpix, 2); if(!same_order) swabip(buf2+32, 2);
    memcpy(buf2+34, &h->dime.dim_un0, 2); if(!same_order) swabip(buf2+34, 2);
    memcpy(buf2+36, h->dime.pixdim, 32); if(!same_order) swawbip(buf2+36, 32);
    memcpy(buf2+68, &h->dime.vox_offset, 4); if(!same_order) swawbip(buf2+68, 4);
    memcpy(buf2+72, &h->dime.funused1, 4); if(!same_order) swawbip(buf2+72, 4);
    memcpy(buf2+76, &h->dime.funused2, 4); if(!same_order) swawbip(buf2+76, 4);
    memcpy(buf2+80, &h->dime.funused3, 4); if(!same_order) swawbip(buf2+80, 4);
    memcpy(buf2+84, &h->dime.cal_max, 4); if(!same_order) swawbip(buf2+84, 4);
    memcpy(buf2+88, &h->dime.cal_min, 4); if(!same_order) swawbip(buf2+88, 4);
    memcpy(buf2+92, &h->dime.compressed, 4); if(!same_order) swawbip(buf2+92, 4);
    memcpy(buf2+96, &h->dime.verified, 4); if(!same_order) swawbip(buf2+96, 4);
    memcpy(buf2+100, &h->dime.glmax, 4); if(!same_order) swawbip(buf2+100, 4);
    memcpy(buf2+104, &h->dime.glmin, 4); if(!same_order) swawbip(buf2+104, 4);
    /* Data history */
    memset(buf3, 0, ANALYZE_HEADER_HISTORY_SIZE);
    memcpy(buf3+0, &h->hist.descrip, 80);
    memcpy(buf3+80, &h->hist.aux_file, 24);
    memcpy(buf3+104, &h->hist.orient, 1);
    memcpy(buf3+105, &h->hist.originator, 10);
    memcpy(buf3+115, &h->hist.generated, 10);
    memcpy(buf3+125, &h->hist.scannum, 10);
    memcpy(buf3+135, &h->hist.patient_id, 10);
    memcpy(buf3+145, &h->hist.exp_date, 10);
    memcpy(buf3+155, &h->hist.exp_time, 10);
    memcpy(buf3+165, &h->hist.hist_un0, 3);
    memcpy(buf3+168, &h->hist.views, 4); if(!same_order) swawbip(buf3+168, 4);
    memcpy(buf3+172, &h->hist.vols_added,4); if(!same_order) swawbip(buf3+172, 4);
    memcpy(buf3+176, &h->hist.start_field,4); if(!same_order) swawbip(buf3+176,4);
    memcpy(buf3+180, &h->hist.field_skip,4); if(!same_order) swawbip(buf3+180, 4);
    memcpy(buf3+184, &h->hist.omax, 4); if(!same_order) swawbip(buf3+184, 4);
    memcpy(buf3+188, &h->hist.omin, 4); if(!same_order) swawbip(buf3+188, 4);
    memcpy(buf3+192, &h->hist.smax, 4); if(!same_order) swawbip(buf3+192, 4);
    memcpy(buf3+196, &h->hist.smin, 4); if(!same_order) swawbip(buf3+196, 4);

    /* Open header file for write */
    fp=fopen(filename, "wb"); if(fp==NULL) return(2);
    /* Write header key */
    if(fwrite(buf1, 1, ANALYZE_HEADER_KEY_SIZE, fp)
             != ANALYZE_HEADER_KEY_SIZE)
    {
        fclose(fp); return(3);
    }
    /* Write image dimension */
    if(fwrite(buf2, 1, ANALYZE_HEADER_IMGDIM_SIZE, fp)
             != ANALYZE_HEADER_IMGDIM_SIZE)
    {
        fclose(fp); return(4);
    }
    /* Write data history */
    if(fwrite(buf3, 1, ANALYZE_HEADER_HISTORY_SIZE, fp)
             != ANALYZE_HEADER_HISTORY_SIZE)
    {
        fclose(fp); return(5);
    }
    fclose(fp);

    return(0);
}
예제 #13
0
int anaReadImagedata(const char *filename, const ANALYZE_DSR *h, int frame, char *data) {
    int dimNr, dimx, dimy, dimz=1, dimt=1, pxlNr=0;
    int i, n, little, start_pos, rawSize;
    char *mdata, *mptr;
    char *fptr;
    float f;
    short int *sptr;
    int *iptr;
    double d;
    FILE *fp;

    /* Open file */
    fp=fopen(filename, "rb");
    if(fp==NULL)
    {
        printf("could not open Image File: %s", filename);
        return 2;
    }

    if(ANALYZE_TEST) printf("anaReadImagedata(fp, h, %d, data)\n", frame);

    /* Check the arguments */
    if(frame<=0 || h==NULL || data==NULL)
    {
        printf("frame must be positive integer, Analyze header filled and the data allocated");
        return 1;
    }

    /* Get the image dimensions from header */
    dimNr=h->dime.dim[0]; if(dimNr<2) return(2);
    dimx=h->dime.dim[1];
    dimy=h->dime.dim[2];
    if(dimNr>2) dimz=h->dime.dim[3];
    if(dimNr>3) dimt=h->dime.dim[4]; if(frame>dimt) return(3);
    pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);

    /* Allocate memory for the binary data */
    if(h->dime.bitpix<8) return(5); /* We don't support bit data */
    rawSize=pxlNr*(h->dime.bitpix/8); if(rawSize<1) return(5);
    if(ANALYZE_TEST>0) printf("  pxlNr=%d  rawSize=%d\n", pxlNr, rawSize);
    mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);

    /* Seek the start of current frame data */
    start_pos=(frame-1)*rawSize;
    n=(int)h->dime.vox_offset; if((n>0 && frame==1) || (n<0)) start_pos+=abs(n);
    if(ANALYZE_TEST>2) printf("start_pos=%d\n", start_pos);
    fseek(fp, start_pos, SEEK_SET);
    if(ftell(fp)!=start_pos) {
        if(ANALYZE_TEST>5) printf("could not move to start_pos\n");
        free(mdata); return(7);
    }

    /* Read the data */
    mptr=mdata;
    if((n=fread(mptr, rawSize, 1, fp)) < 1) {
        if(ANALYZE_TEST>5)
            printf("could read only %d bytes when request was %d\n", n, rawSize);
        free(mdata); return(8);
    }

    /* Convert byte order if necessary */
    little=little_endian(); mptr=mdata;
    if(little!=h->little) {
        if(ANALYZE_TEST>0) printf("byte conversion\n");
        switch(h->dime.bitpix) {
            case 8: /* no conversion needed */ break;
            case 16: swabip(mptr, rawSize); break;
            case 32: swawbip(mptr, rawSize); break;
            case 64: swawbip(mptr, rawSize); break;
            default:
                if(ANALYZE_TEST>5)
                    printf("unsupported anahdr.dime.bitpix := %d\n", h->dime.bitpix);
                free(mdata); return(5);
        }
    }

    /* Get scale factor */
    f=1.0;
    if(h->dime.funused1>0.0) f*=h->dime.funused1;

    /* Copy data to float pixel values */
    mptr=mdata; fptr=data;
    switch(h->dime.datatype) {
        case ANALYZE_DT_UNSIGNED_CHAR:

            if(h->dime.bitpix!=8) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            for(i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(char)(*mptr);
            break;
        case ANALYZE_DT_SIGNED_SHORT:
            if(h->dime.bitpix!=16) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
                sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
            }
            break;
        case ANALYZE_DT_SIGNED_INT:
            if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            if(h->dime.bitpix==16) {
                for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
                    iptr=(int*)mptr; *fptr=f*(float)(*iptr);
                }
            } else if(h->dime.bitpix==32) {
                for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
                    iptr=(int*)mptr; *fptr=f*(float)(*iptr);
                }
            }
            break;
        case ANALYZE_DT_FLOAT:
            if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            if(h->dime.bitpix==16) {
                memcpy(fptr, mptr, pxlNr*4);
                for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
            } else if(h->dime.bitpix==32) {
                memcpy(fptr, mptr, pxlNr*4);
                for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
            }
            break;
        case ANALYZE_DT_COMPLEX:
            if(h->dime.bitpix!=32) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            if(h->dime.bitpix==32) {
                memcpy(fptr, mptr, pxlNr*4);
                for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
            }
            break;
        case ANALYZE_DT_DOUBLE:
            if(h->dime.bitpix!=32) {
                if(ANALYZE_TEST>5)
                    printf("invalid combination of datatype and bitpix (%d, %d)\n",
                        h->dime.datatype, h->dime.bitpix);
                free(mdata); return(5);
            }
            for(i=0; i<pxlNr; i++, mptr+=8, fptr++) {
                memcpy(&d, mptr, 8); *fptr=f*d;
            }
            break;
        default:
            if(ANALYZE_TEST>5)
                printf("unsupported anahdr.dime.datatype := %d\n", h->dime.datatype);
            free(mdata); return(5);
    }

    fclose(fp);
    free(mdata);
    if(ANALYZE_TEST>1) printf("anaReadImagedata() succeeded\n");
    return(0);
}
예제 #14
0
/*!
 * Read ECAT 6.3 scan header
 *
 * @param fp file pointer
 * @param blk block number [2..number of blocks]
 * @param h Ecat 6.3 scan header
 * @return 0 if ok, 1 invalid input, 2 failed to find block, 
 * 3 failed to read block, 4 invalid data type, 5 invalid scale factor, 
 * 6 invalid frame duration
 */
int ecat63ReadScanheader(FILE *fp, int blk, ECAT63_scanheader *h) {
  unsigned char buf[MatBLKSIZE];
  int i;
  int little; /* 1 if current platform is little endian (i386), else 0 */
  int vaxdata=1; /* 1 if data is in VAX format, else 0 */

  if(ECAT63_TEST) printf("ecat63ReadScanheader(fp, %d, sh)\n", blk);
  if(fp==NULL || blk<2 || h==NULL) return(1);
  little=little_endian();
  /* Seek the subheader block */
  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
  /* Read the subheader block */
  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);

  /* Copy char data to header structure */
  memcpy(h->fill1, buf+0, 126);

  /* Copy short ints */
  /* in big endian platform, change byte order temporarily */
  if(!little) swabip(buf, MatBLKSIZE);
  memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
  /*printf("data_type=%d\n", h->data_type);*/
  memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
  memcpy(&h->smoothing, buf+136, 2); memcpy(&h->processing_code, buf+138, 2);
  memcpy(&h->frame_duration_sec, buf+170, 2);
  memcpy(&h->scan_min, buf+192, 2); memcpy(&h->scan_max, buf+194, 2);
  memcpy(h->fill2, buf+468, 44);
  /* Change back the byte order */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy ints */
  h->gate_duration=ecat63rInt(buf+172, vaxdata, little);
  h->r_wave_offset=ecat63rInt(buf+176, vaxdata, little);
  h->prompts=ecat63rInt(buf+196, vaxdata, little);
  h->delayed=ecat63rInt(buf+200, vaxdata, little);
  h->multiples=ecat63rInt(buf+204, vaxdata, little);
  h->net_trues=ecat63rInt(buf+208, vaxdata, little);
  h->total_coin_rate=ecat63rInt(buf+452, vaxdata, little);
  h->frame_start_time=ecat63rInt(buf+456, vaxdata, little);
  h->frame_duration=ecat63rInt(buf+460, vaxdata, little);

  /* Copy floats */
  h->sample_distance=ecat63rFloat(buf+146, vaxdata, little);
  h->isotope_halflife=ecat63rFloat(buf+166, vaxdata, little);
  h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
  for(i=0; i<16; i++) h->cor_singles[i]=ecat63rFloat(buf+316+i*4, vaxdata, little);
  for(i=0; i<16; i++) h->uncor_singles[i]=ecat63rFloat(buf+380+i*4, vaxdata, little);
  h->tot_avg_cor=ecat63rFloat(buf+444, vaxdata, little);
  h->tot_avg_uncor=ecat63rFloat(buf+448, vaxdata, little);
  h->loss_correction_fctr=ecat63rFloat(buf+464, vaxdata, little);

  /* Check that most important contents are ok */
  if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
    if(ECAT63_TEST) printf("Invalid data types; probable conversion error.\n");
    return(4);
  }
  if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
    if(ECAT63_TEST) printf("Invalid scale factor; probable conversion error.\n");
    return(5);
  }
  if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
    if(ECAT63_TEST) printf("Invalid frame duration; probable conversion error.\n");
    return(6);
  }

  return(0);
}
예제 #15
0
/*!
 * Write ECAT 6.3 main header.
 *
 * @param fp target file pointer
 * @param h Ecat 6.3 main header
 * @return 0, if ok, 1 invalid input, 2 failed to find block,
 * 3 failed to write block
 */
int ecat63WriteMainheader(FILE *fp, ECAT63_mainheader *h) {
  char buf[MatBLKSIZE];
  int i, little, tovax;


  if(ECAT63_TEST) printf("ecat63WriteMainheader()\n");
  little=little_endian();
  /* Clear buf */
  memset(buf, 0, MatBLKSIZE);
  /* Check arguments */
  if(fp==NULL || h->data_type<1 || h->data_type>7) return(1);
  if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
    tovax=1; else tovax=0;

  /* Copy short ints to buf */
  memcpy(buf+50, &h->data_type, 2); memcpy(buf+48, &h->sw_version, 2);
  memcpy(buf+52, &h->system_type, 2); memcpy(buf+54, &h->file_type, 2);
  memcpy(buf+66, &h->scan_start_day, 2); memcpy(buf+68, &h->scan_start_month, 2);
  memcpy(buf+70, &h->scan_start_year, 2); memcpy(buf+72, &h->scan_start_hour, 2);
  memcpy(buf+74, &h->scan_start_minute, 2); memcpy(buf+76, &h->scan_start_second, 2);
  memcpy(buf+134, &h->rot_source_speed, 2); memcpy(buf+136, &h->wobble_speed, 2);
  memcpy(buf+138, &h->transm_source_type, 2); memcpy(buf+148, &h->transaxial_samp_mode, 2);
  memcpy(buf+150, &h->coin_samp_mode, 2); memcpy(buf+152, &h->axial_samp_mode, 2);
  memcpy(buf+158, &h->calibration_units, 2); memcpy(buf+160, &h->compression_code, 2);
  memcpy(buf+350, &h->acquisition_type, 2); memcpy(buf+352, &h->bed_type, 2);
  memcpy(buf+354, &h->septa_type, 2); memcpy(buf+376, &h->num_planes, 2);
  memcpy(buf+378, &h->num_frames, 2); memcpy(buf+380, &h->num_gates, 2);
  memcpy(buf+382, &h->num_bed_pos, 2); memcpy(buf+452, &h->lwr_sctr_thres, 2);
  memcpy(buf+454, &h->lwr_true_thres, 2); memcpy(buf+456, &h->upr_true_thres, 2);
  memcpy(buf+472, h->fill2, 40);
  /* big to little endian if necessary */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats to buf */
  ecat63wFloat(&h->isotope_halflife, buf+86, tovax, little);
  ecat63wFloat(&h->gantry_tilt, buf+122, tovax, little);
  ecat63wFloat(&h->gantry_rotation, buf+126, tovax, little);
  ecat63wFloat(&h->bed_elevation, buf+130, tovax, little);
  ecat63wFloat(&h->axial_fov, buf+140, tovax, little);
  ecat63wFloat(&h->transaxial_fov, buf+144, tovax, little);
  ecat63wFloat(&h->calibration_factor, buf+154, tovax, little);
  ecat63wFloat(&h->init_bed_position, buf+384, tovax, little);
  for(i=0; i<15; i++) ecat63wFloat(&h->bed_offset[i], buf+388+4*i, tovax, little);
  ecat63wFloat(&h->plane_separation, buf+448, tovax, little);
  ecat63wFloat(&h->init_bed_position, buf+458, tovax, little);

  /* Copy chars */
  /*memcpy(buf+0, h->ecat_format, 14);*/
  memcpy(buf+14, h->fill1, 14);
  memcpy(buf+28, h->original_file_name, 20); memcpy(buf+56, h->node_id, 10);
  memcpy(buf+78, h->isotope_code, 8); memcpy(buf+90, h->radiopharmaceutical, 32);
  memcpy(buf+162, h->study_name, 12); memcpy(buf+174, h->patient_id, 16);
  memcpy(buf+190, h->patient_name, 32); buf[222]=h->patient_sex;
  memcpy(buf+223, h->patient_age, 10); memcpy(buf+233, h->patient_height, 10);
  memcpy(buf+243, h->patient_weight, 10); buf[253]=h->patient_dexterity;
  memcpy(buf+254, h->physician_name, 32); memcpy(buf+286, h->operator_name, 32);
  memcpy(buf+318, h->study_description, 32); memcpy(buf+356, h->facility_name, 20);
  memcpy(buf+462, h->user_process_code, 10);

  /* Write main header */
  fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(2);
  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);

  return(0);
}
예제 #16
0
/*!
 * Read ECAT 6.3 main header
 *
 * @param fp file pointer
 * @param h target Ecat 6.3 main header struture
 * @return 0 if ok, 1 invalid input, 2 failed to find subheader block, 
 * 3 invalid magic number (should be "ECAT63") at start of file, 
 * 5 invalid data type, 6 invalid calibration factor, 7 invalid file type
 */
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h) {
  unsigned char buf[MatBLKSIZE];
  int i;
  int little; /* 1 if current platform is little endian (i386), else 0 */
  int vaxdata=1; /* 1 if data is in VAX format, else 0 */

  if(ECAT63_TEST) printf("ecat63ReadMainheader()\n");
  if(fp==NULL || h==NULL) return(1);
  little=little_endian();
  /* Seek the first block */
  fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(1);
  /* Read the subheader block */
  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(2);

  /* Copy char data to header structure */
  memcpy(h->ecat_format, buf+0, 14); memcpy(h->fill1, buf+14, 14);
  memcpy(h->original_file_name, buf+28, 20); memcpy(h->node_id, buf+56, 10);
  memcpy(h->isotope_code, buf+78, 8); memcpy(h->radiopharmaceutical, buf+90, 32);
  memcpy(h->study_name, buf+162, 12); memcpy(h->patient_id, buf+174, 16);
  memcpy(h->patient_name, buf+190, 32); h->patient_sex=buf[222];
  memcpy(h->patient_age, buf+223, 10); memcpy(h->patient_height, buf+233, 10);
  memcpy(h->patient_weight, buf+243, 10); h->patient_dexterity=buf[253];
  memcpy(h->physician_name, buf+254, 32); memcpy(h->operator_name, buf+286, 32);
  memcpy(h->study_description, buf+318, 32); memcpy(h->facility_name, buf+356, 20);
  memcpy(h->user_process_code, buf+462, 10);

  /* Copy short ints */
  /* in big endian platform, change byte order temporarily */
  if(!little) swabip(buf, MatBLKSIZE);
  memcpy(&h->data_type, buf+50, 2); if(h->data_type>4) vaxdata=0;
  /*printf("main_header.data_type=%d\n", h->data_type);*/
  memcpy(&h->sw_version, buf+48, 2);
  memcpy(&h->system_type, buf+52, 2); memcpy(&h->file_type, buf+54, 2);
  memcpy(&h->scan_start_day, buf+66, 2); memcpy(&h->scan_start_month, buf+68, 2);
  memcpy(&h->scan_start_year, buf+70, 2); memcpy(&h->scan_start_hour, buf+72, 2);
  memcpy(&h->scan_start_minute, buf+74, 2); memcpy(&h->scan_start_second, buf+76, 2);
  memcpy(&h->rot_source_speed, buf+134, 2); memcpy(&h->wobble_speed, buf+136, 2);
  memcpy(&h->transm_source_type, buf+138, 2); memcpy(&h->transaxial_samp_mode, buf+148, 2);
  memcpy(&h->coin_samp_mode, buf+150, 2); memcpy(&h->axial_samp_mode, buf+152, 2);
  memcpy(&h->calibration_units, buf+158, 2); memcpy(&h->compression_code, buf+160, 2);
  memcpy(&h->acquisition_type, buf+350, 2); memcpy(&h->bed_type, buf+352, 2);
  memcpy(&h->septa_type, buf+354, 2); memcpy(&h->num_planes, buf+376, 2);
  memcpy(&h->num_frames, buf+378, 2); memcpy(&h->num_gates, buf+380, 2);
  memcpy(&h->num_bed_pos, buf+382, 2); memcpy(&h->lwr_sctr_thres, buf+452, 2);
  memcpy(&h->lwr_true_thres, buf+454, 2); memcpy(&h->upr_true_thres, buf+456, 2);
  memcpy(h->fill2, buf+472, 40);
  /* Change back the byte order */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy floats */
  h->isotope_halflife=ecat63rFloat(buf+86, vaxdata, little);
  h->gantry_tilt=ecat63rFloat(buf+122, vaxdata, little);
  h->gantry_rotation=ecat63rFloat(buf+126, vaxdata, little);
  h->bed_elevation=ecat63rFloat(buf+130, vaxdata, little);
  h->axial_fov=ecat63rFloat(buf+140, vaxdata, little);
  h->transaxial_fov=ecat63rFloat(buf+144, vaxdata, little);
  h->calibration_factor=ecat63rFloat(buf+154, vaxdata, little);
  h->init_bed_position=ecat63rFloat(buf+384, vaxdata, little);
  for(i=0; i<15; i++) h->bed_offset[i]=ecat63rFloat(buf+388+i*4, vaxdata, little);
  h->plane_separation=ecat63rFloat(buf+448, vaxdata, little);
  h->collimator=ecat63rFloat(buf+458, vaxdata, little);

  /* Check file format and platform */
  if(ECAT63_TEST) printf("ecat_format='%.14s'\n", h->ecat_format);
  /* if format is not specified, ECAT63 is assumed */
  if(h->ecat_format[0]==(char)0) {
    strcpy(h->ecat_format, "ECAT63");
  }
  /* only ECAT63 format is approved here */
  if(ECAT63_TEST) printf("ecat_format='%.14s'\n", h->ecat_format);
  if(strncmp(h->ecat_format, "ECAT63", 6)!=0) return(3);

  /* Check that most important contents are ok */
  if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
    if(ECAT63_TEST) printf("Invalid data types; probable conversion error.\n");
    return(5);
  }
  if(h->calibration_factor<0.0 || h->calibration_factor>1.0e12) {
    if(ECAT63_TEST) printf("Invalid calibration factor; possible conversion error.\n");
    return(6);
  }
  if(h->file_type!=RAW_DATA && h->file_type!=IMAGE_DATA &&
     h->file_type!=ATTN_DATA && h->file_type!=NORM_DATA) {
    if(ECAT63_TEST) printf("Invalid file types; probable conversion error.\n");
    return(7);
  }

  return(0);
}
예제 #17
0
파일: img_ana.c 프로젝트: phoboz/volkit
/*!
 * Write Analyze 7.5 image.
 *   Analyze database name must be given with path. Path must exist.
 *   Image and header files with .img and .hdr extensions are created.
 *   Existing files are overwritten.
 *   anaFlipping() determines whether image is flipped in z-direction;
 *   image is always flipped in x,y-directions.
 *   Byte order is determined based on _fileFormat field.
 * 
 * @param dbname analyze database name with path, without extension
 * @param img pointer to IMG data
 * @return 0 if ok, 1 invalid input, 2 invalid image status (image not occupied), 
 * 3 failed to resolve extreme values (min and max),
 * 12 failed to allocate temp memory, 14 failed to open file for writing,
 * 15 failed to write data, 21 failed to write header, and
 * sets IMG->statmsg in case of error
*/
int imgWriteAnalyze(const char *dbname, IMG *img) {
  FILE *fp;
  int ret, fi, pi, xi, yi, little;
  float g;
  ANALYZE_DSR dsr;
  char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  const char *cptr;
  int pxlNr=0;
  struct tm *st;
  short int *sdata, *sptr, smin, smax;
  SIF sif;


  if(IMG_TEST) printf("imgWriteAnalyze(%s, *img)\n", dbname);

  /* Check the arguments */
  imgSetStatus(img, STATUS_OK);
  if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
    imgSetStatus(img, STATUS_FAULT); return(2);}
  if(dbname==NULL || !dbname[0]) {imgSetStatus(img, STATUS_FAULT); return(1);}
  
  /* Make the image and header filenames */  
  strcpy(datfile, dbname); strcat(datfile, ".img");
  strcpy(hdrfile, dbname); strcat(hdrfile, ".hdr");
  strcpy(siffile, dbname); strcat(siffile, ".sif");


  /*
   *  Fill Analyze header
   */
  if(img->_fileFormat==IMG_ANA_L) dsr.little=1; else dsr.little=0;
  /* Header key */
  memset(&dsr.hk, 0, sizeof(ANALYZE_HEADER_KEY));
  memset(&dsr.dime, 0, sizeof(ANALYZE_HEADER_IMGDIM));
  memset(&dsr.hist, 0, sizeof(ANALYZE_HEADER_HISTORY));
  dsr.hk.sizeof_hdr=348;
  strcpy(dsr.hk.data_type, "");
  cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
  if(cptr!=NULL) cptr++; if(cptr==NULL) cptr=dbname;
  strncpy(dsr.hk.db_name, cptr, 17);
  dsr.hk.extents=16384;
  dsr.hk.regular='r';
  /* Image dimension */
  dsr.dime.dim[0]=4;
  dsr.dime.dim[1]=img->dimx;
  dsr.dime.dim[2]=img->dimy;
  dsr.dime.dim[3]=img->dimz;
  dsr.dime.dim[4]=img->dimt;
  dsr.dime.datatype=ANALYZE_DT_SIGNED_SHORT;
  dsr.dime.bitpix=16;
  dsr.dime.pixdim[0]=0.0;
  dsr.dime.pixdim[1]=img->sizex;
  dsr.dime.pixdim[2]=img->sizey;
  dsr.dime.pixdim[3]=img->sizez;
  dsr.dime.pixdim[4]=0.0;
  dsr.dime.funused1=0.0; /* Scale factor is set later */
  /* dsr.dime.funused2=img->zoom; */ /* Reconstruction zoom */
  dsr.dime.funused3=img->isotopeHalflife;
  /* Data history */
  if(img->decayCorrection==IMG_DC_CORRECTED)
    strcpy(dsr.hist.descrip, "Decay corrected.");
  else if(img->decayCorrection==IMG_DC_NONCORRECTED) 
    strcpy(dsr.hist.descrip, "No decay correction.");
  else
    strcpy(dsr.hist.descrip, "");
  if(strlen(img->studyNr)>0 && strcmp(img->studyNr, ".")!=0)
    strncpy(dsr.hist.scannum, img->studyNr, 10);
  else
    strcpy(dsr.hist.scannum, "");
  st=localtime(&img->scanStart);
  if(st!=NULL) {
    strftime(dsr.hist.exp_date, 10, "%Y-%m-%d", st);
    strftime(dsr.hist.exp_time, 10, "%H:%M:%S", st);
  } else {
    strncpy(dsr.hist.exp_date, "1900-01-01", 10);
    strncpy(dsr.hist.exp_time, "00:00:00", 10);
  }

  /*
   *  Scale data to short int range
   *  Determine and set scale factor and cal_min & cal_max
   */
  if(IMG_TEST) printf("scaling data to short ints\n");
  ret=imgMinMax(img, &dsr.dime.cal_min, &dsr.dime.cal_max);
  if(ret) {imgSetStatus(img, STATUS_FAULT); return(3);}
  if(fabs(dsr.dime.cal_min)>fabs(dsr.dime.cal_max)) g=fabs(dsr.dime.cal_min);
  else g=fabs(dsr.dime.cal_max);
  if(g<1E-20) g=1.0; else g=32767./g; dsr.dime.funused1=1.0/g;
  if(IMG_TEST) printf("min=%g max=%g scale_factor=%g\n",
    dsr.dime.cal_min, dsr.dime.cal_max, dsr.dime.funused1);

  /* Allocate memory for short int array */
  pxlNr=(img->dimx)*(img->dimy)*(img->dimz);
  sdata=malloc(pxlNr*sizeof(short int));
  if(sdata==NULL) {
    imgSetStatus(img, STATUS_NOMEMORY);
    return 12;
  }

  /* Open image data file for write */
  if((fp=fopen(datfile, "wb")) == NULL) {
    imgSetStatus(img, STATUS_CANTWRITEIMGFILE);
    free(sdata);
    return 14;
  }

  /* Copy and write image matrix data to short int array */
  /* Data is written one frame at a time */
  smin=smax=temp_roundf(g*img->m[0][0][0][0]);
  for(fi=0; fi<img->dimt; fi++) {
    sptr=sdata;
    if(anaFlipping()==0) {
      for(pi=0; pi<img->dimz; pi++)
        for(yi=img->dimy-1; yi>=0; yi--)
          for(xi=img->dimx-1; xi>=0; xi--) {
            *sptr=temp_roundf(g*img->m[pi][yi][xi][fi]);
            if(*sptr>smax) smax=*sptr; else if(*sptr<smin) smin=*sptr;
            sptr++;
          }
    } else {
      for(pi=img->dimz-1; pi>=0; pi--)
        for(yi=img->dimy-1; yi>=0; yi--)
          for(xi=img->dimx-1; xi>=0; xi--) {
            *sptr=temp_roundf(g*img->m[pi][yi][xi][fi]);
            if(*sptr>smax) smax=*sptr; else if(*sptr<smin) smin=*sptr;
            sptr++;
          }
    }
    /* Change byte order if necessary */
    little=little_endian();
    if(little!=dsr.little)
      swabip(sdata, pxlNr*sizeof(short int));
    /* Write image data */
    if(fwrite(sdata, 2, pxlNr, fp) != pxlNr) {
      imgSetStatus(img, STATUS_CANTWRITEIMGFILE);
      free(sdata); fclose(fp);
      return 15;
    }
  }
  /* Done writing */
  fclose(fp);
  free(sdata);

  if(IMG_TEST) printf("smin=%d smax=%d\n", smin, smax);

  /* Set header glmin & glmax */
  dsr.dime.glmin=smin; dsr.dime.glmax=smax;
  
  /* Write Analyze header */
  ret=anaWriteHeader(hdrfile, &dsr);
  if(ret) {
    imgSetStatus(img, STATUS_CANTWRITEHEADERFILE);
    return 21;
  }
  imgSetStatus(img, STATUS_OK);

  /* Otherwise ready, but check if SIF should/can be written */
  sifInit(&sif);
  /* Try to read existing SIF */
  ret=sifRead(siffile, &sif);
  if(ret==0) { // SIF could be read
    if(sif.frameNr==img->dimt) {
      /* If size matches, then update the contents, but keep counts, in case
         previous SIF comes with actual count info from scanner */
      ret=img2sif(img, &sif, 1, 1, 0, IMG_TEST-2);
    } else {
      /* otherwise create SIF contents */
      ret=img2sif(img, &sif, 1, 1, 2, IMG_TEST-2);
    }
  } else {
    /* otherwise create SIF contents */
    ret=img2sif(img, &sif, 1, 1, 2, IMG_TEST-2);
  }
  if(ret!=0) {
    /* SIF data could not be made: do not give error, just do not write it */
    if(IMG_TEST>0) printf("SIF contents could not be filled.\n");
    return 0;
  }
  /* Write SIF */
  ret=sifWrite(&sif, siffile);  
  if(ret!=0) {
    /* SIF could not be written: do not give error, just do not write it */
    if(IMG_TEST>0)
      fprintf(stderr, "Error: SIF could not be written (%d).\n", ret);
  }

  imgSetStatus(img, STATUS_OK);
  return 0;
}
예제 #18
0
/*!
 * Read ECAT 6.3 image header
 *
 * @param fp file pointer
 * @param blk block number [2..number of blocks]
 * @param h Ecat 6.3 image header
 * @return 0 if ok, 1 invalid input, 2 failed to find block, 
 * 3 failed to read block, 4 invalid data type, 5 invalid calibration factor, 
 * 6 invalid frame duration
 */
int ecat63ReadImageheader(FILE *fp, int blk, ECAT63_imageheader *h) {
  unsigned char buf[MatBLKSIZE];
  int i;
  int little; /* 1 if current platform is little endian (i386), else 0 */
  int vaxdata=1; /* 1 if data is in VAX format, else 0 */

  if(ECAT63_TEST) printf("ecat63ReadImageheader(fp, %d ih)\n", blk);
  if(fp==NULL || blk<2 || h==NULL) return(1);
  little=little_endian();
  /* Seek the subheader block */
  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
  /* Read the subheader block */
  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);

  /* Copy char data to header structure */
  memcpy(h->fill1, buf+0, 126); memcpy(h->annotation, buf+420, 40);

  /* Copy short ints */
  /* in big endian platform, change byte order temporarily */
  if(!little) swabip(buf, MatBLKSIZE);
  memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
  /*printf("data_type=%d\n", h->data_type);*/
  memcpy(&h->num_dimensions, buf+128, 2);
  memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
  memcpy(&h->image_min, buf+176, 2); memcpy(&h->image_max, buf+178, 2);
  memcpy(&h->slice_location, buf+200, 2); memcpy(&h->recon_start_hour, buf+202, 2);
  memcpy(&h->recon_start_min, buf+204, 2); memcpy(&h->recon_start_sec, buf+206, 2);
  memcpy(&h->filter_code, buf+236, 2); memcpy(&h->processing_code, buf+376, 2);
  memcpy(&h->quant_units, buf+380, 2); memcpy(&h->recon_start_day, buf+382, 2);
  memcpy(&h->recon_start_month, buf+384, 2); memcpy(&h->recon_start_year, buf+386, 2);
  memcpy(h->fill2, buf+460, 52);
  /* Change back the byte order */
  if(!little) swabip(buf, MatBLKSIZE);

  /* Copy ints */
  h->frame_duration=ecat63rInt(buf+192, vaxdata, little);
  h->frame_start_time=ecat63rInt(buf+196, vaxdata, little);
  h->recon_duration=ecat63rInt(buf+208, vaxdata, little);
  h->scan_matrix_num=ecat63rInt(buf+238, vaxdata, little);
  h->norm_matrix_num=ecat63rInt(buf+242, vaxdata, little);
  h->atten_cor_mat_num=ecat63rInt(buf+246, vaxdata, little);

  /* Copy floats */
  h->x_origin=ecat63rFloat(buf+160, vaxdata, little);
  h->y_origin=ecat63rFloat(buf+164, vaxdata, little);
  h->recon_scale=ecat63rFloat(buf+168, vaxdata, little);
  h->quant_scale=ecat63rFloat(buf+172, vaxdata, little);
  h->pixel_size=ecat63rFloat(buf+184, vaxdata, little);
  h->slice_width=ecat63rFloat(buf+188, vaxdata, little);
  h->image_rotation=ecat63rFloat(buf+296, vaxdata, little);
  h->plane_eff_corr_fctr=ecat63rFloat(buf+300, vaxdata, little);
  h->decay_corr_fctr=ecat63rFloat(buf+304, vaxdata, little);
  h->loss_corr_fctr=ecat63rFloat(buf+308, vaxdata, little);
  h->intrinsic_tilt=ecat63rFloat(buf+312, vaxdata, little);
  h->ecat_calibration_fctr=ecat63rFloat(buf+388, vaxdata, little);
  h->well_counter_cal_fctr=ecat63rFloat(buf+392, vaxdata, little);
  for(i=0; i<6; i++) h->filter_params[i]=ecat63rFloat(buf+396+i*4, vaxdata, little);

  /* Check that most important contents are ok */
  if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
    if(ECAT63_TEST) printf("Invalid data types; probable conversion error.\n");
    return(4);
  }
  if(h->ecat_calibration_fctr<0.0 || h->ecat_calibration_fctr>1.0e10) {
    if(ECAT63_TEST) printf("Invalid calibration factor; probable conversion error.\n");
    return(5);
  }
  if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
    if(ECAT63_TEST) printf("Invalid frame duration; probable conversion error.\n");
    return(6);
  }

  return(0);
}
예제 #19
0
파일: img_ana.c 프로젝트: phoboz/volkit
/*!
 * Write one PET frame from IMG data struct into Analyze 7.5 database file.
 *  This function can be called repeatedly to write all frames one at a time
 *  to conserve memory. This function does not write SIF.
 *
 * @param dbname name of file where IMG contents will be written.
 *  If file does not exist, it is created.
 *  Make sure to delete existing file, unless you want to add data
 * @param frame_to_write PET frame number (1..frameNr) which will be written:
 *  If set to 0, frame data will be written to an existing or new PET file as
 *  a new frame, never overwriting existing data.
 *  If >0, then frame data is written as specified frame number, overwriting
 *  any data existing with the same frame number
 * @param img pointer to the IMG data struct
 * @param frame_index IMG frame index (0..dimt-1) which will be written
 * @param fmin minimum pixel value in all frames that will be written;
 *  used only when writing the first frame
 * @param fmax maximum pixel value in all frames that will be written;
 *  used only when writing the first frame
 * @return errstatus, which is STATUS_OK (0) when call was successful,
 * and >0 in case of an error.
 */
int imgWriteAnalyzeFrame(
  const char *dbname, int frame_to_write, IMG *img, int frame_index,
  float fmin, float fmax
) {
  IMG test_img;
  int ret=0, pxlNr, zi, xi, yi, little;
  FILE *fp;
  short int *sdata=NULL, *sptr;
  char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  ANALYZE_DSR dsr;
  float scale_factor=1.0;


  if(IMG_TEST) printf("\nimgWriteAnalyzeFrame(%s, %d, *img, %d, %g, %g)\n",
    dbname, frame_to_write, frame_index, fmin, fmax);

  /*
   *  Check the input 
   */
  if(dbname==NULL) return STATUS_FAULT;
  if(img==NULL) return STATUS_FAULT;
  if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
  if(frame_to_write<0) return STATUS_FAULT;
  if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
  if(img->_fileFormat!=IMG_ANA_L && img->_fileFormat!=IMG_ANA)
    return STATUS_FAULT;

  /*
   *  If database does not exist, then create it with new header,
   *  and if it does exist, then read and check header information.
   *  Create or edit header to contain correct frame nr.
   *  Determine the global scaling factor.   
   */
  imgInit(&test_img);
  if(anaDatabaseExists(dbname, hdrfile, datfile, siffile)==0) { // not existing

    /* Create database filenames */
    sprintf(hdrfile, "%s.hdr", dbname);
    sprintf(datfile, "%s.img", dbname);
    sprintf(siffile, "%s.sif", dbname);

    /* Set main header */
    imgSetAnalyzeHeader(img, dbname, &dsr, fmin, fmax);
    if(frame_to_write==0) frame_to_write=1;
    dsr.dime.dim[4]=frame_to_write;
    scale_factor=dsr.dime.funused1;
    if(fabs(scale_factor)>1.0E-20) scale_factor=1.0/scale_factor;

    /* Write Analyze header */
    ret=anaWriteHeader(hdrfile, &dsr);
    if(ret && IMG_TEST) printf("anaWriteHeader() := %d\n", ret);
    if(ret) return STATUS_CANTWRITEHEADERFILE;

    /* Remove datafile if necessary */
    if(access(datfile, 0) != -1) remove(datfile);

  } else { /* database does exist */
  
    /* Read header information for checking */
    ret=imgReadAnalyzeHeader(dbname, &test_img);
    if(ret!=0) {imgEmpty(&test_img); return ret;}
    /* Check that file format is the same */
    if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type) {
      imgEmpty(&test_img); return STATUS_WRONGFILETYPE;}
    /* Check that matrix sizes are the same */
    if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
       img->dimy!=test_img.dimy) {
      imgEmpty(&test_img); return STATUS_VARMATSIZE;}
    imgEmpty(&test_img);

    /* Read the header, set new frame number, and write it back */
    /* Get also the scale factor */
    if((ret=anaReadHeader(hdrfile, &dsr))!=0) return STATUS_NOMAINHEADER;
    scale_factor=1.0/dsr.dime.funused1;
    if(frame_to_write==0) frame_to_write=dsr.dime.dim[4]+1;
    if(dsr.dime.dim[4]<frame_to_write) {
      if(dsr.dime.dim[4]+1<frame_to_write) return STATUS_MISSINGMATRIX;
      dsr.dime.dim[4]=frame_to_write;
    }
    if((ret=anaWriteHeader(hdrfile, &dsr))!=0) return STATUS_NOWRITEPERM;
  }
  if(IMG_TEST>2) {
    printf("frame_to_write := %d\n", frame_to_write);
    printf("hdrfile := %s\n", hdrfile);
    printf("datfile := %s\n", datfile);
    printf("siffile := %s\n", siffile);
  }

  /* Allocate memory for matrix short int data (one plane) */
  pxlNr=img->dimx*img->dimy;
  sdata=(short int*)malloc(pxlNr*sizeof(short int));
  if(sdata==NULL) return STATUS_NOMEMORY;

  /* Open datafile, not removing possible old contents */
  if(frame_to_write==1) fp=fopen(datfile, "wb"); else fp=fopen(datfile, "r+b");
  if(fp==NULL) {free(sdata); return STATUS_CANTWRITEIMGFILE;}
  /* Move file pointer to the place of current frame */
  if(fseek(fp, (frame_to_write-1)*pxlNr*img->dimz*sizeof(short int),
           SEEK_SET)!=0) {
    free(sdata); fclose(fp); return STATUS_MISSINGMATRIX;}
  little=little_endian();
  /* Copy, scale and write data plane-by-plane */
  if(anaFlipping()==0) {
    for(zi=0; zi<img->dimz; zi++) {
      sptr=sdata;
     /*printf("plane := %d\n  scale_factor := %g\n", zi+1, scale_factor);*/
      for(yi=img->dimy-1; yi>=0; yi--) for(xi=img->dimx-1; xi>=0; xi--) {
        *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]); sptr++;
      }
      /* Change byte order if necessary */
      sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
      /* Write image data */
      sptr=sdata;
      if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
        free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
      }
    }
  } else {
    for(zi=img->dimz-1; zi>=0; zi--) {
      sptr=sdata;
      for(yi=img->dimy-1; yi>=0; yi--) for(xi=img->dimx-1; xi>=0; xi--) {
        *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]); sptr++;
      }
      /* Change byte order if necessary */
      sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
      /* Write image data */
      sptr=sdata;
      if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
        free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
      }
    }
  }
  free(sdata);
  fclose(fp);

  return STATUS_OK;
}
예제 #20
0
/** Reads microPET image data, scaling values to floats if necessary.
 *  Reads only one frame at a time!
\returns 0 when successful, otherwise <>0.
 */
int upetReadImagedata(
  /** file opened previously in binary mode */
  FILE *fp,
  /** microPET header in IFT struct */
  IFT *ift,
  /** frame number to read [1..number of frames] */
  int frame,
  /** pointer to image float data allocated previously */
  float *data
) {
  int dimx, dimy, dimz=1, dimt=1, pxlNr=0;
  int i, fi, n, data_type, data_bytes, little, start_pos, rawSize;
  char *mdata, *mptr;
  float f, cf, bf, *fptr;
  short int *sptr;
  int *iptr;
  char key[MAX_MICROPET_LINE_LEN], value[MAX_MICROPET_LINE_LEN];


  if(MICROPET_TEST) printf("upetReadImagedata(fp, ift, %d, data)\n", frame);

  /* Check the arguments */
  if(frame<=0 || fp==NULL || ift==NULL || data==NULL) return(1);

  /* Get the image dimensions from header */
  i=iftGetIntValue(ift, 0, "total_frames", &dimt);
  if(i<0 || dimt<1) return 4;
  i=iftGetIntValue(ift, 0, "x_dimension", &dimx);
  if(i<0 || dimx<1) return 4;
  i=iftGetIntValue(ift, 0, "y_dimension", &dimy);
  if(i<0 || dimy<1) return 4;
  i=iftGetIntValue(ift, 0, "z_dimension", &dimz);
  if(i<0 || dimz<1) return 4;
  pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
  if(frame>dimt) return(3); // do not change this return value

  /* Get the data type */
  i=iftGetIntValue(ift, 0, "data_type", &data_type);
  if(i<0 || data_type<1) return 5;
  switch(data_type) {
    case 1: data_bytes=1; little=little_endian(); break;
    case 2: data_bytes=2; little=1; break;
    case 3: data_bytes=4; little=1; break;
    case 4: data_bytes=4; little=1; break;
    case 5: data_bytes=4; little=0; break;
    case 6: data_bytes=2; little=0; break;
    case 7: data_bytes=4; little=0; break;
    default: return 5;
  }
  rawSize=data_bytes*pxlNr;
  if(MICROPET_TEST>0) {
    printf("  data_type=%d\n  data_bytes=%d\n", data_type, data_bytes);
    printf("  pxlNr=%d\n  rawSize=%d\n", pxlNr, rawSize);
  }

  /* Allocate memory for the binary data */
  mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);

  /* Seek the start of current frame data */
  start_pos=(frame-1)*rawSize;
  if(MICROPET_TEST>2) printf("  start_pos=%d\n", start_pos);
  fseek(fp, start_pos, SEEK_SET);
  if(ftell(fp)!=start_pos) {
    if(MICROPET_TEST>5) printf("could not move to start_pos\n");
    free(mdata); return(7);
  }

  /* Read the data */
  mptr=mdata;
  if((n=fread(mptr, rawSize, 1, fp)) < 1) {
    if(MICROPET_TEST>5)
      printf("could read only %d bytes when request was %d\n", n, rawSize);
    free(mdata); return(8);
  }

  /* Convert byte order if necessary */
  mptr=mdata;
  if(little!=little_endian()) {
    if(MICROPET_TEST>0) {printf("byte conversion\n"); fflush(stdout);}
    switch(data_bytes) {
      case 1: /* no conversion needed */ break;
      case 2: swabip(mptr, rawSize); break;
      case 4: swawbip(mptr, rawSize); break;
      default: 
        if(MICROPET_TEST>5)
          printf("unsupported data_type := %d\n", data_type);
        free(mdata); return(5);
    }
  }

  /* Get scale factor for this frame */
  strcpy(key, "frame"); sprintf(value, "%d", frame-1);
  fi=iftGetFullmatchFrom(ift, 0, key, value); if(fi<0) {free(mdata); return(6);}
  i=iftGetFloatValue(ift, fi+1, "scale_factor", &f);
  if(i<0 || f<=0.0) {free(mdata); return(6);}
  if(MICROPET_TEST>5) printf("  scale_factor := %g\n", f);

  /* calibration factor */
  i=iftGetFloatValue(ift, 0, "calibration_factor", &cf);
  if(i<0 || cf<0.0) {free(mdata); return 7;}
  if(MICROPET_TEST>5) printf("  calibration_factor := %g\n", cf);
  /* branching_fraction */
  i=iftGetFloatValue(ift, 0, "isotope_branching_fraction", &bf);
  if(i<0 || bf<0.0) {free(mdata); return 7;}
  if(MICROPET_TEST>5) printf("  branching_fraction := %g\n", bf);
  if(cf>0.0) {f=cf; if(bf>0.0) f/=bf;}
  if(MICROPET_TEST>5) printf("  f := %g\n", f);
 
  /* Copy data to float pixel values */
  mptr=mdata; fptr=data;
  switch(data_type) {
    case 1: // unsigned char
      for(i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(float)(*mptr);
      break;
    case 2: // short int
    case 6:
      for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
        sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
      }
      break;
    case 3: // int
    case 7:
      for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
        iptr=(int*)mptr; *fptr=f*(float)(*iptr);
      }
      break;
    case 4: // float
    case 5:
      memcpy(fptr, mptr, pxlNr*data_bytes);
      for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
      break;
    default:
      if(MICROPET_TEST>5)
        printf("unsupported data_type := %d\n", data_type);
      free(mdata); return(5);
  }

  free(mdata);
  if(MICROPET_TEST>1) printf("anaReadImagedata() succeeded\n");
  return(0);
}