コード例 #1
0
ファイル: afni.c プロジェクト: guo2004131/freesurfer
/*------------------------------------------------------*/
MRI *afniRead(const char *fname, int read_volume)
{

  FILE *fp;
  char header_fname[STRLEN];
  char *c;
  MRI *mri, *header;
  int big_endian_flag;
  long brik_file_length;
  long nvoxels;
  int bytes_per_voxel;
  int i, j, k;
  int swap_flag;
  AF af;
  float scaling = 1.;
  void *pmem = 0;
  float *pf;
  short *ps;
  unsigned char *pc;

  float det;
  float xfov, yfov, zfov;
  float fMin = 0.;
  float fMax = 0.;
  float flMin = 0.;
  float flMax = 0.;
  int initialized = 0;
  int frame;
  int bytes;

  strcpy(header_fname, fname);
  c = strrchr(header_fname, '.');

  if (c == NULL)
  {
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADPARM, "afniRead(): bad file name %s", fname));
  }

  if (strcmp(c, ".BRIK") != 0)
  {
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADPARM, "afniRead(): bad file name %s", fname));
  }

  sprintf(c, ".HEAD");

  if ((fp = fopen(header_fname, "r")) == NULL)
  {
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error opening file %s", header_fname));
  }

  // initialize AFNI structure
  AFinit(&af);

  // read header file
  if (!readAFNIHeader(fp, &af))
    return (NULL);

  printAFNIHeader(&af);

  // well, we don't have time
  if (af.numtypes != 1) // should be the same as af.dataset_rank[1] = subbricks
  {
    errno = 0;
    // ErrorReturn(NULL, (ERROR_UNSUPPORTED, "afniRead(): nframes = %d (only 1 frame supported)", af.numtypes));
    printf("INFO: number of frames dataset_rank[1] = %d : numtypes = %d \n",
           af.dataset_rank[1], af.numtypes);
  }
  // byteorder_string : required field
  if (strcmp(af.byteorder_string, "MSB_FIRST") == 0)
    big_endian_flag = 1;
  else if (strcmp(af.byteorder_string, "LSB_FIRST") == 0)
    big_endian_flag = 0;
  else
  {
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADPARM, "read_afni_header(): unrecognized byte order string %s",
                       af.byteorder_string));
  }
  // brick_types : required field
  if (af.brick_types[0] == 2 // int
      || af.brick_types[0] > 3 )// 4 = double, 5 = complex, 6 = rgb
  {
    errno = 0;
    ErrorReturn(NULL,
                (ERROR_BADPARM,
                 "afniRead(): unsupported data type %d, Must be 0 (byte), 1(short), or 3(float)",
                 af.brick_types[0]));
  }
  //////////////////////////////////////////////////////////////////////////////////
  // now we allocate space for MRI
  // dataset_dimensions : required field
  header = MRIallocHeader(af.dataset_dimensions[0],
                          af.dataset_dimensions[1],
                          af.dataset_dimensions[2],
                          MRI_UCHAR,
                          af.dataset_rank[1]
                          );
  // set number of frames
  header->nframes = af.dataset_rank[1];

  // direction cosines (use orient_specific)
  // orient_specific : required field
  header->x_r = afni_orientations[af.orient_specific[0]][0];
  header->x_a = afni_orientations[af.orient_specific[0]][1];
  header->x_s = afni_orientations[af.orient_specific[0]][2];
  header->y_r = afni_orientations[af.orient_specific[1]][0];
  header->y_a = afni_orientations[af.orient_specific[1]][1];
  header->y_s = afni_orientations[af.orient_specific[1]][2];
  header->z_r = afni_orientations[af.orient_specific[2]][0];
  header->z_a = afni_orientations[af.orient_specific[2]][1];
  header->z_s = afni_orientations[af.orient_specific[2]][2];

  /* --- quick determinant check --- */
  det = + header->x_r * (header->y_a * header->z_s - header->z_a * header->y_s)
        - header->x_a * (header->y_r * header->z_s - header->z_r * header->y_s)
        + header->x_s * (header->y_r * header->z_a - header->z_r * header->y_a);

  if (det == 0)
  {
    MRIfree(&header);
    errno = 0;
    ErrorReturn(NULL,
                (ERROR_BADPARM,
                 "read_afni_header(): error in orientations %d, %d, %d (direction cosine matrix has determinant zero)",
                 af.orient_specific[0], af.orient_specific[1], af.orient_specific[2]));
  }
  // sizes use delta
  // delta : required field
  header->xsize = af.delta[0];
  header->ysize = af.delta[1];
  header->zsize = af.delta[2];

  // uses origin
  // origin : required field
  header->c_r = header->x_r * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) +
                header->y_r * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) +
                header->z_r * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]);

  header->c_a = header->x_a * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) +
                header->y_a * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) +
                header->z_a * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]);

  header->c_s = header->x_s * (header->xsize * (header->width-1.0)/2.0 + af.origin[0]) +
                header->y_s * (header->ysize * (header->height-1.0)/2.0 + af.origin[1]) +
                header->z_s * (header->zsize * (header->depth-1.0)/2.0 + af.origin[2]);

  header->ras_good_flag = 1;

  if (header->xsize < 0)
    header->xsize = -header->xsize;

  if (header->ysize < 0)
    header->ysize = -header->ysize;

  if (header->zsize < 0)
    header->zsize = -header->zsize;

  header->imnr0 = 1;
  header->imnr1 = header->depth;

  header->ps = header->xsize;
  header->thick = header->zsize;

  header->xend = (header->width  / 2.0) * header->xsize;
  header->xstart = -header->xend;
  header->yend = (header->height / 2.0) * header->ysize;
  header->ystart = -header->yend;
  header->zend = (header->depth  / 2.0) * header->zsize;
  header->zstart = -header->zend;

  xfov = header->xend - header->xstart;
  yfov = header->yend - header->ystart;
  zfov = header->zend - header->zstart;

  header->fov = ( xfov > yfov ? (xfov > zfov ? xfov : zfov ) : (yfov > zfov ? yfov : zfov ) );

#if (BYTE_ORDER==LITTLE_ENDIAN)
  //#ifdef Linux
  swap_flag = big_endian_flag;
#else
  swap_flag = !big_endian_flag;
#endif

  if ((fp = fopen(fname, "r")) == NULL)
  {
    MRIfree(&header);
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error opening file %s", header_fname));
  }

  fseek(fp, 0, SEEK_END);
  brik_file_length = ftell(fp);
  fseek(fp, 0, SEEK_SET);

  // number of voxels consecutive

  nvoxels = header->width * header->height * header->depth * header->nframes;

  if (brik_file_length % nvoxels)
  {
    fclose(fp);
    MRIfree(&header);
    errno = 0;
    ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): BRIK file length (%d) is not divisible by the number of voxels (%d)", brik_file_length, nvoxels));
  }
  // bytes_per_voxel = brik_file_length / nvoxels; // this assumes one frame
  bytes_per_voxel = af.brick_types[0] + 1; // 0(byte)-> 1, 1(short) -> 2, 3(float)->4

  bytes = header->width*header->height*header->depth*bytes_per_voxel;

  // this check is for nframes = 1 case which is the one we are supporting
  if (bytes_per_voxel != brik_file_length/nvoxels)
  {
    fclose(fp);
    MRIfree(&header);
    errno = 0;
    ErrorReturn(NULL,
                (ERROR_UNSUPPORTED,
                 "afniRead(): type info stored in header does not agree with the file size: %d != %d/%d",
                 bytes_per_voxel, brik_file_length/nvoxels));
  }

  // if brick_float_facs != 0 then we scale values to be float
  if (af.numfacs != 0 && af.brick_float_facs[0] != 0.)
  {
    header->type = MRI_FLOAT;
    scaling = af.brick_float_facs[0];
  }
  else
  {
    if (bytes_per_voxel == 1)
      header->type = MRI_UCHAR;
    else if (bytes_per_voxel == 2)
      header->type = MRI_SHORT;
    else if (bytes_per_voxel == 4)
      header->type = MRI_FLOAT;
    else
    {
      fclose(fp);
      MRIfree(&header);
      errno = 0;
      ErrorReturn(NULL, (ERROR_UNSUPPORTED, "afniRead(): don't know what to do with %d bytes per voxel", bytes_per_voxel));
    }
  }

  ///////////////////////////////////////////////////////////////////////
  if (read_volume)
  {
    // mri = MRIalloc(header->width, header->height, header->depth, header->type);
    mri = MRIallocSequence(header->width, header->height, header->depth,
                           header->type, header->nframes) ;
    MRIcopyHeader(header, mri);

    for (frame = 0; frame < header->nframes; ++frame)
    {
      initialized = 0;
      for (k = 0;k < mri->depth;k++)
      {
        for (j = 0;j < mri->height;j++)
        {
          if (af.brick_float_facs[frame])
            scaling = af.brick_float_facs[frame];
          else
            scaling = 1.;
          {
            pmem = (void *) malloc(bytes_per_voxel*mri->width);
            if (pmem)
            {
              if (fread(pmem, bytes_per_voxel, mri->width, fp) != mri->width)
              {
                fclose(fp);
                MRIfree(&header);
                errno = 0;
                ErrorReturn(NULL, (ERROR_BADFILE, "afniRead(): error reading from file %s", fname));
              }
              // swap bytes
              if (swap_flag)
              {
                if (bytes_per_voxel == 2) // short
                {
                  swab(pmem, pmem, mri->width * 2);
                }
                else if (bytes_per_voxel == 4) // float
                {
                  pf = (float *) pmem;
                  for (i = 0;i < mri->width;i++, pf++)
                    *pf = swapFloat(*pf);
                }
              }
              // now scaling
              if (bytes_per_voxel == 1) // byte
              {
                pc = (unsigned char *) pmem;
                for (i=0; i < mri->width; i++)
                {
                  if (scaling == 1.)
                    MRIseq_vox(mri, i, j, k, frame) = *pc;
                  else
                    MRIFseq_vox(mri, i, j, k, frame) = ((float) (*pc))*scaling;
                  ++pc;
                }
                findMinMaxByte((unsigned char *) pmem, mri->width, &flMin, &flMax);
              }
              if (bytes_per_voxel == 2) // short
              {
                ps = (short *) pmem;
                for (i=0; i < mri->width; i++)
                {
                  // if (*ps != 0)
                  //   printf("%d ", *ps);
                  if (scaling == 1.)
                    MRISseq_vox(mri, i, j, k, frame) = *ps;
                  else
                    MRIFseq_vox(mri, i, j, k, frame) = ((float) (*ps))*scaling;
                  ++ps;
                }
                findMinMaxShort((short *) pmem, mri->width, &flMin, &flMax);
              }
              else if (bytes_per_voxel == 4) // float
              {
                pf = (float *) pmem;
                for (i=0; i < mri->width; i++)
                {

                  MRIFseq_vox(mri, i, j, k, frame) = (*pf)*scaling;
                  ++pf;
                }
                findMinMaxFloat((float *) pmem, mri->width, &flMin, &flMax);
              }
              free(pmem);
              //
              if (initialized == 0)
              {
                fMin = flMin;
                fMax = flMax;
                initialized = 1;
              }
              else
              {
                if (flMin < fMin)
                  fMin = flMin;
                if (flMax > fMax)
                  fMax = flMax;
                // printf("\n fmin =%f, fmax = %f, local min = %f, max = %f\n", fMin, fMax, flMin, flMax);
              }
            }
            else
            {
              fclose(fp);
              MRIfree(&header);
              errno = 0;
              ErrorReturn(NULL,
                          (ERROR_BADFILE, "afniRead(): could not allocate memory for reading %s", fname));
            }
          }
        } // height
      } // depth
      // valid only for nframs == 1
      {
        printf("BRICK_STATS min = %f <--> actual min = %f\n",
               af.brick_stats[0+2*frame], fMin*scaling);
        printf("BRICK_STATS max = %f <--> actual max = %f\n",
               af.brick_stats[1+2*frame], fMax*scaling);
      }
    } // nframes
  }
  else // not reading volume
    mri = MRIcopy(header, NULL);

  strcpy(mri->fname, fname);

  fclose(fp);

  MRIfree(&header);
  AFclean(&af);

  return(mri);

} /* end afniRead() */
コード例 #2
0
MRI* VolumeFilter::CreateMRIFromVolume( LayerMRI* layer )
{
    vtkImageData* image = layer->GetImageData();
    int mri_type = MRI_FLOAT;
    switch ( image->GetScalarType() )
    {
    case VTK_CHAR:
    case VTK_SIGNED_CHAR:
    case VTK_UNSIGNED_CHAR:
        mri_type = MRI_UCHAR;
        break;
    case VTK_INT:
    case VTK_UNSIGNED_INT:
        mri_type = MRI_INT;
        break;
    case VTK_LONG:
    case VTK_UNSIGNED_LONG:
        mri_type = MRI_LONG;
        break;
    case VTK_SHORT:
    case VTK_UNSIGNED_SHORT:
        mri_type = MRI_SHORT;
        break;
    default:
        break;
    }

    int* dim = image->GetDimensions();
    int zFrames = image->GetNumberOfScalarComponents();
    MRI* mri = MRIallocSequence( dim[0], dim[1], dim[2], mri_type, zFrames );
    if ( !mri )
    {
        cerr << "Can not allocate memory for MRI.\n";
        return NULL;
    }

    for ( int j = 0; j < mri->height; j++ )
    {
        for ( int k = 0; k < mri->depth; k++ )
        {
            for ( int i = 0; i < mri->width; i++ )
            {
                for ( int nFrame = 0; nFrame < mri->nframes; nFrame++ )
                {
                    switch ( mri->type )
                    {
                    case MRI_UCHAR:
                        MRIseq_vox( mri, i, j, k, nFrame ) =
                            (unsigned char)image->GetScalarComponentAsDouble(i, j, k, nFrame);
                        break;
                    case MRI_INT:
                        MRIIseq_vox( mri, i, j, k, nFrame ) =
                            (int)image->GetScalarComponentAsDouble(i, j, k, nFrame);
                        break;
                    case MRI_LONG:
                        MRILseq_vox( mri, i, j, k, nFrame ) =
                            (int)image->GetScalarComponentAsDouble(i, j, k, nFrame);
                        break;
                    case MRI_FLOAT:
                        MRIFseq_vox( mri, i, j, k, nFrame ) =
                            (int)image->GetScalarComponentAsDouble(i, j, k, nFrame);
                        break;
                    case MRI_SHORT:
                        MRISseq_vox( mri, i, j, k, nFrame ) =
                            (int)image->GetScalarComponentAsDouble(i, j, k, nFrame);
                        break;
                    default:
                        break;
                    }
                }
            }
        }
        exec_progress_callback(j, mri->height, 0, 1);
    }

    return mri;
}