diff --git a/Modules/IOExt/Internal/mitkParRecFileReader.cpp b/Modules/IOExt/Internal/mitkParRecFileReader.cpp index 87998a1165..c76470e697 100644 --- a/Modules/IOExt/Internal/mitkParRecFileReader.cpp +++ b/Modules/IOExt/Internal/mitkParRecFileReader.cpp @@ -1,278 +1,280 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkParRecFileReader.h" #include <itkImageFileReader.h> #include <mitkLocaleSwitch.h> #ifdef __GNUC__ #define stricmp strcasecmp #endif void mitk::ParRecFileReader::GenerateOutputInformation() { mitk::Image::Pointer output = this->GetOutput(); if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime())) return; itkDebugMacro(<< "Reading PAR file for GenerateOutputInformation()" << m_FileName); // Check to see if we can read the file given the name or prefix // if (m_FileName == "" && m_FilePrefix == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); } m_RecFileName = ""; if (m_FileName != "") { int extPos = m_FileName.find_last_of("."); if (extPos >= -1) { const char *ext = m_FileName.c_str() + extPos + 1; if (stricmp(ext, "par") == 0) m_RecFileName = m_FileName.substr(0, extPos); else m_RecFileName = m_FileName; } else m_RecFileName = m_FileName; m_RecFileName.append(".rec"); bool headerRead = false; bool signedCharType = true; unsigned int dimension = 0; unsigned int dimensions[4] = {0, 0, 1, 1}; float sliceThickness = 0.0; float sliceGap = 0.0; float sliceSpacing = 0.0; mitk::Vector3D thickness; thickness.Fill(1.0); mitk::Vector3D gap; gap.Fill(0.0); mitk::Vector3D spacing; FILE *f; f = fopen(m_FileName.c_str(), "r"); if (f != nullptr) { while (!feof(f)) { char s[300], *p; - fgets(s, 200, f); + if (fgets(s, 200, f) == nullptr) + throw itk::ImageFileReaderException(__FILE__, __LINE__, "Could not read header"); if (strstr(s, "Max. number of cardiac phases")) { p = strchr(s, ':') + 1; dimensions[3] = atoi(p); if (dimensions[3] > 1) dimension = 4; } else if (strstr(s, "Max. number of slices/locations")) { p = strchr(s, ':') + 1; dimensions[2] = atoi(p); if (dimension == 0) { if (dimensions[2] > 1) dimension = 3; else dimension = 2; } } else if (strstr(s, "Image pixel size")) { p = strchr(s, ':') + 1; int bpe = atoi(p); if (bpe != 8) signedCharType = false; } else if (strstr(s, "Recon resolution")) { p = s + strcspn(s, "0123456789"); sscanf(p, "%u %u", dimensions, dimensions + 1); } else if (strstr(s, "FOV (ap,fh,rl) [mm]")) { p = s + strcspn(s, "0123456789"); mitk::LocaleSwitch localeSwitch("C"); sscanf(p, "%lf %lf %lf", &thickness[0], &thickness[1], &thickness[2]); } else if (strstr(s, "Slice thickness [mm]")) { p = s + strcspn(s, "0123456789"); mitk::LocaleSwitch localeSwitch("C"); sscanf(p, "%f", &sliceThickness); } else if (strstr(s, "Slice gap [mm]")) { p = s + strcspn(s, "-0123456789"); mitk::LocaleSwitch localeSwitch("C"); sscanf(p, "%f", &sliceGap); } } fclose(f); // C:\home\ivo\data\coronaries\ucsf-wholeheart-2.par sliceSpacing = sliceThickness + sliceGap; if ((dimension > 0) && (dimensions[0] > 0) && (dimensions[1] > 0) && (sliceThickness > 0) && (sliceSpacing > 0)) { headerRead = true; if (fabs(thickness[0] / dimensions[2] - sliceSpacing) < 0.0001) thickness[0] = thickness[1]; else if (fabs(thickness[1] / dimensions[2] - sliceSpacing) < 0.0001) thickness[1] = thickness[0]; thickness[2] = sliceSpacing; thickness[0] /= dimensions[0]; thickness[1] /= dimensions[1]; spacing = thickness + gap; } } if (headerRead == false) { itk::ImageFileReaderException e(__FILE__, __LINE__); std::ostringstream msg; msg << " Could not read file " << m_FileName.c_str(); e.SetDescription(msg.str().c_str()); throw e; return; } // define types mitk::PixelType SCType = mitk::MakeScalarPixelType<signed char>(); mitk::PixelType SSType = mitk::MakeScalarPixelType<signed short>(); if (signedCharType) output->Initialize(SCType, dimension, dimensions); else output->Initialize(SSType, dimension, dimensions); output->GetSlicedGeometry()->SetSpacing(spacing); // output->GetSlicedGeometry()->SetPlaneGeometry(mitk::Image::BuildStandardPlanePlaneGeometry(output->GetSlicedGeometry(), // dimensions).GetPointer(), 0); output->GetSlicedGeometry()->SetEvenlySpaced(); } m_ReadHeaderTime.Modified(); } void mitk::ParRecFileReader::GenerateData() { mitk::Image::Pointer output = this->GetOutput(); // Check to see if we can read the file given the name or prefix // if (m_RecFileName == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "FileName for rec-file empty"); } if (m_RecFileName != "") { FILE *f = fopen(m_RecFileName.c_str(), "r"); if (f == nullptr) { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Could not open rec-file."); } int zstart, zmax; int tstart, tmax; zstart = output->GetRequestedRegion().GetIndex(2); tstart = output->GetRequestedRegion().GetIndex(3); zmax = zstart + output->GetRequestedRegion().GetSize(2); tmax = tstart + output->GetRequestedRegion().GetSize(3); int sliceSize = output->GetDimension(0) * output->GetDimension(1) * output->GetPixelType().GetBpe() / 8; void *data = malloc(sliceSize); bool ignore4Dtopogram = false; { int slicePlusTimeSize = output->GetDimension(0) * output->GetDimension(1) * output->GetDimension(3) * output->GetPixelType().GetBpe() / 8; if (output->GetDimension(3) > 1) ignore4Dtopogram = true; int z, t; for (t = tstart; t < tmax; ++t) for (z = zstart; z < zmax; ++z) { if (ignore4Dtopogram) fseek(f, slicePlusTimeSize * z + (sliceSize + 1) * t, SEEK_SET); else fseek(f, slicePlusTimeSize * z + sliceSize * t, SEEK_SET); - fread(data, sliceSize, 1, f); + if(fread(data, sliceSize, 1, f) < 1) + throw itk::ImageFileReaderException(__FILE__, __LINE__, "Could not read slice."); output->SetSlice(data, z, t, 0); } } // else //{ // for(;z<zmax;++z) // { // fseek(f,sliceSize*z,SEEK_SET); // fread(data, sliceSize, 1, f); // output->SetSlice(data,z,0,0); // } //} free(data); fclose(f); } } bool mitk::ParRecFileReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/) { // First check the extension if (filename == "") { // MITK_INFO<<"No filename specified."<<std::endl; return false; } bool extensionFound = false; std::string::size_type PARPos = filename.rfind(".par"); if ((PARPos != std::string::npos) && (PARPos == filename.length() - 4)) { extensionFound = true; } PARPos = filename.rfind(".PAR"); if ((PARPos != std::string::npos) && (PARPos == filename.length() - 4)) { extensionFound = true; } if (!extensionFound) { // MITK_INFO<<"The filename extension is not recognized."<<std::endl; return false; } return true; } mitk::ParRecFileReader::ParRecFileReader() : m_FileName(""), m_FilePrefix(""), m_FilePattern("") { } mitk::ParRecFileReader::~ParRecFileReader() { }