/*------------------------------------------------------*/ 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() */
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; }