fslio.c

来自「DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.」· C语言 代码 · 共 1,842 行 · 第 1/5 页

C
1,842
字号
    fslio->niftiptr->dy = fabs(fslio->niftiptr->dy);
    fslio->niftiptr->dz = fabs(fslio->niftiptr->dz);
    fslio->niftiptr->pixdim[1] = fabs(fslio->niftiptr->pixdim[1]);
    fslio->niftiptr->pixdim[2] = fabs(fslio->niftiptr->pixdim[2]);
    fslio->niftiptr->pixdim[3] = fabs(fslio->niftiptr->pixdim[3]);
  }
  /* set up pointer at end of iname_offset , ready for reading */
  FslSeekVolume(fslio,0);  

  return fslio;

}



/***************************************************************
 * FslReadAllVolumes
 ***************************************************************/
/*! \fn void* FslReadAllVolumes(FSLIO* fslio, char* filename)
    \brief Read the header and all data into the FSLIO structure

        There is no need for FslOpen or FslClose calls when FslReadAllVolumes()
        is called.  
        <br>This routine allocates the buffer to hold the entire dataset. 
        <br>The data block returned will contain the data in whatever
        datatype it is stored as on disk (therefore it is a void *).
        <br>The data buffer will be byteswapped to native-endian.
        <br>The data buffer will not be scaled. 
        <br>The best call to make before this is FslInit() or a calloc() for 
        fslio.  (??? why calloc if this allocates the buffer ???)

    \param fslio pointer to an open dataset
    \param filename Name of the dataset to read.
    \return A pointer to the data block buffer (allocated by this function).
        <br> Return Null on error ??? is this true ???
        <ul>
        <li>Note this pointer is also in the FSLIO structure as 
        fslio->niftiptr->data.</li>
        <li>Note a void pointer is returned, as the datablock is of
        variable datatype.</li>
        </ul>

 */
void* FslReadAllVolumes(FSLIO* fslio, char* filename)
{

  int imgtype;
  if (fslio==NULL)  FSLIOERR("FslReadAllVolumes: Null pointer passed for FSLIO");

  /* see if the extension indicates a minc file */
  imgtype = FslFileType(filename);
  if ((imgtype>=0) && (FslBaseFileType(imgtype)==FSL_TYPE_MINC)) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
    return NULL;
  }

  /** otherwise it is a nifti file - so read it! **/
  fslio->mincptr = NULL;
  /* make sure an FslOpen hasn't locked the file */
  if (!znz_isnull(fslio->fileptr)) FslClose(fslio);  
  
  fslio->niftiptr = nifti_image_read(filename,1);

  /* check for failure, from David Akers */
  if (fslio->niftiptr == NULL) {
        FSLIOERR("FslReadAllVolumes: error reading NIfTI image");
        return(NULL);
  }

  FslSetFileType(fslio,fslio->niftiptr->nifti_type);
  FslSetWriteMode(fslio,0);
  return fslio->niftiptr->data;
}



/***************************************************************
 * FslReadVolumes
 ***************************************************************/
/*! \fn size_t FslReadVolumes(FSLIO *fslio, void *buffer, size_t nvols)
    \brief Read the first nvols Volumes from a 4D dataset

    \param fslio pointer to open dataset
    \param buffer buffer to read data into, allocated by ???
    \param nvols  number of volumes to read
    \return Number of volumes read.
 */
size_t FslReadVolumes(FSLIO *fslio, void *buffer, size_t nvols)
{
  int volbytes;
  size_t retval=0;
  if (fslio==NULL)  FSLIOERR("FslReadVolumes: Null pointer passed for FSLIO");
  if (znz_isnull(fslio->fileptr))  FSLIOERR("FslReadVolumes: Null file pointer");
  if (fslio->niftiptr!=NULL) {
    fslio->niftiptr->data = buffer;
    volbytes = FslGetVolSize(fslio)  * fslio->niftiptr->nbyper;
    retval = nifti_read_buffer(fslio->fileptr,fslio->niftiptr->data,nvols*volbytes,fslio->niftiptr);
    retval /= volbytes;
  }

  if (fslio->mincptr!=NULL) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
  }
  return retval;
}



/***************************************************************
 * FslWriteAllVolumes
 ***************************************************************/
/*! \fn void FslWriteAllVolumes(FSLIO *fslio, const void *buffer)
    \brief  Writes all data from buffer (using size info from fslio) to file.
        
        Dimension and datatype of buffer are as is specified in nifti_image structure
        fslio->niftiptr.
        Note: If file format is Analyze (not nifti) and in Neurological order then 
        SWAP DATA into Radiological order.

    \param fslio pointer to open dataset
    \param buffer pointer to data array. Size and datatype of this buffer  
 */
void FslWriteAllVolumes(FSLIO *fslio, const void *buffer)
{
  short x,y,z,t;

  if (fslio==NULL)  FSLIOERR("FslWriteAllVolumes: Null pointer passed for FSLIO");

  FslGetDim(fslio,&x,&y,&z,&t);
  FslWriteHeader(fslio);
  FslWriteVolumes(fslio,buffer,t);
  return;
}



/***************************************************************
 * FslWriteVolumes
 ***************************************************************/
/*! \fn size_t FslWriteVolumes(FSLIO *fslio, const void *buffer, size_t nvols)
    \brief Write the first nvols volumes in buffer to disk.  

        Dimension and datatype of buffer are as is specified in nifti_image structure
        fslio->niftiptr.
        Note: If file format is Analyze (not nifti) and in Neurological order then 
        SWAP DATA into Radiological order.

        
    \param fslio        pointer to open dataset
    \param buffer       pointer to data array. Size and datatype of this buffer  
    \param nvols        number of volumes to write
    \return ??? looks like return of retval is missing ???  0 on error.
 */
size_t FslWriteVolumes(FSLIO *fslio, const void *buffer, size_t nvols)
{
  /* The dimensions and datatype must be set before calling this function */
  int retval;
  if (fslio==NULL)  FSLIOERR("FslWriteVolumes: Null pointer passed for FSLIO");
  if ( (!fslio->written_hdr) && (FslIsSingleFileType(FslGetFileType(fslio))) &&
       (FslIsCompressedFileType(FslGetFileType(fslio))) )
    { FSLIOERR("FslWriteVolumes: header must be written before data for single compressed file types"); }
  
  if (fslio->niftiptr!=NULL) {
    long int nbytes, bpv;
    bpv = fslio->niftiptr->nbyper;  /* bytes per voxel */
    nbytes = nvols * FslGetVolSize(fslio) * bpv;

    if ( (FslBaseFileType(FslGetFileType(fslio))==FSL_TYPE_ANALYZE)
         && (FslGetLeftRightOrder(fslio)==FSL_NEUROLOGICAL) ) {
      /* If it is Analyze and Neurological order then SWAP DATA into Radiological order */
      /* This is nasty - but what else can be done?!? */
      char *tmpbuf, *inbuf;
      long int x, b, n, nrows;
      short nx, ny, nz, nv;
      inbuf = (char *) buffer;
      tmpbuf = (char *)calloc(nbytes,1);
      FslGetDim(fslio,&nx,&ny,&nz,&nv);
      nrows = nbytes / (nx * bpv);
      for (n=0; n<nrows; n++) {
        for (x=0; x<nx; x++) {
          for (b=0; b<bpv; b++) {
            tmpbuf[b +  bpv * (n*nx + nx - 1 - x)] = inbuf[b + bpv * (n*nx + x)];
          }
        }
      }
      retval = nifti_write_buffer(fslio->fileptr, tmpbuf, nbytes);
      free(tmpbuf);
    } else {
      retval = nifti_write_buffer(fslio->fileptr, buffer, nbytes);
    }
  }
  if (fslio->mincptr!=NULL) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
  }
  return 0;  /* failure */
}


/***************************************************************
 * FslWriteHeader
 ***************************************************************/
/*! \fn void FslWriteHeader(FSLIO *fslio)
    \brief Writes nifti/anz header and opens img file ready for writing
        
    \param fslio        pointer to open dataset
 */
void FslWriteHeader(FSLIO *fslio)
{
  /* writes header and opens img file ready for writing */
  if (fslio==NULL)  FSLIOERR("FslWriteHeader: Null pointer passed for FSLIO");

  if (fslio->niftiptr!=NULL) {
    fslio->written_hdr = 1;
    if (znz_isnull(fslio->fileptr)) FSLIOERR("FslWriteHeader: no file opened!");

    strcpy(fslio->niftiptr->descrip,"FSL3.2beta");
    if (FslIsSingleFileType(FslGetFileType(fslio))) {
      /* write header info but don't close the file */
      nifti_image_write_hdr_img2(fslio->niftiptr,2,"wb",fslio->fileptr,NULL);
      /* set up pointer at end of iname_offset for single files only */
      FslSeekVolume(fslio,0);
    } else {
      /* open a new hdr file, write it and close it */
      nifti_image_write_hdr_img(fslio->niftiptr,0,"wb");
    }
  }

  if (fslio->mincptr!=NULL) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
  }
  return;
}


/***************************************************************
 * FslReadSliceSeries
 ***************************************************************/
/*! \fn size_t FslReadSliceSeries(FSLIO *fslio, void *buffer, short slice, size_t nvols)
    \brief Read one slice from each of the first nvols volumes in the dataset, ie get an xyt buffer.

        Dimension and datatype of buffer are as is specified in nifti_image structure
        fslio->niftiptr.
        Note: filepointer in file data array is restored to its initial position.
        
    \param fslio        pointer to open dataset
    \param buffer       buffer large enough to hold 1 slice from each volume
    \param slice        slice number (0 based) to read  [0 z-1]
    \param nvols        number of volumes to read a slice from 
    \return             Number of volumes from which a slice was successfully read. 0 on error.
 */
size_t FslReadSliceSeries(FSLIO *fslio, void *buffer, short slice, size_t nvols)
{
  size_t slbytes,volbytes;
  size_t n, orig_offset;
  short x,y,z,v,type;

  if (fslio==NULL)  FSLIOERR("FslReadSliceSeries: Null pointer passed for FSLIO");
  if (fslio->niftiptr!=NULL) {
    
    FslGetDim(fslio,&x,&y,&z,&v);
    
    if ((slice<0) || (slice>=z)) FSLIOERR("FslReadSliceSeries: slice outside valid range");
    
    slbytes = x * y * (FslGetDataType(fslio, &type) / 8);
    volbytes = slbytes * z;
    
    orig_offset = znztell(fslio->fileptr);
    znzseek(fslio->fileptr, slbytes*slice, SEEK_CUR);
    
    for (n=0; n<nvols; n++) {
      if (n>0) znzseek(fslio->fileptr, volbytes - slbytes, SEEK_CUR);
      if (znzread((char *)buffer+n*slbytes, 1, slbytes, fslio->fileptr) != slbytes)
        FSLIOERR("FslReadSliceSeries: failed to read values");
     if (fslio->niftiptr->byteorder != nifti_short_order())
        nifti_swap_Nbytes(slbytes / fslio->niftiptr->swapsize,
                          fslio->niftiptr->swapsize, (char *)buffer+n*slbytes);
     }
    
    
    /* restore file pointer to original position */
    znzseek(fslio->fileptr,orig_offset,SEEK_SET);
    return n;
  }
  if (fslio->mincptr!=NULL) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
  }
  return 0;
}


/***************************************************************
 * FslReadRowSeries
 ***************************************************************/
/*! \fn size_t FslReadRowSeries(FSLIO *fslio, void *buffer, short row, short slice, size_t nvols)
    \brief Read one row from one slice for first nvols volumes in dataset; ie get an xt buffer.

        Dimension and datatype of buffer are as is specified in nifti_image structure
        fslio->niftiptr.
        Note: filepointer in file data array is restored to its initial position.
        
    \param fslio        pointer to open dataset
    \param buffer       buffer to hold one row from each volume.
    \param row          row number (0 based) to read [0 y-1]
    \param slice        slice number (0 based) to read
    \param nvols        number of volumes to read a row from 
    \return Number of volumes from which a row was successfully read. 0 on error.
 */
size_t FslReadRowSeries(FSLIO *fslio, void *buffer, short row, short slice, size_t nvols)
{
  size_t rowbytes,slbytes,volbytes;
  size_t n, orig_offset;
  short x,y,z,v,type;
  
  if (fslio==NULL)  FSLIOERR("FslReadRowSeries: Null pointer passed for FSLIO");
  if (fslio->niftiptr!=NULL) {
    
    FslGetDim(fslio,&x,&y,&z,&v);
    
    if ((slice<0) || (slice>=z)) FSLIOERR("FslReadRowSeries: slice outside valid range");
    if ((row<0) || (row>=y)) FSLIOERR("FslReadRowSeries: row outside valid range");
    
    rowbytes = x * (FslGetDataType(fslio, &type)) / 8;
    slbytes = rowbytes * y;
    volbytes = slbytes * z;
    
    orig_offset = znztell(fslio->fileptr);
    znzseek(fslio->fileptr, rowbytes*row + slbytes*slice, SEEK_CUR);
    
    for (n=0; n<nvols; n++){
      if (n>0) znzseek(fslio->fileptr, volbytes - rowbytes, SEEK_CUR);
      if (znzread((char *)buffer+n*rowbytes, 1, rowbytes, fslio->fileptr) != rowbytes)
        FSLIOERR("FslReadRowSeries: failed to read values");
      if (fslio->niftiptr->byteorder != nifti_short_order())
        nifti_swap_Nbytes(rowbytes / fslio->niftiptr->swapsize,
                          fslio->niftiptr->swapsize, (char *)buffer+n*rowbytes);
    }
    
    /* restore file pointer to original position */
    znzseek(fslio->fileptr,orig_offset,SEEK_SET);
    return n;
  }
  if (fslio->mincptr!=NULL) {
    fprintf(stderr,"Warning:: Minc is not yet supported\n");
  }
  return 0;
}


/***************************************************************
 * FslReadTimeSeries
 ***************************************************************/
/*! \fn size_t FslReadTimeSeries(FSLIO *fslio, void *buffer, short xVox, short yVox, short zVox, size_t nvols)
    \brief Read one voxel (xyz location) from first nvols volumes in dataset; ie get a t  dim buffer.

        Dimension and datatype of buffer are as is specified in nifti_image structure
        fslio->niftiptr.
        Note: filepointer in file data array is restored to its initial position.
        
    \param fslio        pointer to open dataset
    \param buffer       buffer to hold one timeseries vector
    \param xVox         x voxel [0 x-1]
    \param yVox         y voxel [0 y-1]
    \param zVox         z voxel [0 z-1]
    \param nvols        number of volumes to read a voxel from
    \return Number of volumes from which a voxel was successfully read. 0 on error.
 */
size_t FslReadTimeSeries(FSLIO *fslio, void *buffer, short xVox, short yVox, short zVox, 
                         size_t nvols)
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?