19 #include <vnl/vnl_vector.h>
23 #define MINC2_MAXDIM 15
24 #define MINC2_MAXUSE 5
30 itkDebugMacro(<<
"No filename specified.");
36 if (miopen_volume(file,MI2_OPEN_READ,&volume)< 0)
38 itkDebugMacro(<<
" Can not open File:" << file <<
"\n");
41 if (miclose_volume(volume) < 0)
43 itkDebugMacro(<<
" Can not close File:" << file <<
"\n");
55 if (miopen_volume(
m_FileName.c_str(),MI2_OPEN_READ,&volume)< 0)
58 itkDebugMacro(
"Could not open file \"" <<
m_FileName.c_str() <<
"\".");
61 mitype_t volume_data_type;
62 if(miget_data_type(volume,&volume_data_type) < 0)
64 itkDebugMacro(
" Can not get volume data type!!\n");
66 int slice_scaling_flag;
68 if (miget_slice_scaling_flag(volume, &slice_scaling_flag) < 0)
70 itkDebugMacro(
" Can not get slice scaling flag!!\n");
72 double valid_max, valid_min;
74 if(miget_volume_valid_range(volume,&valid_max,&valid_min) <0)
76 itkDebugMacro(
" Can not get valid max or min!!\n");
79 miclass_t volume_data_class;
80 if(miget_data_class(volume,&volume_data_class) < 0)
82 itkDebugMacro(
" Can not get volume data class!!\n");
90 unsigned int usefulDimensions = 0;
102 midimhandle_t *hdims =
new midimhandle_t[usefulDimensions];
103 if(miget_volume_dimensions(volume,MI_DIMCLASS_ANY, MI_DIMATTR_REGULARLY_SAMPLED,MI_DIMORDER_FILE, this->
m_NDims, hdims) < 0)
105 itkDebugMacro(
" Can not get dimension handles!!\n");
109 midimhandle_t *apparent_order =
new midimhandle_t[usefulDimensions];
113 for( i = 0; i < 5; i++ )
123 for( i = 0; i < usefulDimensions; i++ )
128 if(miset_apparent_dimension_order(volume,usefulDimensions ,apparent_order) < 0)
130 itkDebugMacro(
" Can not get apparent dimension order!!\n");
137 delete [] apparent_order;
140 for( i = 0; i < (this->
m_NDims-usefulDimensions); i++ )
158 if( usefulDimensions == 5 )
161 unsigned int icount = count[i];
162 if( miget_dimension_size(apparent_order[3], &icount) < 0 )
164 itkDebugMacro(
" Can not get dimension size \n");
170 if (miget_dimension_size(apparent_order[4], &icount) < 0)
172 itkDebugMacro(
" Can not get dimension size \n");
176 if (usefulDimensions == 4)
179 unsigned int icount = count[i];
180 if (miget_dimension_size(apparent_order[3], &icount) < 0)
182 itkDebugMacro(
" Can not get dimension size \n");
188 switch (volume_data_class)
191 case MI_CLASS_COMPLEX:
193 if( slice_scaling_flag )
196 if( miget_real_value_hyperslab(volume, volume_data_type, start, count,buffer) < 0 )
198 itkDebugMacro(
" Can not get real value hyperslab!!\n");
203 if( miget_voxel_value_hyperslab(volume, volume_data_type, start, count,buffer) < 0 )
205 itkDebugMacro(
" Can not get voxel value hyperslabs!!\n");
210 if( miget_voxel_value_hyperslab(volume, volume_data_type, start, count,buffer) < 0 )
212 itkDebugMacro(
" Can not get voxel value hyperslabs!!\n");
215 case MI_CLASS_UNIFORM_RECORD:
217 itkDebugMacro(
" Leave this until minc2.0 support it complete!!\n");
223 if( miclose_volume(volume)< 0 )
225 itkDebugMacro(
" Can not close volume!\n");
270 os << indent <<
"NDims: " <<
m_NDims << std::endl;
279 if (miopen_volume(
m_FileName.c_str(),MI2_OPEN_READ,&volume)< 0)
282 itkDebugMacro(
"Could not open file \"" <<
m_FileName.c_str() <<
"\".");
288 int numberOfDimensions;
289 if(miget_volume_dimension_count(volume, MI_DIMCLASS_ANY, MI_DIMATTR_REGULARLY_SAMPLED, &numberOfDimensions) < 0)
291 itkDebugMacro(
"Could not get the number of dimensions in the volume!");
294 m_NDims =
static_cast<unsigned int>( numberOfDimensions );
299 itkDebugMacro(
"Number of dimensions exceeds expectation!");
304 midimhandle_t *hdims =
new midimhandle_t[
m_NDims];
305 if(miget_volume_dimensions(volume,MI_DIMCLASS_ANY, MI_DIMATTR_REGULARLY_SAMPLED,MI_DIMORDER_FILE,
m_NDims, hdims) < 0)
307 itkDebugMacro(
"Could not get dimension handles!");
318 if (miget_dimension_name(hdims[i],&name) < 0 )
321 itkDebugMacro(
"Could not get dimension name!");
331 unsigned int *sizes =
new unsigned int[
m_NDims];
332 if (miget_dimension_sizes(hdims, m_NDims, sizes) < 0 )
335 itkDebugMacro(
"Could not get dimension sizes!");
344 unsigned int numberOfComponents = 1;
348 if(miget_dimension_separations(hdims, MI_ORDER_FILE, m_NDims, separations) < 0)
350 itkDebugMacro(
" Could not dimension sizes");
354 if(miget_dimension_starts(hdims, MI_ORDER_FILE, this->m_NDims, starts) < 0)
356 itkDebugMacro(
" Could not dimension sizes");
362 int j=this->m_NDims - 1;
363 for (i=0; i < this->
m_NDims; i++)
373 vnl_vector<double> row(3),column(3), slice(3);
384 if ( this->m_NDims > 2 )
392 mitype_t volume_data_type;
393 if(miget_data_type(volume,&volume_data_type) < 0)
395 itkDebugMacro(
" Can not get volume data type!!\n");
398 switch (volume_data_type)
424 case MI_TYPE_SCOMPLEX:
427 case MI_TYPE_ICOMPLEX:
430 case MI_TYPE_FCOMPLEX:
433 case MI_TYPE_DCOMPLEX:
437 itkDebugMacro(
"Bad data type ");
444 int slice_scaling_flag;
445 if (miget_slice_scaling_flag(volume, &slice_scaling_flag) < 0)
447 itkDebugMacro(
" Can not get slice scaling flag!!\n");
449 miclass_t volume_data_class;
451 if(miget_data_class(volume,&volume_data_class) < 0)
453 itkDebugMacro(
" Could not get data class");
456 switch (volume_data_class)
460 if( !(volume_data_type == MI_TYPE_FLOAT || volume_data_type == MI_TYPE_DOUBLE) )
462 if(slice_scaling_flag)
474 if( slice_scaling_flag )
487 case MI_CLASS_COMPLEX:
490 numberOfComponents *= 2;
493 itkDebugMacro(
"Bad data class ");
500 if (miclose_volume(volume)< 0)
503 itkDebugMacro(
"Could not close file \"" <<
m_FileName.c_str() <<
"\".");
527 std::string filename = name;
530 std::transform( filename.begin(), filename.end(), filename.begin(), (int(*)(int)) std::tolower );
534 itkDebugMacro(<<
"No filename specified.");
538 std::string::size_type mncPos = filename.rfind(
".mnc");
539 if ( (mncPos != std::string::npos)
541 && (mncPos == filename.length() - 4) )
546 mncPos = filename.rfind(
".mnc2");
547 if ( (mncPos != std::string::npos)
549 && (mncPos == filename.length() - 5) )
562 std::cout <<
"WriteImageInformation" << std::endl;
566 template <
class TBuffer>
567 void MINCComputeScalarRange(
int itkNotUsed(Strides)[3],
int Sizes[3],
int nComponents,
double& maxval,
double& minval,TBuffer *buffer)
576 double tmpminval = 1000.0;
577 double tmpmaxval = 0.0;
580 for( idZ = 0; idZ < Sizes[2]; idZ++ )
582 for( idY = 0; idY < Sizes[1]; idY++ )
584 for( idX = 0; idX < Sizes[0]*nComponents; idX++ )
586 TBuffer val = *buffer++;
606 template<
class TBuffer>
610 const unsigned long start[],
611 const unsigned long count[],
619 unsigned long size = 1;
621 for (i = 1; i < ndims; i++)
623 tmpstart[i] = start[i];
625 tmpcount[i] = count[i];
627 size = size*count[i];
631 TBuffer *tmpbuffer =
new TBuffer[size];
632 for (i = 0; i < count[0]; i++)
639 for (j = 0; j < size; j++)
641 tmpbuffer[j] = buffer[j];
645 miset_voxel_value_hyperslab(volume, minctype,
646 tmpstart, tmpcount, tmpbuffer);
667 vnl_matrix<double> dircosmatrix(3,3);
668 for( i = 0; i < 3; i++ )
670 for( j = 0; j < 3; j++ )
676 vnl_matrix<double> inverseDirectionCosines=vnl_matrix_inverse<double>(dircosmatrix);
687 for( i = 0; i < 3; i++ )
698 itkDebugMacro(
"MINC does not support 8-bit complex types");
703 itkDebugMacro(
"MINC does not support unsigned complex types");
737 const char *vname =
"vector_dimension";
738 const char *tname =
"tspace";
739 const char *xname =
"xspace";
740 const char *yname =
"yspace";
741 const char *zname =
"zspace";
762 else if (dimchar ==
't')
771 else if (dimchar ==
'x')
776 else if (dimchar ==
'y')
781 else if (dimchar ==
'z')
809 if ((tsize == 0 ? 1 : tsize)*(vsize == 0 ? 1 : vsize)*
810 (usize == 0 ? 1 : usize)*csize != ncomp)
816 int dimprod = (usize == 0 ? 1 : usize)*(tsize == 0 ? 1 : tsize)*csize;
818 if (ncomp % dimprod != 0)
820 itkDebugMacro(
"Write: Product of non-spatial dimension sizes does not match number of scalar components: " << tsize <<
"*" << usize*csize <<
"!=" << ncomp);
830 for (cp = userdimorder; *cp !=
'\0'; cp++)
845 vsize = ncomp/dimprod;
851 for (cp = userdimorder; *cp !=
'\0'; cp++)
854 if (dimchar == xname[0] || dimchar == yname[0] || dimchar == zname[0])
856 userdimorder[i++] = dimchar;
858 else if ((dimchar == tname[0] && tsize != 0) ||
859 (dimchar == vname[0] && vsize != 0))
861 userdimorder[i++] = dimchar;
869 userdimorder[i++] = dimchar;
878 itkDebugMacro(
"Failed sanity check: i != ndims (" <<
879 i <<
"!=" << ndims <<
")");
883 userdimorder[i++] =
'\0';
894 for (i = 0; i < ndims; i++)
896 unsigned long dimsize = 0;
897 midimclass_t dimclass = MI_DIMCLASS_ANY;
898 const char *dimname = 0;
899 int dimchar = userdimorder[i];
900 double dimseparation = 1.0;
901 double dimstart = 0.0;
903 if( dimchar == xname[0] || dimchar == yname[0] || dimchar == zname[0] )
905 if( dimchar == xname[0] )
912 else if (dimchar == yname[0])
926 dimclass = MI_DIMCLASS_SPATIAL;
927 if( strcmp(&dimname[1],
"frequency") == 0 )
929 dimclass = MI_DIMCLASS_SFREQUENCY;
932 else if (dimchar == tname[0] && tsize != 0)
936 dimclass = MI_DIMCLASS_TIME;
937 if( strcmp(&dimname[1],
"frequency") == 0 )
939 dimclass = MI_DIMCLASS_TFREQUENCY;
942 else if (dimchar == vname[0] && vsize != 0)
946 dimclass = MI_DIMCLASS_RECORD;
957 dimclass = MI_DIMCLASS_USER;
963 micreate_dimension(dimname, dimclass, MI_DIMATTR_REGULARLY_SAMPLED,dimsize, &dim[i]);
966 if (dimclass == MI_DIMCLASS_SPATIAL || dimclass == MI_DIMCLASS_SFREQUENCY)
968 miset_dimension_units(dim[i],
"mm");
969 miset_dimension_start(dim[i], dimstart);
970 miset_dimension_separation(dim[i], dimseparation);
974 if( dimname[0] ==
'x' )
980 else if ( dimname[0] ==
'y' )
986 else if ( dimname[0] ==
'z' )
993 miset_dimension_cosines(dim[i], dircos);
995 else if (dimclass == MI_DIMCLASS_TIME || dimclass == MI_DIMCLASS_TFREQUENCY)
997 miset_dimension_units(dim[i],
"s");
1006 minctype = MI_TYPE_BYTE;
1009 minctype = MI_TYPE_UBYTE;
1012 minctype = MI_TYPE_SHORT;
1015 minctype = MI_TYPE_USHORT;
1018 minctype = MI_TYPE_INT;
1021 minctype = MI_TYPE_UINT;
1024 minctype = MI_TYPE_FLOAT;
1027 minctype = MI_TYPE_DOUBLE;
1030 itkDebugMacro(
"Bad data type ");
1035 miclass_t mincclass = MI_CLASS_REAL;
1038 mincclass = MI_CLASS_COMPLEX;
1041 result = micreate_volume(
m_FileName.c_str(), ndims, dim, minctype , mincclass,
NULL,&volume);
1044 result = micreate_volume_image(volume);
1049 for (i = 0; i < ndims; i++)
1051 mifree_dimension_handle(dim[i]);
1053 itkDebugMacro(
"Couldn't open minc file " <<
m_FileName.c_str());
1059 dimnames[i] = zname; counts[i] = zsize; offsets[i++] = 0;
1060 dimnames[i] = yname; counts[i] = ysize; offsets[i++] = 0;
1061 dimnames[i] = xname; counts[i] = xsize; offsets[i++] = 0;
1064 dimnames[i] = tname; counts[i] = tsize; offsets[i++] = 0;
1084 dimnames[i] = vname;
1090 for (i = 0; i < ndims; i++)
1092 dimorder[i] = dimnames[i][0];
1094 dimorder[ndims] =
'\0';
1096 if (strcmp(dimorder, userdimorder) != 0)
1098 miset_apparent_dimension_order_by_name(volume, ndims, (
char **)dimnames);
1105 minctype = MI_TYPE_BYTE;
1109 minctype = MI_TYPE_UBYTE;
1110 MINCWriteHyperSlab(volume, ndims, minctype, offsets, counts,(
unsigned char *)buffer);
1113 minctype = MI_TYPE_SHORT;
1117 minctype = MI_TYPE_USHORT;
1118 MINCWriteHyperSlab(volume, ndims, minctype, offsets, counts,(
unsigned short *)buffer);
1121 minctype = MI_TYPE_INT;
1125 minctype = MI_TYPE_UINT;
1129 minctype = MI_TYPE_FLOAT;
1133 minctype = MI_TYPE_DOUBLE;
1137 itkDebugMacro(
"Bad data type ");
1142 if (mincclass == MI_CLASS_REAL &&
1143 minctype != MI_TYPE_FLOAT && minctype != MI_TYPE_DOUBLE)
1146 double minval, maxval;
1170 case MI_TYPE_USHORT:
1180 itkDebugMacro(
"Bad data type ");
1183 miset_volume_valid_range(volume, maxval, minval);
1186 miclose_volume(volume);
1187 for (i = 0; i < ndims; i++)
1189 mifree_dimension_handle(dim[i]);
1199 unsigned long * coords=
new(
unsigned long[this->
m_NDims]);
1200 double slice_max, slice_min;
1201 double max=-1e300, min=1e300;
1202 double valid_max, valid_min;
1204 if(miget_volume_valid_range(volume,&valid_max,&valid_min) <0)
1206 itkDebugMacro(
"Could not get volume valid range ");
1210 mitype_t volume_data_type;
1212 if(miget_data_type(volume,&volume_data_type) < 0)
1214 itkDebugMacro(
" Can not get volume data type!!\n");
1218 for(i = 0; i < this->
m_NDims; i++)
1226 for( i = 0; i < this->
GetDimensions(this->m_NDims - 1); i++ )
1229 if ( this->m_NDims > 3 )
1234 if (miget_slice_range(volume, coords, this->m_NDims, &slice_max, &slice_min) < 0)
1236 itkDebugMacro(
"Could not get slice range");
1240 if (slice_min < min)
1244 if (slice_max > max)
1252 if (miget_slice_range(volume, coords, this->m_NDims, &slice_max, &slice_min) < 0)
1254 itkDebugMacro(
"Could not get slice range");
1257 if (slice_min < min)
1261 if (slice_max > max)
1267 m_Scale = (max-min)/(valid_max - valid_min);
1274 double volume_max, volume_min;
1275 double valid_max, valid_min;
1277 if(miget_volume_valid_range(volume,&valid_max,&valid_min) <0)
1279 itkDebugMacro(
"Could not get volume valid range ");
1282 if(miget_volume_range(volume,&volume_max,&volume_min) < 0)
1284 itkDebugMacro(
"Could not get volume range");
1288 m_Scale = (volume_max-volume_min)/(valid_max-valid_min);
1296 midimclass_t dim_class;
1297 double direction_cosines[3];
1298 double dircos[3][3] = { { 1, 0, 0},
1306 unsigned int counter=0;
1307 unsigned int counter2=5;
1309 for(i=0; i < this->
m_NDims; i++)
1311 if(miget_dimension_class(hdims[i],&dim_class) < 0)
1314 itkDebugMacro(
"Could not get dim class\"" <<
m_FileName.c_str() <<
"\".");
1320 case MI_DIMCLASS_SPATIAL:
1321 case MI_DIMCLASS_SFREQUENCY:
1324 if (miget_dimension_cosines(hdims[i],direction_cosines) < 0)
1327 itkDebugMacro(
"Could not getdirection cosines!");
1332 dircos[0][counter] = direction_cosines[0];
1333 dircos[1][counter] = direction_cosines[1];
1334 dircos[2][counter] = direction_cosines[2];
1335 dim_indices[counter]=i;
1338 case MI_DIMCLASS_TIME:
1339 case MI_DIMCLASS_TFREQUENCY:
1344 case MI_DIMCLASS_RECORD:
1348 case MI_DIMCLASS_ANY:
1349 case MI_DIMCLASS_USER:
1350 dim_indices[counter2] = i;
1371 if((dircos[2][0] >= dircos[2][1]) && (dircos[2][0] >= dircos[2][2]))
1378 if( dircos[1][1] >= dircos[1][2] )
1389 temp = dim_indices[1];
1390 dim_indices[1] = dim_indices[2];
1391 dim_indices[2] = temp;
1400 else if ((dircos[2][1] >= dircos[2][0]) && (dircos[2][1] >= dircos[2][2]))
1405 temp = dim_indices[0];
1406 dim_indices[0] = dim_indices[1];
1407 if( dircos[1][0] >= dircos[1][2] )
1409 dim_indices[1] = temp;
1419 dim_indices[1] = dim_indices[2];
1420 dim_indices[2] = temp;
1434 temp = dim_indices[0];
1435 dim_indices[0] = dim_indices[2];
1436 if( dircos[1][0] >= dircos[1][1] )
1438 dim_indices[2] = dim_indices[1];
1439 dim_indices[1] = temp;
1449 dim_indices[2] = temp;
1478 for(j = 0; j < i; j++)
1480 if (userdimorder[i] == userdimorder[j])
1482 itkDebugMacro(
"Invalid DimensionOrder " << userdimorder);
1492 int dimchar = userdimorder[i];
1494 if (dimchar !=
'x' && dimchar !=
'y' && dimchar !=
'z')
1504 if (j == MINC2_MAXDIM)
1506 memmove(&userdimorder[i],&userdimorder[i+1],MINC2_MAXDIM-i-1);
1507 userdimorder[MINC2_MAXDIM-1] =
'\0';
1514 static const char *spatial =
"xyz";
1515 for (i = 0; i < 3; i++)
1517 int dimchar = spatial[i];
1520 for (j = 0; userdimorder[j] && j <= MINC2_MAXDIM-1; j++)
1522 if( userdimorder[j] == dimchar )
1530 memmove(&userdimorder[1],&userdimorder[0],MINC2_MAXDIM-1);
1531 userdimorder[0] = dimchar;
1546 for (j = 0; userdimorder[j] && j <= MINC2_MAXDIM-1; j++)
1548 if (userdimorder[j] == dimchar)
1558 memmove(&userdimorder[1],&userdimorder[0],MINC2_MAXDIM-1);
1559 userdimorder[0] = dimchar;
1563 userdimorder[j] = dimchar;