Exemplo n.º 1
0
/*
******** nrrdAlloc_va()
**
** Handy wrapper around nrrdAlloc_nva, which takes, as its vararg list,
** all the axes sizes.
*/
int
nrrdAlloc_va(Nrrd *nrrd, int type, unsigned int dim, ...)
{
  char me[]="nrrdAlloc_va", err[BIFF_STRLEN];
  size_t size[NRRD_DIM_MAX];
  unsigned int ai;
  va_list ap;

  if (!nrrd)
  {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err);
    return 1;
  }
  va_start(ap, dim);
  for (ai=0; ai<dim; ai++)
  {
    size[ai] = va_arg(ap, size_t);
  }
  va_end(ap);
  if (nrrdAlloc_nva(nrrd, type, dim, size))
  {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err);
    return 1;
  }
  return 0;
}
Exemplo n.º 2
0
/*
******** nrrdMaybeAlloc_nva
**
** calls nrrdAlloc_nva if the requested space is different than
** what is currently held
**
** also subscribes to the "don't mess with peripheral information" philosophy
*/
int
nrrdMaybeAlloc_nva(Nrrd *nrrd, int type,
                   unsigned int dim, const size_t *size)
{
  char me[]="nrrdMaybeAlloc_nva", err[BIFF_STRLEN];
  size_t sizeWant, sizeHave, numWant, elementSizeWant;
  int need;
  unsigned int ai;

  if (!nrrd)
  {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err);
    return 1;
  }
  if (airEnumValCheck(nrrdType, type))
  {
    sprintf(err, "%s: type (%d) is invalid", me, type);
    biffAdd(NRRD, err);
    return 1;
  }
  if (nrrdTypeBlock == type)
  {
    if (nrrdTypeBlock == nrrd->type)
    {
      sprintf(err, "%s: can't change from one block nrrd to another", me);
      biffAdd(NRRD, err);
      return 1;
    }
    if (!(0 < nrrd->blockSize))
    {
      sprintf(err, "%s: given nrrd->blockSize " _AIR_SIZE_T_CNV " invalid",
              me, nrrd->blockSize);
      biffAdd(NRRD, err);
      return 1;
    }
    elementSizeWant = nrrd->blockSize;
  }
  else
  {
    elementSizeWant = nrrdTypeSize[type];
  }
  if (_nrrdSizeCheck(size, dim, AIR_TRUE))
  {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err);
    return 1;
  }

  if (!(nrrd->data))
  {
    need = 1;
  }
  else
  {
    numWant = 1;
    for (ai=0; ai<dim; ai++)
    {
      numWant *= size[ai];
    }
    if (!nrrdElementSize(nrrd))
    {
      sprintf(err, "%s: nrrd reports zero element size!", me);
      biffAdd(NRRD, err);
      return 1;
    }
    sizeHave = nrrdElementNumber(nrrd) * nrrdElementSize(nrrd);
    /* fprintf(stderr, "##%s: sizeHave = %d * %d = %d\n", me,
            (int)(nrrdElementNumber(nrrd)),
            (int)(nrrdElementSize(nrrd)), (int)sizeHave); */
    sizeWant = numWant * elementSizeWant;
    /* fprintf(stderr, "##%s: sizeWant = %d * %d = %d\n", me,
            (int)(numWant),
            (int)(elementSizeWant), (int)sizeWant); */
    need = sizeHave != sizeWant;
    /* fprintf(stderr, "##%s: need = %d\n", me, need); */
  }
  if (need)
  {
    if (nrrdAlloc_nva(nrrd, type, dim, size))
    {
      sprintf(err, "%s:", me);
      biffAdd(NRRD, err);
      return 1;
    }
  }
  else
  {
    if (nrrdWrap_nva(nrrd, nrrd->data, type, dim, size))
    {
      sprintf(err, "%s:", me);
      biffAdd(NRRD, err);
      return 1;
    }
    /* but we do have to initialize memory! */
    memset(nrrd->data, 0, nrrdElementNumber(nrrd)*nrrdElementSize(nrrd));
  }

  return 0;
}
Exemplo n.º 3
0
/* *************************************************************** */
Nrrd *reg_io_nifti2nrrd(nifti_image *niiImage)
{
    // Create a nrrd image
    Nrrd *nrrdImage = nrrdNew();

    // Set the nrrd image size
    size_t size[NRRD_DIM_MAX];
    for(int i=1;i<=niiImage->ndim;++i)
        size[i-1]=niiImage->dim[i];

    // Allocate the nrrd data array based on the nii image data type
    switch(niiImage->datatype){
    case NIFTI_TYPE_UINT8:
        nrrdAlloc_nva(nrrdImage,nrrdTypeUChar,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_INT8:
        nrrdAlloc_nva(nrrdImage,nrrdTypeChar,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_UINT16:
        nrrdAlloc_nva(nrrdImage,nrrdTypeUShort,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_INT16:
        nrrdAlloc_nva(nrrdImage,nrrdTypeShort,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_UINT32:
        nrrdAlloc_nva(nrrdImage,nrrdTypeUInt,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_INT32:
        nrrdAlloc_nva(nrrdImage,nrrdTypeInt,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_FLOAT32:
        nrrdAlloc_nva(nrrdImage,nrrdTypeFloat,niiImage->ndim,size);
        break;
    case NIFTI_TYPE_FLOAT64:
        nrrdAlloc_nva(nrrdImage,nrrdTypeDouble,niiImage->ndim,size);
        break;
    default:
        fprintf(stderr, "[NiftyReg ERROR] reg_io_nifti2nrrd - The data type is not supported\n");
        exit(1);
    }

    // Rescale the nii image intensity if required
    if(niiImage->scl_slope!=1 && niiImage->scl_slope!=0){
        reg_tools_addSubMulDivValue(niiImage, niiImage,niiImage->scl_slope,2); // *(niiImage->scl_slope)
        niiImage->scl_slope=1;
    }
    if(niiImage->scl_inter!=0){
        reg_tools_addSubMulDivValue(niiImage, niiImage,niiImage->scl_inter,0); // +(niiImage->scl_inter)
        niiImage->scl_inter=0;
    }

    // Set the space if suitable with the nrrd file format
    if(niiImage->qform_code>0 || niiImage->sform_code>0){
        // Set the space dim variable
        nrrdImage->spaceDim=niiImage->ndim<3?niiImage->ndim:3;
        // Create a matrix to store the relevant information
        mat44 currentAffineMatrix;
        // Use the sform information if it is defined
        if(niiImage->sform_code>0)
            currentAffineMatrix=niiImage->sto_xyz;
        // Use the qform orientation otherwise
        else currentAffineMatrix=niiImage->qto_xyz;
        if(niiImage->ndim>2){
/** @todo need to investigate what ITK is doing with the SPACE as all images seems to be LPS */
//            // The space orientation is extracted
//            int i_orient, j_orient, k_orient;
//            nifti_mat44_to_orientation(currentAffineMatrix,&i_orient,&j_orient,&k_orient);
//            if(i_orient==NIFTI_L2R && j_orient==NIFTI_P2A && k_orient==NIFTI_I2S){
//                if(niiImage->nt>1)
//                    nrrdImage->space=nrrdSpaceRightAnteriorSuperiorTime;
//                else nrrdImage->space=nrrdSpaceRightAnteriorSuperior;
//            }
//            else if(i_orient==NIFTI_R2L && j_orient==NIFTI_P2A && k_orient==NIFTI_I2S){
//                if(niiImage->nt>1)
//                    nrrdImage->space=nrrdSpaceLeftAnteriorSuperiorTime;
//                else nrrdImage->space=nrrdSpaceLeftAnteriorSuperior;
//            }
//            else if(i_orient==NIFTI_R2L && j_orient==NIFTI_A2P && k_orient==NIFTI_I2S){
//                if(niiImage->nt>1)
//                    nrrdImage->space=nrrdSpaceLeftPosteriorSuperiorTime;
//                else nrrdImage->space=nrrdSpaceLeftPosteriorSuperior;
//            }
//            else{
//                nrrdImage->space=nrrdSpaceUnknown;
//                fprintf(stderr, "[NiftyReg WARNING] reg_io_nifti2nrrd - The nifti qform information can be stored in the space variable.\n");
//                fprintf(stderr, "[NiftyReg WARNING] reg_io_nifti2nrrd - The space direction will be used.\n");
//            }
            nrrdImage->space=nrrdSpaceUnknown;
        }

        // The matrix is flipped to go from nifti to nrrd
        // and follow the ITK style
        for(unsigned int i=0;i<2;++i)
            for(unsigned int j=0;j<4;++j)
                currentAffineMatrix.m[i][j]*=-1.0f;

        // the space direction is initialised to identity
        nrrdImage->axis[0].spaceDirection[0]=1;
        nrrdImage->axis[0].spaceDirection[1]=0;
        nrrdImage->axis[0].spaceDirection[2]=0;
        nrrdImage->axis[1].spaceDirection[0]=0;
        nrrdImage->axis[1].spaceDirection[1]=1;
        nrrdImage->axis[1].spaceDirection[2]=0;
        nrrdImage->axis[2].spaceDirection[0]=0;
        nrrdImage->axis[2].spaceDirection[1]=0;
        nrrdImage->axis[2].spaceDirection[2]=1;
        for(int i=0;i<(niiImage->ndim<3?niiImage->ndim:3);++i)
            for(int j=0;j<(niiImage->ndim<3?niiImage->ndim:3);++j)
                nrrdImage->axis[i].spaceDirection[j]=currentAffineMatrix.m[i][j];

        // Set the origin of the image
        nrrdImage->spaceOrigin[0]=currentAffineMatrix.m[0][3];
        nrrdImage->spaceOrigin[1]=currentAffineMatrix.m[1][3];
        if(niiImage->ndim>2)
            nrrdImage->spaceOrigin[2]=currentAffineMatrix.m[2][3];
    }
    else{
        for(int i=0;i<niiImage->ndim;i++){
            // Set the spacing values if qform and sform are not defined
            nrrdImage->axis[i].spacing=niiImage->pixdim[i+1];
            // As well as the origin to zero
            nrrdImage->spaceOrigin[i]=0;
        }
    }
    // Set the units if they are defined
    for(int i=0; i<NRRD_SPACE_DIM_MAX; i++){
      airFree(nrrdImage->spaceUnits[i]);
      nrrdImage->spaceUnits[i] = NULL;
    }
    switch(niiImage->xyz_units){
    case NIFTI_UNITS_METER:
        for(int i=0;i<(niiImage->ndim<3?niiImage->ndim:3);++i){
            nrrdImage->spaceUnits[i]=(char *)malloc(200);
            sprintf(nrrdImage->spaceUnits[i],"m");
            nrrdImage->axis[i].kind=nrrdKindDomain;
        }
        break;
    case NIFTI_UNITS_MM:
        for(int i=0;i<(niiImage->ndim<3?niiImage->ndim:3);++i){
            nrrdImage->spaceUnits[i]=(char *)malloc(200);
            sprintf(nrrdImage->spaceUnits[i],"mm");
            nrrdImage->axis[i].kind=nrrdKindDomain;
        }
        break;
    case NIFTI_UNITS_MICRON:
        for(int i=0;i<(niiImage->ndim<3?niiImage->ndim:3);++i){
            nrrdImage->spaceUnits[i]=(char *)malloc(200);
            sprintf(nrrdImage->spaceUnits[i],"um");
            nrrdImage->axis[i].kind=nrrdKindDomain;
        }
        break;
    }

    // Set the time unit if it is defined
    if(niiImage->ndim>3){
        switch(niiImage->time_units){
        case NIFTI_UNITS_SEC:
            nrrdImage->spaceUnits[4]=(char *)"sec";
            nrrdImage->axis[4].kind=nrrdKindTime;
            break;
        case NIFTI_UNITS_MSEC:
            nrrdImage->spaceUnits[4]=(char *)"msec";
            nrrdImage->axis[4].kind=nrrdKindTime;
            break;
        }
    }

    // Check if the image is a vector field
    if(niiImage->intent_code==NIFTI_INTENT_VECTOR){
        // The intensity array has to be reoriented
        switch(niiImage->datatype){
        case NIFTI_TYPE_FLOAT32:
            reg_convertVectorField_nifti_to_nrrd<float>(niiImage,nrrdImage);
            break;
        case NIFTI_TYPE_FLOAT64:
            reg_convertVectorField_nifti_to_nrrd<double>(niiImage,nrrdImage);
            break;
        default:
            fprintf(stderr, "[NiftyReg ERROR] - reg_convertVectorField_nifti_to_nrrd - unsupported datatype\n");
            exit(1);
        }

        // The orientation flag are re-organised
        for(int i=niiImage->nu;i>0;--i){
            for(int j=0;j<niiImage->nu;++j){
                nrrdImage->axis[i].spaceDirection[j]=nrrdImage->axis[i-1].spaceDirection[j];
            }
            nrrdImage->axis[i].size=nrrdImage->axis[i-1].size;
            nrrdImage->axis[i].spacing=nrrdImage->axis[i-1].spacing;
            nrrdImage->axis[i].kind=nrrdKindDomain;
            nrrdImage->spaceUnits[i]=nrrdImage->spaceUnits[i-1];
        }
        nrrdImage->axis[0].size=niiImage->nu;
        nrrdImage->axis[0].spaceDirection[0]=std::numeric_limits<double>::quiet_NaN();
        nrrdImage->axis[0].spaceDirection[1]=std::numeric_limits<double>::quiet_NaN();
        nrrdImage->axis[0].spaceDirection[2]=std::numeric_limits<double>::quiet_NaN();
        nrrdImage->axis[0].kind=nrrdKindVector;
        nrrdImage->spaceUnits[0]=NULL;

        nrrdImage->dim=niiImage->nu+1;

        // Check if the image is a stationary field from NiftyReg
        if(strcmp(niiImage->intent_name,"NREG_VEL_STEP")==0){
            // The number of step is store in the nrrdImage->axis[0].label pointer
            char temp[64];
            sprintf(temp,"NREG_VEL_STEP %f",niiImage->intent_p1);
            std::string str=temp;
            if(nrrdImage->axis[0].label!=NULL) free(nrrdImage->axis[0].label);
            nrrdImage->axis[0].label=(char *)malloc(str.length()*sizeof(char));
            strcpy(nrrdImage->axis[0].label,str.c_str());

        }
        else if(strcmp(niiImage->intent_name,"NREG_CPP_FILE")==0){
            std::string str="NREG_CPP_FILE";
            if(nrrdImage->axis[0].label!=NULL) free(nrrdImage->axis[0].label);
            nrrdImage->axis[0].label=(char *)malloc(str.length()*sizeof(char));
            strcpy(nrrdImage->axis[0].label, str.c_str());
        }
    }
    else{
        // Copy the data from the nifti image to the nrrd image
        memcpy(nrrdImage->data, niiImage->data, niiImage->nvox*niiImage->nbyper);
    }

    return nrrdImage;
}