00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkParRecFileReader.h"
00020 #include <itkImageFileReader.h>
00021
00022 #ifdef __GNUC__
00023 #define stricmp strcasecmp
00024 #endif
00025
00026 void mitk::ParRecFileReader::GenerateOutputInformation()
00027 {
00028 mitk::Image::Pointer output = this->GetOutput();
00029
00030 if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime()))
00031 return;
00032
00033 itkDebugMacro(<<"Reading PAR file for GenerateOutputInformation()" << m_FileName);
00034
00035
00036
00037 if ( m_FileName == "" && m_FilePrefix == "" )
00038 {
00039 throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty");
00040 }
00041
00042 m_RecFileName = "";
00043 if( m_FileName != "")
00044 {
00045 int extPos=m_FileName.find_last_of(".");
00046 if(extPos>=-1)
00047 {
00048 const char *ext=m_FileName.c_str()+extPos+1;
00049 if(stricmp(ext,"par")==0)
00050 m_RecFileName = m_FileName.substr(0,extPos);
00051 else
00052 m_RecFileName = m_FileName;
00053 }
00054 else
00055 m_RecFileName = m_FileName;
00056
00057 m_RecFileName.append(".rec");
00058
00059 bool headerRead = false;
00060
00061 mitk::PixelType type;
00062 unsigned int dimension=0;
00063 unsigned int dimensions[4]={0,0,1,1};
00064 float sliceThickness=0.0;
00065 float sliceGap=0.0;
00066 float sliceSpacing=0.0;
00067 mitk::Vector3D thickness; thickness.Fill(1.0);
00068 mitk::Vector3D gap; gap.Fill(0.0);
00069 mitk::Vector3D spacing;
00070
00071 FILE *f;
00072 f=fopen(m_FileName.c_str(), "r");
00073 if(f!=NULL)
00074 {
00075 while(!feof(f))
00076 {
00077 char s[300], *p;
00078 char* ignored = fgets(s,200,f);
00079 ++ignored;
00080 if(strstr(s,"Max. number of cardiac phases"))
00081 {
00082 p=strchr(s,':')+1;
00083 dimensions[3]=atoi(p);
00084 if(dimensions[3]>1)
00085 dimension=4;
00086 }
00087 else
00088 if(strstr(s,"Max. number of slices/locations"))
00089 {
00090 p=strchr(s,':')+1;
00091 dimensions[2]=atoi(p);
00092 if(dimension==0)
00093 {
00094 if(dimensions[2]>1)
00095 dimension=3;
00096 else
00097 dimension=2;
00098 }
00099 }
00100 else
00101 if(strstr(s,"Image pixel size"))
00102 {
00103 p=strchr(s,':')+1;
00104 int bpe=atoi(p);
00105 if(bpe==8)
00106 type=typeid(mitkIpUInt1_t);
00107 else
00108 type=typeid(mitkIpUInt2_t);
00109 }
00110 else
00111 if(strstr(s,"Recon resolution"))
00112 {
00113 p=s+strcspn(s,"0123456789");
00114 sscanf(p,"%u %u", dimensions, dimensions+1);
00115 }
00116 else
00117 if(strstr(s,"FOV (ap,fh,rl) [mm]"))
00118 {
00119 p=s+strcspn(s,"0123456789");
00120 sscanf(p,"%f %f %f", &thickness[0], &thickness[1], &thickness[2]);
00121 }
00122 else
00123 if(strstr(s,"Slice thickness [mm]"))
00124 {
00125 p=s+strcspn(s,"0123456789");
00126 sscanf(p,"%f", &sliceThickness);
00127 }
00128 else
00129 if(strstr(s,"Slice gap [mm]"))
00130 {
00131 p=s+strcspn(s,"-0123456789");
00132 sscanf(p,"%f", &sliceGap);
00133 }
00134 }
00135 fclose(f);
00136
00137
00138 sliceSpacing = sliceThickness+sliceGap;
00139 if((dimension>0) && (dimensions[0]>0) && (dimensions[1]>0) && (sliceThickness>0) && (sliceSpacing>0))
00140 {
00141 headerRead = true;
00142 if(fabs(thickness[0]/dimensions[2]-sliceSpacing)<0.0001)
00143 thickness[0]=thickness[1];
00144 else
00145 if(fabs(thickness[1]/dimensions[2]-sliceSpacing)<0.0001)
00146 thickness[1]=thickness[0];
00147 thickness[2]=sliceSpacing;
00148
00149 thickness[0]/=dimensions[0];
00150 thickness[1]/=dimensions[1];
00151 spacing=thickness+gap;
00152 }
00153 }
00154
00155 if( headerRead == false)
00156 {
00157 itk::ImageFileReaderException e(__FILE__, __LINE__);
00158 itk::OStringStream msg;
00159 msg << " Could not read file "
00160 << m_FileName.c_str();
00161 e.SetDescription(msg.str().c_str());
00162 throw e;
00163 return;
00164 }
00165
00166 output->Initialize(type, dimension, dimensions);
00167 output->GetSlicedGeometry()->SetSpacing(spacing);
00168
00169
00170 output->GetSlicedGeometry()->SetEvenlySpaced();
00171 }
00172
00173 m_ReadHeaderTime.Modified();
00174 }
00175
00176 void mitk::ParRecFileReader::GenerateData()
00177 {
00178 mitk::Image::Pointer output = this->GetOutput();
00179
00180
00181
00182 if ( m_RecFileName == "" )
00183 {
00184 throw itk::ImageFileReaderException(__FILE__, __LINE__, "FileName for rec-file empty");
00185 }
00186
00187 if( m_RecFileName != "")
00188 {
00189 FILE *f = fopen(m_RecFileName.c_str(), "r");
00190 if(f==NULL)
00191 {
00192 throw itk::ImageFileReaderException(__FILE__, __LINE__, "Could not open rec-file.");
00193 }
00194
00195 int zstart, zmax;
00196 int tstart, tmax;
00197
00198 zstart=output->GetRequestedRegion().GetIndex(2);
00199 tstart=output->GetRequestedRegion().GetIndex(3);
00200
00201 zmax=zstart+output->GetRequestedRegion().GetSize(2);
00202 tmax=tstart+output->GetRequestedRegion().GetSize(3);
00203
00204 int sliceSize=output->GetDimension(0)*output->GetDimension(1)*output->GetPixelType().GetBpe()/8;
00205 void *data = malloc(sliceSize);
00206
00207 bool ignore4Dtopogram=false;
00208 {
00209 int slicePlusTimeSize=output->GetDimension(0)*output->GetDimension(1)*output->GetDimension(3)*output->GetPixelType().GetBpe()/8;
00210 if(output->GetDimension(3)>1)
00211 ignore4Dtopogram=true;
00212
00213 int z,t;
00214 for(t=tstart;t<tmax;++t)
00215 for(z=zstart;z<zmax;++z)
00216 {
00217 if(ignore4Dtopogram)
00218 fseek(f,slicePlusTimeSize*z+(sliceSize+1)*t,SEEK_SET);
00219 else
00220 fseek(f,slicePlusTimeSize*z+sliceSize*t,SEEK_SET);
00221 size_t ignored = fread(data, sliceSize, 1, f);
00222 ++ignored;
00223 output->SetSlice(data,z,t,0);
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 free(data);
00236
00237 fclose(f);
00238 }
00239 }
00240
00241 bool mitk::ParRecFileReader::CanReadFile(const std::string filename, const std::string , const std::string )
00242 {
00243
00244 if( filename == "" )
00245 {
00246
00247 return false;
00248 }
00249
00250 bool extensionFound = false;
00251 std::string::size_type PARPos = filename.rfind(".par");
00252 if ((PARPos != std::string::npos)
00253 && (PARPos == filename.length() - 4))
00254 {
00255 extensionFound = true;
00256 }
00257
00258 PARPos = filename.rfind(".PAR");
00259 if ((PARPos != std::string::npos)
00260 && (PARPos == filename.length() - 4))
00261 {
00262 extensionFound = true;
00263 }
00264
00265 if( !extensionFound )
00266 {
00267
00268 return false;
00269 }
00270
00271 return true;
00272 }
00273
00274 mitk::ParRecFileReader::ParRecFileReader()
00275 : m_FileName(""), m_FilePrefix(""), m_FilePattern("")
00276 {
00277 }
00278
00279 mitk::ParRecFileReader::~ParRecFileReader()
00280 {
00281 }